I need to navigate to a route after an event is successful. This seems to have changed since previous versions. Previously we would do this:
import { browserHistory } from 'react-router';
...
handleClick(){
doSomething();
browserHistory.push('/some/path');
}
The primary way you programmatically navigate using React Router v4+ is by using a <Redirect /> component, and it's a recommended method that helps the user navigate between routes. Using the Redirect component is a different approach but just as valid.
There are two ways to programmatically navigate with React Router - <Navigate /> and navigate() . You can get access to Navigate by importing it from the react-router-dom package and you can get access to navigate by using the custom useNavigate Hook.
Since v4 of React Router, there are three approaches that you can take to programmatic routing within components. Use the withRouter higher-order component. Use the context .
This example works in react-router and react-router-dom v4.0.0.
We have 3 components:
To navigate programmatically, you can use react-router history object.
this.props.history.push('path');
This will work right off the bat for components rendered via Route, as these components will already have access to the route props (history). In our example this is Component2. However, for components that are not rendered via a Route (e.g. Component1), you would need to wrap it in withRouter to give you access to the history object.
App.js
import React, { Component } from 'react';
import { BrowserRouter, Route } from 'react-router-dom';
import Component1 from './Component1';
import Component2 from './Component2';
class App extends Component {
render() {
return (
<BrowserRouter>
<div>
<Component1 />
<Route path="/render1" render={() => <div>Rendered from Component1</div>} />
<Route path="/" component={Component2} />
<Route path="/render2" render={() => <div>Rendered from Component2</div>} />
</div>
</BrowserRouter>
)
}
}
export default App;
Component1.js
import React from 'react';
import { withRouter } from 'react-router';
class Component1 extends React.Component {
handleButtonClick() {
this.props.history.push('/render1');
}
render() {
return (
<div>
<h1>Component 1</h1>
<button onClick={this.handleButtonClick.bind(this)}>Component 1 Button</button>
</div>
);
}
}
const Component1WithRouter = withRouter(Component1);
export default Component1WithRouter;
For Component1, we wrapped it in withRouter, and then exported the returned wrapped object. Some gotcha, notice that in App.js, we still reference it as Component1 instead of Component1WithRouter
Component2.js
import React from 'react';
class Component2 extends React.Component {
handleButtonClick() {
this.props.history.push('/render2');
}
render() {
return (
<div>
<h1>Component 2</h1>
<button onClick={this.handleButtonClick.bind(this)}>Component 2 Button</button>
</div>
);
}
}
export default Component2;
For Component2, the history object is already available from this.props. You just need to invoke the push function.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With