浅谈hooks——useEffect
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>
);
}
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的更多相关文章
- 浅谈angular2+ionic2
浅谈angular2+ionic2 前言: 不要用angular的语法去写angular2,有人说二者就像Java和JavaScript的区别. 1. 项目所用:angular2+ionic2 ...
- 浅谈 Requests包
浅谈 Requests包 一:Requests包是做什么的? 简单地说,是用python处理HTTP的一个包. 它的标志也非常有气质,是一个双蛇杖,按照官方的说法,一条蛇代表client,一条代表se ...
- 开发工具--浅谈Git
工具|浅谈Git Git这个工具,是我一直想写文章,终于我实现了我的想法.在我开始写之前,发表一下自己的看法,git只是一个工具,既然已经认定是一个工具,那么一定具备工具这类的共同特征,请用面向对象的 ...
- 浅谈 Fragment 生命周期
版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Fragment 文中如有纰漏,欢迎大家留言指出. Fragment 是在 Android 3.0 中 ...
- 浅谈 LayoutInflater
浅谈 LayoutInflater 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/View 文中如有纰漏,欢迎大家留言指出. 在 Android 的 ...
- 浅谈Java的throw与throws
转载:http://blog.csdn.net/luoweifu/article/details/10721543 我进行了一些加工,不是本人原创但比原博主要更完善~ 浅谈Java异常 以前虽然知道一 ...
- 浅谈SQL注入风险 - 一个Login拿下Server
前两天,带着学生们学习了简单的ASP.NET MVC,通过ADO.NET方式连接数据库,实现增删改查. 可能有一部分学生提前预习过,在我写登录SQL的时候,他们鄙视我说:“老师你这SQL有注入,随便都 ...
- 浅谈WebService的版本兼容性设计
在现在大型的项目或者软件开发中,一般都会有很多种终端, PC端比如Winform.WebForm,移动端,比如各种Native客户端(iOS, Android, WP),Html5等,我们要满足以上所 ...
- iOS开发之浅谈MVVM的架构设计与团队协作
今天写这篇博客是想达到抛砖引玉的作用,想与大家交流一下思想,相互学习,博文中有不足之处还望大家批评指正.本篇博客的内容沿袭以往博客的风格,也是以干货为主,偶尔扯扯咸蛋(哈哈~不好好工作又开始发表博客啦 ...
随机推荐
- Json序列化与反序列化导致多线程运行速度和单线程运行速度一致问题
紧跟上篇文章 十个进程开启十个bash后一致写入命令执行完毕之后产生了很多很多的文件,博主需要对这些文件同意处理,也就是说对几十万个文件进行处理,想了又想,单线程处理那么多数据肯定不行,于是乎想到了使 ...
- PTA 7-4 堆栈操作合法性 (20 分)
假设以S和X分别表示入栈和出栈操作.如果根据一个仅由S和X构成的序列,对一个空堆栈进行操作,相应操作均可行(如没有出现删除时栈空)且最后状态也是栈空,则称该序列是合法的堆栈操作序列.请编写程序,输入S ...
- java并发编程-StampedLock高性能读写锁
目录 一.读写锁 二.悲观读锁 三.乐观读 欢迎关注我的博客,更多精品知识合集 一.读写锁 在我的<java并发编程>上一篇文章中为大家介绍了<ReentrantLock读写锁> ...
- 软件项目管理 ——1.2.PMBOK与软件项目管理知识体系
软件项目管理 --1.2.PMBOK与软件项目管理知识体系 归档于软件项目管理初级学习路线 第一章 软件项目管理基本概念 <初级学习路线合集 > @ 目录 软件项目管理 --1.2.PMB ...
- redis & redis sentinel
Redis 命令参考 Redis Sentinel Cheat Sheet Redis 哨兵节点之间相互自动发现机制(自动重写哨兵节点的配置文件) Redis哨兵模式(sentinel)学习总结及部署 ...
- 48. Rotate Image - LeetCode
Question 48. Rotate Image Solution 把这个二维数组(矩阵)看成一个一个环,循环每个环,循环每条边,每个边上的点进行旋转 public void rotate(int[ ...
- PKUSC2022 游记
PKUSC2022 游记 Day1 上午随便看了点题,感觉没看什么题就开考了. 开考之后先看 T1,发现 T1 好像不是那么简单. T1 : 九条可怜有两个账号,她每次都会打 \(\rm rating ...
- 通过CSS让图片变的清楚
image { width: 100%; height: 100%; border-radius: 10upx; //让图片变清楚 image-rendering: -moz-crisp-edges; ...
- 喜提JDK的BUG一枚!多线程的情况下请谨慎使用这个类的stream遍历。
你好呀,我是歪歪. 前段时间在 RocketMQ 的 ISSUE 里面冲浪的时候,看到一个 pr,虽说是在 RocketMQ 的地盘上发现的,但是这个玩意吧,其实和 RocketMQ 没有任何关系. ...
- 使用node.js如何简单快速的搭建一个websocket聊天应用
初始化项目 npm init 安装nodejs-websocket npm install nodejs-websocket 创建并编辑启动文件 创建一个名为app.js文件,并且编辑它. var w ...