如何在react-native中的应用程序负载下从redux-persist获取存储?

时间:2018-07-21 15:22:48

标签: reactjs react-native redux redux-persist

我在运行react-native应用程序时遇到问题。我有一家使用redux-persist和其他中间件的商店,问题是当应用加载时,商店中的数据不在那儿,只有默认值。但是,一旦我触摸任何按钮,数据就在那里,所以问题是我不能延迟渲染,直到商店补水。我尝试过使用带有PersistGateloading值的bootstrapped包装应用程序的选项,但是这对我不起作用。当前代码是:

存储配置:

import { createStore, applyMiddleware, compose } from 'redux';
import promise from 'redux-promise-middleware';
import thunk from 'redux-thunk';
import { persistStore, persistReducer } from 'redux-persist';
import { AsyncStorage } from 'react-native';
import autoMergeLevel2 from 'redux-persist/lib/stateReconciler/autoMergeLevel2';
import rootReducer from './reducers';

const middleware = [
  promise(),
  thunk,
];

if (__DEV__) { // eslint-disable-line
  // middlewares.push();
}

const enhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; // eslint-disable-line

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

const pReducer = persistReducer(persistConfig, rootReducer);

export const store = createStore(pReducer, {}, enhancers(applyMiddleware(...middleware)));
export const persistor = persistStore(store);

减根剂:

import { combineReducers } from 'redux';
import loginScreenReducer from 'screens/login/LoginScreen.reducer';

export default combineReducers({
  loginScreenReducer,
});

应用程序:

import { AppLoading } from 'expo';
import React from 'react';
import { PersistGate } from 'redux-persist/integration/react';
import { Provider } from 'react-redux';

import Root from 'Root.component';
import { store, persistor } from 'reduxConfig/store';

export default class App extends React.Component {
  state = { }

  render() {
    return (
      <Provider store={store}>
        <PersistGate persistor={persistor}>
          {(bootstrapped) => {
            if (bootstrapped) {
              console.log(store.getState());
              return <Root />;
            }

            return <AppLoading />;
          }}
        </PersistGate>
      </Provider>
    );
  }
}

我要使其正常工作的组件:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import Navigator from './Navigator';
import { LoginScreen } from '../screens';

@connect(
  state => ({
    token: state.loginScreenReducer.token,
    isLogged: state.loginScreenReducer.isLogged,
  }),
)
export default class AppNavigator extends Component {
  state = { }

  render() {
    const {
      token,
    } = this.props;

    if (token) {
      return <Navigator />;
    }

    return <LoginScreen />;
  }
}

export const { router } = Navigator;

该组件首先显示登录屏幕,但是如果我触摸其上的任何按钮,它将呈现Navigator组件。同样,当我得到商店的状态(应用程序,在返回<Root />之前,它具有下一个结构,其中包含空对象,这是loginScreenReducer当前的默认设置:

Store contents

redux-persist以外,该应用程序均可正常运行。

1 个答案:

答案 0 :(得分:0)

=====新答案=====

旧答案有误,问题稍后再出现。好像是redux-persist甚至expo,react-native-scripts或其他问题,我无法找到问题的根源。我之前描述的行为来自redux-persist无法访问AsyncStorage。但是,现在唯一有帮助的是,在该redux-persist能够再次访问AsyncStorage之后,完全停止expo并再次运行它。

如果完全不能停止,则禁用实时重新加载确实可以解决该问题。

=====旧答案=====

我最终通过将react-redux包降级到4.4.9版本,看起来这已经解决了问题,否则我最初发布的代码应该完全可以。按钮按下时自动填充状态的问题是由于我在BE和FE方面都犯了一些自己的错误,导致商店中充满了不同的物品。它们不在给定的代码中。另外,我对商店进行了一些更改,我不确定最初的问题是否与enhancers合并有关。所以现在我的商店看起来像这样:

import { createStore, applyMiddleware } from 'redux';
import { persistStore, persistReducer } from 'redux-persist';
import autoMergeLevel2 from 'redux-persist/lib/stateReconciler/autoMergeLevel2';
import { AsyncStorage } from 'react-native';
import thunk from 'redux-thunk';
import promiseMiddleware from 'redux-promise-middleware';
import { createLogger } from 'redux-logger';
import { LOGOUT } from 'screens/login/LoginScreen.actions';
import appReducer from './reducers';

const middlewares = [
  promiseMiddleware(),
  thunk,
];

if (__DEV__) { // eslint-disable-line
  middlewares.push(createLogger());
}

const rootReducer = (state, action) => {
  if (action.type === LOGOUT) {
    state = undefined;
  }

  return appReducer(state, action);
};

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

const persistedReducer = persistReducer(persistConfig, rootReducer);

export const store = createStore(persistedReducer, undefined, applyMiddleware(...middlewares));
export const persistor = persistStore(store);

我希望这会对某人有所帮助。