Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React-router 2.0: programmatically change route (URL not updated)

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?

like image 991
emooheo Avatar asked Mar 23 '16 19:03

emooheo


2 Answers

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...

like image 168
Fred Avatar answered Nov 09 '22 20:11

Fred


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

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

when inside of a component

like image 35
northsideknight Avatar answered Nov 09 '22 19:11

northsideknight