react hooks之useReducer+useContext实现redux简易版

useReducer+useContext≈Redux

思路

  1. 创建全局的Context
  2. 创建全局的Reducer
  3. 将全局useReducer返回的state和dispatch传递给全局Context.Provider的value中
  4. 用全局构建好的带有Context的组件包裹应用根组件

编码(暂且叫Reduxx)

/**
 * 文件名 Reduxx.js
 */
import React, { useReducer, createContext } from "react";

// 1. 创建全局的Context
const Context = createContext();
export default Context;


// 2. 创建全局的Reducer
const initState = {};

const reducer = (state, action) => {
  switch (action.type) {
    case "setState":
      return { ...state, ...action.payload };
    default:
      return state;
  }
};


// 3. 将全局useReducer返回的state和dispatch传递给全局Context.Provider的value中
export const Provider = ({ children }) => {
  const [state, dispatch] = useReducer(reducer, initState);

  return (
    <Context.Provider value={{ state, dispatch }}>{children}</Context.Provider>
  );
};

用Reduxx包裹应用根组件

import { Provider } from "./Reduxx";
import ReduxDemo from "./components/ReduxDemo";
export default function App() {
  return (
    <Router>
      <Provider>
        <div className="App">
          <h3>Hooks 学习</h3>
          <ul>
            <li>
              <Link to="/">useState</Link>
            </li>
            <li>
              <Link to="/reduxDeom">useReducer+useContext≈Redux</Link>
            </li>
          </ul>
          <div className="show">
            <Route path="/" exact render={() => <div>useState so easy</div>} />  
            <Route path="/reduxDeom" exact component={ReduxDemo} />
          </div>
        </div>
      </Provider>
    </Router>
  );
}

使用

/**
* ReduxDemo.js
**/
import React, { useContext } from "react";
import Context from "../Reduxx";

export default () => {
  const { state, dispatch } = useContext(Context);

  return (
    <div>
      <h3>useReducer+useContext≈Redux</h3>
      <div>{JSON.stringify(state)}</div>
      <button
        onClick={() => {
          dispatch({ type: "setState", payload: { time: Date.now() } });
        }}
      >
        set Time
      </button>
      <button
        onClick={() => {
          dispatch({ type: "setState", payload: { random: Math.random() } });
        }}
      >
        set Random
      </button>
    </div>
  );
};

效果演示

完整代码

点赞

发表评论

电子邮件地址不会被公开。必填项已用 * 标注