New version react router not working with redux

Perhaps this problem is due to the fact that the new version of react router has a few days to go, but I read about this issue and I want to clarify what is going on. I am using the latest react router and I want to do routing via abbreviation. I am following the steps listed in the redux router module documentation: https://github.com/ReactTraining/react-router/tree/master/packages/react-router-redux , but I get this error when I execute the implementation: (I know that the problem is the server rendering)

Invariant Violation: Browser history needs a DOM

      

Here is my code (important parts):

server.js

import { Provider } from 'react-redux';
import store from './store';

lisaApp.get('*', function (req, res) {
  const context = {};

  const html = renderToString(
    <Provider store={store}>
      <MuiThemeProvider muiTheme={getMuiTheme()}>
        <StaticRouter location={req.url} context={context}>
          <Routes />
        </StaticRouter>
      </MuiThemeProvider>
    </Provider>,
  );

  res.setHeader('Content-Type', 'text/html');

  if (context.url) {
    res.writeHead(301, {
      Location: context.url,
    });
    res.end();
  }

  res.write(
    renderToStaticMarkup(<Layout title={req.title} content={html} />),
  );

  res.end();
}

      

client.js

import { Provider } from 'react-redux';
import createHistory from 'history/createBrowserHistory';
import { BrowserRouter } from 'react-router-dom';
import store from './store';

render((
  <Provider store={store}>
    <MuiThemeProvider muiTheme={getMuiTheme()}>
      <BrowserRouter history={createHistory()}>
        <Routes />
      </BrowserRouter>
    </MuiThemeProvider>
  </Provider>),
  document.getElementById('app'));

      

store.js

import { createStore, combineReducers, applyMiddleware } from 'redux'
import createHistory from 'history/createBrowserHistory'
import { ConnectedRouter, routerReducer, routerMiddleware, push } from 'react-router-redux'
import thunk from 'redux-thunk';

import reducer from './reducer';

const history = createHistory()
const middlewareHistory = routerMiddleware(history)

const store = createStore(
  combineReducers({
    reducer,
    router: routerReducer
  }),
  applyMiddleware(
    middlewareHistory,   
    thunk
  )
);

export default store;

      

component.js (submission)

const mapDispatchToProps = dispatch => {
  return {
    onNavigateTo(dest) {
      dispatch(push(dest));
    }
  };
};

      

Obviously dispatch from my component is never called. Can anyone please clarify to me where I am going wrong? or maybe this feature is not yet implemented in the relay module of the reactive router? Thank you in advance.

+3


source to share


2 answers


Use ConnectedRouter from react-router-redux library instead of BrowserRouter:



import { Provider } from 'react-redux';
import createHistory from 'history/createBrowserHistory';
import { ConnectedRouter } from 'react-router-redux';
import store from './store';

render((
    <Provider store={store}>
        <MuiThemeProvider muiTheme={getMuiTheme()}>
            <ConnectedRouter history={createHistory()}>
                <Routes />
            </ConnectedRouter>
        </MuiThemeProvider>
    </Provider>),
    document.getElementById('app'));

      

+1


source


I faced the same problem a few days ago. In your browser, you manually create and pass the browserHistory object. Then when you need access to the history object that you import, like in your store.js, which is shared with the server and client. However, there is no DOM on the server, hence the error.

I fixed the issue by NOT manually creating the history object, this is unnecessary since you are using BrowserRouter. As stated in the documentation, BrowserRouter:

A <Router> that uses the HTML5 history API (pushState, replaceState and popstate event) to keep your interface in sync with the url.

Rather than importing history manually when you need it, just use a higher-order router - friendly component. Thus, in your details you will get access not only to the history, but also to the closest match <Routines>. More on this here .



As for your last point about the newsletter, you are correct that it was not called. Whenever you create a component through a react-shorten connection, remember to wrap it in a higher order component with a router . More on this here .

I believe the above will fix your problem. I can share a working example if you want, but my solution is very similar to what you have, except for my comments.

Hope this helps.

0


source







All Articles