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.pswp.cn/news/250812.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/250812.shtml
英文地址,請注明出處:http://en.pswp.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 [,…