ReactJS MobX and react-router v4 issue with url history

All we need is an easy explanation of the problem, so here it is.

I am making web-application with ReactJS, MobX, and react-router v4 and I have some problems with router history and redirections.
I am trying to redirect the user the home page when he will logout or login, and I am trying to implement this in my store. Here is the source code:

index.js

const APP = document.getElementById('app');

render(
    (
        <Provider {...stores} >
            <MuiThemeProvider>
              <Router history={history} >
                  <div>
                    <Routes />
                  </div>
              </Router>
            </MuiThemeProvider>
        </Provider>
    ) , APP);

Routes.js

@inject('userStore', 'commonStore')
@withRouter
@observer
class Routes extends Component {

    render() {

        return (
            <div>

                    </div>
                    <switch>

                        <Route exact path="/create_listing" render={() =>
                            (<CreateListing store={clStore} />)}
                        />

                        <Route path="/create_listing/description" render={() =>(
                            <CLLayout store={clStore} />
                        )}/>

                        <Route path="/create_listing/amenities" render={() =>(
                            <CLLayout store={clStore} />
                        )}/>

                        <Route path="/create_listing/optional" render={() =>(
                            <CLLayout store={clStore} />
                        )}/>

                        <Route path="/create_listing/media" render={() =>(
                            <CLLayout store={clStore} />
                        )}/>

                        <Route path="/create_listing/preview" render={() =>(
                            <CLLayout store={clStore} />
                        )}/>

                        <Route path="/create_listing/done" render={() =>(
                            <CLLayout store={clStore} />
                        )}/>

                        <Route exact path="/" component={ FrontPageIndex }/>
                    </switch>

            </div>
        );
    }
}

export default Routes;

history.js

import createBrowserHistory from 'history/createBrowserHistory';
import createMemoryHistory from 'history/createMemoryHistory';

export default process.env.BROWSER? createBrowserHistory() : createMemoryHistory();

store.js

@action logout() {
        return agent.Auth.logout()
            .catch(action((err) => {
                this.errors = err.response && err.response.body && err.response.body.errors;
                throw err;
            }))
            .finally(action(() => {
                commonStore.setToken({});
                userStore.forgetUser();
                this.inProgress = false;
                history.replace('/');
            }));
    }

The method history.replace(‘/’); actually, replaces the URL in the browser, but doesn’t render the new component ( the home component ), to do so I should refresh the webpage manually.

Any suggestions on this?

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

I Solved this issue.

As a router, I Should be Use the Default Router from react-dom, instead of BrowserRouter or HashRouter from react-router-dom as I was using.

Here is example :

import { Router } from 'react-router';
import history                  from './History';


const APP = document.getElementById('app');

render(
    (
        <Provider {...stores} >
            <MuiThemeProvider>
              <Router history={history}>
                  <div>
                    <Routes />
                  </div>
              </Router>
            </MuiThemeProvider>
        </Provider>
    ) , APP);

Also for the history file, here is the code:

import createBrowserHistory from 'history/createBrowserHistory';

const history = createBrowserHistory();
export default  history;

Seems that the problem was in the BrowserRouter or HashRouter since those both keep their own history. It worked for me with default Router from ‘react-router’

Method 2

Did you try using Router.transitionTo ? https://github.com/ReactTraining/react-router/issues/311

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply