大家好,我是江湖不渡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不小心的话就会返回一个对象。
然后也有一个警告⚠️:
这到底是为什么呐?怎么会无限循环?这代码看着也没啥毛病呀!
当我认真看了看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这样设计肯定有解决的方法只不过是我还没学习到,继续加油!💪