副作用:和外部有交互

  1. 引用外部变量
  2. 调用外部函数
  3. 修改dom、全局变量
  4. ajax
  5. 计时器(依赖window.setTimeout)
  6. 存储相关

纯函数:相同的输入一定会得到相同的输出
Effect Hook可以让你在函数组件中执行副作用操作

类组件中处理副作用

  • componentDidMount/componentDidUpdate声明周期中(真实dom构建以前)

useEffect执行时机

  • 初次渲染之后 didMount(真实dom构建以后)
  • 渲染更新时 didUpdate
  • 是异步的,在回调函数中拿到更新的state

存在清理函数

  1. 首次执行: render → useEffect
  2. 再次执行: render → 清理函数 → useEffect
  3. 清理函数:组件更新、组件销毁时执行

组件更新

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相关推荐

  1. reactjs三个常用的Hook:State Hook、 Effect Hook、 Ref Hook

    1. React Hook/Hooks是什么? (1). Hook是React 16.8.0版本增加的新特性/新语法 (2). 可以让你在函数组件中使用 state 以及其他的 React 特性 2. ...

  2. React Hook之Effect Hook

    文章目录 Effect Hook概念性内容介绍: 如果朋友们想在里面进行异步操作的话请这样用[或者你可以把这个方法放到外面在这里调用即可]: 我们可以监听某个状态的变化来进行一些操作 useEffec ...

  3. Hook 学习系列(二) —— Effect Hook

    Effect Hook 清除 effect 多个effect 跳过 Effect 今天学习另一个 Hook: useEffect,它能在函数组件中执行副作用,与 class 中的生命周期函数极为类似. ...

  4. 前端学习(3294):effect hook

  5. 前端学习(3293):effect hook

  6. React Hook的用法: State + Effect(一)

    React Hook 简述 React Hook 是React 16.8 这个版本新增的一个特性.在此之前我们编写React组件一般大多数都是用 class组件,而非函数组件,因为函数组件不具有cla ...

  7. 如何使用React Hook

    class组件和函数组件 我们希望编写代码的时候,尽可能将整块可复用的部分封装起来.这样可以一定程度提高代码的内聚性,将其耦合性,使得程序开发变得更加可维护.通常情况下,我们将代码块抽离成组件来实现封 ...

  8. react --- Hook的使用

    Hook 是React16.8一个新增项,它可以让你在不编写class的情况下使用state以及其他的React特性 特点: 无需修改组件结构的情况下复用状态逻辑 将组件相互关联的部分拆分成更小的函数 ...

  9. React hook 中的数据获取

    相关说明: 对于hook相关词不翻译,感觉翻译后怪怪的. effect hook 效果钩子,用于执行一些副作用例如获取数据 . state hook 状态钩子. 使用----------- 和 --- ...

最新文章

  1. irobot擦地机器人故障_自己动手修复 iRobot braava380t 电机故障
  2. Ubuntu 安装docker-engine的三种方法
  3. ASUS WL-500W企业级无线路由器试用
  4. 利用计算机峰值,计算机的峰值速度
  5. 内存条上面参数详解_价格极低的国产颗粒内存条:光威弈系列Pro评测,超频表现超稳定...
  6. svn checkout 提示“由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。”解决方法...
  7. SQL Server生成含有数据的脚本文件
  8. 中兴F460电信光纤猫超级用户密码
  9. MATLAB学习笔记 plotyy双y轴
  10. 基于R语言的模型组合
  11. “博客之星”年度评选
  12. html相同数据合并单元格合并单元格,Javascript合并表格中具有相同内容单元格示例...
  13. POI XWPFParagraph.getRuns分段混乱问题解决
  14. 蓝桥杯JAVA答题技巧,第九届蓝桥杯大赛个人赛省赛(软件类)C/C++ 大学B组比赛心得(还在更新)...
  15. 鸿蒙试用体验,华为手机鸿蒙OS 2.0试用体验:手表可接收滴滴网约车动态 抬腕可看导航路线...
  16. CSS——CSS浮动与清除浮动
  17. 推荐6款非常实用的工具,你用过几款呢?
  18. gocolly-OnResponse的使用(3)
  19. gt爵士变形步骤_代码广播简介:编码时您可以收听的24/7爵士节奏
  20. 如何配置TeXstudio+SumatraPDF+Texlive

热门文章

  1. python读取大文件目录_65.Python读取大文件
  2. java jai create 方法_使用JAI扩展Java Image的功能
  3. java web 线程数_Java Web应用调优线程池
  4. scrapy如何指定生成python3的项目_新手学习scrapy的坑(都是泪)
  5. java changestr,java change
  6. 看了数百个PPT封面,我只想告诉你这两个套路!
  7. mysql之库操作_创建用户_修改用户权限_修改用户密码
  8. JAVA EE 基本了解
  9. hdu 5273 Dylans loves sequence 逆序数 区间dp
  10. SPSS输出的结果都要写到文章中吗