Skip to content
This repository has been archived by the owner on Sep 11, 2018. It is now read-only.

Initial Server State #71

Closed
dvdzkwsk opened this issue Sep 12, 2015 · 4 comments
Closed

Initial Server State #71

dvdzkwsk opened this issue Sep 12, 2015 · 4 comments

Comments

@dvdzkwsk
Copy link
Owner

Currently initial server state is entirely separate from what may be produced through initial application events (e.g. componentWillMount). This is fine for basic state injections and store configuration, but ideally the server should be more closely tied to the application (especially for async actions initiated during the componentWillMount event).

Investigate solutions when time allows.

@MrEfrem
Copy link

MrEfrem commented Sep 17, 2015

I solved it so far so:
https://github.com/MrEfrem/react-redux-starter-kit/blob/master/src/entry-points/client.js

...
import { fetchComponentData } from '../utils';

const target = document.getElementById('root');
const store  = configureStore(window.__INITIAL_STATE__);

function onRouteEnter(nextState, transition, done) {
  fetchComponentData(store.dispatch, nextState.routes.map(b => b.component), nextState.params)
    .catch(err => {
      if (!__PROD__) {
        window.console.log(err);
      }
    });
  done();
}

const node = (
  <Root store={store}>
    <Router history={createBrowserHistory()}>
      {createRoutes(onRouteEnter)}
    </Router>
  </Root>
);
ReactDOM.render(node, target);

https://github.com/MrEfrem/react-redux-starter-kit/blob/master/src/utils/index.js

export function fetchComponentData (dispatch, components, params) {
  const needs = components.reduce( (prev, current) => {
    return (current.needs || [])
      .concat((current.WrappedComponent ? current.WrappedComponent.needs : []) || [])
      .concat(prev);
  }, []);

  const promises = needs.map(need => dispatch(need(params)));

  return Promise.all(promises);
}

https://github.com/MrEfrem/react-redux-starter-kit/blob/master/server/middleware/render-route.js

export default function *renderRouteMiddleware (next) {
  const props  = yield route(this.request.url);

  let store = configureStore();

  yield fetchComponentData(store.dispatch, props.components, props.params);

  if (config.get('globals').__DEBUG__) {
    store = configureStore(store.getState());
  }

  const markup = ReactDOM.renderToString(
    <Root store={store}>
      <RoutingContext {...props} />
    </Root>
  );

  this.body = renderIntoTemplate(template, markup, store.getState());
}

https://github.com/MrEfrem/react-redux-starter-kit/blob/master/src/routes/index.js

export default (onEnter) => {
  return (
    <Route component={CoreLayout}>
      <Route path='/' component={HomeView} onEnter={onEnter}/>
      <Route path='/test' component={TestView} onEnter={onEnter}/>
    </Route>
  );
};

https://github.com/MrEfrem/react-redux-starter-kit/blob/master/src/views/HomeView.js

import * as CounterActions from '../reducers/counter';

const mapStateToProps = (state) => ({
  counter : state.counter
});
export class HomeView extends React.Component {
  static propTypes = {
    dispatch : React.PropTypes.func,
    counter  : React.PropTypes.number
  }

  constructor () {
    super();
  }

  static needs = [
    CounterActions.setCounter
  ]

@MrEfrem
Copy link

MrEfrem commented Sep 17, 2015

I took as a basis from here:
https://github.com/bananaoomarang/chapters

@dvdzkwsk
Copy link
Owner Author

Wow awesome, this looks great. I'll take a deeper look a bit later when I get a chance. Thanks!

@dvdzkwsk
Copy link
Owner Author

Might fork the project to provide a better server environment, but for now the starter kit no longer comes with a server, so closing this for now.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants