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. python数据类型、用户交互和运算符

    基本数据类型 1.字典dict(dictionary) 能够准确的记录储存的信息 """ 大括号里面 放多个元素 之间用逗号隔开 元素为K:V键表示储存 K相对于V一般表 ...

  2. Volatile的学习

    首先先介绍三个性质 可见性 可见性代表主内存中变量更新,线程中可以及时获得最新的值. 下面例子证明了线程中可见性的问题 由于发现多次执行都要到主内存中取变量,所以会将变量缓存到线程的工作内存,这样当其 ...

  3. linux篇-linux awstats搭建

    1安装lnmp模式 2安装awstats 2# tar xf awstats-6.5.tar.gz 解压下载到/root下的压缩包 mkdir /var/lib/awstats chmod 755 / ...

  4. Fail2ban 命令详解 fail2ban-client

    Fail2ban的客户端操作命令,用于控制服务端. root@ubuntu:~# fail2ban-client --help Usage: /usr/bin/fail2ban-client [OPT ...

  5. 在 Git 提交信息中使用 Emoji

    Gitmoji 旨在解释如何在 Git 提交消息时使用表情符号.在提交信息时使用表情符号,可以更容易地识别提交的目的或意图. Emoji 列表 :优化项目结构 / 代码格式 :art: ️ :性能提升 ...

  6. 通过一次生产case深入理解tomcat线程池

    最近生产上遇到一个case,终于想明白了原因,今天周末来整理一下 生产case 最近测试istio mesh的预热功能(调用端最小连接数原则) 来控制调用端进入k8s刚扩出来的容器的流量 因为刚启动的 ...

  7. Mac下iTerm2安装rzsz后上传下载失败解决

    背景描述 mac环境,安装了iTerm2,需要使用ssh登陆linux服务器.服务器登陆需要经过以下步骤 输入token 输入登陆选项 输入IP 因此写了expect脚本来完成自动输入 但是在上传下载 ...

  8. CSS的几种选择器

    选择器 目录 选择器 基础选择器 标签选择器 类选择器 id选择器 通配符选择器 复合选择器 后代选择器 子选择器 并集选择器 伪类选择器 基础选择器 标签选择器 标签选择器可以把一类标签全部选择出来 ...

  9. 【clickhouse专栏】clickhouse性能为何如此卓越

    在<clickhouse专栏>上一篇文章中<数据库.数据仓库之间的区别与联系>,我们介绍了什么是数据库,什么是数据仓库,二者的区别联系.clickhouse的定位是" ...

  10. conda install和pip install区别

    conda ≈ pip(python包管理) + virtualenv(虚拟环境) + 非python依赖包管理 级别不一样conda和yum比较类似,可以安装很多库,不限于Python.conda是 ...