React中useEffect不触发、DOM未更新问题求助及复现代码
问题分析与解决方案
嘿,这个问题我之前也踩过坑!核心原因是你违反了React状态的不可变性原则,导致React没能检测到状态发生了变化。
为什么会出现这个问题?
你看这段代码:
const arr = mark; arr.push("hello");
这里的arr只是复制了mark数组的引用,并不是创建了一个全新的数组。所以arr.push其实是直接修改了原状态数组,之后你通过setMark返回的还是同一个引用的数组。React在对比状态变化时,会检查引用是否改变——因为引用没变化,它就认为状态根本没更新,自然不会触发重新渲染,useEffect也不会执行。
怎么修复?
我们需要创建一个新的数组来更新状态,让React能明确检测到状态变化。这里有几种常用的方式:
方式1:使用展开运算符(最推荐)
直接在setMark里基于之前的状态创建新数组,这种写法简洁且符合React的最佳实践:
function ChangeValue() { setMark(prevMark => [...prevMark, "hello"]); }
如果习惯分步写也可以:
function ChangeValue() { const newArr = [...mark]; newArr.push("hello"); setMark(newArr); }
方式2:使用concat方法
concat方法会返回一个新数组,不会修改原数组,也能达到同样的效果:
function ChangeValue() { setMark(prevMark => prevMark.concat("hello")); }
修改后的完整代码
import React, { useEffect, useState } from "react"; export default function App() { const [mark, setMark] = useState([]); function ChangeValue() { setMark(prevMark => [...prevMark, "hello"]); } useEffect(() => { console.log("ADDED VALUE"); }, [mark]); return ( <div className="App"> <h1>Hello CodeSandbox</h1> {mark.map((item, index) => { // 注意map渲染要加key属性,这里用index临时替代,实际项目建议用唯一业务id return <h3 key={index}>{item}</h3>; })} <button onClick={() => ChangeValue()}>Add More</button> </div> ); }
内容的提问来源于stack exchange,提问作者Marcos Oliveira
相关产品推荐
相关产品推荐

