在嵌套对象中,在React with Hooks中更新状态的正确方法是什么?

export Example = () => {
  const [exampleState, setExampleState] = useState(
  {masterField: {
        fieldOne: "a",
        fieldTwo: {
           fieldTwoOne: "b"
           fieldTwoTwo: "c"
           }
        }
   })

如何使用setExampleState将exampleState更新为a(附加字段)?

const a = {
masterField: {
        fieldOne: "a",
        fieldTwo: {
           fieldTwoOne: "b",
           fieldTwoTwo: "c"
           }
        },
  masterField2: {
        fieldOne: "c",
        fieldTwo: {
           fieldTwoOne: "d",
           fieldTwoTwo: "e"
           }
        },
   }
}

b(改变值)?

const b = {masterField: {
        fieldOne: "e",
        fieldTwo: {
           fieldTwoOne: "f"
           fieldTwoTwo: "g"
           }
        }
   })

当前回答

,就像这个例子:

首先创建对象的状态:

const [isSelected, setSelection] = useState([{ id_1: false }, { id_2: false }, { id_3: false }]);

然后更改它们的值:

// if the id_1 is false make it true or return it false.

onValueChange={() => isSelected.id_1 == false ? setSelection([{ ...isSelected, id_1: true }]) : setSelection([{ ...isSelected, id_1: false }])}

其他回答

可以使用useReducer钩子来管理复杂的状态,而不是useState。要做到这一点,首先初始化状态和更新函数如下所示:

const initialState = { name: "Bob", occupation: "builder" };
const [state, updateState] = useReducer(
  (state, updates) => ({ ...state, ...updates }),
  initialState
);

然后你可以通过只传递部分更新来更新状态,就像这样:

updateState({ occupation: "postman" })

我认为更优雅的解决方案是创建更新后的状态对象,同时保留以前的state值。需要更新的Object属性可以以这样的数组形式提供

import React,{useState, useEffect} from 'react'
export default function Home2(props) {
    const [x, setX] = useState({name : '',add : {full : '', pin : '', d : { v : '' }}})
    const handleClick = (e, type)=>{
        let obj = {}
        if(type.length > 1){
            var z = {}
            var z2 = x[type[0]]
        
        type.forEach((val, idx)=>{
            if(idx === type.length - 1){
                z[val] = e.target.value
            }
            else if(idx > 0){
                Object.assign(z , z2) /*{...z2 , [val]:{} }*/
                z[val] = {}
                z = z[val]
                z2 = z2[val]
            }else{
                z = {...z2}
                obj = z
            }
        })
    }else obj = e.target.value
    setX( { ...x ,   [type[0]] : obj  } )
    
}
return (
    <div>
        <input value = {x.name} onChange={e=>handleClick(e,["name"])}/>
        <input value = {x.add.full} onChange={e=>handleClick(e,["add","full"])}  />
        <input value = {x.add.pin} onChange={e=>handleClick(e,["add","pin"])}  /><br/>
        <input value = {x.add.d.v} onChange={e=>handleClick(e,["add","d","v"])}  /><br/>
        {x.name} <br/>
        {x.add.full} <br/>
        {x.add.pin} <br/>
        {x.add.d.v}
    </div>
)
}

如果你使用布尔值和数组,这可以帮助你:

const [checkedOrders, setCheckedOrders] = useState<Record<string, TEntity>>({});

const handleToggleCheck = (entity: TEntity) => {
  const _checkedOrders = { ...checkedOrders };
  const isChecked = entity.id in checkedOrders;

  if (isChecked) {
    delete _checkedOrders[entity.id];
  } else {
    _checkedOrders[entity.id] = entity;
  }

  setCheckedOrders(_checkedOrders);
};

谢谢Philip,这帮助了我-我的用例是我有一个有很多输入字段的表单,所以我保持初始状态为对象,我不能更新对象状态。上面的帖子帮助了我:)

const [projectGroupDetails, setProjectGroupDetails] = useState({
    "projectGroupId": "",
    "projectGroup": "DDD",
    "project-id": "",
    "appd-ui": "",
    "appd-node": ""    
});

const inputGroupChangeHandler = (event) => {
    setProjectGroupDetails((prevState) => ({
       ...prevState,
       [event.target.id]: event.target.value
    }));
}

<Input 
    id="projectGroupId" 
    labelText="Project Group Id" 
    value={projectGroupDetails.projectGroupId} 
    onChange={inputGroupChangeHandler} 
/>


你可以像这样传递新值:

  setExampleState({...exampleState,  masterField2: {
        fieldOne: "a",
        fieldTwo: {
           fieldTwoOne: "b",
           fieldTwoTwo: "c"
           }
        },
   })