Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save Emiklad24/ea026db2819a1da739d506e5638cde67 to your computer and use it in GitHub Desktop.
Save Emiklad24/ea026db2819a1da739d506e5638cde67 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