Javascript React:设置带有挂钩的深度嵌套对象的状态

Javascript React:设置带有挂钩的深度嵌套对象的状态,javascript,reactjs,state,react-hooks,setstate,Javascript,Reactjs,State,React Hooks,Setstate,我正在使用React中的一个嵌套很深的状态对象。我的代码库要求我们尽量使用函数组件,因此每当我想更新嵌套对象中的键/值对时,我必须使用钩子来设置状态。不过,我似乎无法理解更深层次的嵌套项。我有一个带有onChange处理程序的下拉菜单。onChange处理程序中有一个内联函数,用于直接设置正在更改的任何key/val对的值 但是,我在每个内联函数中的spread运算符之后使用的语法是错误的 作为一种解决方法,我已经求助于将内联函数分解为它自己的函数,该函数每次状态改变时都会重写整个状态对象,但这

我正在使用React中的一个嵌套很深的状态对象。我的代码库要求我们尽量使用函数组件,因此每当我想更新嵌套对象中的键/值对时,我必须使用钩子来设置状态。不过,我似乎无法理解更深层次的嵌套项。我有一个带有onChange处理程序的下拉菜单。onChange处理程序中有一个内联函数,用于直接设置正在更改的任何key/val对的值

但是,我在每个内联函数中的spread运算符之后使用的语法是错误的

作为一种解决方法,我已经求助于将内联函数分解为它自己的函数,该函数每次状态改变时都会重写整个状态对象,但这非常耗时且难看。我更愿意像下面这样做:

 const [stateObject, setStateObject] = useState({

    top_level_prop: [
      {
        nestedProp1: "nestVal1",
        nestedProp2: "nestVal2"
        nestedProp3: "nestVal3",
        nestedProp4: [
          {
            deepNestProp1: "deepNestedVal1",
            deepNestProp2: "deepNestedVal2"
          }
        ]
      }
    ]
  });

<h3>Top Level Prop</h3>

   <span>NestedProp1:</span>
     <select
       id="nested-prop1-selector"
       value={stateObject.top_level_prop[0].nestedProp1}
       onChange={e => setStateObject({...stateObject, 
       top_level_prop[0].nestedProp1: e.target.value})}
     >
      <option value="nestVal1">nestVal1</option>
      <option value="nestVal2">nestVal2</option>
      <option value="nestVal3">nestVal3</option>
     </select>

<h3>Nested Prop 4</h3>

   <span>Deep Nest Prop 1:</span>
     <select
       id="deep-nested-prop-1-selector"
       value={stateObject.top_level_prop[0].nestprop4[0].deepNestProp1}
       onChange={e => setStateObject({...stateObject, 
       top_level_prop[0].nestedProp4[0].deepNestProp1: e.target.value})}
     >
      <option value="deepNestVal1">deepNestVal1</option>
      <option value="deepNestVal2">deepNestVal2</option>
      <option value="deepNestVal3">deepNestVal3</option>
     </select>

const[stateObject,setStateObject]=useState({
顶级道具:[
{
nestedProp1:“nestVal1”,
nestedProp2:“nestVal2”
nestedProp3:“nestVal3”,
nestedProp4:[
{
deepNestProp1:“deepNestedVal1”,
deepNestProp2:“deepNestedVal2”
}
]
}
]
});
顶级道具
NestedProp1:
setStateObject({…stateObject,
顶层_prop[0].nestedProp1:e.target.value}
>
内斯特瓦尔1
内斯特瓦尔2
内斯特瓦尔3
嵌套道具4
深巢1号支柱:
setStateObject({…stateObject,
顶层_-level_-prop[0]。nestedProp4[0]。deepNestProp1:e.target.value}
>
深谷1
深谷谷2
深水河谷3

上面代码的结果给了我一个“nestProp1”和“deepNestProp1”未定义,可能是因为每个选择器从未到达/更改它们的状态。我的预期输出将是与选择器的当前val值匹配的所选选项(在状态更改后)。任何帮助都将不胜感激。

我认为您应该使用
setState
的函数形式,这样您就可以访问当前状态并对其进行更新

比如:

看看这是否有帮助:

函数应用程序(){
const[nestedState,setNestedState]=React.useState({
顶级道具:[
{
nestedProp1:“nestVal1”,
nestedProp2:“nestVal2”,
nestedProp3:“nestVal3”,
nestedProp4:[
{
deepNestProp1:“deepNestedVal1”,
deepNestProp2:“deepNestedVal2”
}
]
}
]
});
返回(
这是我的嵌套状态:
{JSON.stringify(nestedState)}
setNestedState((prevState)=>{
prevState.top_level_prop[0]。nestedProp4[0]。deepNestProp1='XXX';
返回({
…前州
})
}
)}
>
单击以更改nestedProp4[0]。deepNestProp1
);
}
ReactDOM.render(,document.getElementById('root'))

另一种方法是使用

const-App=()=>{
const reducer=(状态、操作)=>{
返回{…状态,[action.type]:action.payload}
}
const[state,dispatch]=React.useReducer(reducer{
propA:‘foo1’,
道具:“bar1”
});
常量更改选择=(属性、事件)=>{
const newValue=event.target.value;
分派({type:prop,payload:newValue});
}
返回(
我的嵌套状态:
{JSON.stringify(state)}
changeSelect('propA',e)}
>
foo1
食物2
foo3
changeSelect('propB',e)}
>
bar1
bar2
三维直方图
);
}
ReactDOM.render(,document.getElementById('root'))


创建一个最小的可重复示例,以便我们可以测试问题。这管用!非常感谢。现在要将此操作转换为下拉列表。是否需要将其作为内联函数?将其设置为独立函数并以选项值作为参数调用会更容易,不是吗?不一定。但我需要能够运行带有事件的内联函数,而不是像他那样手动为其分配字符串值。现在想弄明白。您知道如何运行您刚才引用的函数,同时从下拉列表中传入事件吗?我添加了一个新示例。看看这是否有帮助。
setState((prevState) => 
  //DO WHATEVER WITH THE CURRENT STATE AND RETURN A NEW ONE
  return newState;
);