You can use the history methods outside of your components. Try by the following way. First, create a history object used the history package: But to use this method, your existing component should have access to history object. We can get access by "Rather than dispatching actions to navigate you can pass the history object provided to route components to your actions and navigate with it there."
this.props.history.push({
pathname: '/template',
search: '?query=abc',
state: {
detail: response.data
}
})
// src/history.js
import {
createBrowserHistory
} from 'history';
export default createBrowserHistory();
Then wrap it in <Router>
(please note, you should use import { Router }
instead of import { BrowserRouter as Router }
):
// src/index.jsx
// ...
import { Router, Route, Link } from 'react-router-dom';
import history from './history';
ReactDOM.render(
<Provider store={store}>
<Router history={history}>
<div>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/login">Login</Link></li>
</ul>
<Route exact path="/" component={HomePage} />
<Route path="/login" component={LoginPage} />
</div>
</Router>
</Provider>,
document.getElementById('root'),
);
Instead you should use the withRouter
high order component, and wrap that to the component that will push to history. For example:
import React from "react";
import {
withRouter
} from "react-router-dom";
class MyComponent extends React.Component {
...
myFunction() {
this.props.history.push("/some/Path");
}
...
}
export default withRouter(MyComponent);
Using the context might be one of the easiest solutions, but being an experimental API it is unstable and unsupported. Use it only when everything else fails. Here's an example:
import React from "react";
import PropTypes from "prop-types";
class MyComponent extends React.Component {
static contextTypes = {
router: PropTypes.object
}
constructor(props, context) {
super(props, context);
}
...
myFunction() {
this.context.router.history.push("/some/Path");
}
...
}
Import the history package from react router dom. import { useHistory } from “react-router-dom” Assign the history function to a variable (not necessary but. recommended) const history = useHistory() import { useHistory } from “react-router-dom”; The history. push() function belongs to react-router-dom and used to move from the current page to another one. It takes the first argument as a destination path and a second argument as the state.21-Feb-2021
In this session, we’ll try our hand at solving the React Router History Push Parameter puzzle by using the computer language. The code that is displayed below illustrates this point.
this.props.history.push({
pathname: '/template',
search: '?query=abc',
state: {
detail: response.data
}
})
push(path, [state]): pushes new entry on history stack location: contains the same information as below length: number of entries in the history stack This allowed the router information to follow the component when it gets linked to, so the app still updates when the Redux state changes.
Previously, IndexRoute
was used as a route for some default UI of a parent Route. But, in v4, IndexRoute
is no longer used, since this functionality is now available in Route.
For providing default UI, multiple Routes that have the same path will let all of the associated components render:
import { BrowserRouter as Router, Route } from 'react-router-dom';
<Router>
// example of our route components
<Route path="/" component={Home} />
<Route path="/" component={About} />
<Route path="/" component={Contact} />
</Router>
So, all of the Components — Home
, About
, and Contact
— will render. Because of this, you can no longer nest Routes, either.
Additionally, to allow for better matching without the use of IndexRoute
, you can use the exact keyword.
import { BrowserRouter as Router, Route } from 'react-router-dom';
<Router>
// example of our route components
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
</Router>
After adding in the exact keyword, “something.com/about”
will be routed to when the router sees a path “/about”
. But now what if you have another path, “/about/team”
? As I stated before, the router will render anything that matches. So, the components associated with both “/about”
and “/about/team”
will render. If that’s what you intended, then that’s great! However, if this isn’t what you want, you may have to put a Switch around this group of Routes. This will allow the first path that matches the URL to render.
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
<Router>
<Switch>
<Route exact path ="/" component={Home} />
<Route path="/about/team" component={Team} />
<Route path="/about" component={About} />
</Switch>
</Router>
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
<Router>
<Switch>
<Route exact path ="/" component={Home} />
<Route path="/about/team" component={Team} />
<Route path="/about" component={About} />
<Route component={NotFound} />
</Switch>
</Router>
...
componentDidMount() {
this.props.fetchInfo();
}
...
We’ll focus on the history prop. The history prop keeps track of all the session history under the hood and provides us with different methods to manipulate it. The main focus of this article was to share how you can safely navigate between components using the React Router package. In other words, this works when the component is being rendered by React Router, bypassing the component as a Component prop to a Route. If this is the case, the React Router exposes three props to the component: location, match and history.
Here’s a code example of how to use the Redirect component.
Codesandbox: https://codesandbox.io/s/gallant-meitner-bshng?file=/src/App.js
import React, { useState } from 'react';
import { Redirect } from 'react-router-dom';
import { userLogin } from './userAction';
import Form from './Form';
const Login = () => {
const [isLoggedIn, setIsLoggedIn] = useState(false);
const handleLogin = async (userDetail) => {
const success = await userLogin(userDetail);
if(success) setIsLoggedIn(true);
}
if (isLoggedIn) {
return <Redirect to='/profile' />
}
return (
<>
<h1>Login</h1>
<Form onSubmit={handleLogin} />
</>
)
}
export default Login;
The push
method is essential and is used to push a path as a route to the history stack, which executes as Last In First Out (LIFO). This causes the app to redirect to the last route added, thereby redirecting the user to a specified route. The example below assumes the component is rendered with React Router.
Codesandbox: https://codesandbox.io/s/angry-saha-djh3z?file=/src/App.js
import React from "react";
import { userLogin } from "./userAction";
import Form from "./Form";
const Login = props => {
const handleLogin = async userDetail => {
const success = await userLogin(userDetail);
if (success) props.history.push("/profile");
};
return (
<>
<h1>Login</h1>
<Form onSubmit={handleLogin} />
</>
);
};
export default Login;
We mentioned earlier that for a component to have access props.history.push
it must have been rendered with React Router. There are cases where this might not be the case. Thus, we render a component ourselves. To make the history
property available to the component, the React Router team created the Higher Order Component (HOC) withRouter. Wrapping a component with this HOC exposes the properties as well.
Codesandbox: https://codesandbox.io/s/silent-rain-l19lg?file=/src/App.js:0-442
import React from 'react';
import { withRouter } from 'react-router-dom';
import { userLogin } from './userAction';
import Form from './Form';
const Login = (props) => {
const handleLogin = async (userDetail) => {
const success = await userLogin(userDetail);
if(success) props.history.push('/profile');
}
return (
<>
<h1>Login</h1>
<Form onSubmit={handleLogin} />
</>
)
}
export default withRouter(Login);
The real workhorse of React Router is the History library. Under the hood, it's what's keeping track of session history for React Router. When React Router v4 renders a component, it'll pass that component three props: location, match, and history. This history prop comes from the History library and has a ton of fancy properties on it related to routing. In this case, the one we're interested in is history.push. What it does is it pushes a new entry into the history stack - aka redirecting the user to another route. The typical use case for routing programmatically is routing on some sort of user event that isn't a Link click. So in our example, let's navigate the user to /dashboard once they've registered for our app. After reading that, there's at least a small chance that you hate it. Instead of using an imperative API (history.push), we're using a declarative Redirect component. Again, the reason for this is because it aligns exactly with the principles of React itself.
class Register extends React.Component { state = { toDashboard: false, }; handleSubmit = (user) => { saveUser(user).then(() => this.setState(() => ({ toDashboard: true, })) ); }; render() { if (this.state.toDashboard === true) { return <Redirect to="/dashboard" />; }
return ( <div> <h1>Register</h1> <Form onSubmit={this.handleSubmit} /> </div> ); }}
class Register extends React.Component { handleSubmit = (user) => { saveUser(user).then(() => this.props.history.push('/dashboard') )) } render() { return ( <div> <h1>Register</h1> <Form onSubmit={this.handleSubmit} /> </div> ) }}
import { withRouter } from 'react-router-dom'
class Register extends React.Component { handleSubmit = (user) => { saveUser(user).then(() => this.props.history.push('/dashboard') )) } render() { return ( <div> <h1>Register</h1> <Form onSubmit={this.handleSubmit} /> </div> ) }}
export default withRouter(Register)
The search property is used to pass query params in push() method. While navigating you can pass props to the history object: Made by Michael Sakhniuk
this.props.history.push({
pathname: '/template',
search: '?name=sudheer',
state: {
detail: response.data
},
});