Javascript 更新嵌套状态的替代方法或解决方案
在我的react应用程序中,有一个设置“页面”,其中包含不同的设置类别和相应的设置项目。 因此,我需要一个嵌套状态(?)来避免有很多名为“category1id”、“category1-element1-id”等属性 情况如下:Javascript 更新嵌套状态的替代方法或解决方案,javascript,reactjs,nested,setstate,Javascript,Reactjs,Nested,Setstate,在我的react应用程序中,有一个设置“页面”,其中包含不同的设置类别和相应的设置项目。 因此,我需要一个嵌套状态(?)来避免有很多名为“category1id”、“category1-element1-id”等属性 情况如下: this.state = { categories: [ { id: 1, label: "Category 1",
this.state = {
categories: [
{
id: 1,
label: "Category 1",
elements: [
{ id: 1, label: "Option 1", selected: true },
{ id: 2, label: "Option 2", selected: false },
],
},
{
id: 2,
label: "Category 2",
elements: [
{ id: 1, label: "Option 1", selected: true },
{ id: 2, label: "Option 2", selected: false },
{ id: 3, label: "Option 3", selected: false },
],
},
Other property: "...",
要更新状态,我需要一个深拷贝而不是浅拷贝。我如何做到这一点?是否有其他替代解决方案?
使用
不起作用(错误),也不是真正的防故障
由于这是我的应用程序中唯一的嵌套状态,我希望避免使用lodash&co
单击该选项时调用的函数如下所示。但这直接改变了状态
handleOptionSelect = (categoryId, option) => {
const categories = [...this.state.categories];
// FIND INDEX OF CATEGORY
const category = categories.find((category) => category.id === categoryId);
const indexCat = categories.indexOf(category);
// //FIND INDEX OF ELEMENT
const elements = [...category.elements];
const indexEle = elements.indexOf(element);
//MODIFY COPIED STATE
const e = categories[indexCat].elements[indexEle];
e.selected = e.selected ? false : true;
// //SET NEW STATE
this.setState({ categories });
}
非常感谢你的帮助!我还在开始尝试学习React和JS:)如果使用对象存储类别呢?我的意思是,使用键值的散列,其中每个键都是类别的id
this.state = {
categories: {
1: {
label: "Category 1",
elements: [
{ id: 1, label: "Option 1", selected: true },
{ id: 2, label: "Option 2", selected: false },
],
},
2: {...}
}
}
这将帮助您添加或更新任何类别,例如:
// Update category of id 4
this.setState({...categories, 4: updatedCategory })
如果使用对象存储类别的元素,则相同的原则也应适用于这些元素。您知道,您只能导入特定的lodash函数,可以只安装一个特定的包,也可以从整个库中导入特定的函数?如果您不想这样做,您只需要在自己的代码中重新创建相同的功能<代码>从“lodash/cloneDeep”导入cloneDeep或。如果你还想自己写,这里有一个答案,列出了所有选项:谢谢,我不知道(我对编程很陌生)!实际上,我在实施您的解决方案时遇到了一些困难。我确实在终端中使用了
npm I lodash.clonedeep
,添加了import clonedeep from“lodash/clonedeep”
,并替换了const categories=[…this.state.categories]代码>使用const categories=\uu.cloneDeep(this.state.categority)
但是我得到一个错误,说“没有定义没有未定义”。我做错了什么?对不起,我的错-我发布的两件事是两种不同的方法。您将使用import cloneDeep from'lodash/cloneDeep
与整个lodash包结合使用(npm i lodash
)。它仍然只是导入您指定的模块,但是如果您在其他地方需要它们,您可以导入更多模块npm i lodash.clonedeep
只安装独立的clonedeep函数,您只需从“lodash.clonedeep”导入import clonedeep即可使用它。当您想使用它时,您不需要使用前导的。
,因为您直接导入了该函数,而不是在名称空间下。谢谢!在这种情况下,我不能使用诸如.map之类的函数来呈现类别,.filter来仅将选定的选项传递给“执行”组件,可以吗?我认为您仍然可以使用对象.keys
来实现这一点。类似于Object.keys(categories).map(key=>categories[key])
// Update category of id 4
this.setState({...categories, 4: updatedCategory })