Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass state via Link while redirected to a new tab

case 1: Redirected to a new route in the same tab.

<Link to={{ pathname: "/modify_items", state: { foo: "bar" } }} >

When I type console.log(this.props.location.state); the state { foo: "bar" } get printed.

case 2: Redirected to a new route in a new tab.

<Link to={{ pathname: "/modify_items", state: { foo: "bar" } }} target="_blank" >

When I type console.log(this.props.location.state); the state becomes undefined.

My goal is to pass data to a new tab. Please guide me if there is any other way to achieve this in React.js. I just want to pass data to a new tab.

like image 999
Abhiz Avatar asked Jul 29 '20 09:07

Abhiz


People also ask

How do I open a link in a new tab in React?

To open a link in a new tab in React, use the <a> element and set its target prop to _blank , e.g. <a href="https://google.com" target="_blank" rel="noopener noreferrer"></a> . The _blank value means that the resource is loaded into a new tab.

How do you pass a state from one page to another in React?

You can use the Link component from react-router and specify to={} as an object where you specify pathname as the route to go to. Then add a variable e.g. data to hold the value you want to pass on.

How do I redirect to another path?

import { Redirect } from "react-router-dom"; The easiest way to use this method is by maintaining a redirect property inside the state of the component. Whenever you want to redirect to another path, you can simply change the state to re-render the component, thus rendering the <Redirect> component.

How do you open another page on click of button in React?

To open a page in a new tab on button click in React:Add an onClick prop to the button. When the button is clicked, use the window. open() method to load the resource. Set the target parameter to _blank when calling the open() method.


2 Answers

I think this is not possible with Link state. Cause if you leave the page your memory will be clean. You might want to use query or path params if you want to share state over different tabs.

For path params: Get path params in react-router v4

For query variables: Set the Link as followed:

<Link to={{ pathname: '/foo', query: { foo: "bar" } }}/>

and use maybe a library to get the query param. Such as https://www.npmjs.com/package/query-string.

like image 196
Raoul Avatar answered Oct 09 '22 16:10

Raoul


Since the _blank opens a new tab so it is another instance of your app even the app is the same app the internals are different. But you can use something like localStorage.

Since they will be persisted and will be shared for same origin you will have access to it in the new or any tab or window of your application. You need to query it in the component mount or after first render with and useEffect hook with a second parameter being probably empty array, []. For hooks checkout React docs if you use them.

Another way is to use the querystring. You can receive the query string from your opened comopenent instance.

I am sure you can use any other persistense mechanism, like Indexed DB, Cookies, etc.

There are a few other ways coming into my mind under the umbrella web messaging; Broadcast Channel API, Window.postMessage, and Channel Messaging API that you may make use of.

If you state is relatively small it mifght be good to use querystring, or localStorage is the easiest way to go. If your data way more bigger you can use Indexed DB. It is async. Only be careful when it completes write, then you get it in your new window, tab.

In persistence usage cases, write to persistence before you navigate, just wait the write process if it is async before you navigate (by opening new tab/window in your specific use case).

One might navigate to a new tab maybe by right clicking and selecting from the context menu. ın that case Page Visibility API can be used on the right clicked page in a React effect (attaching its effects in an React effect with an empty second argument to React effect) and the data can be written again to a persistence mechanism, one of above mentioned ones, and the rest I mean the operations in the opening tab will be the same.

Since the writing mechanism can be late and even it is a sync one opening of a new tab if it is not programmatical might happen before the writing is done. In that case the opening tab's React effect to read the data written might be early to read. To circumvent these workarounds like waiting via a setTimeout to read can be used simply, however, a programmatically correct and a guaranteedly timed way would be using one of the appropriate web messaging apis I have mentioned above like Broadcast Channel, postMessage, and Channel Messaging API.

like image 2
sçuçu Avatar answered Oct 09 '22 16:10

sçuçu