Skip to content

Instantly share code, notes, and snippets.

@ali-master
Forked from tannerlinsley/useBroadcastLeader.ts
Created April 4, 2024 04:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ali-master/a33855b26e0dc5f0b18826a86919113a to your computer and use it in GitHub Desktop.
Save ali-master/a33855b26e0dc5f0b18826a86919113a to your computer and use it in GitHub Desktop.
A React Hook to determine if a tab of your application is the "leader" using BroadcastChannel and leader election
import { BroadcastChannel, createLeaderElection } from 'broadcast-channel'
import React from 'react'
const channels = {}
export function useBroadcastLeader(id = 'default') {
const [isBroadcastLeader, setIsBroadcastLeader] = React.useState(false)
React.useEffect(() => {
if (!channels[id]) {
const channel = new BroadcastChannel('useBroadcastLeader_' + id)
const elector = createLeaderElection(channel)
channels[id] = {
channel,
elector,
subscribers: [],
}
elector.awaitLeadership().then(() => {
channels[id].subscribers.forEach(sub => {
sub(true)
})
})
}
channels[id].subscribers.push(setIsBroadcastLeader)
return () => {
channels[id].subscribers = channels[id].subscribers.filter(
d => d !== setIsBroadcastLeader
)
if (!channels[id].subscribers.length) {
channels[id].elector.die()
channels[id].channel.close()
delete channels[id]
}
}
}, [id])
const waitForBroadcastLeader = React.useCallback(
() => channels[id].awaitLeadership(),
[id]
)
return {
isBroadcastLeader,
waitForBroadcastLeader,
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment