記錄一下開發過程中遇到的BUG以及原因分析。
發生情境
先描述一下這個BUG發生的情境:
應用有兩個視窗,分別為A,B視窗,我會在A視窗中進行設定,然後實時在B視窗上看到修改。資料使用Zustand保存,修改設定值時會使用ipc event傳給B視窗:
// useDataStore.ts
export const useDataStore = create()(
persist(
(set) => ({
data: {
title: 'demo',
size: 'sm',
color: '#ffffff'
},
setData: (newData) => {
set((state) => {
window.electron.ipcRenderer.send('UPDATE-DATA', newData)
return { data: newData }
})
},
setColor: (newColor) => {
set((state) => {
// ...略
return { color: newColor }
})
}
}),
{
name: 'data-store',
storage: createJSONStorage(() => localStorage),
},
),
)
在B視窗中可以接收修改後的state,有些設定值也會在B視窗中進行修改,比如color:
// B視窗
const { setColor } = useDataStore()
useEffect(() => {
window.electron.ipcRenderer.on(
'UPDATE-DATA',
(...args) => {
const newData = args[0]
// ...
}
)
window.electron.ipcRenderer.on(
'COLOR-CHANGED',
(...args) => {
const newColor = args[0]
setColor(newColor)
}
)
}, [setData, setColor])
現在,在A視窗中修改title, size,更新後的data為:
data: {
title: 'new title',
size: 'md',
color: '#ffffff'
}
接著我在B視窗中更改顏色為 #000000
,預期更新後的data應為:
data: {
title: 'new title',
size: 'md',
color: '#000000'
}
可實際上更改 color 後 data 為:
data: {
title: 'demo',
size: 'sm',
color: '#000000'
},
可以看出 title, size 變回初始值,只有 color 更新了。
發生原因
詢問chatGPT後得到的答案是:
並且 chatGPT 建議的解決方法是:
如果你的 widget 和主視窗資料交互比較多,而且要保持一致,最佳做法是把 state 放在 main process,讓它變成「單一真實資料源」,再透過 IPC 讓多視窗同步,這樣最穩定。