React router, pass data when navigating programmatically? - reactjs

We could navigate to different path using
this.props.router.push('/some/path')
Is there a way to send params (object) along when navigating?
There are other options I can think of, but wonder if passing object is possible at all?
I could embed id of the object and refetch the object from server
from the new page.
Or I could store the object in global storage like redux store. (This object needs to be removed from the store soon. So I'm thinking it might not be good to put it there in the first place)

The current answers are outdated.
React Router 6:
Use the useNavigate hook:
const navigate = useNavigate();
navigate('/other-page', { state: { id: 7, color: 'green' } });
Then, you can access the state data in '/other-page' via the useLocation hook:
const {state} = useLocation();
const { id, color } = state; // Read values passed on state
React Router 4 or 5:
Call history.push, and pass an object as the 2nd param to pass state:
props.history.push('/other-page', { id: 7, color: 'green' }))
Then, you can access the state data in '/other-page' via:
props.location.state

React Router uses location objects. One of the properties of a location object is state.
this.props.router.push({
pathname: '/other-page',
state: {
id: 7,
color: 'green'
}
})
On the page that is navigated to, the current location will be injected into the component whose route matched, so you can access the state using this.props.location.state.
One thing to keep in mind is that there will be no state if a user navigates directly to the page, so you will still need some mechanism to load the data when it does not exist.

Best way to pass data to the target Component, just copy paste the code and see the magic, I also explained it in depth.
Remember: in react-router-dom v6 you can use hooks instead.
version 5.X
Let's suppose we have two Components first and second. The first has the link which will target the second component.
The first Component where the link is, by clicking the link you will go to the target path as in my case it is:"/details".
import React from 'react';
import {Link} from 'react-router-dom';
export default function firstComponent() {
return(
<>
<Link to={{
pathname: '/details',
state: {id: 1, name: 'sabaoon', shirt: 'green'}
}} >Learn More</Link>
</>
)
}
Now in the second Component you can access the passed object as:
import React from 'react'
export default class Detials extends React.Component{
constructor(props){
super(props);
this.state={
value:this.props.location.state,
}
}
alertMessage(){
console.log(this.props.location.state.id);
}
render(){
return (
<>
{/* the below is the id we are accessing */}
hay! I am detail no {this.props.location.state.id} and my name is
{this.props.location.state.name}
<br/>
<br/>
{/* press me to see the log in your browser console */}
<button onClick={()=>{this.alertMessage()}}>click me to see log</button>
</>
)
}
}
note:In version 6 of react-router-dom the above method won't work on class components though you can use functional components of react by using useLocation hook and then you can draw the state object through that location in another component.
version 6
How to achieve the same using hooks v6 of react-router-dom
Let's suppose we have two functional components, first component A, second component B. The component A wants to share data to component B.
usage of hooks: (useLocation,useNavigate)
import {Link, useNavigate} from 'react-router-dom';
function ComponentA(props) {
const navigate = useNavigate();
const toComponentB=()=>{
navigate('/componentB',{state:{id:1,name:'sabaoon'}});
}
return (
<>
<div> <a onClick={()=>{toComponentB()}}>Component B<a/></div>
</>
);
}
export default ComponentA;
Now we will get the data in Component B.
import {useLocation} from 'react-router-dom';
function ComponentB() {
const location = useLocation();
return (
<>
<div>{location.state.name}</div>
</>
)
}
export default ComponentB;

For functional component and react-router-dom:^5.2.0 let's take a very simple example to make the concept precise
import { useHistory } from "react-router-dom";
function Sender(){
const history = useHistory();
const goToReceiver = () => {
history.push("/receiver", { name:'Mr',age:23 });
}
return <button onClick={goToReceiver}>Go To Receiver</button>
}
Now lets see how tha data came to receiver route
import { useLocation } from "react-router-dom";
function Receiver(){
const location = useLocation();
return <div>
<p>{location.state.name}</p>
<p>{location.state.age}</p>
</div>
}

