關于hooks中useEffect()的使用總結
常見使用
獲取數(shù)據案例:
import React, { useState, useEffect } from 'react'; import axios from 'axios'; function App() { const [data, setData] = useState({ hits: [] }); useEffect(() => { const fetchData = async () => { const result = await axios( 'https://hn.algolia.com/api/v1/search?query=redux', ); setData(result.data); }; fetchData(); }, []); return ( <ul> {data.hits.map(item => ( <li key={item.objectID}> <a href={item.url}>{item.title}</a> </li> ))} </ul> ); } export default App;
上面例子中,useState()用來生成一個狀態(tài)變量(data),保存獲取的數(shù)據;useEffect()的副效應函數(shù)內部有一個 async 函數(shù),用來從服務器異步獲取數(shù)據。拿到數(shù)據以后,再用setData()觸發(fā)組件的重新渲染。
由于獲取數(shù)據只需要執(zhí)行一次,所以上例的useEffect()的第二個參數(shù)為一個空數(shù)組
useEffect() 的第二個參數(shù)說明
有時候,我們不希望useEffect()每次渲染都執(zhí)行,這時可以使用它的第二個參數(shù),使用一個數(shù)組指定副效應函數(shù)的依賴項,只有依賴項發(fā)生變化,才會重新渲染。
function Welcome(props) { useEffect(() => { document.title = `Hello, ${props.name}`; }, [props.name]); return <h1>Hello, {props.name}</h1>; }
上面例子中,useEffect()的第二個參數(shù)是一個數(shù)組,指定了第一個參數(shù)(副效應函數(shù))的依賴項(props.name)。
只有該變量發(fā)生變化時,副效應函數(shù)才會執(zhí)行。如果第二個參數(shù)是一個空數(shù)組,就表明副效應參數(shù)沒有任何依賴項。因此,副效應函數(shù)這時只會在組件加載進入 DOM 后執(zhí)行一次,后面組件重新渲染,就不會再次執(zhí)行。
這很合理,由于副效應不依賴任何變量,所以那些變量無論怎么變,副效應函數(shù)的執(zhí)行結果都不會改變,所以運行一次就夠了。
useEffect() 第一個函數(shù)參數(shù)的返回值
副效應是隨著組件加載而發(fā)生的,那么組件卸載時,可能需要清理這些副效應。
useEffect()允許返回一個函數(shù),在組件卸載時,執(zhí)行該函數(shù),清理副效應。如果不需要清理副效應,useEffect()就不用返回任何值。
useEffect(() => { const subscription = props.source.subscribe(); return () => { subscription.unsubscribe(); }; }, [props.source]);
上面例子中,useEffect()在組件加載時訂閱了一個事件,并且返回一個清理函數(shù),在組件卸載時取消訂閱。
實際使用中,由于副效應函數(shù)默認是每次渲染都會執(zhí)行,所以清理函數(shù)不僅會在組件卸載時執(zhí)行一次,每次副效應函數(shù)重新執(zhí)行之前,也會執(zhí)行一次,用來清理上一次渲染的副效應。
useEffect() 的注意點
使用useEffect()時,有一點需要注意。如果有多個副效應,應該調用多個useEffect(),而不應該合并寫在一起。
錯誤寫法:
function App() { const [varA, setVarA] = useState(0); const [varB, setVarB] = useState(0); useEffect(() => { const timeoutA = setTimeout(() => setVarA(varA + 1), 1000); const timeoutB = setTimeout(() => setVarB(varB + 2), 2000); return () => { clearTimeout(timeoutA); clearTimeout(timeoutB); }; }, [varA, varB]); return <span>{varA}, {varB}</span>; }
上面的例子是錯誤的寫法,副效應函數(shù)里面有兩個定時器,它們之間并沒有關系,其實是兩個不相關的副效應,不應該寫在一起。
正確的寫法是將它們分開寫成兩個useEffect()。
正確寫法:
function App() { const [varA, setVarA] = useState(0); const [varB, setVarB] = useState(0); useEffect(() => { const timeout = setTimeout(() => setVarA(varA + 1), 1000); return () => clearTimeout(timeout); }, [varA]); useEffect(() => { const timeout = setTimeout(() => setVarB(varB + 2), 2000); return () => clearTimeout(timeout); }, [varB]); return <span>{varA}, {varB}</span>; }
總結
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
React超詳細分析useState與useReducer源碼
我正在處理的組件是表單的時間輸入。表單相對復雜,并且是動態(tài)生成的,根據嵌套在其他數(shù)據中的數(shù)據顯示不同的字段。我正在用useReducer管理表單的狀態(tài),到目前為止效果很好2022-11-11React使用高德地圖的實現(xiàn)示例(react-amap)
這篇文章主要介紹了React使用高德地圖的實現(xiàn)示例(react-amap),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-04-04