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
Start the app
npm start
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
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>
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">
// ...
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>
// ...
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'), [])
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
}, [])
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.
Resource(s): 1
Top comments (0)