【问题标题】:redux persist not storing store in the async storageredux坚持不在异步存储中存储存储
【发布时间】:2021-03-17 21:08:42
【问题描述】:

注意- 如果你想总结我的问题,那么我会说我有 5 个减速器。其中只有 2 个被持久化,而 3 个没有被持久化。

我的redux-persist 版本是 6.0.0。现在我来解决我的问题。我的 react-native 应用程序正在从 json-server 获取数据并将其存储在 redux-store 中。 redux-store 又将其存储在 AsyncStorage 中,因为我在我的代码中打印了 storage 的内容。到现在都没问题。

但现在我关闭了我的json-server 并在我的android 设备上退出我的应用程序以测试redux-persist(我不重新编译它,我只是退出它)。当我再次打开它时,redux,而不是查看AsyncStorage,它再次尝试联系json-server 以获取数据(而不是它应该查看asyncstorage)。现在由于服务器没有运行,应用程序无法获取数据并将错误消息写入状态(因为我已经这样配置了它)。所以,AsyncStorage 再次被清空,应用程序什么也不渲染。现在我给你configureStore.js的代码:


import {createStore, applyMiddleware} from 'redux';
import { dishes } from './dishes';
import { comments } from './comments';
import { promotions } from './promotions';
import { leaders } from './leaders';
import { favorite } from './favorite.js';
import thunk from 'redux-thunk';
import { logger } from "redux-logger";
import { persistStore, persistCombineReducers } from 'redux-persist';
import AsyncStorage from '@react-native-community/async-storage';

const config = {
    key: 'root',
    storage: AsyncStorage,
    debug: true
  }

export const ConfigureStore = () => {
    const store = createStore(
        persistCombineReducers(config,{
            dishes,
            comments,
            promotions,
            leaders,
            favorite
        }),
        applyMiddleware(thunk, logger)
    );

    const persistor = persistStore(store)
    return {persistor, store};
}

下面是 App.js:


import React from 'react';
import Main from './components/MainComponent';
import { Provider } from 'react-redux';
import { ConfigureStore } from './redux/configureStore';
import { PersistGate } from 'redux-persist/es/integration/react'
import  Loading  from './components/LoadingComponent';

const { persistor, store } = ConfigureStore();
//const store=ConfigureStore();


class App extends React.Component{
  
  render(){
    return (
      <Provider store={store}>
        <PersistGate 
          loading={<Loading />}
          persistor={persistor}>
          <Main /></PersistGate>
      </Provider>
  );
}
};

export default App;

我必须告诉你的另一件奇怪的事情是,在 5 个 reducer 中,只有 cmets 和 favourites 是两个 reducer,即使在应用重启后数据仍然存在,我也没有让它与其他 3 个有任何不同。

下面是 cmets.js 减速器:

import * as ActionTypes from './ActionTypes';

export const comments = (state = { errMess: null, comments:[]}, action) => {
  switch (action.type) {
    case ActionTypes.ADD_COMMENTS:
      return {...state, errMess: null, comments: action.payload};

    case ActionTypes.COMMENTS_FAILED:
      return {...state, errMess: action.payload};

    case ActionTypes.ADD_COMMENT:
      {action.payload.id=state.comments.length;console.log("hello from reducer",action.payload);return {...state,comments: [...state.comments,action.payload]}}

    default:
      return state;
  }
};

下面是dishs.js:

import * as ActionTypes from './ActionTypes';


export const dishes = (state = { isLoading: true,
                                 errMess: null,
                                 dishes:[]}, action) => {
    switch (action.type) {
        
        case ActionTypes.ADD_DISHES:
            return {...state, isLoading: false, errMess: null, dishes: action.payload};

        case ActionTypes.DISHES_LOADING:
            return {...state, isLoading: true, errMess: null, dishes: []}

        case ActionTypes.DISHES_FAILED:
            return {...state, isLoading: false, errMess: action.payload};

        default:
          return state;
      }
};

【问题讨论】:

    标签: reactjs react-native redux react-redux redux-persist


    【解决方案1】:

    我建议使用白名单和黑名单。

    const persistConfig = {
      key: 'root',
      storage: storage,
      blacklist: ['navigation'] // navigation will not be persisted
    };
     
    // WHITELIST
    const persistConfig = {
      key: 'root',
      storage: storage,
      whitelist: ['navigation'] // only navigation will be persisted
    };
    

    试试这个方法:

    const persistConfig = {
        key: 'root',
        storage: AsyncStorage,
        whitelist: ["dishes, comments, promotions, leader, favorite"]
      }
    
    const rootReducer = combineReducers({
        dishes: dishes,
        comments: comments,
        promotions: promotions,
        leaders: leaders,
        favorite: favorite
    });
    
    const persistReducer = persistReducer(persistConfig, rootReducer);
    
    const store = createStore(persistReducer,  applyMiddleware(thunk));
    
    let persistor = persistStore(store);
    
    export {store, persistor};
    

    【讨论】:

    • 我已经用过它了,但效果不好。我不明白为什么只保留 cmets 和 favorite 。除了这两个之外,当我重新启动应用程序时,一切都丢失了。
    • 我想知道如果我的问题得到解决并且一切正常时会发生什么,应用程序再次尝试联系服务器,当它什么也得不到时,它会向状态写入一条错误消息,它会更新,用户界面会消失??会发生吗??
    • 我必须假设在 API 调用成功时,此操作称为 ActionTypes.ADD_DISHES,即使它返回 0 数据。 ActionTypes.DISHES_FAILED 当出现服务器错误或超时时。仍然需要完整的代码来分析为什么会在您的情况下发生这种情况。
    • 是的,你是对的。但我的导师使用完全相同的代码没有任何问题。
    • 等等。我给你 git repo。
    【解决方案2】:
    • 列表项

    在摸索了将近一天之后,所有减速器中只有一个开关盒引起了问题。那个案例是LOADING 案例。我像这样制作了 disc.js 减速器:

    import * as ActionTypes from './ActionTypes';
    
    
    export const dishes = (state = { isLoading: true,
                                     errMess: null,
                                     dishes:[]}, action) => {
        switch (action.type) {
            
            case ActionTypes.ADD_DISHES:
                return {...state, isLoading: false, errMess: null, dishes: action.payload};
    
            
            case ActionTypes.DISHES_FAILED:
                return {...state, isLoading: false, errMess: action.payload};
    
            default:
              return state;
          }
    };
    
    

    我以同样的方式更改了其他减速器,一切都开始像魅力一样工作!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-17
      • 2020-01-14
      • 1970-01-01
      • 2018-08-13
      • 1970-01-01
      • 2020-08-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多