https://juejin.im/post/5ceb36dd51882530be7b1585
一.
对于class component :
- 首先state是Immutable的, setState后一定会生成一个全新的state引用。
- 但是class component是通过this.state的方式读取的,这导致每次代码执行都会拿到最新的state引用。
对于Function component:
- useState产生的数据也是immutable的,通过数组第二个参数set一个新值后, 原来的值会在下次渲染时形成一个新的引用。
- 但由于对state的读取没有通过this.的方式,使得每次setTimeout都读取了当时渲染时闭包环境里的数据,虽然state跟着最新的渲染变了,但旧的渲染里,状态依然是旧值。
function Counter() {
const [count, setCount] = useState();
const log = () => {
setCount(count+1);
setTimeout(() => {
console.log(count);
}, 3000);
};
return (
<div>
<p>you clickeed {count} times</p>
<button onclick={log}>click me</button>
</div>
);
}
打印 0、1、2
二.
useRef: 通过useRef创建的对象,其值只有一份,而且在所有Rerender之间共享。
所以我们对count.current赋值或读取,读到的永远是其最新的值,而与渲染闭包无关。
function Counter() {
const count = useRef(0);
const log = () => {
count.current++;
setTimeout(() => {
console.log(count.current);
}, 3000);
};
return (
<div>
<p>you clicked {count.current} times</p>
<button onClick={log}>click me</button>
</div>
);
}
答案: 3、3、3
三.
useEffect: 使用useRef会改变原始值,为了不改变原始值且达到相同效果,可以使用useEffect