1、每一次渲染都有它自己的 Props and State
当我们更新状态的时候,React会重新渲染组件。每一次渲染都能拿到独立的state 状态,这个状态值是函数中的一个常量。
2、每一次渲染都有它自己的事件处理函数
在任意一次渲染中,props和state是始终保持不变的。如果props和state在不同的渲染中是相互独立的,那么使用到它们的任何值也是独立的(包括事件处理函数)。它们都“属于”一次特定的渲染。即便是事件处理中的异步函数调用“看到”的也是这次渲染中的状态值。
3、每次渲染都有它自己的Effects
React会记住你提供的effect函数,并且会在每次更改作用于DOM并让浏览器绘制屏幕后去调用它。
所以虽然我们说的是一个 effect,但其实每次渲染都是一个不同的函数 — 并且每个effect函数“看到”的props和state都来自于它属于的那次特定渲染。
我们可以明确地喊出下面重要的事实:每一个组件内的函数(包括事件处理函数,effects,定时器或者API调用等等)会捕获某次渲染中定义的props和state。
4、在组件内什么时候去读取props或者state是无关紧要的。因为它们不会改变。在单次渲染的范围内,props和state始终保持不变。(解构赋值的props使得这一点更明显。)
当你想要从过去渲染中的函数里读取未来的props和state时,可以使用useRef。
5、那Effect中的清理(useEffect中return一个函数清理之前的useEffect中的状态)又是怎样的呢?
组件内的每一个函数(包括事件处理函数,effects,定时器或者API调用等等)会捕获定义它们的那次渲染中的props和state。因此答案是显而易见的。effect的清除并不会读取“最新”的props。它只能读取到定义它的那次渲染中的props值。所以清理的时序为:
1、React 渲染UI
2、浏览器绘制
3、React 清除上一次的effect
4、React 运行新的effect
6、告诉React去比对你的Effects
如果想要避免effects不必要的重复调用,你可以提供给useEffect一个依赖数组参数(deps),也就是useEffect的第二个参数。如果当前渲染中的这些依赖项和上一次运行这个effect的时候值一样,因为没有什么需要同步React会自动跳过这次effect。
7、另一种告知依赖的方法
useEffect(() => {
const id = setInterval(() => {
setCount(c => c + 1);
}, 1000);
return () => clearInterval(id);
}, []);
参考:https://overreacted.io/zh-hans/a-complete-guide-to-useeffect/