文章目錄
- 一,useEffect描述
- 二,它的執行時機
- 三,useEffect分情況使用
- 1,不寫第二個參數 說明監測所有state,其中一個變化就會觸發此函數
- 2,第二個參數如果是`[]`空數組,說明誰也不監測
- 3,第二個參數如果只傳需要監測的state,那只會根據此狀態來執行函數
- 4,useEffect 里面return一個回調函數,相當于組件即將卸載的聲明周期
- 5,注意
一,useEffect描述
我們知道,react 的函數組件里面沒有生命周期的,也沒有 state,沒有 state 可以用
useState
來替代,那么生命周期呢?
useEffect
是 react v16.8
新引入的特性。我們可以把 useEffect hook 看作是componentDidMount、componentDidUpdate、componentWillUnmounrt三個生命周期的組合。可以讓你在函數式組件中執行一些副作用操作;
一般副作用操作有:
- 發送ajax請求
- 設置訂閱 / 啟動定時器
- 手動更改真實DOM
二,它的執行時機
可以看做這三個生命周期函數的組合,也就是在這三個時候會執行
componentDidMount(組件已經掛載)
componentDidUpdate(組件已經更新)
componentWillUnmount(組件即將卸載)
三,useEffect分情況使用
useEffect()
有兩個參數:第一個參數是要執行的回調函數,第二個參數是一個依賴項數組數組(根據需求第二個參數可選是否填寫),根據數組里的變量是否變化決定是否執行函數;
先看下面簡單的案例 ,下面會分情況討論:
useEffect.js
import React, { useState, useEffect, useRef } from "react";// 類型約定
interface interList {id: number | string; // 類型可能是number也可能是stringtext: string;done: boolean;
}
// 渲染數據
const myList: Array<interList> = [{ id: 0, text: "參觀卡夫卡博物館", done: true },{ id: 1, text: "看木偶戲", done: true },{ id: 2, text: "打卡列儂墻", done: true }
];const UseEffect: React.FC = (props: any) => {let [num, setNum] = useState(100);let [useInfo, SetUserInfo] = useState(myList);// 0,什么都不傳 就是監聽所有數據的變化useEffect(() => {console.log("我改變了-all");}); // 1,此處相當于 componentDidUpdate生命周期 組件已經更新完成useEffect(() => {console.log("我改變了");}, [num]); // 只監聽num的變化,useInfo的變化不會被監聽到// 2,此處相當于componentDidMount生命周期 組件已經掛載完成useEffect(() => {console.log("componentDidMount");console.log("可以拿到num的值:", num);}, []);// 3,此處相當于 componentWillUnmount生命周期 組件即將卸載useEffect(() => {// 返回一個回調函數return () => {console.log("組件將要卸載了");};}, []);// 其實傳不傳空數組或不是空數組,useEffect函數里面的回調都會執行一次,也就是說componentWillUnmount這個生命周期頁面進來就會執行// useEffect 這個hoosk也是可以寫多個的,盡量不同的處理寫在不同useEffect里面// 點擊改變用戶信息const change = () => {// react 建議不要更改原數組 返回一個數組的拷貝const newList = [...useInfo, { id: 3, text: "優菈", done: false }];SetUserInfo(newList);};// 點擊加一const add = () => {setNum(++num);};const lis = useInfo.map((item, index) => {return (<li key={index}>{index}:{item.text}</li>);});return (<><div><h3>userEffect 副作用hooks函數</h3><br /><button onClick={add}>點擊加一</button><p>{num}</p><br /><button onClick={change}>改變用戶信息</button><ul>{lis}</ul></div></>);
};
export default UseEffect;
效果圖:
上面代碼實現的效果很簡單,兩個按鈕分別改變各自數據的狀態,狀態的改變會觸發 useEffec
t函數的執行,第二個參數的傳參影響著此函數的變化,所以下面進行分情況討論:
1,不寫第二個參數 說明監測所有state,其中一個變化就會觸發此函數
若不寫第二個參數,函數操作每次都會執行 useEffect(method)
監測所有state,相當于 componentDidUpdate
生命周期 - 組件已經更新完成。
import {useEffect } from "react";useEffect(() => {console.log("我改變了-all");}); // 監聽所有數據的變化
2,第二個參數如果是[]
空數組,說明誰也不監測
第二個參數如果是[]
空數組,說明誰也不監測,此時useEffect回調函數
的作用就相當于
componentDidMount
生命周期 - 組件已經掛載完成;
// 2,此處相當于componentDidMount生命周期 組件已經掛載完成useEffect(() => {console.log("componentDidMount");console.log("可以拿到num的值:", num);}, []);
3,第二個參數如果只傳需要監測的state,那只會根據此狀態來執行函數
如果第二個參數中的數組只傳了 num
,說明只有 num
改變時,才會觸發此useEffect
回調函數,相當于對此數據的監聽。
// 1,此處相當于 componentDidUpdate生命周期 組件已經更新完成useEffect(() => {console.log("num改變了");}, [num]); // 只監聽num的變化
當然數組里面也可以寫多個([num,userInfo]
),同時監聽多個數據的變化。
4,useEffect 里面return一個回調函數,相當于組件即將卸載的聲明周期
這句話什么意思呢?
通常,組件是有卸載的生命周期的,使用useEffect 函數
只需在里面return一個回調函數,這個回調函數就相當于componentWillUnmount
聲明周期,可以在里面清除創建的訂閱或計時器 ID 等資源。
// 3,此處相當于 componentWillUnmount生命周期 組件即將卸載useEffect(() => {// 返回一個回調函數return () => {console.log("組件將要卸載了");};}, []);
這里傳了空數組說明我不想監聽數據的變化,只想在卸載組件的時候執行該邏輯;
5,注意
其實第二個傳不傳空數組或不是空數組,useEffect函數里面的回調都會執行一次,也就是說頁面進來就會自動執行componentWillUnmount
這個生命周期;
useEffect函數
這個hoosk也是可以寫多個的,盡量不同的業務處理寫在不同useEffect里面;