umi-plugin-dva 支持引入 redux-persist

Created on 23 Mar 2018  ·  17Comments  ·  Source: umijs/umi

import { persistStore, autoRehydrate } from 'redux-persist';
const app = dva({
extraEnhancers: [autoRehydrate()],
});
persistStore(app._store);

ref:

  • dvajs/dva#1573
pkg(umi-plugin-dva) type(enhancement)

Most helpful comment

有一种解决方法 利用 store enhancer 在src目录下的dva.js

import { persistStore, persistReducer } from 'redux-persist';
import storage from "redux-persist/es/storage/session";

const persistConfig = {
  key: 'xxx',
  storage,
};
const persistEnhancer = ()=>createStore=>(reducer, initialState, enhancer)=>{
  const store = createStore(persistReducer(persistConfig, reducer), initialState, enhancer);
  const persist = persistStore(store);
  return {...store, persist };
};
export function config() {
    return {
      onError(err) {
        err.preventDefault();
        console.error(err.message);
      },
      extraEnhancers:[
        persistEnhancer()
      ]
    };
}

我这用的redux-persist 5.10.0

All 17 comments

表示关注 👀

写在哪一个文件中?dva.js ?

无法写入dvaContainer.js啊,会被刷新

有一种解决方法 利用 store enhancer 在src目录下的dva.js

import { persistStore, persistReducer } from 'redux-persist';
import storage from "redux-persist/es/storage/session";

const persistConfig = {
  key: 'xxx',
  storage,
};
const persistEnhancer = ()=>createStore=>(reducer, initialState, enhancer)=>{
  const store = createStore(persistReducer(persistConfig, reducer), initialState, enhancer);
  const persist = persistStore(store);
  return {...store, persist };
};
export function config() {
    return {
      onError(err) {
        err.preventDefault();
        console.error(err.message);
      },
      extraEnhancers:[
        persistEnhancer()
      ]
    };
}

我这用的redux-persist 5.10.0

有一种解决方法 利用 store enhancer 在src目录下的dva.js

import { persistStore, persistReducer } from 'redux-persist';
import storage from "redux-persist/es/storage/session";

const persistConfig = {
  key: 'xxx',
  storage,
};
const persistEnhancer = ()=>createStore=>(reducer, initialState, enhancer)=>{
  const store = createStore(persistReducer(persistConfig, reducer), initialState, enhancer);
  const persist = persistStore(store);
  return {...store, persist };
};
export function config() {
    return {
      onError(err) {
        err.preventDefault();
        console.error(err.message);
      },
      extraEnhancers:[
        persistEnhancer()
      ]
    };
}

我这用的redux-persist 5.10.0

在开发环境下能够获取到全部models的存的值,但是打包后只能一部分的models的值被取到。

wechatimg6282
wechatimg6283
利用的是ant design pro v2.0脚手架

@zhilianbi520 我这边用起来都是正常的 没在ant design pro上试过 你看看是不是你那边生产环境配置了黑名单

@zhilianbi520 我这边用起来都是正常的 没在ant design pro上试过 你看看是不是你那边生产环境配置了黑名单

pages下的models都存不到。models目录下的都能缓存上。。感觉好像跟环境配置没啥关系。

@zhilianbi520 我这边用起来都是正常的 没在ant design pro上试过 你看看是不是你那边生产环境配置了黑名单

pages下的models都存不到。models目录下的都能缓存上。。感觉好像跟环境配置没啥关系。

刚学习antd pro,没太明白怎么处理这个问题

@zhilianbi520 我这边用起来都是正常的 没在ant design pro上试过 你看看是不是你那边生产环境配置了黑名单

pages下的models都存不到。models目录下的都能缓存上。。感觉好像跟环境配置没啥关系。

刚学习antd pro,没太明白怎么处理这个问题

目前还是无解状态。。求解。

@zhilianbi520 我这边用起来都是正常的 没在ant design pro上试过 你看看是不是你那边生产环境配置了黑名单

pages下的models都存不到。models目录下的都能缓存上。。感觉好像跟环境配置没啥关系。

刚学习antd pro,没太明白怎么处理这个问题

目前还是无解状态。。求解。

import { persistStore, persistReducer } from 'redux-persist';
import storage from 'redux-persist/es/storage/session';

const persistConfig = {
  key: 'redux-storage',
  storage,
};
const persistEnhancer = () => createStore => (reducer, initialState, enhancer) => {
  const store = createStore(persistReducer(persistConfig, reducer), initialState, enhancer);
  const persist = persistStore(store);
  return { ...store, persist };
};

