atomWithBroadcast
atomWithBroadcast
创建一个原子。这个原子将在浏览器的标签页和框架之间共享,类似于atomWithStorage
,但是有初始化的限制。
这在你希望状态之间相互作用,而不使用localStorage的时候会很有用。 通过使用BroadcastChannel API,你可以在同一源上的窗口、标签、框架、组件或iframe,以及工作器之间启用基本的通信。 根据MDN文档,BroadcastChannel在初始化期间不支持接收消息,但是如果你想支持那个功能,你可能需要向atomWithBroadcast添加额外的选项,比如本地存储。
import { atom } 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<Value, { isEvent: boolean; value: Value }>((get) => get(baseAtom),(get, set, update) => {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<Value, Value>((get) => get(broadcastAtom),(get, set, update) => {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>)}