Open6
[Astro] コンポーネント間通信
Nano Storesのグローバル値を使って、Reactコンポーネント間通信のしくみを作る。
関連のないコンポーネント間でメソッドが実行できるもの。
Emitterのようなもの。
これが使えそう。
ストアを作る。
store/event.ts
import { atom } from 'nanostores'
const isEventUpdated = atom<number>(0)
// イベントの更新を通知
const notifyEventUpdate = () => {
isEventUpdated.set(isEventUpdated.get() === 0 ? 1 : 0)
}
export { isEventUpdated, notifyEventUpdate }
ストアの値の変更を検知して、メソッドを呼び出す処理は元のコードを少し修正する。
元のままではストアの値が0で初期化されたときも実行されてしまう。
watchState.tsx
import { useEffect, useRef } from 'react'
const useWatch = (value: any, callBack = (previousValue: any, newValue: any) => {}) => {
const ref = useRef(null)
useEffect(() => {
ref.current = value
}, [])
useEffect(() => {
const triggerCallback = async (newValue: any, previousValue: any) => {
// 初期値設定時はコールバックを実行しない
if (newValue === previousValue) return
await callBack(newValue, previousValue)
ref.current = value
}
triggerCallback(value, ref.current)
}, [value])
}
export default useWatch
通知イベントを受信するコンポーネントはこうなる。
CompA.tsx
import useWatch from '@/lib/watchState.tsx'
import { isEventUpdated } from '@/store/event'
import { useStore } from '@nanostores/react'
export default function CompA() {
// ストアされている値をコンポーネント側でも参照する
const $isEventUpdated = useStore(isEventUpdated)
/**
* 他コンポーネントからの通知で実行
*/
useWatch($isEventUpdated, () => {
// 実行したい処理
})
...
送信するコンポーネント側ではただ通知関数を呼び出すだけ。
import { notifyEventUpdate } from '@/store/event'
notifyEventUpdate()