最近在学习React,在useState部分被困扰了半天,分享一下问题!如下代码:
import React, { useState, useEffect } from 'react';
function Counter() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log(`Count updated to ${count}`);
}, [count]);
const increment = () => {
setCount(count + 1);
};
const reset = () => {
setCount(0);
};
return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>Increment</button>
<button onClick={reset}>Reset</button>
</div>
);
}
export default Counter;
流程解析
-
初始状态
count为0。- 页面显示
0。 - 输出
Count updated to 0。
-
状态值不同的情况
- 用户点击“Increment”按钮,调用
setCount(count + 1)。 count变为1。- 页面显示
1。 - 输出
Count updated to 1。
- 用户点击“Increment”按钮,调用
-
状态值不同的情况
- 用户点击“Reset”按钮,调用
setCount(0)。 count变为0。- 页面显示
0(记作01)。 - 输出
Count updated to 0。
- 用户点击“Reset”按钮,调用
-
状态值相同的情况
- 用户再次点击“Reset”按钮,调用
setCount(0)。 count仍然是0。- React 检查状态值是否相同(当前值为
0,新值也是0)。 - 由于值相同,React 不会触发实际的 DOM 更新。
- 但是,React 会执行一次“比较渲染”,确保状态的一致性。
- 输出
Count updated to 0(记作02)。
- 用户再次点击“Reset”按钮,调用
最终显示的值
- 最终状态值:最后一次调用
setCount(0)后,状态值仍然是0。 - 页面显示的值:页面显示的值是最后一次更新后的
0(记作02)。
总结
- 内存地址:尽管
01和02的内存地址不同,页面上显示的值仍然是0。 - 实际渲染 vs. 比较渲染:当状态值相同但
setCount被调用时,React 会执行一次“比较渲染”,确保状态的一致性,但不会实际更新 DOM。 - 页面显示:页面显示的值是最后一次更新后的
0(记作02)。
这个时候我的疑问出来了,明明01到02的变化是实实在在的替换,虽然是0 -->0的过程,但应该也算是重新渲染,为什么却叫做“比较渲染”。最后查了半天才发现是我钻牛角尖了。
从 01 到 02 的过程虽然涉及状态值的重新赋值,但由于值相同,React 不会触发实际的 DOM 更新。页面上的显示值仍然是 0,只是内存地址不同。这种情况下不算实际的重新渲染。

1228

被折叠的 条评论
为什么被折叠?



