useReducer
作用:和useState的作用類似,用來管理相對復(fù)雜的狀態(tài)數(shù)據(jù)
基礎(chǔ)用法
- 定義一個(gè)reducer函數(shù)(根據(jù)不同的action返回不同的新狀態(tài))
- 在組件中調(diào)用useReducer,并傳入reducer函數(shù)和狀態(tài)的初始值
- 事件發(fā)生時(shí),通過dispatch函數(shù)分派一個(gè)action對象(通知reducer要返回哪個(gè)新狀態(tài)并渲染UI)

分派action時(shí)傳參

useReducer-小結(jié)

useMemo
作用:在組件每次重新渲染的時(shí)候緩存計(jì)算的結(jié)果
看個(gè)需求:

count2變化時(shí),會觸發(fā)組件重新渲染,從而觸發(fā)fn重新執(zhí)行。使用useMemo可以避免出現(xiàn)這種情況。
基礎(chǔ)語法

說明:使用useMemo做緩存之后可以保證只有count1依賴項(xiàng)發(fā)生變化時(shí)才會重新計(jì)算
React.memo
作用:允許組件在Props沒有改變的情況下跳過渲染
React組件默認(rèn)的渲染機(jī)制:只要父組件重新渲染子組件就會重新渲染

思考:如果Son組件本身并不需要做渲染更新,是不是存在浪費(fèi)?
基礎(chǔ)語法

說明:經(jīng)過memo函數(shù)包裹生成的緩存組件只有在props發(fā)生變化的時(shí)候才會重新渲染
import { memo, useState } from "react"
const MemoSon = memo(function Son () {
console.log('我是子組件,我重新渲染了')
return <div>this is son</div>
})
function App () {
const [count, setCount] = useState(0)
return (
<div className="App">
<button onClick={() => setCount(count + 1)}>+{count}</button>
{/* <Son /> */}
<MemoSon />
</div>
)
}
props的比較機(jī)制
機(jī)制: 在使用memo緩存組件之后,React會對每一個(gè) prop 使用 Object.is 比較新值和老值,返回true,表示沒有變化
prop是簡單類型:
Object.is(3, 3) => true 沒有變化
prop是引用類型(對象 / 數(shù)組):
Object.is([], []) => false 有變化,React只關(guān)心引用是否變化
useCallback
作用:在組件多次重新渲染的時(shí)候緩存函數(shù)

基礎(chǔ)語法

說明:使用useCallback包裹函數(shù)之后,函數(shù)可以保證在App重新渲染的時(shí)候保持引用穩(wěn)定
forwardRef和useInperativeHandle
作用:forwardRef使用ref暴露DOM節(jié)點(diǎn)給父組件,useInperativeHandle通過ref暴露子組件中的方法
場景說明

import { forwardRef, useImperativeHandle, useRef } from "react"
// 子組件
const Son = forwardRef((props, ref) => {
// 實(shí)現(xiàn)聚焦邏輯
const inputRef = useRef(null)
const focusHandler = () => {
inputRef.current.focus()
}
// 把聚焦方法暴露出去
useImperativeHandle(ref, () => {
return {
// 暴露的方法
focusHandler
}
})
return <input type="text" ref={inputRef} />
})
// 父組件
function App () {
const sonRef = useRef(null)
const focusHandler = () => {
console.log(sonRef.current)
sonRef.current.focusHandler()
}
return (
<>
<Son ref={sonRef} />
<button onClick={focusHandler}>focus</button>
</>
)
}
export default App