Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/429.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 反应:如何更新深度属性?_Javascript_Reactjs - Fatal编程技术网

Javascript 反应:如何更新深度属性?

Javascript 反应:如何更新深度属性?,javascript,reactjs,Javascript,Reactjs,我有一个简单的状态: const state = { title: "The title", colorSet: { multiple: true, colors: [ 'red', 'green', 'blue', 'yellow', 'gray', 'white',

我有一个简单的状态:

const state = {
    title: "The title",
    colorSet: {
        multiple: true,
        colors: [
            'red',
            'green',
            'blue',
            'yellow',
            'gray',
            'white',
        ],
        selected: [
            'green',
            'yellow',
        ],
    }
};
我们只将需要应用的更改传递到
setState()
函数中。例如,如果我只需要更新
标题
,我就会这样做:
this.SetState({title:“Updated title”})
。但如果我需要更深入地更新属性,例如:
state.colorSet.selected
,我该怎么做呢

它不工作:
this.setState({colorSet:{selected}})
。我是否可以只将更改传递到
setState()
中,而不传递已应用更改的状态的完整深度克隆?

尝试以下操作:

让newState=this.state;
newState.colorSet.selected=选中;

this.setState(newState)您可以对嵌套属性使用扩展运算符,以不改变原始对象

const state={
标题:“标题”,
颜色集:{
多重:对,
颜色:[
“红色”,
“绿色”,
“蓝色”,
“黄色”,
“灰色”,
“白色”,
],
选定:[
“绿色”,
“黄色”,
],
}
};
常数a={
……国家,
颜色集:{…state.colorSet,所选:[…state.colorSet.selected,'black']}
}

log(a)
您可以传递一个函数,该函数接受当前状态作为参数,并且只传递更改后的值

this.setState((currentState) => {
   return {
      ...currentState,
      colorSet: {
            ...currentState.colorSet,
            selected
      }
   }
})

处理嵌套对象时,不应直接改变状态,而应创建要更新的顶级对象的副本。然后,复制要变异的嵌套对象。然后更新顶级复制对象,最后更新状态

简而言之,您必须重建顶级对象。在您的情况下,您必须重建
colorSet
对象

// make a copy of colorSet object
const colorSetCopy = { ...this.state.colorSet };
// make a copy of the selected array
const selectedCopy = [...colorSetCopy.selected];
// update selectedCopy 
selectedCopy.push('red');
// update colorSetCopy
colorSetCopy.selected = selectedCopy;
// finally update the state
this.setState({ colorSet: colorSetCopy });
您可以将上述步骤组合为:

const selectedCopy = [...this.state.colorSet];
selectedCopy.push('red');
this.setState(prevState => (
     { colorSet: {...prevState.colorSet, selected: selectedCopy} }
));
我是否可以只将更改传递到setState(),而不传递完全更改 应用更改对我的状态进行深度克隆

这将直接改变状态,你不应该这样做

状态是对更改发生时组件状态的引用 正在应用。它不应该直接变异。取而代之的是变化 应通过基于来自的输入构建新对象来表示 状态和道具


在功能组件中,如果状态中有复杂的对象,最好使用
useReducer
hook而不是
useState
hook。

如果要更新deep-nested属性,最好这样做:

this.setState(prevState => ({colorSet: {...prevState.colorSet, selected: newSelectedArray }}))

正如一些人已经告诉过你的,解决这个问题最常用的方法是使用扩散算子。但我认为避免这些复杂嵌套状态结构的最好方法是重构有状态组件以使用react钩子。通过这种方式,您可以为每个状态域设置一个
useState
hook,从而缩小每个状态的范围

对于给定的示例,我可能会在这里使用3种状态:
title
colorSet
colorsSetSeleted


在这里你可以找到关于这个钩子用法的文档:

你的意思是
newState.colorSet.selected=selected。但在这种情况下,
newState
并不是原始版本的完全深度克隆。我以后会有问题吗?哎呀,我的错。答案是固定的。对我来说不是。SetState应负责更新。如果没有,请尝试以下操作:
let newState={…this.state}我知道,但对于复杂状态来说,这可能会很乏味。