Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding hashrouter to routes makes 'push' to stop render components

I have a ConnectedRouter to which I wanted to add hashes to all the routes so I added the HashRouter component like this:

// @flow
import React from 'react';

import { Router, Route,Switch } from 'react-router'
import { HashRouter } from 'react-router-dom'
import { ConnectedRouter } from 'react-router-redux';
import { routerActions } from 'react-router-redux';
import { UserAuthWrapper } from 'redux-auth-wrapper';
import StudiesViewContainer from './components/views/studies/StudiesViewContainer';
import NotificationsViewContainer from './components/views/notifications/NotificationsViewContainer';
import UserView from './components/views/user/UserView';
import StudyViewContainer from './components/views/studies/StudyViewContainer';
import { getUser } from './reducers';
import LoginView from './components/views/login';
import NotFoundView from './components/views/notFound';
import ForbiddenView from './components/views/forbidden';

const UserIsAuthenticated = UserAuthWrapper({
  authSelector: getUser,
  redirectAction: routerActions.replace,
  failureRedirectPath: '/',
  wrapperDisplayName: 'UserIsAuthenticated'
});

const configRouter = (history: Object) => {
  return () =>
    <ConnectedRouter history={ history }>
      <HashRouter>
        <Switch>
          <Route path="/studies" component={ StudiesViewContainer } />
          <Route path="/study/:id" component={ StudyViewContainer } />
          <Route path="/user"  component={ UserView } />
          <Route path="/notifications" component={ NotificationsViewContainer } />
          <Route path="/forbidden" component={ ForbiddenView } />
          <Route path="/not-found" component={ NotFoundView } />
          <Route path="/" component={ LoginView } />
          <Route path="*" component={ NotFoundView } />
        </Switch>
      </HashRouter>
    </ConnectedRouter>
};

export default configRouter;

The problem is that when I do something like this:

push('studies')

The route does not add the hash and the new components are not rendered.

I added the browser history to my store, here is the configureStore file:

// @flow
import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import createHistory from 'history/createBrowserHistory'
import { routerMiddleware } from 'react-router-redux';
import createSagaMiddleware from 'redux-saga'
import {
  persistStore,
  autoRehydrate,
  createTransform
} from 'redux-persist';

import mainSaga from '../sagas';
import reducer from '../reducers';

const history = createHistory();
const routingMiddleware = routerMiddleware(history);
const sagaMiddleware = createSagaMiddleware();

// Remove error field from persisted auth substate
let authTransform = createTransform(
  (inboundState, key) =>
    key === 'auth' ?
      { ...inboundState, error: undefined }:
      inboundState,
  outboundState => outboundState,
  {
    whitelist: [
      'auth',
      'permissions'
    ]
  }
);

const configureStore = (): Promise<*> => {
  let middlewares = [routingMiddleware,thunk, sagaMiddleware ];
  let composeEnhancers = compose;

  if(process.env.NODE_ENV !== 'production') {
    composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
  }

  const store = createStore(
    reducer,
    composeEnhancers(
      applyMiddleware(...middlewares),
      autoRehydrate()));

  sagaMiddleware.run(mainSaga);

  return new Promise(resolve => {
    persistStore(
      store, {
        whitelist: ['auth', 'permissions'],
        debounce: 500,
        transforms: [
          authTransform
        ]
      },
      () => resolve({ store, history })
    );
  });
};

export default configureStore;

Can anyone help me get the push working as expected?

I am using the following versions of router in package json:

"react-router": "^4.2.0",
"react-router-dom": "^4.2.2",
"react-router-redux": "next",
like image 550
Pablo Estrada Avatar asked Nov 16 '17 18:11

Pablo Estrada


People also ask

Which is true about BrowserRouter and HashRouter?

Simply, BrowserRouter syncs the UI with the current URL in your browser, This is done by the means of HTML-5 History API. On the other hand, HashRouter uses the Hash part of your URL to sync.

Should I use BrowserRouter or HashRouter?

HashRouter: When we have small client side applications which doesn't need backend we can use HashRouter because when we use hashes in the URL/location bar browser doesn't make a server request. BrowserRouter: When we have big production-ready applications which serve backend, it is recommended to use <BrowserRouter> .

What is the use of HashRouter in react?

A <Router> that uses the hash portion of the URL (i.e. window. location. hash ) to keep your UI in sync with the URL.

How does hash routing work?

There are two ways to support routing in single-page apps: Hashed URL Paths — We break the URL path with a # (Hash) so that the browser understands it's just a virtual fragment. Ordinary URL Paths (Non-Hashed URL Paths) — The server needs to intercept the request and return the index.


1 Answers

I had a similar problem, I solved it by using

import createHistory from 'history/createHashHistory'

instead of

import createHistory from 'history/createBrowserHistory'

Also added withRouter when exporting components as suggested in https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/guides/blocked-updates.md

like image 77
F. Msacky Avatar answered Sep 20 '22 13:09

F. Msacky