react 16.8发布以来,函数式写法逐渐取代class的写法,在react函数式写法中,最重要是就是react所推出的新特性:hook,今天就来简单谈谈最基础的hook——useEffect

在react的类时代,人们最关心的便是类中生命周期方法,你熟悉 React class 的生命周期函数,你可以把 useEffect Hook 看做 componentDidMount(组件挂载即被执行)componentDidUpdate(组件更新执行) 和 componentWillUnmount(组件卸载执行) 这三个函数的组合

那针对这三种方法,我们便来看看useEffect是如何使用的

在此贴上官方最经典的案例

import React, { useState, useEffect } from 'react';

function Example() {
const [count, setCount] = useState(0); useEffect(() => {
document.title = `You clicked ${count} times`;
}); return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}

由上述代码可知,我们在函数中使用hook,当组件进行挂载,更新,以及卸载时,都会执行一遍useEffect中的方法,在某些class的场景中会遇到生命周期写相同的方法,这在代码优雅性显得没那么好看,而在新推出的hook方法中,只需要一个hook即可处理相同生命周期的方法,这样子的代码是否更好看些了呢?

在官方的代码中,我们执行后便会发现,当组件进行挂载,更新,以及卸载时都会执行一遍方法,那么我们如何控制他们呢?尤其在组件更新时,我们肯定是不想在必要的更新中执行非必要的代码

hook提供了两种方法供我们控制不同的时间段执行的代码

useEffect'提供两种入参,第一个入参:函数 第二个入参:数据(可选)

入参一即hook中处理的方法,入参二就是控制hook的执行的变量了

如何与组件挂载,更新,卸载联系呢?

组件挂载:即入参一的函数执行

组件更新:即入参二的数据监听

组件卸载:即入参一的函数返回

直接贴出代码

组件挂载我们不用多说,当你写出useEffect时,无论如何,在组件挂载时都会执行,所以我们着重讲下组件的更新及卸载import React, { useState, useEffect } from 'react';

function Example() {
const [count, setCount] = useState(0); useEffect(() => {
document.title = `You clicked ${count} times`;
   return ()=>{
    console.log("组件卸载")
  }
}); return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}

组件卸载:将上面代码进行修改,你只需知道,我们传入函数到react中的时候,既然是函数,自然有返回值,当你返回一个函数时,你所返回的函数就会在卸载时执行,当你进行点击时,你会发现,日志中一直打印组件卸载,这其实是因为effect 发生在“渲染之后”这种概念,不用再去考虑“挂载”还是“更新”。React 保证了每次运行 effect 的同时,DOM 都已经更新完毕。

function Example() {
const [count, setCount] = useState(0);
 const [change,setChange] = useState(false) useEffect(() => {
document.title = `You clicked ${count} times`;
   return ()=>{
    console.log("组件卸载")
  }
},[change]); return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
    <button onClick={()=>setChange(!change)}>
     change Click 
     </button>
</div>
);
}
 依旧是上述代码,我们在useEffect第二个参数传入一个数组,该数组中传入change变量,那么当change发生改变时,useEffect就会重新渲染执行
function Example() {
const [count, setCount] = useState(0);
 const [change,setChange] = useState(false) useEffect(() => {
document.title = `You clicked ${count} times`;
   return ()=>{
    console.log("组件卸载")
  }
},[]); return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
    <button onClick={()=>setChange(!change)}>
     change Click 
     </button>
</div>
);
}

当我们传入空数组时,那么useEffect在组件的生命周期中就只会执行一次

至此useEffect的基础使用就已经阐述完毕,但在实际的使用中,我们会遇到许多问题,下面就提出我遇到的一个问题,也是促使我写此博客的缘由

看下如下代码

function Example() {
const [count, setCount] = useState(0);
 const [change,setChange] = useState(false) useEffect(() => {
document.title = `You clicked ${count} times`;
   return ()=>{
    console.log("组件卸载")
console.log('只执行一次的hook',change)
  }
},[]); useEffect(() => {
document.title = `You clicked ${count} times`;
   return ()=>{
    console.log("组件卸载")
console.log(change)
  }
},[change]); return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
  <button onClick={()=>setChange(!change)}>
   change Click 
  </button>
</div>
);
}

在上述代码中,我们写了两个useEffect,一个有change的监听,一个只执行一遍,我们都在卸载时打印change的值,会发现有监听的hook,在监听的变量发生改变时就会打印改变前的变量,无监听则会在组件卸载时执行一次,effect原理其实可以理解成,在组件挂载时就会将数据记录,当卸载hook时执行的方法,只会取到挂载时的变量,无法拿到最新的变量。因此若hook只执行一次,我们就不应当在hook卸载的方法中,去获取最新的数据,因为这是获取不到的

传递给 useEffect 的函数在每次渲染中都会有所不同,这是刻意为之的。事实上这正是我们可以在 effect 中获取最新的 count 的值,而不用担心其过期的原因。每次我们重新渲染,都会生成新的 effect,替换掉之前的。

React 何时清除 effect? React 会在组件卸载的时候执行清除操作。正如之前学到的,effect 在每次渲染的时候都会执行。这就是为什么 React 在执行当前 effect 之前对上一个 effect 进行清除。

