最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一文帶你搞懂React中的useReducer

 更新時(shí)間:2023年06月16日 09:44:49   作者:何遇er  
useReducer 是除useState之外另一個(gè)與狀態(tài)管理相關(guān)的 hook,這篇文章主要為大家介紹了useReducer應(yīng)用的相關(guān)知識(shí),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

useReducer 是除useState之外另一個(gè)與狀態(tài)管理相關(guān)的 hook,對(duì)于熟悉 Redux 的工程師而言,理解 useReducer 將變得簡(jiǎn)單,在 React 內(nèi)部,useState 由 useReducer 實(shí)現(xiàn)。

useReducer 的類型定義

useReducer 的類型定義如下:

function useReducer<R extends ReducerWithoutAction<any>, I>(
    reducer: R,
    initializerArg: I,
    initializer: (arg: I) => ReducerStateWithoutAction<R>
): [ReducerStateWithoutAction<R>, DispatchWithoutAction];
function useReducer<R extends ReducerWithoutAction<any>>(
    reducer: R,
    initializerArg: ReducerStateWithoutAction<R>,
    initializer?: undefined
): [ReducerStateWithoutAction<R>, DispatchWithoutAction];
function useReducer<R extends Reducer<any, any>, I>(
    reducer: R,
    initializerArg: I & ReducerState<R>,
    initializer: (arg: I & ReducerState<R>) => ReducerState<R>
): [ReducerState<R>, Dispatch<ReducerAction<R>>];
function useReducer<R extends Reducer<any, any>, I>(
    reducer: R,
    initializerArg: I,
    initializer: (arg: I) => ReducerState<R>
): [ReducerState<R>, Dispatch<ReducerAction<R>>];
function useReducer<R extends Reducer<any, any>>(
    reducer: R,
    initialState: ReducerState<R>,
    initializer?: undefined
): [ReducerState<R>, Dispatch<ReducerAction<R>>];

useReducer 的類型定義很復(fù)雜,一共有 5 個(gè)重載,總體而言,它最多接受3個(gè)參數(shù),第 1 個(gè)參數(shù)是一個(gè)用于更新狀態(tài)的函數(shù),之后將它稱為 reducer。第 3 個(gè)參數(shù)非必填,如果不存在第 3 個(gè)參數(shù),那么第 2 個(gè)參數(shù)將作為狀態(tài)的初始值;如果存在第 3 個(gè)參數(shù),那么它必須是函數(shù),此時(shí)第 2 個(gè)參數(shù)被傳遞給該函數(shù)用于計(jì)算狀態(tài)的初始值,該函數(shù)只在組件初始渲染時(shí)執(zhí)行一次。useReducer 的返回值是一個(gè)長度為 2 的數(shù)組,數(shù)組的第 1 個(gè)位置是狀態(tài)值,第 2 個(gè)位置是一個(gè)用于觸發(fā)狀態(tài)更新的函數(shù),將它記為dispatch,調(diào)用 dispatch 將導(dǎo)致 reducer 被調(diào)用。接下來通過計(jì)數(shù)器 demo 對(duì)比 useState 和useReducer 用法上的差異。

用 useState 實(shí)現(xiàn)計(jì)數(shù)器

用 useState 實(shí)現(xiàn)計(jì)數(shù)器,代碼如下:

function UseStateCounterDemo() {
    const [value, setValue] = useState<number>(0)
    const [step, setStep] = useState<number>(1)
    const onChangeStep = (ev: React.ChangeEvent<HTMLInputElement>) => {
        setStep(Number(ev.target.value))
    }
    return (
        <div>
            <h2>用useState實(shí)現(xiàn)計(jì)數(shù)器</h2>
            count: {count}; 
            step: <input type='number' value={step} onChange={onChangeStep}/>
            <button onClick={() => setValue(value + step)}>加</button>
            <button onClick={() => setValue(value - step)}>減</button>
            <button onClick={() => {setValue(0); setStep(1)}}>重置</button>
        </div>
    )
}

上述代碼很簡(jiǎn)單,它使用 useState 定義了兩個(gè)狀態(tài),分別表示計(jì)數(shù)器的值和加減步數(shù),在過去的文章里已對(duì) useState 做過詳細(xì)的介紹,這里不再贅述,下面詳細(xì)介紹用 useReducer 實(shí)現(xiàn)計(jì)數(shù)器。

用 useReducer 實(shí)現(xiàn)計(jì)數(shù)器

定義 reducer

使用 useReducer hook 離不開reducer,它是一個(gè)函數(shù),用于更新 useReducer 返回的狀態(tài),代碼如下:

