Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

New version react router doesn't work with redux

maybe this issue is because the new version of the react router have few days, but I have been reading about this issue and I want to clarify what is going on. I am using the last version of the react router and I want to do the routing through redux. I follow the steps that are listed in the documentation of the redux router module: https://github.com/ReactTraining/react-router/tree/master/packages/react-router-redux, but I receive this error when I make the implementation: (I know that the issue is in the server render)

Invariant Violation: Browser history needs a DOM

Here is my code (the 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 (dispatch)

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

Obviously the dispatch, from my component never is called. Anyone can me clarify me where I am wrong? or maybe this feature is not implemented yet in the react router redux module? In advance Thanks.

like image 554
maoooricio Avatar asked May 25 '26 01:05

maoooricio


1 Answers

Instead of BrowserRouter, use ConnectedRouter from the react-router-redux library:

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'));
like image 75
Patrick Hund Avatar answered May 26 '26 15:05

Patrick Hund