浅谈hooks——useEffect的更多相关文章

  1. 浅谈angular2+ionic2

    浅谈angular2+ionic2   前言: 不要用angular的语法去写angular2,有人说二者就像Java和JavaScript的区别.   1. 项目所用:angular2+ionic2 ...

  2. 浅谈 Requests包

    浅谈 Requests包 一:Requests包是做什么的? 简单地说,是用python处理HTTP的一个包. 它的标志也非常有气质,是一个双蛇杖,按照官方的说法,一条蛇代表client,一条代表se ...

  3. 开发工具--浅谈Git

    工具|浅谈Git Git这个工具,是我一直想写文章,终于我实现了我的想法.在我开始写之前,发表一下自己的看法,git只是一个工具,既然已经认定是一个工具,那么一定具备工具这类的共同特征,请用面向对象的 ...

  4. 浅谈 Fragment 生命周期

    版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Fragment 文中如有纰漏,欢迎大家留言指出. Fragment 是在 Android 3.0 中 ...

  5. 浅谈 LayoutInflater

    浅谈 LayoutInflater 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/View 文中如有纰漏,欢迎大家留言指出. 在 Android 的 ...

  6. 浅谈Java的throw与throws

    转载:http://blog.csdn.net/luoweifu/article/details/10721543 我进行了一些加工,不是本人原创但比原博主要更完善~ 浅谈Java异常 以前虽然知道一 ...

  7. 浅谈SQL注入风险 - 一个Login拿下Server

    前两天,带着学生们学习了简单的ASP.NET MVC,通过ADO.NET方式连接数据库,实现增删改查. 可能有一部分学生提前预习过,在我写登录SQL的时候,他们鄙视我说:“老师你这SQL有注入,随便都 ...

  8. 浅谈WebService的版本兼容性设计

    在现在大型的项目或者软件开发中,一般都会有很多种终端, PC端比如Winform.WebForm,移动端,比如各种Native客户端(iOS, Android, WP),Html5等,我们要满足以上所 ...

  9. iOS开发之浅谈MVVM的架构设计与团队协作

    今天写这篇博客是想达到抛砖引玉的作用,想与大家交流一下思想,相互学习,博文中有不足之处还望大家批评指正.本篇博客的内容沿袭以往博客的风格,也是以干货为主,偶尔扯扯咸蛋(哈哈~不好好工作又开始发表博客啦 ...

随机推荐

  1. SHCTF web题

    第一题:直接查看robots.txt,得到flag 第二题:他的题的意思通过get方式一个字符一个字符去猜如果对的话他下面的小方格就会亮起,用python写个脚本就过了 第三题:也是猜flag 解题方 ...

  2. 探索ABP的EventHub解决方案

    在上一章中,我们构建了一个简单的全栈 Web 应用程序,我们已经看到了使用 ABP 框架开发应用的典型流程,在接下来,我们将使用 ABP 框架创建更高级的应用程序. 给出具有现实世界复杂性的例子并不容 ...

  3. 探索 Python/Django 支持分布式多租户数据库,如 Postgres+Citus

    在 确定分布策略 中,我们讨论了在多租户用例中使用 Citus 所需的与框架无关的数据库更改. 在这里,我们专门研究如何借助 django-multitenant 库将多租户 Django 应 用程序 ...

  4. 最新版2022年任我行管家婆工贸版ERP M7 V22.0进销存财务生产管理软件网络版——云上的集团化制造管理系统

    在互联网+制造业的时代背景下,制造业在利用互联网技术进行转型升级的同时,也面临着供应链体系和生产模式的重塑,主要呈现出以下特点: 多元化发展 对外,传统企业正在通过"互联网+"逐步 ...

  5. python面向对象(封装、多态、反射)

    目录 面向对象之封装 @property 面向对象之多态 面向对象之反射 面向对象之封装 含义 将类中的某些名字按照特殊的书写方式"隐藏"起来,不让外界直接调用,目的是为了不然外界 ...

  6. vs2022+resharper创建模板——实现在新建文件的时候自动生成防卫式声明和自定义语句

    在网上找了很久如何让visual studio新建文件的时候自动生成注释和防卫式声明,虽然防卫式声明可以用#proga once替代,但是在clion里可以自动生成vs里面没法自动生成还是觉得难受,于 ...

  7. Python中plt.plot()、plt.scatter()和plt.legend函数的用法示例

    参考:http://www.cppcns.com/jiaoben/python/471948.html https://blog.csdn.net/weixin_44825185/article/de ...

  8. c++ 快速乘

    First 在一些数学题中,两个数相乘运算很多,同时又很容易溢出,如两个 long long 相乘 今天本蒟蒻来总结一下快速乘的两种方法 1:二进制 和快速幂的原理一样,优化一个一个加的算法,复杂度\ ...

  9. 2020 CSP-J 初赛游记

    估分 预估 85 分,一是怕选错,而是最后真的错了一些 考点 排列组合:论临时抱佛脚的作用 靠前看了一下捆绑法和插板法,果然考了. 2.算法常识,和复杂度分析 冒泡排序最小交换次数 = n-1 , G ...

  10. idea 中菜单栏定位到类的图标消失(小齿轮按钮)

    本文链接:https://www.cnblogs.com/hchengmx/p/14533349.html 在2019.2以及以下版本 勾选:Autoscroll from source: 在2019 ...