React中数组对象的SetState

SetState of an Objects of array in React

所以我已经为此工作了一段时间,我想做的是在单击复选框时更改选中的值。

我的初始状态是这样的:

const [todoList, setTodoList] = useState({
    foundation: {
      steps: [
        { key: "1", title: "setup virtual office", isDone: false },
        { key: "2", title: "set mission and vision", isDone: false },
        { key: "3", title: "select business name", isDone: false },
        { key: "4", title: "buy domain", isDone: false },
      ],
    },

    discovery: {
      steps: [
        { key: "1", title: "create roadmap", isDone: false },
        { key: "2", title: "competitor analysis", isDone: false },
      ],
    }
  });

以及我的地图和 onClick 函数(updateCheckFoundation 在单击复选框时起作用)

    {todoList.foundation.steps.map((item) => {
        return (
          <div>
            <input type="checkbox" defaultChecked={item.isDone}
             onClick={(event)=> updateCheckFoundation({
                 isDone:event.target.checked, 
                 key:item.key
                 })}/>
            <span>{item.title}</span>
          </div>
        );
      })}

那么如何使用 setState 更新 todoList?

我的代码 (updateCheckFoundation func.) 像这样并且不起作用 :( :

const updateCheckFoundation = ({isDone, key}) => {
    const updateTodoList = todoList.foundation.steps.map((todo)=> {
     if(todo.key === key){
      return {
        ...todo,
        isDone
      };
    }
    return todo;

    });
    setTodoList(updateTodoList);
 

  }

问题

您的 updateCheckFoundation 回调没有保持状态不变,事实上,除了 foundation.steps 状态数组之外,所有的都被删除了。

const updateCheckFoundation = ({isDone, key}) => {
  const updateTodoList = todoList.foundation.steps.map((todo)=> {
    if(todo.key === key){
      return {
        ...todo,
        isDone
      };
    }
    return todo;

  });
  setTodoList(updateTodoList); // <-- only the state.foundation.steps array!!
}

解决方案

在函数组件中,当使用 useState 状态更新函数时,您需要自己手动处理合并状态(根状态)和嵌套状态。

const updateCheckFoundation = ({ isDone, key }) => {
  setTodoList(state => ({
    ...state, // <-- shallow copy state object
    foundation: {
      ...state.foundation, // <-- shallow copy
      steps: state.foundation.steps.map(todo => todo.key === key
        ? { ...todo, isDone }
        : todo)
    },
  }));
}