Javascript 更换道具时重置状态

Javascript 更换道具时重置状态,javascript,reactjs,Javascript,Reactjs,假设我有两个组件: const availableTasks = [1, 2, 3]; const Task = () => { const [current, setCurrent] = React.useState(0); const getNextTask = () => current + 1 < availableTasks.length ? current + 1 : 0; return ( <div classNa

假设我有两个组件:

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 availableTasks=[1,2,3];
常量任务=()=>{
const[current,setCurrent]=React.useState(0);
const getNextTask=()=>current+1下一个任务
);
};
const TaskVote=({id})=>{
const[count,setCount]=React.useState(0);
React.useffect(()=>{
setInterval(()=>setCount(count=>count+1),1000);//异步数据接收(例如websocket)
}, []);
返回计数:{id},计数:{count};
};
TaskVote
从WebSocket接收数据,并在需要时更新
count
状态。(例如,将其替换为interval)

Task
呈现有关任务的一些信息,它呈现
TaskVote
,以及“下一个任务”
按钮

当用户跳转到下一个任务时,
TaskVote
接收到新密钥,因此它将重新装载,这很好

如果
availableTaks
中只有一个元素,则
属性不会改变,因此
计数
状态不会重置,即使我希望它在单击按钮后重置(即使是同一任务)

我怎么处理这个案子


谢谢

您的问题是,您使用了一个简单的数字作为密钥,如果您的下一个任务与以前相同,则该密钥不会更新

这将导致以下多次渲染:

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>
const[voteState,setVoteState]=useState(0)
...
{
setCurrent(getNextTask())
setVoteState((s)=>s+1)//始终增加
}}>下一项任务
但是,设置多个状态值可能导致多个重新渲染。 您可以通过合并多个值(或通过useReducer)来优化此设置:


const[current,setCurrent]=React.useState({task:0,voteButtonState:0});
... 
{
设置当前值((旧)=>{
返回{
任务:getNextTask(),
voteButtonState:old.voteButtonState+1//始终递增
}
}) 
}>下一项任务

对于
属性,您可以使用与
当前
不同的值,并在每次按下按钮时更改该值,无论有多少任务。
const [voteState, setVoteState] = useState(0)
...
<TaskVote id={availableTasks[current]} key={voteState}/>
<button onClick={() => {
  setCurrent(getNextTask())
  setVoteState((s) => s+1) // always increasing
}}> Next Task</button>