DEV Community

Kamal Hossain
Kamal Hossain

Posted on

Send data between tabs in react app

Yes! You can send data between different tabs or windows of your react app. Confusing hah?

Ok, let's assume you have made a WebRTC app via jitsi. The main goal of your app is video conferencing. Now you don't want any of your users to open two sessions at the same time in their browser for the calling. How can you do that? Here you can use the Broadcast Channel API.

One other important thing is that this will only work only if your app/site is of the same origin.


Let's see that in action by an example.

Create a react app

create-react-app browser-tab-broadcast-react
Enter fullscreen mode Exit fullscreen mode

Start the app

npm start
Enter fullscreen mode Exit fullscreen mode

Modify the App.js file

Remove everything from your App.js file and paste these.

import React from 'react'
import './App.css'

function App() {
  return (
    <div class="App">
      <h1> Something happening in the dom </h1>
    </div>
  )
}
export default App
Enter fullscreen mode Exit fullscreen mode

All that we are doing is just rendering a div with an h1 tag.

// ...
<h1> Something happening in the dom </h1>

<p>Only one tab could open at a time</p>
<button type="button" onClick={refreshPage}>
    <span>Reload</span>
</button>
Enter fullscreen mode Exit fullscreen mode

Now this is the part where we want to show the user, if the page is already opnned in another tab or window of the same browser.

To do that we need a state to handle that. So that we can conditionally render the elements to the user.

// ...
function App() {
  const [isOpnnedAlready, setIsOpnnedAlready] = React.useState(false)

  return (
    <div class="App">
// ...
Enter fullscreen mode Exit fullscreen mode

By default, the state is false and that means this same page is not opened in another tab or window of the browser so we can put the condition in our JSX.

// ...

function refreshPage() {
    window.location.reload()
}

 return (
    <div class="App">
      {!isOpnnedAlready ? (
        <h1>Something happening in the dom</h1>
      ) : (
        <>
          <p>Only one tab could open at a time</p>
          <button type="button" onClick={refreshPage}>
            <span>Reload</span>{' '}
          </button>
        </>
      )}
    </div>
// ...
Enter fullscreen mode Exit fullscreen mode

So now, we need to listen for an event in our component. To see if another page is opened in another tab.

Create a BroadcastChannel instance

For that, we need to create a channel in our app. Which will be available to all other tabs with the same protocol, origin, and port.

// ...
const channel = React.useMemo(() => new BroadcastChannel('couldBeAnything'), [])
Enter fullscreen mode Exit fullscreen mode

Here we have created a new BroadcastChannel instance and stored that in the channel variable. With this couldBeAnything name we are subscribing to a particular channel. By subscribing we are able to post and receive messages from it.

In extra we are using useMemo hook to keep the instance value in memory. So that we don't have to re-run the code on every re-render.

Sending and receiving data via BroadcastChannel


const channel = React.useMemo(() => new BroadcastChannel('couldBeAnything'), [])

React.useEffect(() => {
    channel.postMessage({
      isOpnnedAlready: true,
    })
    channel.addEventListener('message', (e) => {
      setIsOpnnedAlready(e.data.isOpnnedAlready)
    })
    return channel.close
  }, [])

Enter fullscreen mode Exit fullscreen mode

Here we are using useEffect hook. Here we are posting and receiving to the channel after every first render of the component.

By calling postMessage() with our channel instance we are sending an object to the channel (here we can also send string, array etc). Right after that, we are calling addEventListener() to listen to the message event from the channel. And finally, we are closing the channel on component unmount.

When all these things are done open up two tabs one after another, you will notice the changes on the page. The first tab will change its DOM whenever other tabs open in the same browser.

Demo


Resource(s): 1

Discussion (0)