/* eslint-disable */
export const dva = {
  config: {
    onError(e) {
      e.preventDefault();
    },
    extraEnhancers: [persistEnhancer()],
  },
  plugins: [require('dva-logger')()],
};
/* eslint-enable */

在src新建app.js,目前看来没什么问题

@zhilianbi520 我这边用起来都是正常的 没在ant design pro上试过 你看看是不是你那边生产环境配置了黑名单

pages下的models都存不到。models目录下的都能缓存上。。感觉好像跟环境配置没啥关系。

刚学习antd pro,没太明白怎么处理这个问题

目前还是无解状态。。求解。

import { persistStore, persistReducer } from 'redux-persist';
import storage from 'redux-persist/es/storage/session';

const persistConfig = {
  key: 'redux-storage',
  storage,
};
const persistEnhancer = () => createStore => (reducer, initialState, enhancer) => {
  const store = createStore(persistReducer(persistConfig, reducer), initialState, enhancer);
  const persist = persistStore(store);
  return { ...store, persist };
};

/* eslint-disable */
export const dva = {
  config: {
    onError(e) {
      e.preventDefault();
    },
    extraEnhancers: [persistEnhancer()],
  },
  plugins: [require('dva-logger')()],
};
/* eslint-enable */

在src新建app.js,目前看来没什么问题

打包后的文件嘛?sessionStorage存的是所有models里的state嘛?包括pages里的。

什么时候加入redux-persist支持呢

需要在 dva config 里面将 reducer 用 redux-persist 的 reducer 包裹一遍,不然只能得到初始化的 state。代码如下:
app.js

import { persistStore, persistReducer } from 'redux-persist';
import storage from 'redux-persist/lib/storage';

const persistConfig = {
  key: 'root',
  storage,
};

const persistEnhancer = () => createStore => (reducer, initialState, enhancer) => {
  const store = createStore(persistReducer(persistConfig, reducer), initialState, enhancer);
  const persist = persistStore(store, null);
  return { ...store, persist };
};

export const dva = {
  config: {
    onError(err) {
      err.preventDefault();
      console.error(err.message);
    },
    extraEnhancers: [persistEnhancer()],
    onReducer: reducer => persistReducer(persistConfig, reducer),
  },
  plugins: [process.env.APP_TYPE === 'build' ? null : require('dva-logger')()],
};

这儿在 F5 刷新的时候会报 page 下 model key 不存在的错误。是因为 page 下的 model 是动态加载的,在初始化的时候并没有,这时候 redux-persist 会报错,说这个 key 会被忽略,这个应该不影响使用 0.0 。

以上代码生效是在以下依赖版本的基础上的,其他版本请自己摸索调试 ^V^

"umi": "^2.6.3",
"umi-plugin-react": "^1.7.6",
"redux-persist": "^5.10.0"

还是存在问题,更新了 store 里面 state 的内容,但是 persist 并没有刷新 localStorage 里面的内容。不知道为啥,有哪位大佬了解么?

上面的写法对于 hot replacement 存在问题。
优化后如下

let $persistor = null;
const persistConfig = {
  key: "root",
  storage,
  whitelist: ["auth", "config", "nav", "user"],
  stateReconciler: autoMergeLevel2
};
export const onPersistReducer = reducer => {
  let rootReducer = persistReducer(persistConfig, reducer);
  // umi 在进行模块化的异步加载时,会第二次触发 onReducer。
  // 这个时候 Redux-Persist 会重新初始化,导致里面有个默认为 true 参数 _paused 重置了。
  // 这个参数又决定了 redux-persist 是否更新 localstorage 。
  // 而如何将这个参数置为对于我们有利的,就需要重新调用 $persistor.persist()
  // 这儿需要使用 setTimeout 来进行 nextTick 的调用才能赶在 redux init 之后 dispath {type:'PERSIST'} 才能生效
  setTimeout(() => $persistor && $persistor.persist(), 0);
  return rootReducer;
};
export const persistEnhancer = () => createStore => (reducer, initialState, enhancer) => {
  //  persistReducer 已经在 app.js 里面的 onReducer 已经处理过了,所以这儿不用再次进行处理,避免重复
  // const persistReducer = onPersistReducer(reducer);
  const persistReducer = reducer;
  const store = createStore(persistReducer, initialState, enhancer);
  $persistor = persistStore(store, null);
  $persistor.persist();
  return { ...store, $persistor };
};

具体可以参考 commit: lyingd/antd-pro-standalone@24bfb77

Was this page helpful?
0 / 5 - 0 ratings