useEffect依赖项传入数组的长度,无法检测到变化

如下方代码所示,我想用useEffect监听arr的变化作条件渲染,由于useEffect的第二个参数不适合使用引用类型,所以将数组的长度用作了依赖项,点击按钮后更新arr,然后useEffect监听到arr的变化触发重新渲染。但结果是useEffect在数组更新后并没有执行,期望的内容无法渲染出来。

请问我这里是哪里写得有问题吗,有什么解决办法呢?

const demo: React.FC = () => {
    const [arr, setArr] = useState([]);
    useEffect(() => {
        console.log(arr);   // 不打印。。
    }, [arr.length]);
    
    const onClick = () => {
        setArr(() => {
            arr.push({name:"张三",sex:"男"});
            return arr
        })
    }
    return (
        <>
        <button onClick={onClick}>按钮</button>
        <div>
            {arr && arr.length !== 0 && (
                <div>你好</div>
            )}
        </div>
        </>
    )
};
export default demo;
阅读 8.3k
4 个回答

1、setArr的时候应该生成一个新的数组

const onClick = useCallback(() => {
  setArr([...arr, {name:"张三",sex:"男"}])
}, [arr])

2、useEffect第二个参数就可以直接使用arr了

useEffect(() => {
  console.log(arr);
}, [arr]);

React不像Vue,它不是监听对象的变化,而是比较对象有没有变化。
onClick中并没有改变原来的arr,因此不会触发re-render,也就走不到useEffect。

改成:

return [...arr]

这样就会产生依次re-render,然后才能进入useEffect,判断本次渲染时的dep和上一次的是否一样,并决定是否执行callback

React 一个核心思想 数据不可变 他总是要你返回一个新的对象 而不是在原来对象上 修改。
你这就是 没有理解这个 才会出现这个问题的

新手上路,请多包涵

onClick()回调里的setArr()并没有触发组件的re-render,所以组件都不会被重新渲染,自然无法触发useEffect,最好的实现是setArr()返回一个新的数组

setArr(arr => [...arr, {name:"张三",sex:"男"}])
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题