Reactjs React useState update在我通过随机激活器之前不会立即更新
所以我在测试时发现了一个非常奇怪的React-useState行为,但我无法解释原因 下面是我的代码。我正在创建带有复选框的React ListItem。因为用户可以选择多个复选框,所以我觉得最好使用数组存储活动索引。并使用array.includes函数检查某个索引是否处于活动状态。当我这样做的时候,我发现数组useState没有立即更新,所以我的复选框检查不起作用。然而,我添加了一个如下所示的随机激活器,突然数组得到及时更新,我的代码开始工作。我希望我的问题是清楚的。有人能解释为什么会这样吗 我做了更多的测试,发现activator需要传入索引变量。如果我传入一些随机值,它将导致不一致的行为Reactjs React useState update在我通过随机激活器之前不会立即更新,reactjs,use-state,Reactjs,Use State,所以我在测试时发现了一个非常奇怪的React-useState行为,但我无法解释原因 下面是我的代码。我正在创建带有复选框的React ListItem。因为用户可以选择多个复选框,所以我觉得最好使用数组存储活动索引。并使用array.includes函数检查某个索引是否处于活动状态。当我这样做的时候,我发现数组useState没有立即更新,所以我的复选框检查不起作用。然而,我添加了一个如下所示的随机激活器,突然数组得到及时更新,我的代码开始工作。我希望我的问题是清楚的。有人能解释为什么会这样吗
const [activeIndex, setactiveIndex] = useState([]);
const [_, activator] = useState(-1); //If I add this line of code the array gets updated in time
const ModifyActiveIndex = (index) => {
activator(index);
if (!activeIndex.includes(index)) {
const copy = activeIndex;
copy.push(index);
setactiveIndex(copy);
} else {
const filtercopy = activeIndex.filter((item) => {
return item !== index;
});
setactiveIndex(filtercopy);
}
};
const checkEntityactive = (index) => {
return activeIndex.includes(index);
};
const ProductList = temp.map((element, index) => {
return (
<ListItem key={index}>
<Checkbox
checked={checkEntityactive(index)}
onClick={() => ModifyActiveIndex(index)}
/>
</ListItem>
);
});
const[activeIndex,setactiveIndex]=useState([]);
常量[3;,激活器]=useState(-1)//如果我添加这行代码,数组就会及时更新
常量ModifyActiveIndex=(索引)=>{
活化剂(指数);
如果(!activeIndex.includes(index)){
const copy=activeIndex;
复制、推送(索引);
setactiveIndex(副本);
}否则{
const filtercopy=activeIndex.filter((项)=>{
返回项目!==索引;
});
setactiveIndex(filtercopy);
}
};
常量checkEntityactive=(索引)=>{
返回activeIndex.includes(索引);
};
const ProductList=临时映射((元素、索引)=>{
返回(
ModifyActiveIndex(索引)}
/>
);
});
activeIndex
是一个数组,不能以这种方式复制它们
在第一行中,您创建一个名为copy
的指针,并将其指向activeIndex
位置,因此每次对copy的更改(如第二行中的push())都将直接更改activeIndex
,因此您正在更改状态,而无需在第二行中调用setState。(这会导致你的应用程序无法预测)
您可以通过以下方式更改这3行:
setactiveIndex([...activeIndex, index]);
const copy=activeIndex
不创建副本,它本质上只是将activeIndex
重命名为copy
,数组仍然是相同的引用,因此在使用.push()
时,您正在更改您的状态。在执行筛选时,您也不需要创建copy
变量,因为筛选方法将为您创建一个新数组是我在测试期间刚刚添加的代码行。我可以把它拿出来。但这并不能解决问题,我想如果你把它拿出来,那么你可能在做类似于activeIndex.push(index)
?如果是这样的话,如果这样做的话,您仍然在直接修改状态。您需要创建一个新数组,并将新索引添加到setactiveIndex([…activeIndex,index])
是的,我的代码唯一的工作方式仍然是添加activator(index)行。所有其他更改都可以使代码更简单,但这并不能解决问题。我只想知道,当代码被执行到copy.push(index)时,为什么这行代码解决了我的问题代码>,状态已更改,但setactiveIndex(copy)
的参数是数组引用,因此在activator(index)之前不会重新呈现组件代码><代码>激活器(索引)代码>将在copy.push(索引)之后执行代码>因为setState在事件处理程序中是异步的。实际上,如果删除setactiveIndex(复制)代码>。它仍然可以工作。好的,谢谢。它确实解决了问题,但它没有告诉我为什么添加行激活器(索引)也可以工作,因为通过调用“激活器(索引)”,您通过更改索引强制组件重新加载,如果没有索引,您没有使用“setActiveIndex”更新“activeIndex”,因此组件在进入if状态时将永远不会更新
setactiveIndex([...activeIndex, index]);