在嵌套对象中,在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"
           }
        }
   })

当前回答

我认为最好的解决办法是Immer。它允许你像直接修改字段一样更新对象(masterField.fieldOne。Fieldx = 'abc')。但它当然不会改变实际对象。它收集草稿对象上的所有更新,并在最后为您提供一个最终对象,您可以使用它来替换原始对象。

其他回答

谢谢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} 
/>


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

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

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

updateState({ occupation: "postman" })

你想要创建状态的对象

let teams = {
  team: [
    {
      name: "one",
      id: "1"
    },
  ]
}

使团队的状态为对象

const [state, setState] = useState(teams);

像这样更新状态

setState((prevState)=>({...prevState,team:[
     ...prevState.team,
     {
     name: "two",
      id: "2"
     }
]}))

更新后状态变为

{
  team: [
    {
      name: "one",
      id: "1"
    },
    {
      name: "two",
      id: "2"
    }
  ]
}

要渲染项目根据当前状态使用地图功能

{state.team.map((curr_team) => {
      return (
        <div>
           <p>{curr_team.id}</p>
           <p>{curr_team.name}</p>
        </div>
      )
})}
function App() {

  const [todos, setTodos] = useState([
    { id: 1, title: "Selectus aut autem", completed: false },
    { id: 2, title: "Luis ut nam facilis et officia qui", completed: false },
    { id: 3, title: "Fugiat veniam minus", completed: false },
    { id: 4, title: "Aet porro tempora", completed: true },
    { id: 5, title: "Laboriosam mollitia et enim quasi", completed: false }
  ]);

  const changeInput = (e) => {todos.map(items => items.id === parseInt(e.target.value) && (items.completed = e.target.checked));
 setTodos([...todos], todos);}
  return (
    <div className="container">
      {todos.map(items => {
        return (
          <div key={items.id}>
            <label>
<input type="checkbox" 
onChange={changeInput} 
value={items.id} 
checked={items.completed} />&nbsp; {items.title}</label>
          </div>
        )
      })}
    </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);
};