Redux-persist: How would I rewrite my main application.jsx to use your sample of delayed rendering until load?

Created on 22 Jan 2016  路  15Comments  路  Source: rt2zz/redux-persist

Here is my application.jsx right now:

'use strict';

import 'babel-polyfill';

import React from 'react';
import ReactDOM from 'react-dom';
import { Router, Route, IndexRoute } from 'react-router';
import createHistory from 'history/lib/createHashHistory';
import { Provider } from 'react-redux';
import { compose, createStore, combineReducers, applyMiddleware } from 'redux';
import createLogger from 'redux-logger';
import { persistStore, autoRehydrate } from 'redux-persist';
import thunk from 'redux-thunk';
import { syncHistory, routeReducer } from 'redux-simple-router';

import reducers from './reducers';

const history = createHistory();
const logger = createLogger();
const middleware = syncHistory(history);

const reducer = combineReducers(Object.assign({}, reducers, {
  routing: routeReducer
}));

const store = compose(autoRehydrate(), applyMiddleware(
  middleware,
  thunk,
  logger
))(createStore)(reducer);

persistStore(store);

import App from './containers/App';
import Home from './views/Home';
import Login from './views/Login';
import Register from './views/Register';
import About from './views/About';

import './style.css';

ReactDOM.render(
  <Provider store={store}>
    <div>
      <Router history={history}>
        <Route path="/" component={App}>
          <IndexRoute component={Home} />
          <Route path="login" component={Login} />
          <Route path="register" component={Register} />
          <Route path="about" component={About} />
        </Route>
      </Router>
    </div>
  </Provider>,
  document.getElementById('app')
);

Any help would be appreciated! I just tried out the simple solution and works like a charm.

Most helpful comment

Ah I did not notice that, ya I would recommend adding a class component called App so something like:

class App extends Component {
  state = {
    initialized: false
  }

  componentWillMount() {
    persistStore(store, {}, (err, restoredState) => {
      this.setState({initialized: true})
    })
  render() {
    if (!this.state.initialized) return <span>Loading...</span>
    return (<Provider store={store}>
    <Router history={history}>
      <Route component={App} path='/'>
        <IndexRoute component={AppHome} />
        <Route component={AppAbout} path='about' />
        <Route component={AppLogin} path='login' />
        <Route component={AppLostPassword} path='lostPassword' />
        <Route component={AppRegister} path='register' />
        <Route component={AppReset} path='reset' />
        <Route component={AppThanks} path='thanks' />
        <Route component={AppVerify} path='verify' />
      </Route>
      <Route component={User} path='/user' >
        <IndexRoute component={UserHome} />
        <Route component={UserChangePassword} path='changePassword' />
      </Route>
      <Route component={NoMatch} path='*' />
    </Router>
  </Provider>
  )}
}

ReactDOM.render(
  <App />,
  document.getElementById('app')
)

All 15 comments

Basically as in this code chunk: https://github.com/rt2zz/redux-persist#initialstate-rehydration

getStoredState({skipRestore: true}, (err, initialState) => {
  const store = finalCreateStore(reducer, initialState)
  persistStore(store, persistConfig)
  ReactDOM.render(
    <Provider store={store}>
    <div>
      <Router history={history}>
        <Route path="/" component={App}>
          <IndexRoute component={Home} />
          <Route path="login" component={Login} />
          <Route path="register" component={Register} />
          <Route path="about" component={About} />
        </Route>
      </Router>
    </div>
  </Provider>,
  document.getElementById('app')
  );
})

I saw that but the one I was interesting in was the following code example:

import { createStore, combineReducers } from 'redux'
import { persistStore, autoRehydrate } from 'redux-persist'
import reducer from '../reducers'

const store = compose(autoRehydrate())(createStore)(reducer)

export default class AppProvider extends Component {

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

  render() {
    if(!this.state.rehydrated){
      return <div>Loading...</div>
    }
    return (
      <Provider store={store}>
        {() => <App />}
      </Provider>
    )
  }
}

Does that flow along the same lines as well?

Ah yes exactly. That is actually more of the recommended flow at this point in time. Is it working for you?

I can't get it working with my application.jsx right now actually. You can see my code here: https://github.com/awsbb/awsbb

@Icehunter I am working on 2.0 right now which will simplify the usage a little bit and I think make this problem easier to troubleshoot. Are you still stuck?

I've left out the loading screen while refresh for now so not stuck at all; but really looking forward to your updates.

Thanks!

@Icehunter did you ever get this sorted? If not let me know the latest and we can dig deeper.

Hi! Not with the code sample that I had linked before:
https://github.com/awsbb/awsbb/blob/master/webpack/application.jsx and the code snippet above.

I want to make it so that while rehydrating a loader appears but I'm not sure where to place the code or if it's supported in the new version.

Using this package however works perfectly fine; I just don't know how to do the loader. :)

The easiest way to do this is to call persistStore inside of your application.jsx componentWillMount and then when it is complete setState({initialized: true})

I'm still new to react for the most part, because I don't use a "class" in my application.jsx am I doing it the wrong way?

Ah I did not notice that, ya I would recommend adding a class component called App so something like:

class App extends Component {
  state = {
    initialized: false
  }

  componentWillMount() {
    persistStore(store, {}, (err, restoredState) => {
      this.setState({initialized: true})
    })
  render() {
    if (!this.state.initialized) return <span>Loading...</span>
    return (<Provider store={store}>
    <Router history={history}>
      <Route component={App} path='/'>
        <IndexRoute component={AppHome} />
        <Route component={AppAbout} path='about' />
        <Route component={AppLogin} path='login' />
        <Route component={AppLostPassword} path='lostPassword' />
        <Route component={AppRegister} path='register' />
        <Route component={AppReset} path='reset' />
        <Route component={AppThanks} path='thanks' />
        <Route component={AppVerify} path='verify' />
      </Route>
      <Route component={User} path='/user' >
        <IndexRoute component={UserHome} />
        <Route component={UserChangePassword} path='changePassword' />
      </Route>
      <Route component={NoMatch} path='*' />
    </Router>
  </Provider>
  )}
}

ReactDOM.render(
  <App />,
  document.getElementById('app')
)

that code might not be perfect (be sure to check close parens etc.) but it should point you in the right direction

Works like a charm. Thanks so much!

:+1:

I needed to add one level of indirection with render-if to get transitions tracking for my hierarchy, but that example above gave me exactly what I needed to get the preload working. Thanks!

Was this page helpful?
0 / 5 - 0 ratings