2 Effect Hook

副作用:和外部有交互

  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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/250812.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【JUC】CountDownLatch

因为在调用端的异步中&#xff0c;需要调用其他多个服务获取数据再汇总结果返回&#xff0c;所以用到了CountDownLatch CountDownLatch的概念 CountDownLatch是一个同步工具类&#xff0c;用来协调多个线程之间的同步&#xff0c;或者说起到线程之间的通信&#xff08;而不是用…

node --- Missing write access to 解决

今天在使用npm安装animate.css时报错… 大体原因是没有对node_modules没有写的权限. 百度查到是要删除对应的node_modules然后在安装… 但是我并不想这样做…想起前面我为了加快下载速度,好像使用的是cnpm… 于是我使用了nrm ls 查看当前使用的源 更换npm的源可以参考 https:…

vue踩坑- 报错npm ERR! cb() never called!

在vue项目中引入饿了么elementUI组件的步骤之中&#xff0c;出现以下的错误&#xff1a; D:\my-project-first>npm i element-ui -S Unhandled rejection RangeError: Maximum call stack size exceededill install loadIdealTreeat RegExp.test (<anonymous>)at D:\n…

maven之阿里云Maven镜像的使用

Maven中央仓库在国外&#xff0c;速度比较慢&#xff0c;所以我们采用国内的镜像&#xff0c;速度回有质的提升。 配置下setting.xml <mirrors><mirror><id>alimaven</id><name>aliyun maven</name><url>http://maven.aliyun.com/ne…

基于openstack搭建百万级并发负载均衡器的解决方案

最近&#xff0c;喜欢研究一些国外技术大咖们的文章&#xff0c;而这篇文章是基于openstack负载均衡器的解决方案&#xff0c;做的一些总结~希望能够给小伙伴带来一些灵感或者帮助。 openstack现有的负载均衡解决方案&#xff0c;无论是lbaas plugin还是octavia&#xff0c;后端…

5 useMemouseCallback

useMemo 优化渲染 现象 App每次重新执行时&#xff0c;render变化了&#xff0c;引用的render不是同一个函数 import React, { useState, } from "react"; const Foo props > {return <ul>{props.render()}</ul> } function App() {const [range…

6 useRef、useImperativeHandle

useRef在每次执行时返回的是同一个引用&#xff08;返回的ref对象在组件的整个生命周期内保持不变&#xff09;在函数组件中可以使用useRef和createRef但useRef性能比createRef好&#xff0c;快在类组件中&#xff0c;createRef是在初始化constructor时被赋值的&#xff08;执行…

vue --- 列表(v-for渲染)的各种神仙动画效果

通过v-for生成的元素,使用transition包裹将只显示第一条数据,此时需要使用transition-group包裹. <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-wid…

linux命令目录

一、文件和目录。&#xff08;文件目录的增删改查&#xff09; lspwdcdmkdirtouchrmdirlnddrmcpmvnlcattacmorelessheadtailstat###########################################grepawksed findlocatewhichwhereiswc ############################################dfdumountumoun…

vue --- 使用component的 :is属性切换标签页

点击对应的标签,下面切换至对应的模板… // 说明 <component :is"name"></component> // 相当于把id为name的组件放到对应的位置总体代码如下: <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"…

7 useLayoutEffect、useDebugValue

useEffect&#xff1a;dom完成渲染后执行 不传参数&#xff0c;每次都会执行 传空的依赖[]&#xff0c;只会执行一次 有依赖&#xff0c;依赖项变化会执行 useEffect实现动画效果 import { useEffect, useRef, useState } from "react"const App () > {const [,…

es6 --- map的使用

思路: 1.使用一个map数组来保存nums1中出现的元素及其次数. 2.遍历nums2.使用map的has方法来检测nums2中的元素是否出现在map中,若出现则加入返回数组(retArr),且map数组中的次数减1 /*** param {number[]} nums1* param {number[]} nums2* return {number[]}*/ var intersect…

前端面试之Vue相关总结

Vue2中检测数组变化的限制和解决方法 vue2用下标设置数组没效果 arr [1,2] arr[0] 0,页面上显示的arr并没有修改(如果对应下标是原始值&#xff1b;若是引用值)解决1&#xff1a;Vue.Set解决2&#xff1a;arr.splice (Vue会劫持splice方法) Vue2对对象是循环defineProperty…

vue --- ref属性获取dom元素和子组件的方法

说明: // 假设login的组件定义如下: Vue.component(login, {template:<h1>登录</h1>,data(){return {msg:son msg,}},methods(){show(){console.log(调用子组件的方法);}} }) // 在父元素中使用 <div id"app"><login ref"myLogin"&g…

【工程师综合项目二】React + Koa2打造『JS++官网管理后台』

Redis认知、安装与操作 MongoDB&#xff1a;动态数据库&#xff0c;如游戏中需要频繁地保存人物的坐标 Oracle&#xff1a;收费&#xff0c;企业级 mac要安装homebrew&#xff08;包管理工具&#xff09; window安装Redis程序运行教程 命令行Redis操作 启动&#xff1a; redis-…

webpack --- html-webpack-plugin

安装 cnpm i html-webpack-plugin -D配置 (webpack.config.js) // webpack 是基于node构建的,webpack的配置文件中,任何合法的Node代码都是支持的 var path require(path)// 在内存中生成src下的index.html,同时自动将打包好的bundle.js 导入到页面中 var htmlWebpackPlugin…

git 使用

1. 先进入项目文件夹&#xff0c;通过命令 git init 把这个目录变成git可以管理的仓库 git init 2. 把文件添加到版本库中&#xff0c;使用命令 git add .添加到暂存区里面去&#xff0c;不要忘记后面的小数点“.”&#xff0c;意为添加文件夹下的所有文件 git add . 3. 用命令…

软工作业PSP与单元测试训练

一、实现模块判断传入的身份证号码的正确性&#xff1b; 二、针对所实现的模块编写对应的单元测试代码&#xff1b; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.GregorianCalendar; import java.u…

DNN模型训练词向量原理

转自&#xff1a;https://blog.csdn.net/fendouaini/article/details/79821852 1 词向量 在NLP里&#xff0c;最细的粒度是词语&#xff0c;由词语再组成句子&#xff0c;段落&#xff0c;文章。所以处理NLP问题时&#xff0c;怎么合理的表示词语就成了NLP领域中最先需要解决的…

算法 --- reduce的使用.

描述: 难点: 将[[‘a’,‘b’,‘c’],[‘d’,‘e’,‘f’]]输出为[“ad”, “ae”, “af”, “bd”, “be”, “bf”, “cd”, “ce”, “cf”]. 关键代码描述: 1.假设我们已经根据输入的数字得到了 rawArr [[‘a’,‘b’,‘c’],[‘d’,‘e’,‘f’]] 2. 下一步将rawArr[0…