rt2zz / redux-persist

persist and rehydrate a redux store
MIT License
12.93k stars 866 forks source link

initialState after dispatching action #471

Open dvvtms opened 6 years ago

dvvtms commented 6 years ago

hy guys. After Rehydration, i dispatch action, i get back the initialState, not the persisted state. Same result when i dispatch clean redux action or thunk

what i make wrong and how avoid that?


import React from 'react';
import { Provider, connect } from 'react-redux';

import { persistStore } from 'redux-persist';
import { AsyncStorage, View, Text } from 'react-native';
import { Scene, Actions, Router } from 'react-native-router-flux';

import { createStore, combineReducers, applyMiddleware, compose } from 'redux';

import { composeWithDevTools } from 'remote-redux-devtools';
import { autoRehydrate } from 'redux-persist';
import thunk from 'redux-thunk';

import navigator from './navigation';

const reducers = require('./reducers').default;

const store = createStore(
  reducers,
  undefined,
  composeWithDevTools(applyMiddleware(thunk), autoRehydrate()),
);

const ReduxRouter = connect(state => ({ state: state.route }))(Router);

class App extends React.Component {
  constructor() {
    super();
    this.state = { rehydrated: false };
  }

  componentWillMount() {
    persistStore(store, { storage: AsyncStorage }, () => {
      this.setState({ rehydrated: true });
    });
  }

  render() {
    if (!this.state.rehydrated) {
      return (
        <View>
          <Text>Loading...</Text>
        </View>
      );
    }
    return (
      <Provider store={store}>
        <ReduxRouter navigator={navigator} />
      </Provider>
    );
  }
}

export default App;
dvvtms commented 6 years ago

same on V5

dvvtms commented 6 years ago

problem: components don't refreshing after rehydration, but the state changes. Components showing only initialState after dispatching action.

Resolved by adding handler to my rootReducer, as in the example. you can implement same on childReducers for optimization, selecting correct reducer in action.payload.



const appReducer = combineReducers({
  nav: navReducer,
  data: dataReducer,
  services: servicesReducer,
  // components: componentsReducer,
});

let nextState;

const rootReducer = (state, action) => {
  switch (action.type) {
    case action.type === 'SET_APP_RESET':
      nextState = undefined;
      return appReducer(nextState, action);

     // added this
    case action.type === REHYDRATE:
      nextState = { ...state, ...action.payload };
      return appReducer(nextState, action);

    default:
      return appReducer(nextState || state, action);
  }
};```