react-router-server icon indicating copy to clipboard operation
react-router-server copied to clipboard

Redux support needed

Open BerndWessels opened this issue 7 years ago • 6 comments

Hi this is awesome project, but it definitely needs redux support. Is this on the road-map?

BerndWessels avatar Mar 22 '17 19:03 BerndWessels

Do you have an example of how would you envision this to work?

gabrielbull avatar Mar 23 '17 01:03 gabrielbull

Maybe something like this:

import {Provider} from 'preact-redux';
import {applyMiddleware, createStore} from 'redux';
import { renderToString } from 'react-router-server';
...

let store = createStore(
      rootReducer,
      applyMiddleware(epicMiddleware)
    );

renderToString(<Provider store={store}><App/></Provider>)
  .then(({ html, state }) => {
    // state here should actually be the redux-state at the end of all async operations.
  });

and just the normal redux connect within the components.

BerndWessels avatar Mar 23 '17 01:03 BerndWessels

Would also be interested in knowing if this is in the works

pdiniz13 avatar Apr 06 '17 00:04 pdiniz13

How would we know when all async operations are done in redux?

Wouldn't it currently work with redux by doing something like this:

import * as React from 'react';
import {fetchState} from 'react-router-server';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux'

@fetchState(
  state => state,
  actions => ({ done: actions.done })
)
@connect(
  ({ message }) => ({ message }),
  dispatch => ({ actions: bindActionCreators(actionCreators, dispatch) })
)
class Example extends React.PureComponent {
  componentWillMount() {
    this.props.actions.loadSomeMessage()
      .then((message) => this.props.done({ message }));
  }

 render() {
    return (
      <div>{this.props.message || 'Loading...'}</div>
    );
  }
}

export default Example;

gabrielbull avatar Apr 06 '17 01:04 gabrielbull

what seems to be the most popular option is a double render on the server, the first one to create the state and the second to render the code.

    <Root store={store} history={history} />
  );


  // send signal to sagas that we're done
  store.dispatch(END);

  // wait for all tasks to finish
  await sagasDone();

  // capture the state after the first render
  const state = store.getState().toJS();
  const appState = `window.APP_STATE = ${htmlescape(state)}`;

  // 2nd render phase - the sagas triggered in the first phase are resolved by now
  const body = renderToString(
    <Root store={store} history={history} />
  );```

pdiniz13 avatar Apr 07 '17 04:04 pdiniz13

@gabrielbull Could you clarify usage with Redux - use your comment above or the README 'with Redux` section?

oyeanuj avatar Sep 25 '17 18:09 oyeanuj