Skip to main content

React-Effect

Effect

Too many re-renders.

当我们直接在函数体中调用setState时,就会触发上述错误

问题:

不是说过,当新的state值和旧值相同时,它是不会触发组件的重新渲染的

​ setState()的执行流程(函数组件)

  • setCount() --> dispatchSetDate()--> 会先判断,组件当前处于什么阶段

    如果是渲染阶段 --> 不会检查state值是否相同

    如果不是渲染阶段 --> 会检查state的值是否相同

    如果值不相同,则对组件进行重新渲染

    如果值相同,则不对组件进行重新渲染

    ​ 如果值相同,React在一些情况下会继续执行当前组件的渲染但是这个渲染不会触发其子组件的渲染,这次渲染不会产生实际的效果这种情况通常发生在值第一次相同时

什么是Effect

React组件有部分逻辑都可以直接编写到组件的函数体中的,像是对数组调用filter、map等方法,像是判断某个组件是否显示等。但是有一部分逻辑如果直接写在函数体中,会影响到组件的渲染,这部分会产生“副作用”的代码,是一定不能直接写在函数体中。这个时候就可用Effect解决问题。

怎么用Effect

为了解决这个问题React专门为我们提供了钩子函数useEffect(),Effect的翻译过来就是副作用,专门用来处理那些不能直接写在组件内部的代码。

哪些代码不能直接写在组件内部呢?像是:获取数据、记录日志、检查登录、设置定时器等。简单来说,就是那些和组件渲染无关,但却有可能对组件产生副作用的代码。

useEffect语法

useEffect(didUpdate);

useEffect(()=>{
/* 编写那些会产生副作用的代码 */
});

useEffect()中的回调函数会在组件每次渲染完毕之后执行,这也是它和写在函数体中代码的最大的不同,函数体中的代码会在组件渲染前执行,而useEffect()中的代码是在组件渲染后才执行,这就避免了代码的执行影响到组件渲染。

限制useEffect

默认情况下,useEffect()中的函数,会在组件渲染完成后调用, 并且是每次渲染完成后都会调用

在useEffect()可以传递一个第二个参数, 第二个参数是一个数组,在数组中可以指定Effect的依赖项指定后,只有当依赖发生变化时,Effect才会被触发通常会将Effect中使用的所有的局部变量都设置为依赖项 这样一来可以确保这些值发生变化时,会触发Effect的执行 像setState()是由钩子函数useState()生成的useState()会确保组件的每次渲染都会获取到相同setState()对象所以setState()方法可以不设置到依赖中 如果依赖项设置了一个空数组,则意味Effect只会在组件初始化时触发一次

通过使用这个Hook,我设置了React组件在渲染后所要执行的操作。React会将我们传递的函数保存(我们称这个函数为effect),并且在DOM更新后执行调用它。React会确保effect每次运行时,DOM都已经更新完毕。

清除Effect

组件的每次重新渲染effect都会执行,有一些情况里,两次effect执行会互相影响。比如,在effect中设置了一个定时器,总不能每次effect执行都设置一个新的定时器,所以我们需要在一个effect执行前,清除掉前一个effect所带来的影响。要实现这个功能,可以在effect中将一个函数作为返回值返回,像是这样:

useEffect(()=>{
/* 编写那些会产生副作用的代码 */

return () => {
/* 这个函数会在下一次effect执行钱调用 */
};
});

effect返回的函数,会在下一次effect执行前调用,我们可以在这个函数中清除掉前一次effect执行所带来的影响。