先简略温习一下redux工作流程

graph LRA[action]-- dispatch.action-->B[store]B--previousState,action -->C[reducers]C-- newState -->BB-- state -->D[组件]

react-hook替换redux计划

要求列表

  • useReducer、useContext函数
  • action:寄存批改state的action,此处与redux的思维统一
  • reducer:用来解决不同action,此处咱们不提供初始状态的话,默认会去action找。
  • rootReducer:当reducer过多的时候,咱们能够拆分reducer,拆分reducer后,应用combinReducers合并解决成一个大繁多的对象。
  • 顶级组件:

    1. 组件利用provider提供context给子组件
      2.useReducer定义,引入reducer并提供初始化状态initialstate
  • 子组件:

    1. useContext应用顶级组件提供的context
    2. 如果须要异步申请,应用useEffect

实现逻辑要害代码:

  • cartReducer.js

    // 定义一个action typeconst CHANGE_CART_AMOUNT = "CHANGE_CART_AMOUNT";// 初始化状态数据const initialState ={cartList: []};// reducer解决action,返回newStateexport const cartReducer = (state, action) => {switch (action.type) {  case CHANGE_CART_AMOUNT:    let cartList = state?state.cart.cartList:[];    let cartItem = action.payload;    return {      cartList: [...cartList, cartItem]    };  default:    {      return state;    }}};
    当你除了一个cartReducer之外还有很多reducer,这个时候咱们须要拆分并对立治理。
  • rootReducer.js

    import { cartReducer,initialStates } from './cartReducer';import combineReducers from './combineReducers';import { layoutInitialState, layoutReducer } from './layoutReducer';export const initialState = {layout: layoutInitialState,cart: initialStates()};//拆分reducer后,应用combinReducers合并解决成一个大繁多的对象, export const rootReducer = combineReducers({layout: layoutReducer,cart: cartReducer });
    这里的combineReducer依照redux逻辑,间接写,不是用redux的。
    redux的combineReducer工作原理参考:https://www.cnblogs.com/wy193...
  • combineReducers.js

    //将多个reducer合并成一个reducerconst combineReducers = reducers => {return (state = {}, action) => {  const newState = {};  for (let key in reducers) {    newState[key] = reducers[key](state, action);  }  return newState;}; };export default combineReducers;
  • 顶级组件.jsx
    要害代码

    const AppContext = createContext({state: initialState,dispatch: () => {} });//因为创立的contenxt AppContext须要在各个组件都用uesContext应用到,所以须要导出。export default AppContext; //Redux 是通过 createStore(reducer, initialState) 来创立一个 store 实例,// 实例封装了 state 的读写接口和监听接口:getState 、dispatch、subscribe// 在Redux中,store.dispatch 触发事件动作时,Redux 并不会为咱们被动从新渲染视图,而是须要咱们调用 store.subscribe 在监听函数中手动 render 视图//但 useReducer Hook 是没有应用 store 实例,//而是遵循 Hook 总是返回读写接口的规定,间接通过 [state, dispatch] = useReducer(reducer, initialState) 的形式返回状态的读写接口。const [state, dispatch] = useReducer(rootReducer,initialState);//因为布局数据简直不变动,咱们能够应用缓存,等变动再更新,利用dispatch去触发咱们下面定义的rootReducerconst contextValue = useMemo(() => {  return {    state,    dispatch  };}, [state, dispatch]);//Provider传递参数return <AppContext.Provider value={contextValue}>  </AppContext.Provider>;  
  • 子组件.jsx:在react-hook中,咱们只须要触发reducer就能实现像redux-store的dispatch成果一样。

    // 触发dispatchconst {  state,  dispatch} = useAppContext();const handleCartAmountChange = useCallback((amount, product) => () => {  dispatch({    type: "CHANGE_CART_AMOUNT",    payload: { ...product,      qty: amount    }  });}, []);//获取stateconst {  state} = useAppContext();useEffect(() => {  setList(state?state.cart.cartList:[])},[state]);