useOnReady
import { useEffect, useState } from 'react'
import { useEffect, useState } from 'react'
export function useOnReady<T>(callback: T, isReady: boolean | (() => boolean) | (() => Promise<boolean>)) {
const [done, setDone] = useState(false)
const [ready, setReady] = useState(false)
useEffect(() => {
if (typeof isReady === 'boolean') {
setReady(isReady)
}
if (typeof isReady === 'function') {
const res = isReady()
if (typeof res === 'boolean') {
setReady(res)
} else if (typeof res === 'object' && typeof res.then === 'function') {
res.then(setReady)
}
}
}, [isReady])
useEffect(() => {
if (done) return
if (ready) {
if (typeof callback === 'function') {
callback()
setDone(true)
}
}
}, [callback, done, ready])
}
useChannel
import type { BroadcastChannelOptions, OnMessageHandler } from 'broadcast-channel'
import { BroadcastChannel } from 'broadcast-channel'
import { useCallback, useEffect, useRef } from 'react'
export function useChannel<T = any>(params: {
key: string
onMessage?: OnMessageHandler<T>
options?: BroadcastChannelOptions & {
selfMonitoring?: boolean
}
}) {
const senderRef = useRef<BroadcastChannel<T>>()
const receiverRef = useRef<BroadcastChannel<T>>()
useEffect(() => {
const sender = new BroadcastChannel<T>(params.key, params.options)
const receiver = new BroadcastChannel<T>(params.key, params.options)
if (typeof params.onMessage === 'function') {
if (params.options?.selfMonitoring) {
receiver.addEventListener('message', params.onMessage)
} else {
sender.addEventListener('message', params.onMessage)
}
}
senderRef.current = sender
receiverRef.current = receiver
return () => {
if (senderRef.current && receiverRef.current) {
senderRef.current.close()
receiverRef.current.close()
}
}
}, [params])
const send = useCallback((payload: T) => {
if (!senderRef.current) return
senderRef.current.postMessage(payload)
}, [])
const close = useCallback(() => {
senderRef.current?.close()
receiverRef.current?.close()
}, [])
useEffect(() => {
return () => {
senderRef.current?.close()
receiverRef.current?.close()
}
}, [])
return { send, close }
}