阅读Build your own React这篇文章时遇到的问题:它和使用真实的react在某些时候执行结果不同,到底是因为什么?
分别使用文章中实现的react和真实的react来实现一个组件,该组件包括一个h1,点击h1数字会增加。连续点击该组件两次,看它们的
执行结果。
- 利用文章中实现的react实现该组件。完整代码
function Counter() {
const [state, setState] = Didact.useState(1);
return (
<h1 onClick={
() => {
setState(c => c + 1)
setTimeout(() => setState(c => c + 2), 3000)
}
} style="user-select: none">
Count: {state}
</h1>
);
}
const element = <Counter />;
const container = document.getElementById("root");
Didact.render(element, container);
结果:
数字只加1,并没有再加2。
- 利用真实的react来实现 完整代码
import { useState } from 'react';
export default function Counter() {
const [number, setNumber] = useState(0);
return (
<h1 onClick={() => {
setNumber((c) => c + 1)
setTimeout(() => setNumber((c) => c + 2), 3000)
}}>
Count {number}
</h1>
)
}
结果:
数字加1之后又加2了。
根据我对文章的理解, setTimeout(() => setNumber(c => c+2), 3000)
所修改的Intial render中对应fiber中的hook,而不是在setNumber(c => c + 1)所触发的render中相对应的fiber中的hook,因为两个setNumber都是在initial render时在useState中定义的,我们并没有改变setNumber(c => c+1)所产生的fiber树,即上一次render产生的树,对比是发生在当前正在渲染的树和上一次产生的树之间的,两者并没有发生改变,所以只加了1没有再加2。我还画了图帮助理解。但是为什么react既加了1又加了2,我不知道是为什么?两者之间有什么区别?如果第二次渲染复用了第一次渲染的某些fiber节点,那么第二个setNumber是可以改变UI的?