我的State对象是一个保存objects.PS的数组:(可以随意更改结构)下面是结构:
{
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,目前我正在使用此函数,但它不能按预期工作。
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)
};发布于 2021-12-02 15:42:05
这应该可以做到:
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));
}像这样使用:
setList(list => toggleChecked(list));下面是另一个帮助从数组中获取随机项的函数(我注意到您在代码中重复了很多数学表达式来完成此操作):
function getRandomElement (array) {
return array[Math.floor(Math.random() * array.length)];
}像这样使用:
// before
ListOfTypes[Math.floor(Math.random() * ListOfTypes.length)]
// after
getRandomElement(ListOfTypes)发布于 2021-12-02 15:48:23
也许是学习如何使用"immer“库的好时机。它非常适合这样的情况,在这种情况下,您需要对嵌套过深的对象进行更改。如果没有它,对像您正在处理的对象进行更改将变得非常混乱和难以处理。
Immer很容易上手,一两天就能学会。如果你使用它,你的代码可以简化为:
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实际上将创建一个新对象,因此它避免了与可变数据相关的任何令人头疼的问题。
发布于 2021-12-02 15:44:53
请检查以下内容:
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;
})
};https://stackoverflow.com/questions/70202252
复制相似问题