JotaiJotai

상태
React를 위한 기본적이고 유연한 상태 관리

atomWithBroadcast

atomWithBroadcast는 아톰을 생성합니다. 이 아톰은 atomWithStorage와 유사하게 브라우저 탭과 프레임 간에 공유되지만, 초기화에 제한이 있습니다.

이 기능은 localStorage를 사용하지 않고 상태가 서로 상호작용하도록 할 때 유용합니다. BroadcastChannel API를 사용하면 동일한 오리진 내의 윈도우, 탭, 프레임, 컴포넌트, iframe, 워커 간의 기본적인 통신을 활성화할 수 있습니다. MDN 문서에 따르면, BroadcastChannel은 초기화 중에 메시지를 수신하는 것을 지원하지 않습니다. 하지만 해당 기능을 지원하려면, atomWithBroadcast에 로컬 스토리지와 같은 추가 옵션을 제공해야 할 수 있습니다.

import { atom, SetStateAction } from 'jotai'
export function atomWithBroadcast<Value>(key: string, initialValue: Value) {
const baseAtom = atom(initialValue)
const listeners = new Set<(event: MessageEvent<any>) => void>()
const channel = new BroadcastChannel(key)
channel.onmessage = (event) => {
listeners.forEach((l) => l(event))
}
const broadcastAtom = atom(
(get) => get(baseAtom),
(get, set, update: { isEvent: boolean; value: SetStateAction<Value> }) => {
set(baseAtom, update.value)
if (!update.isEvent) {
channel.postMessage(get(baseAtom))
}
},
)
broadcastAtom.onMount = (setAtom) => {
const listener = (event: MessageEvent<any>) => {
setAtom({ isEvent: true, value: event.data })
}
listeners.add(listener)
return () => {
listeners.delete(listener)
}
}
const returnedAtom = atom(
(get) => get(broadcastAtom),
(_get, set, update: SetStateAction<Value>) => {
set(broadcastAtom, { isEvent: false, value: update })
},
)
return returnedAtom
}
const broadAtom = atomWithBroadcast('count', 0)
const ListOfThings = () => {
const [count, setCount] = useAtom(broadAtom)
return (
<div>
{count}
<button onClick={() => setCount(count + 1)}>+1</button>
</div>
)
}