首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >映射函数中的setState嵌套对象

映射函数中的setState嵌套对象
EN

Stack Overflow用户
提问于 2021-12-02 15:33:19
回答 3查看 46关注 0票数 0

我的State对象是一个保存objects.PS的数组:(可以随意更改结构)下面是结构:

代码语言:javascript
复制
    {
        type: ListOfTypes[Math.floor(Math.random() * ListOfTypes.length)],
        name: ListOfNames[Math.floor(Math.random() * ListOfNames.length)],
        id:  nanoid(),
        channels: [
            {
                id:  nanoid(),
                Name: ListOfChannels[Math.floor(Math.random() * ListOfChannels.length)],
                Files: [ { folder: "Folder",  documents: [ { doc: "WordDoc1.doc", isChecked: false, id:nanoid() }, { doc: "WordDoc2.doc", isChecked: false, id:nanoid() }, { doc: "WordDoc3.doc", isChecked: false, id:nanoid() }, { doc: "WordDoc4.doc", isChecked: false, id:nanoid() }] }, ],
            },
            {
                id:  nanoid(),
                Name: ListOfChannels[Math.floor(Math.random() * ListOfChannels.length)],
                Files: [{ folder: "Folder",  documents: [ { doc: "WordDoc1.doc", isChecked: false, id:nanoid() }, { doc: "WordDoc2.doc", isChecked: false, id:nanoid() }, { doc: "WordDoc3.doc", isChecked: false, id:nanoid() }, { doc: "WordDoc4.doc", isChecked: false, id:nanoid() }] }, ],
            },
            {
                id:  nanoid(),
                Name: ListOfChannels[Math.floor(Math.random() * ListOfChannels.length)],
                Files: [{ folder: "Folder", documents: [ { doc: "WordDoc1.doc", isChecked: false, id:nanoid() }, { doc: "WordDoc2.doc", isChecked: false, id:nanoid() }, { doc: "WordDoc3.doc", isChecked: false, id:nanoid() }, { doc: "WordDoc4.doc", isChecked: false, id:nanoid() }] }, ],
            }
        ]
    }

我想要更改每个通道对象中的所有isChecked,目前我正在使用此函数,但它不能按预期工作。

代码语言:javascript
复制
const handleChange = () => {

    const ConnectionsArray = List.map( (connection) => connection.id == connectionId ?
        {
            ...connection,
            channels: connection.channels.map( (channel) =>  channel.Name == channelName ? {
                ...channel,
                Files: channel.Files.map((file) => ({
                    ...file,
                    documents: file.documents.map((doc) => ({ ...doc, isChecked: !doc.isChecked }) )
                }))

            } : channel)
        } : connection)

    setList(ConnectionsArray)

};
EN

回答 3

Stack Overflow用户

发布于 2021-12-02 15:42:05

这应该可以做到:

代码语言:javascript
复制
function toggleChecked (connections) {
  return connections.map(connection => (connection.id === connectionId
    ? {
      ...connection,
      channels: connection.channels.map(channel => (channel.Name === channelName
        ? {
          ...channel,
          Files: channel.Files.map(file => ({
            ...file,
            documents: file.documents.map(doc => ({
              ...doc,
              isChecked: !doc.isChecked,
            })),
          })),
        }
        : channel)),
    }
    : connection));
}

像这样使用:

代码语言:javascript
复制
setList(list => toggleChecked(list));

下面是另一个帮助从数组中获取随机项的函数(我注意到您在代码中重复了很多数学表达式来完成此操作):

代码语言:javascript
复制
function getRandomElement (array) {
  return array[Math.floor(Math.random() * array.length)];
}

像这样使用:

代码语言:javascript
复制
// before
ListOfTypes[Math.floor(Math.random() * ListOfTypes.length)]

// after
getRandomElement(ListOfTypes)
票数 1
EN

Stack Overflow用户

发布于 2021-12-02 15:48:23

也许是学习如何使用"immer“库的好时机。它非常适合这样的情况,在这种情况下,您需要对嵌套过深的对象进行更改。如果没有它,对像您正在处理的对象进行更改将变得非常混乱和难以处理。

Immer很容易上手,一两天就能学会。如果你使用它,你的代码可以简化为:

代码语言:javascript
复制
import produce from 'immer';

const handleChange = ()=>{
    const ConnectionsArray = produce(List, draft=>{
        draft.forEach((object)=>{
            object.channels.forEach((channel)=>{
                channel.Files.forEach((file)=>{
                    file.documents.forEach((document)=>{
                        document.isChecked = !document.isChecked;
                    })
                })
            })
        })
    })
}

我没有运行这段代码,所以不是百分之百确定它能正常工作。无论哪种方式,类似于immer的东西都会工作,并且更容易处理。请注意,您不必处理扩展语法或任何其他语法,immer实际上将创建一个新对象,因此它避免了与可变数据相关的任何令人头疼的问题。

票数 1
EN

Stack Overflow用户

发布于 2021-12-02 15:44:53

请检查以下内容:

代码语言:javascript
复制
const handleChange = () => {
    setList(prevState => {
        let ConnectionsArray = [...prevState];
        const itemIndex = ConnectionsArray.find(item => item.id === connectionId);
        const connection = {...ConnectionsArray[itemIndex]};
        ConnectionsArray[itemIndex] =  {
            ...connection,
            channels: connection.channels.map( (channel) =>  channel.Name == channelName ? {
                ...channel,
                Files: channel.Files.map((file) => ({
                    ...file,
                    documents: file.documents.map((doc) => ({ ...doc, isChecked: !doc.isChecked }) )
                }))

            } : channel)
        };
        return ConnectionsArray;
    })
};
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70202252

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档