[英]Reset state on prop change
假设我有这两个组件:
const availableTasks = [1, 2, 3];
const Task = () => {
const [current, setCurrent] = React.useState(0);
const getNextTask = () => current + 1 < availableTasks.length ? current + 1 : 0;
return (
<div className='task-container'>
<div className='task-information'>
Some information.
</div>
<TaskVote id={availableTasks[current]} key={current}/>
<button onClick={() => setCurrent(getNextTask())}> Next Task</button>
</div>
);
};
const TaskVote = ({ id }) => {
const [count, setCount] = React.useState(0);
React.useEffect(() => {
setInterval(() => setCount(count => count + 1), 1000); // Async data receiving (e.g. websocket)
}, []);
return <div> Counting for: {id}, Counted: {count}</div>;
};
TaskVote
从 websockets 接收数据,并在需要时更新count
状态。 (例如用间隔替换它)
Task
呈现关于任务的一些信息,它呈现TaskVote
和“下一个任务” button
。
当用户跳到下一个任务时, TaskVote
收到新密钥,因此它会重新挂载,这很好。
如果availableTaks
只有一个元素, key
prop 不会改变,所以count
状态不会重置,即使我希望它在点击按钮后重置(即使它是同一个任务)。
我该如何处理这个案子?
谢谢!
你的问题是你使用一个简单的数字作为键,如果你的下一个任务和以前一样,它就不会更新。
这会导致多次呈现以下内容: <TaskVote id={1} key={0}/>
React 无法确定某些内容发生了变化。
一个简单的解决方案是保持一个单独的状态,它可以用作一个键。
const [voteState, setVoteState] = useState(0)
...
<TaskVote id={availableTasks[current]} key={voteState}/>
<button onClick={() => {
setCurrent(getNextTask())
setVoteState((s) => s+1) // always increasing
}}> Next Task</button>
但是,设置多个状态值可能会导致多次重新渲染。 您可以通过合并多个值(或通过 useReducer)来优化它:
const [current, setCurrent] = React.useState({ task: 0, voteButtonState: 0 });
...
<TaskVote id={availableTasks[current]} key={current.voteButtonState}/>
<button onClick={() => {
setCurrent((old) => {
return {
task: getNextTask(),
voteButtonState: old.voteButtonState + 1 // always increasing
}
})
}> Next Task</button>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.