React Redux 实现 (Context 版)

Favori,

React Redux Context

图:nework

redux store

export const createStore = (reducer: Function, initialState: any) => {
  let state = initialState;
  let listeners: Function[] = [];
  const getState = () => {
    return state;
  };
  const subscribe = (listener: Function) => {
    listeners.push(listener);
    return () => {
      listeners = listeners.filter((l) => l !== listener);
    };
  };
  const dispatch = (action: { type: string; payload: any }) => {
    state = reducer(state, action);
    listeners.forEach((l) => l());
  };
  return { dispatch, getState, subscribe };
};
 
export default { createStore };
import { storeContext } from "./context";
 
export const Provider = (props: any) => {
  const { store, children } = props;
  const ProviderComponent = storeContext.Provider;
  return <ProviderComponent value={store}>{children}</ProviderComponent>;
};
 
import React, { useContext, useEffect, useMemo, useState } from "react";
import { storeContext } from "./context";
 
export const ConnectComponent = (props: any) => {
  const {
    WrapperComponent,
    mapStateToProps,
    mapDispatchToProps,
    ...restProps
  } = props;
  const [, forceUpdate] = useState<any>();
  const { dispatch, getState, subscribe } = useContext(storeContext);
  const state = getState();
 
  const mapState = useMemo(() => {
    if (!mapStateToProps) {
      return state;
    }
    return mapStateToProps(state);
  }, [state]);
 
  const mapAction = useMemo(() => {
    if (!mapDispatchToProps) {
      return {};
    }
    return mapDispatchToProps(dispatch);
  }, [dispatch]);
 
  const memoComponent = useMemo(() => {
    return (
      <WrapperComponent
        {...mapState}
        {...mapAction}
        {...restProps}
        dispatch={dispatch}
      />
    );
  }, [mapState, mapAction]);
 
  const unsubscribe = subscribe(() => {
    forceUpdate({});
  });
 
  return memoComponent;
};
 
export const connect = (mapStateToProps?: any, mapDispatchToProps?: any) => {
  return (WrapperComponent: React.ElementType) => (props: any) => (
    <ConnectComponent
      {...props}
      mapStateToProps={mapStateToProps}
      WrapperComponent={WrapperComponent}
      mapDispatchToProps={mapDispatchToProps}
    />
  );
};
 

😅 遇事不决加一层