Skip to content

Instantly share code, notes, and snippets.

@tannerlinsley
Created June 4, 2021 14:37
Show Gist options
  • Star 20 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save tannerlinsley/a7f0db4d02f4a3780baa4842ff8d5632 to your computer and use it in GitHub Desktop.
Save tannerlinsley/a7f0db4d02f4a3780baa4842ff8d5632 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,
}
}
@Emiklad24
Copy link

Thank you

@ruisaraiva19
Copy link

@tannerlinsley should line 44 be something more like the following?

-    () => channels[id].awaitLeadership(),
+    () => channels[id].elector.awaitLeadership(),

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment