Umi: The right way to use umi's redux-persist.

Created on 23 Jan 2019  ·  8Comments  ·  Source: umijs/umi

package.json:

 "umi": "^2.2.8",
 "umi-plugin-react": "^1.1.1",
 "redux-persist": "^5.10.0"

src/app.js:

const persistConfig = {
  timeout: 1000,  // you can define your time. But is required.
  key: 'root',
  storage,
  whitelist: ['xxx'], 
};

const persistEnhancer = () => createStore => (reducer, initialState, enhancer) => {
  const store = createStore(persistReducer(persistConfig, reducer), initialState, enhancer);
  const persist = persistStore(store, null);
  return {
    persist,
    ...store,
  };
};
export const dva =
  process.env.APP_TYPE === 'build'
    ? {
        config: {
          extraEnhancers: [persistEnhancer()],
        },
      }
    : {
        config: {
          extraEnhancers: [persistEnhancer()],
        },
        plugins: [
          {
            // onAction: createLogger(),
          },
        ],
      };

Your top container component:
(in this example it would be BasicLayout.js)
This step is important, because if not wrapped in PersistGate, it may cannot get the models in componentDidmount.

import { PersistGate } from 'redux-persist/integration/react';
import { persistStore } from 'redux-persist';

return (
      <React.Fragment>
        <PersistGate
          persistor={persistStore(window.g_app._store)}
          loading={<Spin indicator={loadingIcon} />}
        >
          <DocumentTitle title={this.getPageTitle(pathname)}>
            <ContainerQuery query={query}>
              {params => (
                <Context.Provider value={this.getContext()}>
                  <div className={classNames(params)}>
                    <Layout style={{ minHeight: '100vh' }}>
                      <Header menuData={menuData} {...this.props} />
                      <Content>{children}</Content>
                    </Layout>
                  </div>
                </Context.Provider>
              )}
            </ContainerQuery>
          </DocumentTitle>
        </PersistGate>
      </React.Fragment>
    );

config/config.js:

dva: {
  dynamicImport: undefined,  // this depend on your business logic.
},
type(documentation)

Most helpful comment

All 8 comments

👍

image
fllowing above, get the errors

.umirc.js
dynamicImport: {
webpackChunkName: true
},
dva: {
dynamicImport: undefined,
hmr: true
},
Follow your steps,it's work. but I set dva--dynamicImport to true, it doesn't work , persist state only at initialization time.....,so I set dynamicImport: {
webpackChunkName: true
} ,

@weishijun14 大佬,就这个问题,能帮忙解答么?我按照您的方法,不生效呀.只存了初始化的state,state变化之后localStorage 里面没有更新.

package.json:

 "umi": "^2.2.8",
 "umi-plugin-react": "^1.1.1",
 "redux-persist": "^5.10.0"

src/app.js:

const persistConfig = {
  timeout: 1000,  // you can define your time. But is required.
  key: 'root',
  storage,
  whitelist: ['xxx'], 
};

const persistEnhancer = () => createStore => (reducer, initialState, enhancer) => {
  const store = createStore(persistReducer(persistConfig, reducer), initialState, enhancer);
  const persist = persistStore(store, null);
  return {
    persist,
    ...store,
  };
};
export const dva =
  process.env.APP_TYPE === 'build'
    ? {
        config: {
          extraEnhancers: [persistEnhancer()],
        },
      }
    : {
        config: {
          extraEnhancers: [persistEnhancer()],
        },
        plugins: [
          {
            // onAction: createLogger(),
          },
        ],
      };

Your top container component:
(in this example it would be BasicLayout.js)
This step is important, because if not wrapped in PersistGate, it may cannot get the models in componentDidmount.

import { PersistGate } from 'redux-persist/integration/react';
import { persistStore } from 'redux-persist';

return (
      <React.Fragment>
        <PersistGate
          persistor={persistStore(window.g_app._store)}
          loading={<Spin indicator={loadingIcon} />}
        >
          <DocumentTitle title={this.getPageTitle(pathname)}>
            <ContainerQuery query={query}>
              {params => (
                <Context.Provider value={this.getContext()}>
                  <div className={classNames(params)}>
                    <Layout style={{ minHeight: '100vh' }}>
                      <Header menuData={menuData} {...this.props} />
                      <Content>{children}</Content>
                    </Layout>
                  </div>
                </Context.Provider>
              )}
            </ContainerQuery>
          </DocumentTitle>
        </PersistGate>
      </React.Fragment>
    );

config/config.js:

dva: {
  dynamicImport: undefined,  // this depend on your business logic.
},

loading={}
loading with a long time

Thank you!! really helpful for me!!

In the umi v3 , window.g_app is no longer be used and change to use the getDvaApp() API
So, The PersistGate persistor change to

import styles from './index.css';
import { getDvaApp } from 'umi'
import { Spin } from 'antd';
import { persistStore } from 'redux-persist'
import { PersistGate } from 'redux-persist/integration/react'

function BasicLayout(props) {
  const app = getDvaApp()
  return (
    <div className={styles.normal}>
        <PersistGate 
          loading={<Spin />} 
          persistor={persistStore(app._store)}
        >
       <h1 className={styles.title}>Yay! Welcome to umi!</h1>
       {props.children}
      </PersistGate>
    </div>
  );
}

But the website just keep showing loading and no errors were issued.

Finally, I notice the persistEnhancer returned persist can be found in getDvaApp()._store

and I use it to replace persistStore(app._store)

import styles from './index.css';
import { getDvaApp } from 'umi'
import { Spin } from 'antd';
import { persistStore } from 'redux-persist'
import { PersistGate } from 'redux-persist/integration/react'

function BasicLayout(props) {
  const app = getDvaApp()
  const persistor = app._store.persist
  return (
    <div className={styles.normal}>
        <PersistGate 
          loading={<Spin />} 
          persistor={persistor}
        >
       <h1 className={styles.title}>Yay! Welcome to umi!</h1>
       {props.children}
      </PersistGate>
    </div>
  );
}

Now, it's work for me and will not get the models in componentDidmount in umi v3

package.json:

    "redux-persist": "^6.0.0",
    "umi": "^3.3.7"
Was this page helpful?
0 / 5 - 0 ratings

Related issues

mizi-lin picture mizi-lin  ·  3Comments

sorrycc picture sorrycc  ·  4Comments

kitebear picture kitebear  ·  3Comments

afc163 picture afc163  ·  3Comments

nguyenhuutinh picture nguyenhuutinh  ·  3Comments