rtk-config-store: 基于 redux-toolkits 的状态管理库

基于 redux-toolkits 扩展的一些功能
更新于: 2024-01-23 13:05:16
项目主页: https://github.com/afeiship/rtk-config-store

特性展示

功能场景代码
nx.$get在非hook场景上取值,值不会更新 UI
// 正常的 state
nx.$get('user.profile')
// selectors 里定义的 computed state
nx.$get('user.username')
nx.$use在 hook 场景下取值,值会更新 UI
// 正常的 state
nx.$use('user.profile')
// selectors 里定义的 computed state
nx.$use('user.username')
nx.$patch代替 dispatch(即 useDispatch 的场景)
nx.$patch('user/setProfile', profile);
nx.$patch({ type: 'user/setProfile', payload: profile });
nx.$store全局的 rootStore 引用-
nx.$slice所有的 slice key/value 引用-
nx.$createSlice代替 createSlice,具有 watch 的 key
export default nx.$createSlice({
  name: 'user',
  initialState: {
    profile: JSON.parse(localStorage.getItem('profile'))
  },
  // ...
  selectors: {
    username: (state) => state.profile.login
  },
  watch: {
    profile: (newValue, oldValue, objectPath) => {
      console.log('profile:', newVal, oldVal, objectPath);
    }
  }
});
nx.$event

全局 emit 了2个事件

如果没有 nx.$event 存在,则不存在这个注册行为

  • rtk.*
  • rtk.${actionType}
// listen 所有的 action 相关的 events
nx.$event.on('rtk.*', ([action, listenerApi])=>{});

// listen 与 user/setProfile 这个 action 相关的
nx.$event.on('rtk.user/setProfile', ([action, listenerApi])=>{});

安装

yarn add @jswork/rtk-config-store

/// <reference types="@jswork/rtk-config-store/global.d.ts" />

tsconfig.ts 配置

{
  "compilerOptions": {
    "noImplicitAny": false,
  },
  "include": ["src"],
  "references": [{ "path": "./tsconfig.node.json" }]
}

使用

src/store.ts

import { scanWebpack } from '@jswork/scan-modules';
import RtkConfigStore from '@jswork/rtk-config-store';

// when webpack
const context = require.context('./modules', true, /\.ts$/);
const modules = scanWebpack(context, { modules: '/modules/' });
export const store = RtkConfigStore({ modules, preloadedState: {}, reducer: {} });

// Infer the `RootState` and `AppDispatch` types from the store itself
export type RootState = ReturnType<typeof store.getState>;
// Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState}
export type AppDispatch = typeof store.dispatch;

入口 Provider 保持不变,main/app.ts

import { Provider } from 'react-redux';
import { store } from '@/shared/stores/root';

interface IReduxProviderProps extends React.PropsWithChildren {}

export default function (props: IReduxProviderProps) {
  const { children } = props;
  return <Provider store={store}>{children}</Provider>;
}

创建一个 store

其实就是扩展了一个 watch ,借助了 redux-watch

export default nx.$createSlice({
  name: 'user',
  initialState: {
    token: null,
    profile: JSON.parse(localStorage.getItem('profile'))
  },
  reducers: {
    setToken: (state, action) => {
      state.token = action.payload;
    },
    setProfile: (state, action) => {
      state.profile = action.payload;
    }
  },
  selectors: {
  	username: (state)=> state.profile.login
  },
  watch: {
    profile: (newValue, oldValue, objectPath) => {
      console.log('profile:', newVal, oldVal, objectPath);
    }
  }
});