我从react开始,我正在尝试创建一个非常简单的TODO应用,该应用将允许用户执行以下操作:
它可以从子状态开始工作,但显然父状态与子状态“不同步”。
这是我的代码:
https://codesandbox.io/s/simplest-todo-app-posible-boyxe
我无法找到解决此问题的方法,看上去是一个非常经典的场景,但是我很抱歉,如果以前有人问过这个问题。
谢谢!
答案 0 :(得分:2)
使Item
为无状态组件,并处理来自父级的所有更改。
从父组件中将toggleComplete
作为prop
传递到Item
,以切换complete
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>
</>
);
}