
大家好,我是小丞同學,一名大二的前端愛好者
這篇文章是學習 React-Redux 資料共享 的學習筆記
非常感謝你的閱讀,不對的地方歡迎指正
願你忠于自己,熱愛生活
hooks 存在的意義
hooks 之間的狀态是獨立的,有自己獨立的上下文,不會出現混淆狀态的情況
讓函數有了狀态管理
解決了 元件樹不直覺、類元件難維護、邏輯不易複用的問題
避免函數重複執行的副作用
應用場景
1.利用 hooks 取代生命周期函數
2.讓元件有了狀态
3.元件輔助函數
4.處理發送請求
5.存取資料
6.做好性能優化
hooks API
從 react 中引入
1. useState
給函數元件添加狀态
·初始化以及更新元件狀态
const [count, setCount] = React.useState(0)
接收一個參數作為初始值,傳回一個數組:第一個是狀态變量,第二個是修改變量的函數
2. useEffect
副作用 hooks
·給沒有生命周期的元件,添加結束渲染的信号
注意:
·render 之後執行的 hooks
第一個參數接收一個函數,在元件更新的時候執行
第二個參數接收一個數組,用來表示需要追蹤的變量,依賴清單,隻有依賴更新的時候才會更新内容
第一個參數的傳回值,傳回一個函數,在 useEffect 執行之前,都會先執行裡面傳回的函數
一般用于添加銷毀事件,這樣就能保證隻添加一個
React.useEffect(() => {
console.log('被調用了');
return () => {
console.log('我要被解除安裝了');
}
}, [count])
列印
3. useLayoutEffect
和 useEffect 很類似
它的作用是:在 DOM 更新完成之後執行某個操作
·有 DOM 操作的副作用 hooks
·在 DOM 更新之後執行
執行時機在 useEffect 之前,其他都和 useEffect 都相同
useEffect 執行時機在 render 之後
useLayoutEffect 執行時機在 DOM 更新之後
4. useMemo
作用:讓元件中的函數跟随狀态更新
注意:優化函數元件中的功能函數
為了避免由于其他狀态更新導緻的目前函數的被迫執行
第一個參數接收一個函數,第二個參數為數組的依賴清單,傳回一個值
const getDoubleNum = useMemo(() => {
console.log('ddd')
return 2 * num
}, [num])
5. useCallback
作用:跟随狀态更新執行
·隻有依賴項改變時才執行
·useMemo( () => fn, deps) 相當于 useCallback(fn, deps)
不同點:
1.useCallback 傳回的是一個函數,不再是值
2.useCallback 緩存的是一個函數,useMemo 緩存的是一個值,如果依賴不更新,傳回的永遠是緩存的那個函數
3.給子元件中傳遞 props 的時候,如果目前元件不更新,不會觸發子元件的重新渲染
6. useRef
作用:長久儲存資料
注意事項:
·傳回一個子元素索引,這個索引在整個生命周期中保持不變
·對象發生改變時,不通知,屬性變更不重新渲染
1.儲存一個值,在整個生命周期中維持不變
2.重新指派 ref.current 不會觸發重新渲染
3.相當于建立一個額外的容器來存儲資料,我們可以在外部拿到這個值
當我們通過正常的方式去擷取計時器的 id 是無法擷取的,需要通過 ref
useEffect(() => {
ref.current = setInterval(() => {
setNum(num => num + 1)
}, 400)
}, [])
useEffect(() => {
if (num > 10) {
console.log('到十了');
clearInterval(ref.current)
}
}, [num])
7. useContext
作用:帶着子元件渲染
·上層資料發生改變,肯定會觸發重新渲染
1.我們需要引入 useContext 和 createContext 兩個内容
2.通過 createContext 建立一個 Context 句柄
3.通過 Provider 确定資料共享範圍
4.通過 value 來分發資料
5.在子元件中,通過 useContext 來擷取資料
import React, { useContext, createContext } from 'react'
const Context = createContext(null)
export default function Hook() {
const [num, setNum] = React.useState(1)
return (
<h1>
這是一個函數元件 - {num}
// 确定範圍
<Context.Provider value={num}>
<Item1 num={num} />
<Item2 num={num} />
</Context.Provider>
</h1>
)
}
function Item1() {
const num = useContext(Context)
return <div>子元件1 {num}</div>
}
function Item2() {
const num = useContext(Context)
return <div>子元件2 {num}</div>
}
8. useReducer
作用:去其他地方借資源
注意:函數元件的 Redux 的操作
1.建立資料倉庫 store 和管理者 reducer
2.通過 useReducer(store,dispatch) 來擷取 state 和 dispatch
const store = {
num: 10
}
const reducer = (state, action) => {
switch (action.type) {
case "":
return
default:
return
}
}
const [state, dispatch] = useReducer(reducer, store)
通過 dispatch 去派發 action
9. 自定義 hooks
放在 utils 檔案夾中,以 use 開頭命名
例如:模拟資料請求的 Hooks
import React, { useState, useEffect } from "react";
function useLoadData() {
const [num, setNum] = useState(1);
useEffect(() => {
setTimeout(() => {
setNum(2);
}, 1000);
}, []);
return [num, setNum];
}
export default useLoadData;
減少代碼耦合
我們希望 reducer 能讓每個元件來使用,我們自己寫一個 hooks
自定義一個自己的 LocalReducer
import React, { useReducer } from "react";
const store = { num: 1210 };
const reducer = (state, action) => {
switch (action.type) {
case "num":
return { ...state, num: action.num };
default:
return { ...state };
}
};
function useLocalReducer() {
const [state, dispatch] = useReducer(reducer, store);
return [state, dispatch];
}
export default useLocalReducer;
1.引入 react 和自己需要的 hook
2.建立自己的hook函數
3.傳回一個數組,數組中第一個内容是資料,第二個是修改資料的函數
4.暴露自定義 hook 函數出去
5.引入自己的業務元件