可以说我有以下两个组成部分:
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
从websocket接收其数据,并在需要时更新count
状态。 (例如,将其替换为时间间隔)
Task
呈现有关该任务的一些信息,它呈现TaskVote
和一个“下一个任务” button
。
当用户跳到下一个任务时,TaskVote
会收到新密钥,因此它将重新安装,就可以了。
在availableTaks
中只有一个元素的情况下,key
道具不会更改,因此count
状态不会重置,即使我希望一旦按钮将其重置也是如此被点击(即使是相同的任务)。
该如何处理?
谢谢!
答案 0 :(得分:0)
您的问题是您使用一个简单的数字作为密钥,如果您的下一个任务与之前的任务相同,则该密钥不会更新。
这将导致以下渲染多次:
<TaskVote id={1} key={0}/>
反应无法确定某些更改。
一个简单的解决方案是保留一个可以用作键的单独状态。
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>