小技巧:使用useContext和useReducer構(gòu)建小型redux

對于兩個子組件間的通信,相信我們開發(fā)中并不少見,基于我們都不怎么喜歡redux的堅持…...其實我一直在用團隊老大此前寫的globalBus持續(xù)真香,我在上一篇文章也有講到那玩意的原理和實現(xiàn),但是老大說現(xiàn)在可以不用啦,新版hooks兩個api聯(lián)用,更香,于是我簡單的實踐了一番,發(fā)現(xiàn)…真香。

首先你需要在兩個子組件之上的一層架設(shè)你的context chilFirst和ChildSecond是我建立的兩個組件,我們將會從first組件發(fā)dipatch,在second組件展示變化的數(shù)據(jù),這個場景開發(fā)中經(jīng)常使用。

首先我們要建立context, 我們需要一個初始狀態(tài)和一個變更state的狀態(tài)管理器,咦,這怎么這么像…..

// Context.js
export const defaultState = {
    value: 0
}

export function reducer(state, action) {
    switch(action.type) {
        case 'ADD_NUM':
            return { ...state, value: state.value + 1 };
        case 'REDUCE_NUM':
            return { ...state, value: state.value - 1 };
        default: 
            throw new Error();
    }
}

Content.js ,這里我們需要顯性聲明Context.Provider 把數(shù)據(jù)傳給包裹組件,這里輪到強大的useReducer出場了,按照官方要求,你需要把reducer(我們此前定義)和默認狀態(tài)傳入https://reactjs.org/docs/hooks-reference.html#usereducer,(這里小小利用hooks組件的狀態(tài),當(dāng)我們向上傳遞修改后,其包裹的組件的引用props更新也會重新獲得新的props)

// Content.js
import React, { useReducer, createContext } from 'react'
import { ChildFirst } from './ChildFirst'
import { ChildSecond } from './ChildSecond'
import { reducer, defaultState } from './reducer'

export const Context = createContext(null)

export function Content() {
    const [state, dispatch] = useReducer(reducer, defaultState)

    return (
        <Context.Provider value={{state, dispatch: dispatch}}>
            <ChildFirst/>
            <ChildSecond/>
        </Context.Provider>
    )
} 

組件First ,在這個組件我們dispatch發(fā)事件試試

// ChildFirst.js
import React, {useContext} from 'react'
import {Context} from './content'

export function ChildFirst() {
    const AppContext = useContext(Context)

    return (
        <div>
            <button onClick={ 
                 () => {
                AppContext.dispatch({
                    type: "ADD_NUM",
                    payload: {}
                  })
                }
            }>addNum</button>
            <button onClick={
                () => {
                AppContext.dispatch({
                    type: "REDUCE_NUM",
                    payload: {}
                    })  
                }
            }>reduceNum</button>
        </div>
    )
} 

組件Second

// ChildSecond.js
import React, {useContext} from 'react'
import {Context} from './content'

export function ChildSecond() {
    const AppContext = useContext(Context)

    return (
        <div>
            {AppContext.state.value + 's'}
        </div>
    )
} 
DEMO

我們發(fā)現(xiàn)在局部地區(qū)架設(shè)局部組件需要公用的context,不僅有利于我們組織結(jié)構(gòu)的解耦,也可以避免我們一開始就要引入redux這種全局狀態(tài)庫或者中途引入帶來的成本。本身作為一個應(yīng)用需要公共管理的狀態(tài)其實并不多,再加之團隊開發(fā)素質(zhì)不一管理不善的話,就很容易濫用redux,極大拖慢了整個應(yīng)用的速度,所以學(xué)會這個技巧,可以優(yōu)化組件間的狀態(tài)管理和應(yīng)用的輕便性能。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容