const initArg: Counter = {value: 0, step: 1}
// 它用于更新state
function reducer(prevState: Counter, action: Action): Counter  {
    switch (action.type) {
        case 'increment':
            return {
                ...prevState,
                value: prevState.value + prevState.step
            }
        case 'decrement':
            return {
                ...prevState,
                value: prevState.value - prevState.step
            }
        case 'reset':
            return initArg
        case 'changeStep':
            return {
                ...prevState,
                step: action.value || initArg.value
            }
        default:
            throw new Error();
    }
}

reducer 用于更新狀態(tài),計(jì)數(shù)器 demo 有兩個(gè)狀態(tài),分別是計(jì)數(shù)器的當(dāng)前值和它的加減步數(shù),這兩個(gè)狀態(tài)密切相關(guān),這里用一個(gè) TS 接口去描述它,代碼如下:

interface Counter {
   // 計(jì)數(shù)器的當(dāng)前值
    value: number
   // 計(jì)數(shù)器的加減步數(shù)
    step: number
}

計(jì)數(shù)器有 3 種操作,分別是加、減、重置和修改步數(shù),這里用 TS 接口描述這些行為,代碼如下:

interface Action {
    type: 'increment' | 'decrement' | 'reset'|'changeStep',
    value?: number
}

在組件中使用 useReducer

// 計(jì)數(shù)器的初始值
const initArg: Counter = {value: 0, step: 1}
function UseReducerCounterDemo() {
    // 使用上一步定義 reducer
    const [counter, dispatch] = useReducer(reducer, initArg)
    const onChangeStep = (ev: React.ChangeEvent<HTMLInputElement>) => {
        dispatch({type: 'changeStep',value: Number(ev.target.value)})
    }
    return (
        <div>
            <h2>用useReducer實(shí)現(xiàn)計(jì)數(shù)器</h2>
            count: {counter.value}; 
            step: <input type='number' value={counter.step} onChange={onChangeStep}/>
            <button onClick={() => dispatch({type: 'increment'})}>加</button>
            <button onClick={() => dispatch({type: 'decrement'})}>減</button>
            <button onClick={() => dispatch({type: 'reset'})}>重置</button>
        </div>
    )
}

只考慮代碼量,讀者應(yīng)該都會(huì)認(rèn)為useState比useReducer更簡(jiǎn)潔。仔細(xì)觀察可以發(fā)現(xiàn),上述計(jì)數(shù)器除了有value還有step,step對(duì)value有影響,UseStateCounterDemo組件將它們零散地保存在不同的狀態(tài)中,UseStateCounterDemo組件將它們關(guān)聯(lián)在同一個(gè)狀態(tài)中,內(nèi)聚性更高。useState與useReducer沒有優(yōu)劣之外,它們有各自適用的場(chǎng)景,這里有如下建議:

1.當(dāng)狀態(tài)是一個(gè)擁有很多屬性的復(fù)雜對(duì)象,并且狀態(tài)更新涉及復(fù)雜的邏輯時(shí),推薦使用useReducer。

2.當(dāng)某個(gè)狀態(tài)的更新受另一個(gè)狀態(tài)影響時(shí),推薦使用 useReducer將它們放在一起。

3.當(dāng)狀態(tài)只是單獨(dú)的基本數(shù)據(jù)類型時(shí),推薦使用 useState。

介紹 useEffect時(shí)曾強(qiáng)調(diào),為了在 effect 中拿到狀態(tài)最新的值,必須給 effect 設(shè)置正確地依賴項(xiàng)。在 useEffect 中使用 useReducer 返回的 dispatch 能讓 effect 自給自足,減少依賴項(xiàng)。示例代碼如下:

function DispatchDemo(props: {step: number}) {
    function reducer(value: number) {
	// 始終能訪問到最新的 step 
        return props.step + value
    }
    const [value, dispatch] = useReducer(reducer, 0)
    useEffect(() => {
        document.body.addEventListener('click', dispatch)
        return () => {
            document.body.removeEventListener('click', dispatch)
        }
    }, [])
    return // todo
}

上述代碼 useEffect 的第二個(gè)參數(shù)為空數(shù)組,這意味著 effect 只在組件初始渲染時(shí)執(zhí)行。由于React 會(huì)讓 dispatch 在組件的每次渲染中保持唯一的引用,所以 dispatch 不必出現(xiàn)在effect的依賴中,此特性與 ref 類似。雖然 dispatch 的引用保持不變,但它能調(diào)用組件本次渲染時(shí)的reducer,在 reducer 作用域?qū)⒌玫阶钚碌?state 和 props。

