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>