React中用splice与filter修改状态数组为何表现不同?
问题解答:为什么splice修改数组后React状态不更新?
核心原因在于JavaScript的引用类型特性,以及React的状态更新机制:
- 数组在JS里是引用类型,
let arr = getResponse这行代码并没有创建新数组,只是把状态数组的内存引用复制给了变量arr——说白了,arr和getResponse指向的是同一个数组。 splice是原地修改数组的方法,它会直接改变原数组的内容,但数组本身的引用(内存地址)没变。当你调用setGetResponse(arr)时,React会对比新旧状态的引用,发现和之前的状态引用完全一样,就会判定“状态没有变化”,因此不会触发组件重新渲染,依赖getResponse的useEffect自然也不会执行。
而用filter的情况完全不同:filter方法会生成并返回一个全新的数组,这个新数组的内存引用和原状态数组完全无关。当你把这个新数组传给setGetResponse时,React检测到引用变化,就会正常更新状态,触发组件重新渲染,对应的useEffect也会被触发。
如果一定要用splice来实现需求,你需要先创建原数组的副本,再修改副本,比如:
useEffect(() => { if (!postLoad && !postError) { const filterIndex = getResponse.findIndex( (filter) => filter.id === postResponse.id ); // 用扩展运算符创建原数组的副本 let arr = [...getResponse]; arr.splice(filterIndex, 1); setGetResponse(arr); } }, [postResponse]);
除了扩展运算符,你也可以用Array.from(getResponse)或者getResponse.slice()来创建数组副本,只要保证修改的是新数组,再把新数组传给状态更新函数,React就能正确识别状态变化了。
内容的提问来源于stack exchange,提问作者Jeje Pro
相关产品推荐
相关产品推荐

