logo科技微讯

React useEffect 零散笔记

作者:科技微讯
日期:2022-05-15
📝 笔记

react 的 component 其实是一个函数,这个 component 函数必须是一个 pure 函数,即:

  • 它不会更改在它执行之前就已经存在的对象或变量;
  • 给它一样的参数,每一次必定返回一样的值;

component 函数在 render 时执行,A (Mostly) Complete Guide to React Rendering Behavior 详细解释了 react 的 render 是什么意思。react 的 render 不同于浏览器 render,“Rendering” is React calling your components

React 的 component 进行 render 主要有两种情况:1、父 component render;2、setState。

如果一个 component 函数不是 pure 函数,例如它改变了它之前的对象或变量,则说明它产生了 side effect。要想改变 component 函数之前的对象或变量,唯一的做法就是不要在 component 函数执行过程中去改变。

由于 component 函数是在页面重新渲染时执行的,所以唯一的做法其实就是不要在渲染过程中去改变这些对象或变量,那就等渲染结束后再去改变吧,通常有 2 种方法:

  • 事件函数:由于事件函数是 component 执行完成之后触发的,所以在事件函数内进行的 side effect 不会让 component 变得 impure;
  • useEffect:可以把 side effect 放在 useEffect 中执行,通过 useEffect 告诉 react 这些代码不要在页面渲染时执行,而是在渲染完成之后执行;

react 的官方文档表示,只有其他方法都不适合产生你需要的 side effect 之后,才使用 useEffect,useEffect 应该是你最后一个选择:

If you’ve exhausted all other options and can’t find the right event handler for your side effect, you can still attach it to your returned JSX with a useEffect call in your component. This tells React to execute it later, after rendering, when side effects are allowed. However, this approach should be your last resort.

useEffect 中的函数默认在 component 每一次 rerender 后执行,但是我们可以告诉 useEffect 只有某些 state 引起的 render 之后才执行,而不是任意 state 引起的 render 都执行,给 useEffect 增加一个 dependencies array 参数即可。

useEffect 的 function 里出现的变量,都应该加入到 dependencies array 中。

有时候要注意 clean effect。通常 useEffect function 不应该是 async 函数:

useEffect takes a function as its parameter. If that function returns something, it needs to be a cleanup function. Otherwise, it should return nothing. If we make it an async function, it automatically retuns a promise instead of a function or nothing. Therefore, if you want to use async operations inside of useEffect, you need to define the function separately inside of the callback.

顺便说一下 useState:为什么 setState 最好提供一个函数作为参数?为什么 useState 有时候应该提供一个函数作为参数?看这篇文章。stackoverflow 这个问答从源码上解释了 useState 和 setState 接收什么参数。

donation赞赏
thumbsup0
thumbsdown0
暂无评论