问题:props、setState 导致的组件从新渲染,宏观上是怎么样的?
比方有如下代码:
const component = (props) => {const [a, setA] = useState(true);
const [b, setB] = useState(true);
const ref = useRef(true);
const fn = useCallback(() => {}, [a]);
const memo = useMemo(() => {}, [b]);
useEffect(() => {setA(false);
}, [b]);
return (
<div>
<div>{a}</div>
<div>{props.c}</div>
</div>
)
}
每一次组件的从新渲染,都会有链表(假如这个链表叫 link1)顺次记录 useState -> useState -> useRef -> useCallback -> useMemo -> useEffect
每一个的区别,具体要看每一个的解析。这里只简述 deps 对函数运行与否的影响。
这里的 deps 会被记录 link1 中。第二次渲染组件开始,会对 deps 比对,如果 deps 不同,就会执行对应办法。
比方 fn = useCallback 这里,第一次渲染组件,把办法赋值给了 fn,记录 [a] 的值
第二次渲染组件开始,会查看 [a] 的值是否更新了(示例代码中是更新了,因为 useEffect),如果更新了,就会把 useCallback 里的第一个参数从新赋值给 fn。
问题:useMemo 和 useEffect 的区别是什么?
不同点如下:
- useMemo 是渲染过程中执行,而 useEffect 是在渲染之后,从新搞一个渲染队列执行
- 因为 1 的起因,会导致在 useMemo 的第一个参数办法里,如果调用了 set…State 办法,会报错。然而在 useEffect 里不会,然而如果在 useEffect 里这么做了,会触发从新渲染。如果从新渲染的值在 useEffect 的 deps 里,那么就造成了循环渲染,最初也会报错。
- 用法上,useMemo 个别会间接给一个值赋值,因为第一个参数办法会有返回值。而 useEffect 没有返回值。
问题:在 useCallback、useMemo、useEffect 中,如果第一个参数的函数中波及的变量,没有都呈现在第二个参数里,会怎么样?
分为几种状况。
状况 1:波及的变量都是 useState 创立的变量
这种状况很显然是不行的,因为如果咱们调用了 set…State,而 deps 中没有更新后的数据,那么这三个 use 返回的内容会齐全不合乎预期
所以,不行。
状况 2:波及的变量是 useRef 创立的
useRef 创立意味着始终不会更新这个值,除非强行用 ref.current 批改。
然而用 ref.current 更新的话,也不会触发这三个 use 办法。所以,这个是能够不放 deps 里的。
状况 3:波及的变量是间接创立的
比方间接用 const a = initValue;
间接创立的变量,每次更新组件都会从新初始化变量。
原则上不倡议这么创立变量。
这个的答案是:不要这么创立变量。
如果硬要这么创立,答案是,这个变量每次都会初始化,之后这个变量的扭转也不会引发三个 use 的从新创立。