React useEffect的理解与使用

 更新时间:2021年04月19日 10:47:58   作者:RedCHr  
这篇文章主要介绍了React useEffect的理解与使用,帮助大家更好的理解和学习使用React,感兴趣的朋友可以了解下

React16.8新增的useEffec这个hook函数就是处理副作用的。

所谓的“副作用”,举个通俗一点的例子,假如感冒了本来吃点药就没事了,但是吃了药发现身体过敏了,而这个“过敏”就是副作用。

放到React中,本来只是想渲染DOM展示到页面上,但除了DOM之外还有数据,而这些数据必须从外部的数据源中获取,这个“获取外部数据源”的过程就是副作用。

useEffect怎么用可以参考官网给出的例子,这里主要针对使用useEffect过程中遇到的问题进行总结。

避免重复循环渲染

利用useEffect接收一个数组作为第二个参数,将第二个参数作为dependence,每次渲染完DOM执行副作用函数时都会浅比较dependence渲染前后的值是否一致,不一致就执行副作用,反之就不执行;如果该dependence为一个空数组[],即没有传入比较变化的变量,则比较结果永远都保持不变,那么副作用逻辑就只能执行一次。

useEffect(() => {
  setTimeout(() => {    
        setCounter(counter + 1);  
    }, 300)
}, []);

初此之外,如果我们还想通过点击刷新按钮实现获取外部数据但又不想造成死循环,那么可以通过一个变量作为“开关”,在实现目的的同时做到避免循环渲染DOM。

画动图太麻烦,各位看注释脑补😂

function App() {  const [count, setCount] = useState(0);  const [loading, setLoading] = useState(true); // loading作为开关  useEffect(() => {    if (loading) { // 注意这里只有当loading为true时才执行      setTimeout(() => {        setCount(count + 1);        setLoading(!loading); // 改变loading值      });    }  }, [loading]); // loading在这里作为dependence
  // 第一次DOM渲染完成后,loading为true,执行副作用函数,count值变为1,loading变为false,由于
  // 改变了state的值,会update,组件会再次render,但此时loading为false,不会执行setTimeout,
  // 避免了循环

  // 当点击Refresh刷新,loading由上一次的false变为了true,函数执行一次update
  // DOM更新完后执行useEffect,因为loading已经为true了,所以副作用函数可执行,count从1变为2,
  // loading又从true变为false,就这样交替进行。。。
  return (    <div>      <h3>{count}</h3>      <button        onClick={() => {          setLoading(true);        }}      >        Refresh      </button>    </div>  );}

关于副作用的清除

useEffect可以返回一个函数来作为清除副作用。

  useEffect(() => {    
    ChatAPI.subscribeToFriendStatus(props.id, handleStatusChange);  
    function clear(){
        ChatAPI.unsubscribeFromFriendStatus(props.id, handleStatusChange);
    }  
    return clear;
});

这里会涉及到useEffect执行和销毁的过程:

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

由此可推测出副作用清除函数的特征:

  • 每次副作用执行都会返回一个清除函数
  • 清除函数会在下一次副作用函数执行之前(DOM渲染完成之后)执行
  • 组件销毁也会执行一次清除函数

从打印出的count值也可以看出,清除函数会在下一次副作用函数执行之前执行,即在清除函数里的count值是上一次缓存的count值:

进一步思考,clear1执行的时候,访问了props.id,那么这个id值是1还是2呢?

这里就涉及到闭包的知识概念了,因为useEffect返回的是个函数,在执行时产生了一个闭包,根据闭包的相关定义,返回的clear函数能访问自身作用域外的变量,当组件第一次渲染时传入id=1,此时的clear函数中的props.id值为1。

以上就是React useEffect的理解与使用的详细内容,更多关于React useEffect的资料请关注脚本之家其它相关文章!

相关文章

  • webpack手动配置React开发环境的步骤

    webpack手动配置React开发环境的步骤

    本篇文章主要介绍了webpack手动配置React开发环境的步骤,webpack手动配置一个独立的React开发环境, 开发环境完成后, 支持自动构建, 自动刷新, sass语法 等功能...感兴趣的小伙伴们可以参考一下
    2018-07-07
  • React文件名和目录规范最佳实践记录(总结篇)

    React文件名和目录规范最佳实践记录(总结篇)

    React在使用时非常灵活,如果没有一个规范约束项目,在开发过程中会非常混乱,本文将介绍几个优秀的规范,介绍文件名和目录前,需要先简述一下几种通用的类型,用来区分文件的功能,感兴趣的朋友一起看看吧
    2022-05-05
  • react搭建环境时执行npm start报错start: 'react-scripts start'的解决

    react搭建环境时执行npm start报错start: 'react-scripts&

    这篇文章主要介绍了react搭建环境时执行npm start报错start: 'react-scripts start'的解决方案,具有很好的参考价值,希望杜对大家有所帮助,
    2023-10-10
  • 一文学会使用Remix写API接口

    一文学会使用Remix写API接口

    这篇文章主要为大家介绍了一文学会Remix写API接口实现示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-04-04
  • react-navigation 如何判断用户是否登录跳转到登录页的方法

    react-navigation 如何判断用户是否登录跳转到登录页的方法

    本篇文章主要介绍了react-navigation 如何判断用户是否登录跳转到登录页的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-12-12
  • React 实现井字棋的示例代码

    React 实现井字棋的示例代码

    本文主要介绍了React 实现井字棋,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-07-07
  • 深入理解React Native核心原理(React Native的桥接(Bridge)

    深入理解React Native核心原理(React Native的桥接(Bridge)

    这篇文章主要介绍了深入理解React Native核心原理(React Native的桥接(Bridge),本文重点给大家介绍React Native的基础知识及实现原理,需要的朋友可以参考下
    2021-04-04
  • React Native 搭建开发环境的方法步骤

    React Native 搭建开发环境的方法步骤

    本篇文章主要介绍了React Native 搭建开发环境的方法步骤,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-10-10
  • react纯函数组件setState更新页面不刷新的解决

    react纯函数组件setState更新页面不刷新的解决

    在开发过程中,经常遇到组件数据无法更新,本文主要介绍了react纯函数组件setState更新页面不刷新的解决,感兴趣的可以了解一下
    2021-06-06
  • React Hooks获取数据实现方法介绍

    React Hooks获取数据实现方法介绍

    这篇文章主要介绍了react hooks获取数据,文中给大家介绍了useState dispatch函数如何与其使用的Function Component进行绑定,实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2022-10-10

最新评论