umi+dva 数据持久化

2,799 阅读1分钟

项目上用到了数据持久化,网络上找到了很多。但是写的都不完整,特此记录下...

版本

"redux-persist": "^6.0.0", "umi": "^3.5.20"
  • Umi 在 .umirc.tsconfig/config.ts 中配置项目和插件,支持 es6。

    export default defineConfig({
      nodeModulesTransform: {
        type: 'none',
      },
      antd: {},
      dva: {  // 这样就开启成功了。
        immer: true,
        hmr: true,
      },
    });
    
  • 需要在app.tsx 种配置 (这个是umi的运行配置,详细可以看文档)

    // 运行时配置
    // 运行时候、配置的区别是跑在浏览器上,可以写函数,jsx,import浏览器依赖import { message } from 'antd';
    import { persistStore, persistReducer } from 'redux-persist';
    import storage from 'redux-persist/lib/storage'; // 用什么缓冲 storage 还是session
    import { getDvaApp } from 'umi';
    import autoMergeLevel2 from 'redux-persist/lib/stateReconciler/autoMergeLevel2';
    ​
    // 这个是redux-persist 的配置
    const persistConfig = {
      key: 'root', // 自动框架生产的根目录id 是root。不变
      storage, // 这个是选择用什么存储,session 还是 storage
    };
    const persistEnhancer = () => (createStore: any) => (reducer: any, initialState: any, enhancer: any) => {
      const store = createStore(persistReducer(persistConfig, reducer), initialState, enhancer);
      const persist = persistStore(store);
      return { ...store, persist };
    };
    ​
    export const dva = {
      config: {
        onAction: createLogger(), // 每次action的时候会触发
        onError(e: Error) { 
          message.error(e.message, 3);
        },
        extraEnhancers: [persistEnhancer()],
      },
    };
    
  • 在layout.tsx上包裹一层

    import * as React from 'react';
    import { Layout, Menu } from 'antd';
    import { Link, connect } from 'umi';
    const { Header, Footer, Sider, Content } = Layout;
    import { getDvaApp } from 'umi';
    import { Spin } from 'antd';
    import { persistStore } from 'redux-persist';
    import { PersistGate } from 'redux-persist/integration/react';
    ​
    export const layout = (props: any) => {
      const { children } = props;
      const app = getDvaApp(); // 获取dva的实例
      const persistor = app._store.persist; 
    ​
      return (
        <PersistGate loading={null} persistor={persistor}>
          <Layout>
            <Content>{children}</Content>
          </Layout>
        </PersistGate>
      );
    };
    ​
    // 需要先定义 mapStateToProps 这个函数来指定如何把当前 Redux store state 映射到展示组件的 props 中。
    function mapStateToProps(store:any){
        // state     index 是namespace
        return {tab:store.index.tab}
        
    }
    ​
    ​
    ​
    ​
    ​
    export default connect(mapStateToProps)(layout);
    ​