美文网首页
React Hook使用useContext和useReduce

React Hook使用useContext和useReduce

作者: 敏0321 | 来源:发表于2020-05-11 15:49 被阅读0次

    useContext介绍

    接收一个 context 对象(React.createContext 的返回值)并返回该 context 的当前值。

    // MyContext由createContext()创建
    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>
      )
    }
    

    调用组件

    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数据流形式。使用state共享数据,dispatch触发数据修改。

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

    useReducer接收3个参数:

    1. 接收一个函数,reducer对数据的具体操作。
    2. state初始值。
    3. 接收一个函数,用于state初始化。

    示例

    修改通过dispatch修改对象中属性为例。

    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;
    

    构建局部Reducer

    大概介绍完useContext和useReducer用法,接下来开始进入正题。结合useContext和useReducer构建局部的Redux。
    我们这里需要创建3个文件

    1. reduceAndContext.js (顶层组件,用于向下分发数据)
    2. reducer.js (reducer的具体操作)
    3. childReducer.js (子组件,向reducer发送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中的数据。

    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>
      )
    }
    

    这里导出两个模块:

    1. MyContext (因为子组件使用useContext需要传入createContext,所以必须导出顶层组件创建的Context)
    2. Reducer (创建useReducer,并且把state和dispatch通过createContext提供的Provider形式传到子组件)
      由此,子组件就可以通过useContext使用父组件传过来的state和dispatch更新Reducer中的state数据。

    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;
    

    相关文章

      网友评论

          本文标题:React Hook使用useContext和useReduce

          本文链接:https://www.haomeiwen.com/subject/flmunhtx.html