You could make a use of useHistory hook of react-router-dom.
Below code is for you to pass your data to the stated route which is "/dashboard".
let history = useHistory();
history.push({
pathname: '/dashboard',
state:{
tags: 'your-value'
}
});
and from the "/dashboard " you can use the useHistory() to receive the above data.
Below code is for you to receive your data.
const Dashboard =()=>{
let {location} = useHistory();
return (<>{location.state.tags}</>)
}

Passing query parameters when programatically navigation in react router
History objects may be used programmatically change the current location using both history.push and history.replace.
history.push('/home?the=query', { some: 'state' })
If we pass the history object down into a component as props. Then we can navigate programatically using the react router methods available on the history object.
Now lets assume you are passing down the history object as a prop called 'router'. So it would be referenced inside a component with class based syntax like:
this.props.router
When using push or replace you can either specify both the URL path and state as separate arguments or include everything in a single location-like object as the first argument.
this.props.router.push('/some/path?the=query')
Or you can use a single location-like object to specify both the URL and state. This is equivalent to the example above.
this.props.router.push({
pathname: '/some/path', //path
search: '?the=query' // query param named 'search'
})
Note - Of course make sure that the this.props.router is actually the history object from the react-router api.

Their are use cases for sharing data using react-router dom
use react-router-dom useNavigate();
than =>
const navigate = useNavigate();
navigate('/toPath', {state: customData})
in other component lets say you want to fetch that data
use another hook that is useLocation()
const location = useLocation()
location.state // data will be shared by navigate

I was not able to get this working with react-router v4+. But the following does work:
//I.e. add navigate using the history stack and pass context as the 2nd parameter
this.props.history.push('/takeTest', {
subjectsList: this.props.subjectsList.filter(f => f.isChecked === true)
})

For sending:
navigate("/success", {
state: {
stripeData: res.data,
products: cart,
},
});
For Receiving:
import { useLocation } from "react-router-dom";
const location = useLocation();
const data = location.state.stripeData;
const cart = location.state.products;

if you want to send it in query string
this.props.router.push({
pathname: '/payment-history',
query: {
email: rowData.email
}
})

Related

How do I pass multiple parameters using history.push?

In React I am trying to pass both pathname and another parameter using history.push.
When it executes the application redirects to the specified page but the state is undefined so I cannot obtain the other parameter.
<Route path='/main' exact component={Main} />
import { useHistory } from "react-router-dom";
var history = useHistory();
function handleSubmit(event) {
event.preventDefault();
history.push("/main", { state: 'test'});
};
const Main= (props) => {
console.log(props.location.state);
};
export default Main;
In Main, props.location.state is undefined. Can you help me please?
You may want to try the object version of the push:
function handleSubmit(event) {
event.preventDefault();
history.push({
pathname: "/main",
state: 'test',
});
};
Please also ensure the receiving component is also receiving route props.
const Main= (props) => {
console.log(props.location.state);
};
If it not then ensure access to the location object via the useLocation hook or the withRouter Higher Order Component to have them injected as props.
For getting location's state in functional component without route props or withRoute HOC, you would use useLocation instead:
import { useHistory } from "react-router-dom";
const Main= () => {
const location = useLocation();
console.log(location);
};
And to pass multiple variables through location state, use object:
history.push("/page1", { pathname: "test", anotherParam: "test2" });
Note that: The second param of history.push is already the state, so you don't need to name it a state
Live Example:

How to send params in useHistory of React Router Dom?

