5

I am having some trouble with programmatically routing with react-router 2.0

The docs say to use

this.context.router.push('/test');

This is navigating correctly, but the URL on my browser stays the same and does not update even though the components from the other page (/test) have rendered and the route change was successful.

How can I get the URL to update?

HoldOffHunger
  • 18,769
  • 10
  • 104
  • 133
emooheo
  • 89
  • 1
  • 1
  • 5
  • It is hard to answer accurately without a test case. Can you reproduce this in a gist and link it here? – hunterc Mar 30 '16 at 13:08

2 Answers2

10

this.props.history.push('/some/path'); been deprecated.

We should now use the following:

import { browserHistory } from 'react-router'

Then, wherever you want to navigate - somewhere in your code - do:

browserHistory.push('/some/path');

This is how I configured my routes.jsx file that handles my routing mechanism:

//Require react.
import React from "react";
//Require routing variables.
import { Router, Route, IndexRoute, browserHistory } from "react-router";
//Example components.
import MainComponent from "../containers/main.js";
import HomeComponent from "../containers/home.js";

var Routes = (
    <Router history={browserHistory}>
        <Route path="/" component={MainComponent}>
            <IndexRoute component={HomeComponent} />
            <Route path="/example" component={ExampleComponent} />
        </Route>
    </Router>
);

module.exports = Routes;

I'm using webpack. In webpack, I also have this:

... bla ... bla... bla ...
module: {

},
devServer: {
    historyApiFallback: true
},
plugins: [

]
... bla ... bla... bla ...

UPDATE 04-Jan-2018:

[Disclaimer: I'm now using TypeScript instead of ES6]

This is how I get things done right now with react ^15.6.1 & react-dom ^15.6.1

index.tsx

import * as React from "react";
import * as ReactDOM from "react-dom";
import Routes from "./configuration/routes";
ReactDOM.render(
  Routes,
  document.getElementById("app")
);

routes.tsx

import * as React from "react";
import { BrowserRouter, HashRouter  } from 'react-router-dom';
import App from "../containers/App";

let Routes: any = (
    // <BrowserRouter>
    //     <App someDefaultValue/>
    // </BrowserRouter>

    // HashRouter adds the # in front of our paths :) - check the browser's URL to see.
    <HashRouter>
        <App someDefaultValue/>
    </HashRouter>
);
export default Routes;

App.tsx

import * as React from "react";
import { Switch, Route } from 'react-router-dom'

import Header from "../components/header-component/header";
import Main from "../components/main-component/main";
import Footer from "../components/footer-component/footer";

interface IComponentProps { someDefaultValue: boolean; }
interface IComponentState { loading: boolean; }

class App extends React.Component<IComponentProps, IComponentState> {
    constructor() {
        super();

        this.state = {
            loading: true
        };
    }

    render() {
        const { loading } = this.state;
        if(loading) {
            //Render something or something else..
        }

        return (
            <div className="app-container">
                <Switch>
                    <Route path='/' component={Header}/>
                </Switch>
                <Switch>
                    <Route path='/' component={Main}/>
                </Switch>
                <Switch>
                    <Route path='/' component={Footer}/>
                </Switch>
            </div>
        );
    }
}
export default App;

You can then use something like this to place navigation on menu items when clicked (or whatever...) menu.tsx

import * as React from "react";
import { Link } from 'react-router-dom'

class Menu extends React.Component {
    render() {
        return (
            <div>
                <Link to='/home'>
                    <div>Home</div>
                </Link>
                <Link to='/about'>
                    <div>About</div>
                </Link>
            </div>);
    }
}
export default Menu;

To navigate 'programically':

this.props.history.push('/wherever');

The reason I am using HashRouter, is because I noticed with BrowserRouter that it breaks when people saved 'bookmarks' etc. HashRouter allows my users to seamlessly navigate my site :)

If I need to show how BrowserRouter works, I can - just ask - it's nearly the same - but you will see that it only behaves when you navigate within the website. When you navigate from the outside, that's when the errors starts to happen.

Oh, yeah, almost forgot - I did not really test this, but I assume we still need

devServer: { historyApiFallback: true } 

in our webpack.config.js? Wouldn't know :)... but it's there in mine right now...

Fred
  • 2,402
  • 4
  • 31
  • 58
  • this worked for me however It's worth mentioning to use the historyAPI you use in your router, I was using `hashHistory` – javiercf Dec 06 '16 at 17:13
  • 1
    I am getting this error 'react-router' does not contain an export named 'browserHistory'. Any Suggestions? – Geek_To_Learn Jan 03 '18 at 19:04
  • LOL, react has, once again, changed since the day this was posted :). I will update my answer shortly. – Fred Jan 04 '18 at 04:27
1

this answer may be what you're looking for it says to use

this.props.history.push('/some/path');

when inside of a component

Community
  • 1
  • 1
northsideknight
  • 1,519
  • 1
  • 15
  • 24