【譯】一文看懂 React useEffect hook 的用法

來源: Joseph Mawa. What is useEffect hook and how do you use it?.2020年6月30日html

目次

  • 介紹
  • useEffect hook 傳遞了哪些參數?
  • useEffect 的第一個參數
  • effect 的返回值
  • useEffect 的第二個參數
  • 傳遞一個函數做爲依賴關係
  • 參考文獻

這是我關於 react hook 系列的第三篇文章。若是你尚未看前兩篇,請按照下面的連接來看。react

  1. What is useState hook and how do you use it?
  2. What is useReducer hook and how do you use it?

useEffect hook 簡介

鉤子是一個函數,它可讓你在不編寫ES6類的狀況下使用狀態和其餘react特性。 useEffect鉤子是react鉤子API的一部分。若是你熟悉react生命週期,useEffect鉤子至關於生命週期方法componentDidMountcomponentDidUpdatecomponentWillUnmount的組合。其實根據React文檔中關於鉤子的介紹useEffect鉤子是爲了解決ES6類組件的生命週期方法帶來的一些挑戰而開發的。因爲本篇文章介紹的是什麼是 effect hook ,以及它的使用方法,因此我就不說它的開發緣由了。你能夠在這裏看一下。 在React功能組件中,咱們在 useEffect 鉤子裏面執行有「反作用」的操做,好比從API中獲取數據或者手動更新DOM。數組

useEffect hook 傳遞了哪些參數?

useEffect是一個接受兩個參數的函數。傳遞給useEffect的第一個參數是一個名爲effect的函數(你能夠猜到爲何這個鉤子叫useEffect),第二個參數(是可選的)是一個存儲依賴關係的數組。下面是它的使用說明。markdown

import React, { useEffect } from "react";
import { render } from "react-dom";
const App = props => {
  useEffect(() => {
    console.log("Effect has been called");
  }); //Second argument to useEffect has been omitted
  return <h1> Hello world! </h1>;
};  
const root = document.getElementById("root");
render(<App />, root);
複製代碼

useEffect的第一個參數

第一個參數稱爲effect,是一個函數,它要麼返回一個函數(稱爲cleanup),要麼返回undefinedeffect在組件被掛載時(第一次渲染時)被執行,在後續的更新中是否被執行由做爲第二個參數傳遞的依賴關係數組決定。dom

effect參數的返回值

在上一節中,咱們說過,useEffect的第一個參數是一個名爲effect的函數。effect不須要參數,它必須返回一個函數或未定義的函數。若是它返回的是一個函數,那麼返回的函數被稱爲cleanupcleanup在調用effect以前被執行(清理以前渲染的效果)。若是你對爲何以及何時須要清理很好奇,能夠看看React文檔中的解釋。因爲effect返回的要麼是函數,要麼是undefined,因此沒有cleanupeffect並很多見。ide

useEffect的第二個參數

useEffect的第二個參數是一個依賴關係的數組。若是你想控制在掛載組件後何時執行effect,那麼就傳遞一個依賴關係數組做爲第二個參數。依賴關係是指定義在useEffect以外,但在useEffect內部使用的值,好比。函數

function App(){
         const[state, setState] = useState(0);
          // state is defined here
         useEffect(() => {
              console.log(state); 
              //value of state is used here therefore must be passed as a dependency
         }, [state])

     }
複製代碼

React會比較依賴關係的當前值和以前渲染的值。若是它們不同,就會調用effect。 這個參數是可選的。若是省略它,effect將在每次渲染後被執行。若是你想讓effect只在第一次渲染時執行,你能夠傳遞一個空數組。oop

useEffect(() => {
       console.log("Effect has been called");
}, []) // Empty array as dependency, useEffect is invoked once
複製代碼

依賴關係能夠是stateprops。須要注意的是,若是要在useEffect內部使用任何定義在useEffect以外、且在組件內部的值,則必須將其做爲依賴關係傳遞。這一點將在下面進行說明。fetch

function App(props) {
     const [count, setCount] = React.useState(1);
     // count and setCount are defined inside component(App) but outside useEffect
     useEffect(() => {
       //count is being used inside useEffect. Therefore must be passed as dependency.
       console.log(count);
}, [count])
}
複製代碼

傳遞一個函數做爲依賴關係

你可能想知道,若是你在useEffect以外定義了一個函數,而後在effect裏面調用它,你須要把它做爲一個依賴關係傳遞給它嗎? 舉個例子。ui

function App(props){
    const [data, setData] = useState(null);
    const fetchData = () => {
         //fetch some data 
    }
    useEffect(() => {
    fetchData(); //Invoked inside useEffect
}, [fetchData])

}
複製代碼

不建議像上面這樣,在外面定義一個函數,而後在effect裏面調用它。上面的狀況會致使每次渲染都會調用fetchData,由於傳遞的依賴是一個函數,而函數是對象。React會比較上一次和當前渲染的fetchData,二者是不同的,所以會觸發對effect的調用。

根據React文檔中關於useEffect hook的部分

很難記住哪些props或state是由effect以外的函數使用的。這就是爲何一般你會但願在effect內部聲明它所須要的函數。這樣就能夠很容易地看到該effect所依賴的組件做用域中的哪些值。
你也能夠把函數移到effect內部,這樣它就不須要在依賴列表中了。

參考文獻

相關文章
相關標籤/搜索