React Hook使用useContext和useReducer構(gòu)建局部Reducer

useContext介紹

接收一個(gè) context 對(duì)象(React.createContext 的返回值)并返回該 context 的當(dāng)前值。

// MyContext由createContext()創(chuàng)建
let count = useContext(MyContext);

常用于容器組件向子組件傳值

示例

這里以父組件向子組件傳count累加值為例

定義容器組件

import { createContext } from "react";
export let MyContext = createContext();

定義子組件

import React, { useContext } from "react";
import { MyContext } from "./myContext";

export default () => {
  let count = useContext(MyContext);
  return (
    <h3>子組件{count}</h3>
  )
}

調(diào)用組件

import React, { createContext, useContext, useState } from "react";

import { MyContext } from "./myContext";
import { Button } from "antd";


function UseContext() {
  const [count, setCount] = useState(0);
  return (
    <>
      <MyContext.Provider value={count}>
        <ChildContext/>
      </MyContext.Provider>
      <Button type={"primary"} onClick={() => {
        setCount(count + 1);
      }}>
        change count
      </Button>
    </>
  )
}

export default UseContext;

useReducer介紹

類似于Redux數(shù)據(jù)流形式。使用state共享數(shù)據(jù),dispatch觸發(fā)數(shù)據(jù)修改。

const [state, dispatch] = useReducer(reducer, initialArg, init);

useReducer接收3個(gè)參數(shù):

  1. 接收一個(gè)函數(shù),reducer對(duì)數(shù)據(jù)的具體操作。
  2. state初始值。
  3. 接收一個(gè)函數(shù),用于state初始化。

示例

修改通過dispatch修改對(duì)象中屬性為例。

import React, { useReducer } from "react";
import { Button } from "antd";

function UseReducer() {
  const [state, dispatch] = useReducer((state, action) => {
    switch (action.type) {
      case 'setName':
        return {
          ...state,
          name: action.name
        }
      default:
        return state;
    }
  }, { name: 'init' });
  return (
    <>
      <h1>{state.name}</h1>
      <Button type={"primary"} onClick={() => {
        dispatch({
          type: 'setName',
          name: 'hzm'
        })
      }}>setName</Button>
    </>
  )
}

export default UseReducer;

構(gòu)建局部Reducer

大概介紹完useContext和useReducer用法,接下來開始進(jìn)入正題。結(jié)合useContext和useReducer構(gòu)建局部的Redux。
我們這里需要?jiǎng)?chuàng)建3個(gè)文件

  1. reduceAndContext.js (頂層組件,用于向下分發(fā)數(shù)據(jù))
  2. reducer.js (reducer的具體操作)
  3. childReducer.js (子組件,向reducer發(fā)送dispatch)

reduceAndContext.js

import React from "react";
import { Reducer } from "./reducer";
import ChildReducer from "./childReducer";

function ReducerAndContext() {
  return (
    <Reducer>
      <ChildReducer/>
    </Reducer>
  )
}

export default ReducerAndContext;

reduceAndContext.js 中引入reducer.js和childReducer.js,讓<Reducer>包裹下的<ChildReducer/>組件能接收到Reducer中的數(shù)據(jù)。

reducer.js

import React, { createContext, useReducer } from "react";

export const MyContext = createContext();

const reducer = (state, action) => {
  switch (action.type) {
    case 'setName':
      return {
        ...state,
        name: action.name
      }
    default:
      return state;
  }
}

const defaultData = {
  name: 'init',
}

export function Reducer(props) {
  const [state, dispatch] = useReducer(reducer, defaultData);
  return (
    <MyContext.Provider value={{ state, dispatch }}>
      {props.children}
    </MyContext.Provider>
  )
}

這里導(dǎo)出兩個(gè)模塊:

  1. MyContext (因?yàn)樽咏M件使用useContext需要傳入createContext,所以必須導(dǎo)出頂層組件創(chuàng)建的Context)
  2. Reducer (創(chuàng)建useReducer,并且把state和dispatch通過createContext提供的Provider形式傳到子組件)
    由此,子組件就可以通過useContext使用父組件傳過來的state和dispatch更新Reducer中的state數(shù)據(jù)。

childReducer.js

import React, { useContext } from "react";
import { MyContext } from "./reducer";
import { Button } from "antd";

function ChildReducer() {
  const { state, dispatch } = useContext(MyContext);
  return (
    <>
      <h1>{state.name}</h1>
      <Button type={"primary"} onClick={() => {
        dispatch({
          type: 'setName',
          name: 'hzm'
        })
      }}>
        change reducer
      </Button>
    </>
  )
}

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

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