繁体   English   中英

在道具更改时重置状态

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM