rt2zz / redux-persist

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

Explore other API options #2

Closed rt2zz closed 9 years ago

rt2zz commented 9 years ago
felixakiragreen commented 9 years ago

:+1:

Definitely would like these. Passing the rehydrated state to initialState is exactly what I need for app launch.

I'm willing to help out with this project if I can!

rt2zz commented 9 years ago

I do not have a good solution for cases where one needs to get all of the persisted state before rending the app. One possibility would look something like:

let persist = persistStore(store)

export default class App extends Component {
  getInitialState(){
    persist.afterRehydration(() => this.setState({rehydrated: true})
    return {rehydrated: false}
  }
  render() {
    if(!this.state.rehydrated){ 
      return <div>Loading...</div> 
    }
    return (
      <Provider store={store}>
        {() => <ZeitApp />}
      </Provider>
    )
  }
}

I realize that is a lot of boilerplate though...

rt2zz commented 9 years ago

FWIW if you need this and if you are building a web app your best bet is to probably write a synchronous rehydrator much like https://github.com/gaearon/redux-devtools/blob/master/src/persistState.js

In my use case I am ok with getting the data asynchronously (potentially after the first App render). Also I need react-native support which is async storage.

felixakiragreen commented 9 years ago

I'm using react-native with AsyncStorage

rt2zz commented 9 years ago

Or a simpler approach that works with the current API is to call persist in componentWillMount:

export default class App extends Component {
  componentWillMount() {
    persistStore(store, {}, () => {
      this.setState({rehydrated: true})
    })
  },
  render() {
    if(!this.state.rehydrated){ 
      return <LoadingView /> 
    }
    return (
      <Provider store={store}>
        {() => <TheApp />}
      </Provider>
    )
  }
}
rt2zz commented 9 years ago

Just released 0.2.3 with experimentalAutoRehydrate. I suspect it will need much improvement, but I believe this is the right API (a higher order reducer):

import { createStore, applyMiddleware, combineReducers } from 'redux'
import persistStore, { experimentalAutoRehydrate } from 'redux-persist-store'
import * as reducers from '../reducers'

const reducer = experimentalAutoRehydrate(combineReducers(reducers))
const store = createStore(reducer)
persistStore(store)
rt2zz commented 9 years ago

Ok I am starting to feel decent about this.

Renamed project to redux-persist Renamed experimentalAutoRehydrate to autoRehydrate

It now auto rehydrates only keys that have not been modified by it's child reducers. That means if a reducer handlers its own rehydrate action, autoRehydrate will skip that reducer.

I am however still unsure how to allow for custom actionCreators in autoRehydrate.

felixakiragreen commented 9 years ago

Great progress! I'm not sure I follow- what do you mean by custom actionCreators?

rt2zz commented 9 years ago

persistStore optionally takes a custom action creator in the config argument which may be useful if you want to supply your own action type constant or trigger conditional logic/api calls based on rehydration.

For example I have a custom action creator to detects if my AccessToken is being rehydrated, and if so checks with the server to make sure it is valid.

felixakiragreen commented 9 years ago

Aha! I'm actually going to need to implement the exact same with my access tokens.

rt2zz commented 9 years ago

I am fairly satisfied. Closing until there is clarity on https://github.com/gaearon/redux/issues/350