推薦閱讀:

我搞懂了 React 的 useState 和 useEffect

到此這篇關(guān)于一文帶你搞懂React中的useReducer的文章就介紹到這了,更多相關(guān)React useReducer內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • React組件學(xué)習(xí)之Hooks使用

    React組件學(xué)習(xí)之Hooks使用

    這篇文章主要介紹了React hooks組件通信,在開發(fā)中組件通信是React中的一個(gè)重要的知識(shí)點(diǎn),本文通過實(shí)例代碼給大家講解react hooks中常用的父子、跨組件通信的方法,需要的朋友可以參考下
    2022-08-08
  • 在Create React App中啟用Sass和Less的方法示例

    在Create React App中啟用Sass和Less的方法示例

    這篇文章主要介紹了在Create React App中啟用Sass和Less的方法示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-01-01
  • react中的forwardRef 和memo的區(qū)別解析

    react中的forwardRef 和memo的區(qū)別解析

    forwardRef和memo是React中用于性能優(yōu)化和組件復(fù)用的兩個(gè)高階函數(shù),本文給大家介紹react中的forwardRef 和memo的區(qū)別及適用場(chǎng)景,感興趣的朋友跟隨小編一起看看吧
    2023-10-10
  • React中實(shí)現(xiàn)插槽效果的方案詳解

    React中實(shí)現(xiàn)插槽效果的方案詳解

    在React中是沒有插槽的概念的, 或者說在React中是不需要插槽的, 因?yàn)镽eact對(duì)于這種需要插槽的情況非常靈活,本文給大家分享兩種方案實(shí)現(xiàn),分別是children實(shí)現(xiàn)插槽和props實(shí)現(xiàn)插槽,結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2022-09-09
  • Objects are not valid as a React child報(bào)錯(cuò)解決

    Objects are not valid as a Rea

    這篇文章主要為大家介紹了Objects are not valid as a React child報(bào)錯(cuò)解決方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • React Component存在的幾種形式詳解

    React Component存在的幾種形式詳解

    這篇文章主要給大家介紹了關(guān)于React Component存在的幾種形式,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-11-11
  • react-router?重新加回跳轉(zhuǎn)攔截功能詳解

    react-router?重新加回跳轉(zhuǎn)攔截功能詳解

    這篇文章主要為大家介紹了react-router?重新加回跳轉(zhuǎn)攔截功能詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • react 組件表格固定底部的實(shí)現(xiàn)代碼

    react 組件表格固定底部的實(shí)現(xiàn)代碼

    在React中,要實(shí)現(xiàn)一個(gè)組件表格并且固定底部,可以使用CSS的固定定位或絕對(duì)定位來實(shí)現(xiàn),下面通過示例代碼給大家分享react 組件表格固定底部的實(shí)現(xiàn)代碼,感興趣的朋友跟隨小編一起看看吧
    2024-05-05
  • React通過useContext特性實(shí)現(xiàn)組件數(shù)據(jù)傳遞

    React通過useContext特性實(shí)現(xiàn)組件數(shù)據(jù)傳遞

    本文主要介紹了React如何通過useContext特性實(shí)現(xiàn)組件數(shù)據(jù)傳遞,文中有相關(guān)的代碼示例供大家參考,對(duì)我們學(xué)習(xí)React有一定的幫助,需要的朋友可以參考下
    2023-06-06
  • React useState 使用從基礎(chǔ)到高級(jí)應(yīng)用示例小結(jié)

    React useState 使用從基礎(chǔ)到高級(jí)應(yīng)用示例小結(jié)

    React 的 useState 是一個(gè)內(nèi)置的 Hook,它允許我們?cè)诤瘮?shù)組件中添加和管理狀態(tài),本文給大家介紹React useState 使用從基礎(chǔ)到高級(jí)應(yīng)用示例小結(jié),感興趣的朋友一起看看吧
    2025-09-09

最新評(píng)論

宜阳县| 运城市| 高陵县| 满洲里市| 宁城县| 施秉县| 福清市| 大邑县| 天门市| 信宜市| 胶州市| 左权县| 遂宁市| 璧山县| 瓮安县| 罗甸县| 武隆县| 芮城县| 盐亭县| 法库县| 息烽县| 化德县| 新郑市| 涡阳县| 冀州市| 孟村| 嘉义市| 元阳县| 铁岭县| 鹿邑县| 科尔| 枞阳县| 阿克陶县| 新安县| 犍为县| 台南市| 保康县| 库伦旗| 镇平县| 白沙| 繁昌县|