發(fā)布于:2021-02-02 10:25:20
0
102
0
React Hooks是React世界的新熱點。我正在穩(wěn)步地寫越來越多的書,我想有一個參考的備忘單會很有用,它包含了基本的鉤子和復雜的useEffect
。查看官方的Hooks API參考以獲取更深入的信息。
useEffect(用于生命周期方法)
useEffect
等,允許您編寫自己的副作用,并在需要時觸發(fā)重新渲染。
但為了更簡單,useffect還替代了生命周期方法。讓我們談談他們。
替換componentDidUpdate+componentDidMount
什么時候開始?每次渲染
有什么問題嗎?它不僅僅是一個componentDidUpdate
替代品,它還可以在掛載上運行。所以不是1比1。
重要功能?useffect可以接受第二個參數(shù),您必須跳過該參數(shù)。您也可以返回一個函數(shù),我們將在下一節(jié)中介紹。
語法:
import { useEffect } from 'react'; useEffect(() => { // whatever runs here will run on each re-render });
替換為componentDidMount+componentWillUnmount
什么時候開始?安裝和卸載組件時
有什么問題嗎?語法與前面的用例非常接近。好幾次我都被它甩了,但只要你看了文件就明白了。如果效果運行多次,請確保傳入了第二個參數(shù)
重要功能?這是一個只運行一次的效果。mount邏輯放在effect函數(shù)的主體中,unmount/cleanup邏輯放在從effect返回的函數(shù)中。
語法:
import { useEffect } from 'react'; useEffect(() => { // run mount logic here such as fetching some data return () => { // unmount logic goes here }; }, []); // note the empty array
您可以將mount
或unmount
邏輯保留為空,以便只處理其中一個生命周期替代項。意思是:
保持mount
邏輯為空,以便只有unmount
邏輯運行(僅替換componentWillUnmount
)
不返回任何內(nèi)容,以便只有mount
邏輯運行(僅替換componentDidMount
)
useEffect的副作用
useEffect
的主要目標是包含您可能想要使用的任何副作用。副作用本質上是你在你的組件中所做的影響整個世界的事情。無論是網(wǎng)絡請求、設置文檔標題,還是其他什么。
必要時運行
什么時候開始?當組件重新呈現(xiàn)時,useEffect
將檢查依賴項。如果依賴項值更改,useffect將運行該效果
有什么問題嗎?React做了一個淺顯的比較。如果您使用一個對象或一個數(shù)組,您的反應會認為沒有改變。
重要特性useEffect在情況不變時跳過運行效果。實際上,您不必在效果中使用依賴項值。可以作為依賴項傳入prop值。
語法:
import { useEffect } from 'react'; function SomeComponent(props) { useEffect(() => { // logic runs only when dependency variables changed }, [arrOfDependency, values, props.id]); // array of values to check if they've changed }
潛在用例
由于鉤子更難解釋,我想提供一個用例列表
當?shù)谰吒囊垣@取新數(shù)據(jù)時運行副作用(如獲?。?/span>
僅當計算值更改時運行資源密集型計算
當值更新時更新頁面(如文檔標題)
useState
狀態(tài)可能是人們從無狀態(tài)(功能)組件切換到類組件的原因。useState
允許我們擁有無類的有狀態(tài)組件。
它返回什么?當前狀態(tài)和用于設置狀態(tài)的函數(shù)
有什么問題嗎?狀態(tài)設置函數(shù)將用新狀態(tài)替換以前的狀態(tài),而不是像類狀態(tài)那樣合并它們。在設置狀態(tài)之前,您需要自己合并對象。
重要功能您可以在組件中使用任意多個useState
掛鉤。將任何值傳遞給useState
將創(chuàng)建初始狀態(tài)。這也是一種慣例,不調(diào)用變量state
和setState
,而是使用上下文名稱(例如user
和setUser
)。接受狀態(tài)的任何值,它不必是對象。
語法:
import { useState } from 'react'; // setup const defaultValue = { name: "Antonin" }; const [state, setState] = useState(defaultValue); // scenario 1 usage // resulting state only contains key `user` with value 'antjanus' setState({ user: 'antjanus' }); // scenario 2 usage // resulting state contains key `name` with value 'A. Januska' setState({ name: 'A. Januska' }); // scenario 3 usage // resulting state is a merger between `{ name: 'A. Januska' }` and `{ user: 'antjanus'}` setState({ ...state, user: 'antjanus'});
useReducer
useReducer
是useState
的另一種選擇,如果您以前使用過Redux,這看起來會很熟悉。
有什么爭論?它返回什么?useReducer
采用reducer
函數(shù)和initialState
。它返回當前的state
和adispatcher
(聽起來很熟悉?)
它是如何運行的?在狀態(tài)更改時,dispatch
具有類型和數(shù)據(jù)有效負載的對象(有關更多信息,請參閱flux標準操作)。傳遞給useReducer的reducer
將接收當前狀態(tài)和已調(diào)度對象。它返回新狀態(tài)。
有什么問題嗎?這是一個更復雜的工作流,但它的工作原理與您使用Redux時所期望的一樣。
重要功能減速機每次調(diào)度都會運行。它可以訪問以前的狀態(tài)。useReducer
還包括可用于創(chuàng)建初始狀態(tài)的第三個參數(shù)。
語法
import { useReducer } from 'react'; function reducer(currentState, action) { switch(action.type) { // handle each action type and how it affects the current state here } } function SomeComponent() { const [state, dispatch] = useReducer(reducer, initialState); dispatch({ type: 'ADD', payload: data }); // { type: 'ADD', payload: data } gets passed into the `reducer` as the `action` argument while `state` gets passed in as the `currentState` argument }
建立自己的鉤子
關于構建自己的鉤子的簡短說明。這就像使用現(xiàn)有的鉤子并將它們組合在一個以use
開頭的函數(shù)中一樣簡單。下面是一個useUser
鉤子的快速示例。
有什么要求?函數(shù)以關鍵字use
開始。例如useUser
或useSomethingElse
。
重要特性:您可以調(diào)用自定義鉤子中的任何鉤子,并按預期工作。
語法:
import { useEffect } from 'react'; function useUser(userId) { let [user, setUser] = useState(null); useEffect(() => { fetch(`/api/user/${userId}`) .then(data => data.toJSON()) .then(data => setUser(data)); }, [userId]); return user; } function SomeComponent(props) { const user = useUser(props.id); }
剩下的呢?
您還可以使用其他掛鉤,如useMemo
、useCallback
等等。我想說那些是更高級的鉤子,如果你了解基本的鉤子,那就去看看官方文檔吧。
我也知道其中有很多高級用法示例(比如將useReducer的dispatch
傳遞到幾個級別)。
如果您發(fā)現(xiàn)一些不正確的或一些額外的有用的信息是不包括在內(nèi),讓我知道!我會把它包括在內(nèi)!