浅谈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的架构设计与团队协作
今天写这篇博客是想达到抛砖引玉的作用,想与大家交流一下思想,相互学习,博文中有不足之处还望大家批评指正.本篇博客的内容沿袭以往博客的风格,也是以干货为主,偶尔扯扯咸蛋(哈哈~不好好工作又开始发表博客啦 ...
随机推荐
- 用 Python 为接口测试自动生成用例
用Python为接口自动生成测试用例 基于属性的测试会产生大量的.随机的参数,特别适合为单元测试和接口测试生成测试用例 尽管早在2006年haskell语言就有了QuickCheck来进行" ...
- selenium模块 phantomJs 谷歌无可视界面
参考微博: 什么是selenium 一款基于浏览器自动化的模块 什么是浏览器自动化 通过脚本程序或者python代码,这组程序或者代码表示一些行为动作,selenium可以让这些行为动作映射到浏览器中 ...
- 基于C++11的线程池实现
1.线程池 1.1 线程池是什么? 一种线程管理方式. 1.2 为什么用线程池? 线程的创建和销毁都需要消耗系统开销,当线程数量过多,系统开销过大,就会影响缓存局部性和整体性能.而线程池能够在充分利用 ...
- 论文解读(ClusterSCL)《ClusterSCL: Cluster-Aware Supervised Contrastive Learning on Graphs》
论文信息 论文标题:ClusterSCL: Cluster-Aware Supervised Contrastive Learning on Graphs论文作者:Yanling Wang, Jing ...
- CI/CD介绍以及jenkins安装 1.1
一 .CI/CD介绍 互联网软件开发和发布,形成了一套流程标准,分为几个阶段:编码,构建,集成,测试,交付,部署 持续集成(continuous integration).持续交付(conti ...
- 个人冲刺(三)——体温上报app(二阶段)
冲刺任务:完成用户类.温度数据和第二页面类的编写 User.java package com.example.helloworld; class User { private String usern ...
- 编程语言与python与pycharm的下载
目录 编程语言的发展史 编程语言的分类 python解释器 python解释器的下载与安装 环境变量 执行python程序方式 pycharm编辑器 编程语言的发展史 机器语言是最开始的编程语言,之后 ...
- Linux系统执行命令方法
现在我们无论是工作中还是学习中很多情况下用到Linux系统,当我们需要在C#代码中调用类似与cmd窗口执行命令时候,就需要用到此方法 public static Process CommitComma ...
- sqlserver 插入 更新 删除 语句中的 output子句
官方文档镇楼: https://docs.microsoft.com/zh-cn/previous-versions/sql/sql-server-2008/ms177564(v=sql.100) 从 ...
- 定制ASP.NET 6.0的应用配置
大家好,我是张飞洪,感谢您的阅读,我会不定期和你分享学习心得,希望我的文章能成为你成长路上的垫脚石,让我们一起精进. 本文的主题是应用程序配置.要介绍的是如何使用配置.如何自定义配置,以采用不同的方式 ...