2 Effect Hook
副作用:和外部有交互
- 引用外部变量
- 调用外部函数
- 修改dom、全局变量
- ajax
- 计时器(依赖window.setTimeout)
- 存储相关
纯函数:相同的输入一定会得到相同的输出
Effect Hook可以让你在函数组件中执行副作用操作
类组件中处理副作用
- 在
componentDidMount
/componentDidUpdate
声明周期中(真实dom构建以前)
useEffect执行时机
- 初次渲染之后 didMount(真实dom构建以后)
- 渲染更新时 didUpdate
- 是异步的,在回调函数中拿到更新的state
存在清理函数
- 首次执行: render → useEffect
- 再次执行: render → 清理函数 → useEffect
- 清理函数:组件更新、组件销毁时执行
组件更新
useEffect(() => {console.log('useEffect')return () => {console.log('clear Effect')}
})
import { useState, useEffect } from 'react'
export default function App(props) {const [count, setCount] = useState(() => {console.log(1); // 惰性初始化,只会打印一次return 1});useEffect(() => {// 持续递增console.log('useEffect')let timer = setInterval(() => { // 2. 每一次副作用都会重新初始化一个timersetCount(count + 1)}, 1000)return () => {clearInterval(timer) // 1.闭包 第二次运行时,先清理上一次的timerconsole.log('clear Effect')}})return (<><h1>{count}</h1></>)
}
组件销毁
import { useState, useEffect } from 'react'
function Test() {const [count, setCount] = useState(1);useEffect(() => {console.log('useEffect')return () => {console.log('clear Effect') // 组件更新、销毁时执行}})return (<><h1>{count}</h1><button onClick={() => setCount(count + 1)}>add</button></>)
}
export default function App() {const [show, setShow] = useState(true)return (<>{show && <Test />}<button onClick={() => setShow(!show)}>changeShow</button></>)
}
只在didMount时执行
依赖项
- 指定当前effect函数所需要的依赖项
- 若依赖项是
[]
,在初次渲染和卸载的时候执行 - 若依赖项不变,effect不执行
- 存在依赖项 && 依赖项更新时,effect执行
import { useState, useEffect } from 'react'
function Test() {const [count, setCount] = useState(1);useEffect(() => {console.log('useEffect')let timer = setInterval(() => { // didMount时执行一次// setCount(count + 1) // 若在依赖项中未填入count,则此时count拿到的一直是0!// 但填入count依赖不能解决“只在didMount时执行”的问题// 改成回调的方式,能获取最新的countsetCount(count => count + 1)}, 1000)return () => {clearInterval(timer) // 组件销毁时执行,didMount时不执行console.log('clear Effect')}}, []) // 增加了依赖项return (<><h1>{count}</h1><button onClick={() => setCount(count + 1)}>add</button></>)
}
export default function App() {const [show, setShow] = useState(true)return (<>{show && <Test />}<button onClick={() => setShow(!show)}>changeShow</button></>)
}
竞态问题
- 接口返回的时长不同,后返回的覆盖了之前的数据,导致没有渲染正确的结果
现象:结果3覆盖了4
import { useState, useEffect } from 'react'
const API = {async queryEmployeesByid(id) {return new Promise((resolve) => {setTimeout(() => {resolve({id,currentDepartment: `currentDepartment:${id}`})}, 300 * (10 - id))// id越大,返回越快,模拟后发的请求比先发的请求快})}
}
const Department = props => {let { id } = props;let [employees, setEmployees] = useState({})useEffect(() => {let didCancel = false; // 解决竞态问题(async function fetchData() {let employee = await API.queryEmployeesByid(id)// 解决竞态问题,最后一次点的时候先true再false,拿到对应id的请求结果if (!didCancel) {setEmployees(employee)}})()return () => { // 解决竞态问题didCancel = true}}, [id])return (<>{employees.currentDepartment}</>)
}
const App = params => {let [id, setId] = useState(1)return (<><p>id:{id}</p><Department id={id} /><br /><button onClick={() => setId(id + 1)}>id++</button></>)
}
export default App
2 Effect Hook相关推荐
- reactjs三个常用的Hook:State Hook、 Effect Hook、 Ref Hook
1. React Hook/Hooks是什么? (1). Hook是React 16.8.0版本增加的新特性/新语法 (2). 可以让你在函数组件中使用 state 以及其他的 React 特性 2. ...
- React Hook之Effect Hook
文章目录 Effect Hook概念性内容介绍: 如果朋友们想在里面进行异步操作的话请这样用[或者你可以把这个方法放到外面在这里调用即可]: 我们可以监听某个状态的变化来进行一些操作 useEffec ...
- Hook 学习系列(二) —— Effect Hook
Effect Hook 清除 effect 多个effect 跳过 Effect 今天学习另一个 Hook: useEffect,它能在函数组件中执行副作用,与 class 中的生命周期函数极为类似. ...
- 前端学习(3294):effect hook
- 前端学习(3293):effect hook
- React Hook的用法: State + Effect(一)
React Hook 简述 React Hook 是React 16.8 这个版本新增的一个特性.在此之前我们编写React组件一般大多数都是用 class组件,而非函数组件,因为函数组件不具有cla ...
- 如何使用React Hook
class组件和函数组件 我们希望编写代码的时候,尽可能将整块可复用的部分封装起来.这样可以一定程度提高代码的内聚性,将其耦合性,使得程序开发变得更加可维护.通常情况下,我们将代码块抽离成组件来实现封 ...
- react --- Hook的使用
Hook 是React16.8一个新增项,它可以让你在不编写class的情况下使用state以及其他的React特性 特点: 无需修改组件结构的情况下复用状态逻辑 将组件相互关联的部分拆分成更小的函数 ...
- React hook 中的数据获取
相关说明: 对于hook相关词不翻译,感觉翻译后怪怪的. effect hook 效果钩子,用于执行一些副作用例如获取数据 . state hook 状态钩子. 使用----------- 和 --- ...
最新文章
- irobot擦地机器人故障_自己动手修复 iRobot braava380t 电机故障
- Ubuntu 安装docker-engine的三种方法
- ASUS WL-500W企业级无线路由器试用
- 利用计算机峰值,计算机的峰值速度
- 内存条上面参数详解_价格极低的国产颗粒内存条:光威弈系列Pro评测,超频表现超稳定...
- svn checkout 提示“由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。”解决方法...
- SQL Server生成含有数据的脚本文件
- 中兴F460电信光纤猫超级用户密码
- MATLAB学习笔记 plotyy双y轴
- 基于R语言的模型组合
- “博客之星”年度评选
- html相同数据合并单元格合并单元格,Javascript合并表格中具有相同内容单元格示例...
- POI XWPFParagraph.getRuns分段混乱问题解决
- 蓝桥杯JAVA答题技巧,第九届蓝桥杯大赛个人赛省赛(软件类)C/C++ 大学B组比赛心得(还在更新)...
- 鸿蒙试用体验,华为手机鸿蒙OS 2.0试用体验:手表可接收滴滴网约车动态 抬腕可看导航路线...
- CSS——CSS浮动与清除浮动
- 推荐6款非常实用的工具,你用过几款呢?
- gocolly-OnResponse的使用(3)
- gt爵士变形步骤_代码广播简介:编码时您可以收听的24/7爵士节奏
- 如何配置TeXstudio+SumatraPDF+Texlive
热门文章
- python读取大文件目录_65.Python读取大文件
- java jai create 方法_使用JAI扩展Java Image的功能
- java web 线程数_Java Web应用调优线程池
- scrapy如何指定生成python3的项目_新手学习scrapy的坑(都是泪)
- java changestr,java change
- 看了数百个PPT封面,我只想告诉你这两个套路!
- mysql之库操作_创建用户_修改用户权限_修改用户密码
- JAVA EE 基本了解
- hdu 5273 Dylans loves sequence 逆序数 区间dp
- SPSS输出的结果都要写到文章中吗