React核心 -- React-Hooks
hooks 存在的意義

hooks 之間的狀態(tài)是獨立的,有自己獨立的上下文,不會出現(xiàn)混淆狀態(tài)的情況
讓函數(shù)有了狀態(tài)管理
解決了 組件樹不直觀、類組件難維護、邏輯不易復(fù)用的問題
避免函數(shù)重復(fù)執(zhí)行的副作用
應(yīng)用場景
利用 hooks 取代生命周期函數(shù)
讓組件有了狀態(tài)
組件輔助函數(shù)
處理發(fā)送請求
存取數(shù)據(jù)
hooks API
從 react 中引入
1. useState
給函數(shù)組件添加狀態(tài)
初始化以及更新組件狀態(tài)
const [count, setCount] = React.useState(0)
接收一個參數(shù)作為初始值,返回一個數(shù)組:第一個是狀態(tài)變量,第二個是修改變量的函數(shù)
2. useEffect
副作用 hooks
給沒有生命周期的組件,添加結(jié)束渲染的信號
注意:
render 之后執(zhí)行的 hooks
第一個參數(shù)接收一個函數(shù),在組件更新的時候執(zhí)行
第二個參數(shù)接收一個數(shù)組,用來表示需要追蹤的變量,依賴列表,只有依賴更新的時候才會更新內(nèi)容
第一個參數(shù)的返回值,返回一個函數(shù),在 useEffect 執(zhí)行之前,都會先執(zhí)行里面返回的函數(shù)
一般用于添加銷毀事件,這樣就能保證只添加一個
React.useEffect(() => { console.log('被調(diào)用了'); return () => { console.log('我要被卸載了'); } }, [count])
打印
3. useLayoutEffect
和 useEffect 很類似
它的作用是:在 DOM 更新完成之后執(zhí)行某個操作
注意:
有 DOM 操作的副作用 hooks
在 DOM 更新之后執(zhí)行
執(zhí)行時機在 useEffect 之前,其他都和 useEffect 都相同
useEffect 執(zhí)行時機在 render 之后
useLayoutEffect 執(zhí)行時機在 DOM 更新之后
4. useMemo
作用:讓組件中的函數(shù)跟隨狀態(tài)更新
注意:優(yōu)化函數(shù)組件中的功能函數(shù)
為了避免由于其他狀態(tài)更新導(dǎo)致的當(dāng)前函數(shù)的被迫執(zhí)行
第一個參數(shù)接收一個函數(shù),第二個參數(shù)為數(shù)組的依賴列表,返回一個值
const getDoubleNum = useMemo(() => { console.log('ddd') return 2 * num }, [num])
作用:跟隨狀態(tài)更新執(zhí)行
注意:
只有依賴項改變時才執(zhí)行
useMemo( () => fn, deps) 相當(dāng)于 useCallback(fn, deps)
不同點:
useCallback 返回的是一個函數(shù),不再是值
useCallback 緩存的是一個函數(shù),useMemo 緩存的是一個值,如果依賴不更新,返回的永遠是緩存的那個函數(shù)
給子組件中傳遞 props 的時候,如果當(dāng)前組件不更新,不會觸發(fā)子組件的重新渲染
6. useRef
作用:長久保存數(shù)據(jù)
注意事項:
返回一個子元素索引,這個索引在整個生命周期中保持不變
對象發(fā)生改變時,不通知,屬性變更不重新渲染
保存一個值,在整個生命周期中維持不變
重新賦值 ref.current 不會觸發(fā)重新渲染
相當(dāng)于創(chuàng)建一個額外的容器來存儲數(shù)據(jù),我們可以在外部拿到這個值
當(dāng)我們通過正常的方式去獲取計時器的 id 是無法獲取的,需要通過 ref
useEffect(() => { ref.current = setInterval(() => { setNum(num => num + 1) }, 400) }, []) useEffect(() => { if (num > 10) { console.log('到十了'); clearInterval(ref.current) } }, [num])
7. useContext
作用:帶著子組件渲染
注意:
上層數(shù)據(jù)發(fā)生改變,肯定會觸發(fā)重新渲染
我們需要引入 useContext 和 createContext 兩個內(nèi)容
通過 createContext 創(chuàng)建一個 Context 句柄
通過 Provider 確定數(shù)據(jù)共享范圍
通過 value 來分發(fā)數(shù)據(jù)
在子組件中,通過 useContext 來獲取數(shù)據(jù)
import React, { useContext, createContext } from 'react' const Context = createContext(null) export default function Hook() { const [num, setNum] = React.useState(1) return (
這是一個函數(shù)組件 - {num} // 確定范圍
) } function Item1() { const num = useContext(Context) return 8. useReducer
作用:去其他地方借資源
注意:函數(shù)組件的 Redux 的操作
創(chuàng)建數(shù)據(jù)倉庫 store 和管理者 reducer
通過 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 去派發(fā) action
9. 自定義 hooks
放在 utils 文件夾中,以 use 開頭命名
例如:模擬數(shù)據(jù)請求的 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;
引入 react 和自己需要的 hook
創(chuàng)建自己的hook函數(shù)
返回一個數(shù)組,數(shù)組中第一個內(nèi)容是數(shù)據(jù),第二個是修改數(shù)據(jù)的函數(shù)
暴露自定義 hook 函數(shù)出去
引入自己的業(yè)務(wù)組件
React 數(shù)據(jù)結(jié)構(gòu) 渲染
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。