Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

useSyncExteranlStore を使うように変更 #66

Open
wants to merge 17 commits into
base: feat/v0.6.0
Choose a base branch
from

Conversation

naporin0624
Copy link

こっちのほうが美しい

Comment on lines +18 to +29
const inputs = useSyncExternalStore(
inputsStore.subscribe,
inputsStore.getValue,
)
const settings = useSyncExternalStore(
settingsStore.subscribe,
settingsStore.getValue,
)
const actionInfos = useSyncExternalStore(
actionInfoStore.subscribe,
actionInfoStore.getValue,
)
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

なぜ mini-store を毎回作っているのか?

useSyncExternalStore は getValue で受け入れた値が not shallow equal だと再レンダリングトリガーされるため getValue は cached な値である必要がある。
headlessStreamDeck から返却される getActionInfo, getActionInfos は計算して返却されるため、object が毎回異なる
xxxStore は event があるたびに値を更新し、それを保持するため getValue は cached な値になるため Infinite Loop を回避する
ちなみにこの辺は rxjs と jotai を使うと簡単に回避できるのだが、jotai は内部的に useSyncExternalStore を使っていないため本質的には別物になる

Source/pi/vite.config.ts Outdated Show resolved Hide resolved
setSettings(s)
sd?.setSettings(s)
}
headlessStreamDeck.setSettings(s)
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

headlessStreamDeck.setSettings 内部では didReceiveSettings が内部向けに先んじて発火するので settingsStore の subscribe が発火し、settings が更新される(

this.listeners.dispatch('didReceiveSettings', payload)
)

後からサーバーから websocket の message を受信して実際の設定が更新される

this.listeners.dispatch('didReceiveSettings', parsed.payload)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

更新するときに発火し useSyncExternalStore に通知する部分

subscribe(callback: Subscriber<unknown>) {
listeners.add(callback)
if (listeners.size === 1) {
headlessStreamDeck.addEventListener('didReceiveSettings', handler)
}
return () => {
listeners.delete(callback)
if (listeners.size === 0) {
headlessStreamDeck.removeEventListener(
'didReceiveSettings',
handler,
)
}
}
},

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant