Hooks-useEffect

Effect hook 可以让你在函数组件中执行副作用操作。

在 React 中,由 state 的变化导致 UI 发生变化的过程是正常操作,其他操作行为:如数据请求、直接操作 DOM(改变 Document.title)等都是副作用操作。React 无法感知它的变化,所以被归类到 effect。

副作用操作时相对于操作 state 而言的。

每一次因为 state 的改变,都有一次对应副作用函数的执行时机。

基本使用

语法:

1
useEffect(() => {}, []);

Effect 的第一个参数为回调函数,该函数会在每次 DOM 渲染完成之后执行。在事件循环里,useEffect 在下一轮事件循环执行。
我们可以在 effect 中获取到最新的 count值,因为他在函数的作用域内。

第二个参数为一个数组,这是一个优化性能的可选项。

  1. 如果不传第二个参数,那么回调函数会在每一次渲染完成后执行
  2. 如果传入一个空数组[],那么回调函数会在组件挂载和卸载时执行
  3. 如果传入依赖项数组,如[count],那么仅会在依赖项改变时重新执行
1
2
3
useEffect(() => {
document.title = `You clicked ${count} times`;
}, [count]); // 仅在 count 更改时更新

如何清除副作用

1
2
3
4
5
6
7
useEffect(() => {
ChatAPI.subscribeToFriendStatus(props.id, handleStatusChange);
function clear() {
ChatAPI.unsubscribeFromFriendStatus(props.id, handleStatusChange);
}
return clear;
});

假设 props 参数 id 改变了两次,第一次传入id: 1,第二次传入id: 2,那么过程如下:

  1. 传入props.id = 1
  2. 组件渲染
  3. DOM 渲染完成,执行副作用逻辑,返回清除副作用的函数clear,命名为clear1
  4. 传入props.is = 2
  5. 组件渲染
  6. 组件渲染完成,clear1执行
  7. 副作用逻辑执行,返回另一个 clear 函数,命名为clear2
  8. 组件销毁,clear2执行

总结 clear 函数的执行,它的特征如下:

  • 每次副作用执行,都会返回一个新的 clear 函数
  • clear 函数会在下一次副作用逻辑执行之前执行(DOM 渲染完成之后)
  • 组件销毁时会执行一次

其他

渲染其实是一个比较模糊的概念。像div.style.left = '20px'这段代码,可以分为派发指令和 GUI 执行两个步骤。

1
2
3
4
5
div.style.left = '20px';

useLayoutEffect(() => {
div.style.left = '30px';
}, []);

像上面这个例子,useLayoutEffect 回调函数中的 div.style.left = '30px',会在 DOM 变更之后同步调用,在 GUI 线程执行之前执行,也就是在浏览器执行渲染之前执行。

Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×