I am using React Router hooks for navigation useHistory.
Navigate : history.push("/home", { update: true });
In home : I am trying to get params let {update} = useParams();
But update is always undefined. Whats wrong with this code. Any suggestions ?
The second parameter in the history.push() method is actually known as the location state,
history.push(path, [state])
Depending on your requirements, you may want to pass update as part of the location state, or the query string.
history.push({
pathname: '/home',
search: '?update=true', // query string
state: { // location state
update: true,
},
});
As stated on the React-Router documentation, you can access the state by accessing the location props. In your case, to get the value for update,
On class components, assuming that it is connected to the router,
this.props.location
For functional components, you can use the useLocation hook to access the location object.
import { useLocation } from 'react-router-dom';
.
.
const location = useLocation();
console.log(location.state.update) // for location state
console.log(location.search) // for query strings;
If you are using React Hooks follow this method because this.props is only available in React Class.
Component One:
import React from 'react'
import { useHistory } from "react-router-dom";
const ComponentOne = () => {
const history = useHistory();
const handleSubmit = () => {
history.push('/component-two',{params:'Hello World'})
}
return (
<div>
<button onClick={() => {handleSubmit()}}>Fire</button>
</div>
)
}
Component Two:
import React from 'react'
import { useLocation } from "react-router-dom";
const ComponentTwo = () => {
const location = useLocation();
const myparam = location.state.params;
return (
<div>
<p>{myparam}</p>
</div>
)
}
This is how you can pass
history.push("/home", { update: true });
and access like this if it's stateless component.
props.location.state.update;
if class based component.
this.props.location.update;
There's also a simpler way to access the state passed on if you're using functional components:
First, pass in the state in history.push
history = useHistory();
history.push('/path-to-component-2', 'state')
Next, u can retrieve the state in the location props
const Component2 = ({ location }) => {
console.log(location.state);
return null;
};

