返回

Hooks风格的简易多模块Redux的秘密

前端

在使用React开发项目时,我们不可避免地需要状态管理。尽管各种状态管理库层出不穷,但有时一个项目并不需要太重的状态管理库。

随着React 16.8推出Hooks写法,我们可以利用这一新特性,手写一个Hooks风格的简易多模块Redux。

具体步骤如下:

  1. 创建StateContext和DispatchContext。
import React from "react";
const StateContext = React.createContext();
const DispatchContext = React.createContext();

// 创建Provider
const Provider = ({children, state, dispatch}) => {
  return (
    <StateContext.Provider value={state}>
      <DispatchContext.Provider value={dispatch}>
        {children}
      </DispatchContext.Provider>
    </StateContext.Provider>
  );
};

// 导出Hooks
export const useState = () => {
  const context = useContext(StateContext);
  if (context === undefined) {
    throw new Error("useState must be used within a Provider");
  }
  return context;
};

export const useDispatch = () => {
  const context = useContext(DispatchContext);
  if (context === undefined) {
    throw new Error("useDispatch must be used within a Provider");
  }
  return context;
};

export {Provider};
  1. 创建reducer。
const reducer = (state, action) => {
  switch (action.type) {
    case 'ADD_TODO':
      return {...state, todos: [...state.todos, action.payload]};
    case 'REMOVE_TODO':
      return {...state, todos: state.todos.filter(todo => todo.id !== action.payload)};
    default:
      return state;
  }
};
  1. 创建store。
import {createStore} from "redux";
import {reducer} from "./reducer";
const store = createStore(reducer, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__());
export default store;
  1. 使用Provider包裹应用。
import React from "react";
import {Provider} from "./StateContext";
import {store} from "./store";
const App = () => {
  return (
    <Provider state={store.getState()} dispatch={store.dispatch}>
      <div>
        {/* 应用内容 */}
      </div>
    </Provider>
  );
};

export default App;
  1. 在组件中使用Hooks。
import React, {useState, useDispatch} from "./StateContext";
const Component = () => {
  const [state] = useState();
  const dispatch = useDispatch();
  // 使用state和dispatch
  return (
    <div>
      {/* 组件内容 */}
    </div>
  );
};

export default Component;

这样,我们就手写了一个简易的Hooks风格的多模块Redux。我们可以根据项目需求,进一步完善它,使其更加灵活和强大。