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:…

3 useReducer及其实现

pureComponent import { useState } from "react" // useReducer, // 统一调度 function reducer(state, action) {console.log(reducer接收参数, state, action)const { type } actionswitch (type) {case add:return { num: state.num 1 }case minus:return { n…

Django 之 权限系统(组件)

参考: http://www.cnblogs.com/yuanchenqi/articles/7609586.html 转载于:https://www.cnblogs.com/bigtreei/p/8564243.html

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…

vue --- 使用animate.css实现动画

1.下载animate.css npm install --save-dev animate.css// 注意你使用的源 nrm ls(若没有改变可以忽略)2.导入animate.css <link rel"stylesheet" href"../node_modules/animate.css/animate.css"> // 注意你的当前文件和node_moudules文件夹的相对…

4 contextHook

类组件createContext、静态属性contextType 与函数组件useContext 的对比 import { Component, createContext, useContext } from react const AppContext createContext(0) class Foo extends Component {render() {return (<AppContext.Consumer>{value > (Foo: …

【leetcode 简单】 第一百一十题 分发饼干

假设你是一位很棒的家长&#xff0c;想要给你的孩子们一些小饼干。但是&#xff0c;每个孩子最多只能给一块饼干。对每个孩子 i &#xff0c;都有一个胃口值 gi &#xff0c;这是能让孩子们满足胃口的饼干的最小尺寸&#xff1b;并且每块饼干 j &#xff0c;都有一个尺寸 sj 。…

基于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…

vue --- 动画执行的周期(动画的钩子函数)

如下8个: <transitionv-on:before-enter "beforeEnter"v-on:enter "enter"v-on:after-enter "afterEnter"v-on:enter-cancelled "enterCancelled"v-on:before-leave "beforeLeave"v-on:leave "leave"v-…

二分查找c++

相信对于二分查找的原理大家已经明白&#xff0c;接下来就是代码实现了 1 #include <iostream>2 #include <cstdio>3 #include <algorithm>4 #include <cstring>5 #include <string>6 #include <cstdlib>7 8 using namespace std;9 10 in…

php获取网址

1 #测试网址: http://localhost/blog/testurl.php?id52 3 //获取域名或主机地址 4 echo $_SERVER[HTTP_HOST]."<br>"; #localhost5 6 //获取网页地址 7 echo $_SERVER[PHP_SELF]."<br>"; #/blog/testurl.php8 9 //获取网址参数 10 echo …

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"…

3-15 《元编程》第6章 3-16 hook method

Code That Writes Code 6.1 Coding your way to the weekend 6.2 Kernel#eval, Binding#eval Binding: Objects of class Binding(类Binding的对象) encapsulate &#xff08;密封&#xff09;the execution context at some particular place in the code and retain this c…

7 useLayoutEffect、useDebugValue

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