如何修改父组件的组件状态?

时间:2019-08-28 14:15:31

标签: reactjs

我从react开始,我正在尝试创建一个非常简单的TODO应用,该应用将允许用户执行以下操作:

  • 分别在每个TODO上切换完成状态。
  • 同时切换所有TODO。

它可以从子状态开始工作,但显然父状态与子状态“不同步”。

这是我的代码:

https://codesandbox.io/s/simplest-todo-app-posible-boyxe

我无法找到解决此问题的方法,看上去是一个非常经典的场景,但是我很抱歉,如果以前有人问过这个问题。

谢谢!

1 个答案:

答案 0 :(得分:2)

使Item为无状态组件,并处理来自父级的所有更改。

从父组件中将toggleComplete作为prop传递到Item,以切换complete

sandbox

const mockData = [{ id: 1, complete: false }, { id: 2, complete: true }];

const Item = ({ id, complete, toggleComplete }) => (
  <li>
    Task {id} is {complete ? "completed" : "not completed"}
    <button onClick={toggleComplete}>Toggle</button>
  </li>
);

function App() {
  const [data, setData] = useState(mockData);

  const markAllAsComplete = () => {
    const newData = data.map(item => {
      console.log(`Item ${item.id} is ${item.complete}`);
      item.complete = true;
      return item;
    });

    setData(newData);
  };

  const toggleAll = () => {
    const newData = data.map(item => {
      item.complete = !item.complete;
      return item;
    });

    setData(newData);
  };

  // added this
  const toggleComplete = id => () => {
    setData(prevData =>
      prevData.map(d => (d.id === id ? { ...d, complete: !d.complete } : d))
    );
  };

  return (
    <>
      <button onClick={toggleAll}>Toggle all</button>
      <ul>
        {data.map(item => (
          <Item
            key={item.id}
            id={item.id}
            complete={item.complete}
            toggleComplete={toggleComplete(item.id)}
          />
        ))}
      </ul>
      <ul>
        {data.map(item => (
          <li key={item.id}>
            Task id: {item.id} is
            {item.complete ? " completed" : " not completed"}
          </li>
        ))}
      </ul>
      <pre>{JSON.stringify(data)}</pre>
    </>
  );
}