passing parameters through this.props.history.push('/xyz) in react router [duplicate]

How can we pass parameter with this.props.history.push('/page') in React-Router v4?
.then(response => {
var r = this;
if (response.status >= 200 && response.status < 300) {
r.props.history.push('/template');
});
First of all, you need not do var r = this; as this in if statement refers to the context of the callback itself which since you are using arrow function refers to the React component context.
According to the docs:
history objects typically have the following properties and methods:
length - (number) The number of entries in the history stack
action - (string) The current action (PUSH, REPLACE, or POP)
location - (object) The current location. May have the following properties:
pathname - (string) The path of the URL
search - (string) The URL query string
hash - (string) The URL hash fragment
state - (string) location-specific state that was provided to e.g. push(path, state) when this location was pushed onto the
stack. Only available in browser and memory history.
push(path, [state]) - (function) Pushes a new entry onto the history stack
replace(path, [state]) - (function) Replaces the current entry on the history stack
go(n) - (function) Moves the pointer in the history stack by n entries
goBack() - (function) Equivalent to go(-1)
goForward() - (function) Equivalent to go(1)
block(prompt) - (function) Prevents navigation
So while navigating you can pass props to the history object like
this.props.history.push({
pathname: '/template',
search: '?query=abc',
state: { detail: response.data }
})
or similarly for the Link component or the Redirect component
<Link to={{
pathname: '/template',
search: '?query=abc',
state: { detail: response.data }
}}> My Link </Link>
and then in the component which is rendered with /template route, you can access the props passed like
this.props.location.state.detail
Also keep in mind that, when using history or location objects from props you need to connect the component with withRouter.
As per the Docs:
withRouter
You can get access to the history object’s properties and the closest
<Route>'s match via the withRouter higher-order component. withRouter
will re-render its component every time the route changes with the
same props as <Route> render props: { match, location, history }.
Extending the solution (suggested by Shubham Khatri) for use with React hooks (16.8 onwards):
package.json (always worth updating to latest packages)
{
...
"react": "^16.12.0",
"react-router-dom": "^5.1.2",
...
}
Passing parameters with history push:
import { useHistory } from "react-router-dom";
const FirstPage = props => {
let history = useHistory();
const someEventHandler = event => {
history.push({
pathname: '/secondpage',
search: '?query=abc',
state: { detail: 'some_value' }
});
};
};
export default FirstPage;
Accessing the passed parameter using useLocation from 'react-router-dom':
import { useEffect } from "react";
import { useLocation } from "react-router-dom";
const SecondPage = props => {
const location = useLocation();
useEffect(() => {
console.log(location.pathname); // result: '/secondpage'
console.log(location.search); // result: '?query=abc'
console.log(location.state.detail); // result: 'some_value'
}, [location]);
};
For the earlier versions:
history.push('/[pathToSomeWhere]', yourData);
And get the data in the related component just like below:
this.props.location.state // it is equal to yourData
For the newer versions the above way works well but there is a new way:
history.push({
pathname: '/[pathToSomeWhere]',
state: yourData,
});
And get the data in the related component just like below:
Class Component
this.props.location.state; // it is equal to yourData
Function Component
const location = useLocation();
location.state; // it is equal to yourData
Sometime it will be needed to use Link or NavLink component instead of using history.push function. you can use like below:
<Link
to={{
pathname: '/[pathToSomeWhere]',
state: yourData
}}
>
...
</Link>
Hint: the state key name should be used in the latest version.
you can use,
this.props.history.push("/template", { ...response })
or
this.props.history.push("/template", { response: response })
then you can access the parsed data from /template component by following code,
const state = this.props.location.state
Read more about React Session History Management
If you need to pass URL params
theres a great post explanation by Tyler McGinnis on his site, Link to the post
here are code examples:
on the history.push component:
this.props.history.push(`/home:${this.state.userID}`)
on the router component you define the route:
<Route path='/home:myKey' component={Home} />
on the Home component:
componentDidMount(){
const { myKey } = this.props.match.params
console.log(myKey )
}
React TypeScript with Hooks
From a Class
this.history.push({
pathname: "/unauthorized",
state: { message: "Hello" },
});
UnAuthorized Functional Component
interface IState {
message?: string;
}
export default function UnAuthorized() {
const location = useLocation();
const message = (location.state as IState).message;
return (
<div className="jumbotron">
<h6>{message}</h6>
</div>
);
}
Pass
history.push({pathname:"/yourroute",state: {_id: "0001", name: "AZ"}})
Read
import React from 'react';
const YourRoute = props=> {
const { _id, name } = (props.location && props.location.state) || {};
//_id and name will contain the passed data
.
.
.
}
Here is a working example
I created a custom useQuery hook
import { useLocation } from "react-router-dom";
const useQuery = (): URLSearchParams => {
return new URLSearchParams(useLocation().search)
}
export default useQuery
Use it as
const query = useQuery();
const id = query.get("id") as string
Send it as so
history.push({
pathname: "/template",
search: `id=${values.id}`,
});
To use React 16.8 (withHooks) functional component you can use this way
We sending PhoneNumber to Next Page
Login.js
import { useHistory } from 'react-router-dom';
const history = useHistory();
const handleOtpVerify=(phoneNumber)=>
{
history.push("/OtpVerifiy",{mobNo:phoneNumber})
}
<button onClick={handleOtpVerify}> Submit </button>
OtpVerify.js
import useLocation from 'react-router-dom';
const [phoneNumber, setphoneNumber] = useState("")
useEffect(() => {
setphoneNumber(location.state.mobNo)
}, [location]);
return (
<p>We have sent Verification Code to your</p>
<h1>{phoneNumber}</h1>
)
react router dom version 6.2.1
useHistory() deprecated changed useNavigate()
import { useNavigate } from "react-router-dom";
const navigate = useNavigate()
onClick={() => { navigate('/OtpVerifiy',{mobNo:phoneNumber}) }}
You can use location to send state to other component, like this
In your Source Component
this.props.history.push(pathComponent, sendState);
pathComponent is target component that will receive the state
In your Target Component
you can receive the state like this if your use class component
Javascript version
constructor(props) {
this.state = this.props.location.state
}
Typescript version
constructor(props: {}) {
const receiveState = this.props.location.state as StateType // you must parse into your state interface or type
this.state = receiveState
}
Bonus
If you want to reset the received state. Use history to replace the location, like this
this.props.history({pathName: currentPath, state: resetState})
currentPath is the Target Component path
resetState is new value state whatever you want
It is not necessary to use withRouter. This works for me:
In your parent page,
<BrowserRouter>
<Switch>
<Route path="/routeA" render={(props)=> (
<ComponentA {...props} propDummy={50} />
)} />
<Route path="/routeB" render={(props)=> (
<ComponentB {...props} propWhatever={100} />
)} />
</Switch>
</BrowserRouter>
Then in ComponentA or ComponentB you can access
this.props.history
object, including the this.props.history.push method.
To use React 16.8+(withHooks) you can use this way
import React from 'react';
import { useHistory } from 'react-router-dom';
export default function SomeFunctionalComponent() {
let history = useHistory(); // should be called inside react component
const handleClickButton = () => {
"funcionAPICALL"
.then(response => {
if (response.status >= 200 && response.status < 300) {
history.push('/template');
});
}
return ( <div> Some component stuff
<p>To make API POST request and redirect to "/template" click a button API CALL</p>
<button onClick={handleClickButton}>API CALL<button>
</div>)
}
Source here to read more https://reacttraining.com/react-router/web/example/auth-workflow
Add on info to get query parameters.
const queryParams = new URLSearchParams(this.props.location.search);
console.log('assuming query param is id', queryParams.get('id');
For more info about URLSearchParams check this link
URLSearchParams

Navigate to another route on button click and pass props to it [duplicate]

How can we pass parameter with this.props.history.push('/page') in React-Router v4?
.then(response => {
var r = this;
if (response.status >= 200 && response.status < 300) {
r.props.history.push('/template');
});
First of all, you need not do var r = this; as this in if statement refers to the context of the callback itself which since you are using arrow function refers to the React component context.
According to the docs:
history objects typically have the following properties and methods:
length - (number) The number of entries in the history stack
action - (string) The current action (PUSH, REPLACE, or POP)
location - (object) The current location. May have the following properties:
pathname - (string) The path of the URL
search - (string) The URL query string
hash - (string) The URL hash fragment
state - (string) location-specific state that was provided to e.g. push(path, state) when this location was pushed onto the
stack. Only available in browser and memory history.
push(path, [state]) - (function) Pushes a new entry onto the history stack
replace(path, [state]) - (function) Replaces the current entry on the history stack
go(n) - (function) Moves the pointer in the history stack by n entries
goBack() - (function) Equivalent to go(-1)
goForward() - (function) Equivalent to go(1)
block(prompt) - (function) Prevents navigation
So while navigating you can pass props to the history object like
this.props.history.push({
pathname: '/template',
search: '?query=abc',
state: { detail: response.data }
})
or similarly for the Link component or the Redirect component
<Link to={{
pathname: '/template',
search: '?query=abc',
state: { detail: response.data }
}}> My Link </Link>
and then in the component which is rendered with /template route, you can access the props passed like
this.props.location.state.detail
Also keep in mind that, when using history or location objects from props you need to connect the component with withRouter.
As per the Docs:
withRouter
You can get access to the history object’s properties and the closest
<Route>'s match via the withRouter higher-order component. withRouter
will re-render its component every time the route changes with the
same props as <Route> render props: { match, location, history }.
Extending the solution (suggested by Shubham Khatri) for use with React hooks (16.8 onwards):
package.json (always worth updating to latest packages)
{
...
"react": "^16.12.0",
"react-router-dom": "^5.1.2",
...
}
Passing parameters with history push:
import { useHistory } from "react-router-dom";
const FirstPage = props => {
let history = useHistory();
const someEventHandler = event => {
history.push({
pathname: '/secondpage',
search: '?query=abc',
state: { detail: 'some_value' }
});
};
};
export default FirstPage;
Accessing the passed parameter using useLocation from 'react-router-dom':
import { useEffect } from "react";
import { useLocation } from "react-router-dom";
const SecondPage = props => {
const location = useLocation();
useEffect(() => {
console.log(location.pathname); // result: '/secondpage'
console.log(location.search); // result: '?query=abc'
console.log(location.state.detail); // result: 'some_value'
}, [location]);
};
For the earlier versions:
history.push('/[pathToSomeWhere]', yourData);
And get the data in the related component just like below:
this.props.location.state // it is equal to yourData
For the newer versions the above way works well but there is a new way:
history.push({
pathname: '/[pathToSomeWhere]',
state: yourData,
});
And get the data in the related component just like below:
Class Component
this.props.location.state; // it is equal to yourData
Function Component
const location = useLocation();
location.state; // it is equal to yourData
Sometime it will be needed to use Link or NavLink component instead of using history.push function. you can use like below:
<Link
to={{
pathname: '/[pathToSomeWhere]',
state: yourData
}}
>
...
</Link>
Hint: the state key name should be used in the latest version.
you can use,
this.props.history.push("/template", { ...response })
or
this.props.history.push("/template", { response: response })
then you can access the parsed data from /template component by following code,
const state = this.props.location.state
Read more about React Session History Management
If you need to pass URL params
theres a great post explanation by Tyler McGinnis on his site, Link to the post
here are code examples:
on the history.push component:
this.props.history.push(`/home:${this.state.userID}`)
on the router component you define the route:
<Route path='/home:myKey' component={Home} />
on the Home component:
componentDidMount(){
const { myKey } = this.props.match.params
console.log(myKey )
}
React TypeScript with Hooks
From a Class
this.history.push({
pathname: "/unauthorized",
state: { message: "Hello" },
});
UnAuthorized Functional Component
interface IState {
message?: string;
}
export default function UnAuthorized() {
const location = useLocation();
const message = (location.state as IState).message;
return (
<div className="jumbotron">
<h6>{message}</h6>
</div>
);
}
Pass
history.push({pathname:"/yourroute",state: {_id: "0001", name: "AZ"}})
Read
import React from 'react';
const YourRoute = props=> {
const { _id, name } = (props.location && props.location.state) || {};
//_id and name will contain the passed data
.
.
.
}
Here is a working example
I created a custom useQuery hook
import { useLocation } from "react-router-dom";
const useQuery = (): URLSearchParams => {
return new URLSearchParams(useLocation().search)
}
export default useQuery
Use it as
const query = useQuery();
const id = query.get("id") as string
Send it as so
history.push({
pathname: "/template",
search: `id=${values.id}`,
});
To use React 16.8 (withHooks) functional component you can use this way
We sending PhoneNumber to Next Page
Login.js
import { useHistory } from 'react-router-dom';
const history = useHistory();
const handleOtpVerify=(phoneNumber)=>
{
history.push("/OtpVerifiy",{mobNo:phoneNumber})
}
<button onClick={handleOtpVerify}> Submit </button>
OtpVerify.js
import useLocation from 'react-router-dom';
const [phoneNumber, setphoneNumber] = useState("")
useEffect(() => {
setphoneNumber(location.state.mobNo)
}, [location]);
return (
<p>We have sent Verification Code to your</p>
<h1>{phoneNumber}</h1>
)
react router dom version 6.2.1
useHistory() deprecated changed useNavigate()
import { useNavigate } from "react-router-dom";
const navigate = useNavigate()
onClick={() => { navigate('/OtpVerifiy',{mobNo:phoneNumber}) }}
You can use location to send state to other component, like this
In your Source Component
this.props.history.push(pathComponent, sendState);
pathComponent is target component that will receive the state
In your Target Component
you can receive the state like this if your use class component
Javascript version
constructor(props) {
this.state = this.props.location.state
}
Typescript version
constructor(props: {}) {
const receiveState = this.props.location.state as StateType // you must parse into your state interface or type
this.state = receiveState
}
Bonus
If you want to reset the received state. Use history to replace the location, like this
this.props.history({pathName: currentPath, state: resetState})
currentPath is the Target Component path
resetState is new value state whatever you want
It is not necessary to use withRouter. This works for me:
In your parent page,
<BrowserRouter>
<Switch>
<Route path="/routeA" render={(props)=> (
<ComponentA {...props} propDummy={50} />
)} />
<Route path="/routeB" render={(props)=> (
<ComponentB {...props} propWhatever={100} />
)} />
</Switch>
</BrowserRouter>
Then in ComponentA or ComponentB you can access
this.props.history
object, including the this.props.history.push method.
To use React 16.8+(withHooks) you can use this way
import React from 'react';
import { useHistory } from 'react-router-dom';
export default function SomeFunctionalComponent() {
let history = useHistory(); // should be called inside react component
const handleClickButton = () => {
"funcionAPICALL"
.then(response => {
if (response.status >= 200 && response.status < 300) {
history.push('/template');
});
}
return ( <div> Some component stuff
<p>To make API POST request and redirect to "/template" click a button API CALL</p>
<button onClick={handleClickButton}>API CALL<button>
</div>)
}
Source here to read more https://reacttraining.com/react-router/web/example/auth-workflow
Add on info to get query parameters.
const queryParams = new URLSearchParams(this.props.location.search);
console.log('assuming query param is id', queryParams.get('id');
For more info about URLSearchParams check this link
URLSearchParams

How to pass params with history.push/Link/Redirect in react-router v4?

How can we pass parameter with this.props.history.push('/page') in React-Router v4?
.then(response => {
var r = this;
if (response.status >= 200 && response.status < 300) {
r.props.history.push('/template');
});
First of all, you need not do var r = this; as this in if statement refers to the context of the callback itself which since you are using arrow function refers to the React component context.
According to the docs:
history objects typically have the following properties and methods:
length - (number) The number of entries in the history stack
action - (string) The current action (PUSH, REPLACE, or POP)
location - (object) The current location. May have the following properties:
pathname - (string) The path of the URL
search - (string) The URL query string
hash - (string) The URL hash fragment
state - (string) location-specific state that was provided to e.g. push(path, state) when this location was pushed onto the
stack. Only available in browser and memory history.
push(path, [state]) - (function) Pushes a new entry onto the history stack
replace(path, [state]) - (function) Replaces the current entry on the history stack
go(n) - (function) Moves the pointer in the history stack by n entries
goBack() - (function) Equivalent to go(-1)
goForward() - (function) Equivalent to go(1)
block(prompt) - (function) Prevents navigation
So while navigating you can pass props to the history object like
this.props.history.push({
pathname: '/template',
search: '?query=abc',
state: { detail: response.data }
})
or similarly for the Link component or the Redirect component
<Link to={{
pathname: '/template',
search: '?query=abc',
state: { detail: response.data }
}}> My Link </Link>
and then in the component which is rendered with /template route, you can access the props passed like
this.props.location.state.detail
Also keep in mind that, when using history or location objects from props you need to connect the component with withRouter.
As per the Docs:
withRouter
You can get access to the history object’s properties and the closest
<Route>'s match via the withRouter higher-order component. withRouter
will re-render its component every time the route changes with the
same props as <Route> render props: { match, location, history }.
Extending the solution (suggested by Shubham Khatri) for use with React hooks (16.8 onwards):
package.json (always worth updating to latest packages)
{
...
"react": "^16.12.0",
"react-router-dom": "^5.1.2",
...
}
Passing parameters with history push:
import { useHistory } from "react-router-dom";
const FirstPage = props => {
let history = useHistory();
const someEventHandler = event => {
history.push({
pathname: '/secondpage',
search: '?query=abc',
state: { detail: 'some_value' }
});
};
};
export default FirstPage;
Accessing the passed parameter using useLocation from 'react-router-dom':
import { useEffect } from "react";
import { useLocation } from "react-router-dom";
const SecondPage = props => {
const location = useLocation();
useEffect(() => {
console.log(location.pathname); // result: '/secondpage'
console.log(location.search); // result: '?query=abc'
console.log(location.state.detail); // result: 'some_value'
}, [location]);
};
For the earlier versions:
history.push('/[pathToSomeWhere]', yourData);
And get the data in the related component just like below:
this.props.location.state // it is equal to yourData
For the newer versions the above way works well but there is a new way:
history.push({
pathname: '/[pathToSomeWhere]',
state: yourData,
});
And get the data in the related component just like below:
Class Component
this.props.location.state; // it is equal to yourData
Function Component
const location = useLocation();
location.state; // it is equal to yourData
Sometime it will be needed to use Link or NavLink component instead of using history.push function. you can use like below:
<Link
to={{
pathname: '/[pathToSomeWhere]',
state: yourData
}}
>
...
</Link>
Hint: the state key name should be used in the latest version.
you can use,
this.props.history.push("/template", { ...response })
or
this.props.history.push("/template", { response: response })
then you can access the parsed data from /template component by following code,
const state = this.props.location.state
Read more about React Session History Management
If you need to pass URL params
theres a great post explanation by Tyler McGinnis on his site, Link to the post
here are code examples:
on the history.push component:
this.props.history.push(`/home:${this.state.userID}`)
on the router component you define the route:
<Route path='/home:myKey' component={Home} />
on the Home component:
componentDidMount(){
const { myKey } = this.props.match.params
console.log(myKey )
}
React TypeScript with Hooks
From a Class
this.history.push({
pathname: "/unauthorized",
state: { message: "Hello" },
});
UnAuthorized Functional Component
interface IState {
message?: string;
}
export default function UnAuthorized() {
const location = useLocation();
const message = (location.state as IState).message;
return (
<div className="jumbotron">
<h6>{message}</h6>
</div>
);
}
Pass
history.push({pathname:"/yourroute",state: {_id: "0001", name: "AZ"}})
Read
import React from 'react';
const YourRoute = props=> {
const { _id, name } = (props.location && props.location.state) || {};
//_id and name will contain the passed data
.
.
.
}
Here is a working example
I created a custom useQuery hook
import { useLocation } from "react-router-dom";
const useQuery = (): URLSearchParams => {
return new URLSearchParams(useLocation().search)
}
export default useQuery
Use it as
const query = useQuery();
const id = query.get("id") as string
Send it as so
history.push({
pathname: "/template",
search: `id=${values.id}`,
});
To use React 16.8 (withHooks) functional component you can use this way
We sending PhoneNumber to Next Page
Login.js
import { useHistory } from 'react-router-dom';
const history = useHistory();
const handleOtpVerify=(phoneNumber)=>
{
history.push("/OtpVerifiy",{mobNo:phoneNumber})
}
<button onClick={handleOtpVerify}> Submit </button>
OtpVerify.js
import useLocation from 'react-router-dom';
const [phoneNumber, setphoneNumber] = useState("")
useEffect(() => {
setphoneNumber(location.state.mobNo)
}, [location]);
return (
<p>We have sent Verification Code to your</p>
<h1>{phoneNumber}</h1>
)
react router dom version 6.2.1
useHistory() deprecated changed useNavigate()
import { useNavigate } from "react-router-dom";
const navigate = useNavigate()
onClick={() => { navigate('/OtpVerifiy',{mobNo:phoneNumber}) }}
You can use location to send state to other component, like this
In your Source Component
this.props.history.push(pathComponent, sendState);
pathComponent is target component that will receive the state
In your Target Component
you can receive the state like this if your use class component
Javascript version
constructor(props) {
this.state = this.props.location.state
}
Typescript version
constructor(props: {}) {
const receiveState = this.props.location.state as StateType // you must parse into your state interface or type
this.state = receiveState
}
Bonus
If you want to reset the received state. Use history to replace the location, like this
this.props.history({pathName: currentPath, state: resetState})
currentPath is the Target Component path
resetState is new value state whatever you want
It is not necessary to use withRouter. This works for me:
In your parent page,
<BrowserRouter>
<Switch>
<Route path="/routeA" render={(props)=> (
<ComponentA {...props} propDummy={50} />
)} />
<Route path="/routeB" render={(props)=> (
<ComponentB {...props} propWhatever={100} />
)} />
</Switch>
</BrowserRouter>
Then in ComponentA or ComponentB you can access
this.props.history
object, including the this.props.history.push method.
To use React 16.8+(withHooks) you can use this way
import React from 'react';
import { useHistory } from 'react-router-dom';
export default function SomeFunctionalComponent() {
let history = useHistory(); // should be called inside react component
const handleClickButton = () => {
"funcionAPICALL"
.then(response => {
if (response.status >= 200 && response.status < 300) {
history.push('/template');
});
}
return ( <div> Some component stuff
<p>To make API POST request and redirect to "/template" click a button API CALL</p>
<button onClick={handleClickButton}>API CALL<button>
</div>)
}
Source here to read more https://reacttraining.com/react-router/web/example/auth-workflow
Add on info to get query parameters.
const queryParams = new URLSearchParams(this.props.location.search);
console.log('assuming query param is id', queryParams.get('id');
For more info about URLSearchParams check this link
URLSearchParams

Resources