Reacthook中陷入无限循环的alert

324 阅读2分钟

大家好,我是江湖不渡i,前端菜鸡,react初学者。
今天在学习的过程中遇到一个问题我的代码居然无限循环了,给我的老式笔记本差点搞炸了😓
简化代码如下:

const Test = () => {
    const value = { name: 1 };
    const [num, setNum] = useState(0);
    useEffect(() => {
        setNum(num => num += 1);
        console.log("render");
    }, [value]);
    return (
        <div className="App">
            <h1>{num}</h1>
        </div>
    );
}
export default Test
解释一下正常情况下应该不会const value = { name: 1 };这样写,但是是用别的工具函数或者hook不小心的话就会返回一个对象。

然后也有一个警告⚠️:

截屏2021-11-18 下午5.32.04.png

这到底是为什么呐?怎么会无限循环?这代码看着也没啥毛病呀!
当我认真看了看react的官方文档还有度娘之后,我悟了〇🈚️
下面分析分析代码:
首先useEffect是依赖项发生变化之后会执行力里面的副作用函数,这个函数组件在执行的时候会对value进行定义,发生了变化。
所以useEffect执行里面的函数,里面的函数改变了useState声明的num变量。
这时候我们要知道使用useState声明的变量,再调用改变的方法的时候,react都会对该组件进行重新render,这时候函数组件Test重新渲染了。
重点来了: 函数组件重新渲染,value又被重新定义了,value虽然看似内容是相同的,但是重新渲染后的value的指向或者说是内存空间已经发生了变化,所以此value非彼value
所以现在的流程是: 组件渲染 → useEffect执行 → setCount触发循环 → 组件渲染 → useEffect执行 → setCount触发循环... 所以就无限循环了。
至于怎么解决这样的问题可以用官方提供的hook:useRef、useMemo,大佬们可以看一下我的另外一篇文章写有类似这个方面的问题 Reacthooks引发的有趣闭包问题

说到底其实还是和基础有关,基本数据类型和引用数据类型的区别:

// 为什么?
let a = 1; 
let b = 1;
a === b; // true
const obj = {
    value: 1
};
const obj1 = {
    value: 1
};
obj === obj1; // false

其实这个组件重复渲染的问题,我觉得也是一个坑。这样性能问题不也是太过明显了?但是我相信react这样设计肯定有解决的方法只不过是我还没学习到,继续加油!💪