前几天发了一个帖子关于如何实现 electron 多窗口开发,发现思路有点问题。今天又想到了可以用 localStorage+hook 的方式。浏览器 window 可以监听 storage 的变化。并用 mobx 来管理状态,当状态值发生变化的时候,往 localStorage 中写入新的序列化后的值。
有评论区大哥说可以封装一个 ipc 的 proxy 。 但是我觉得 ipc 这玩意还是太过复杂,不如把所有的逻辑都放在渲染进程写。
hook 代码
import { autorun, observable } from "mobx";
import { useEffect } from "react";
export const useLocalStorage = <T>(storageKey: string, fallbackState: T) => {
const state = observable({
value: JSON.parse(localStorage.getItem(storageKey)) ?? fallbackState,
});
autorun(() => {
localStorage.setItem(storageKey, JSON.stringify(state.value));
});
const onStorageUpdate = (e) => {
const { key, newValue } = e;
state.value = JSON.parse(newValue);
};
useEffect(() => {
localStorage.setItem(storageKey, JSON.stringify(state.value));
window.addEventListener("storage", onStorageUpdate);
return () => {
window.removeEventListener("storage", onStorageUpdate);
};
}, [state.value, storageKey]);
return [state.value];
};
主窗口
const App = observer(() => {
const [store, setStore] = useLocalStorage("store", countStore);
return (
<div>
<h1>I am Main Window</h1>
<button
onClick={() => {
const win = window.open("child.html");
}}
>
Open Child Window
</button>
<div>store.count = {store.count}</div>
<button
onClick={() => {
store.count--;
}}
>
minus-
</button>
<button
onClick={() => {
store.count++;
}}
>
plus+
</button>
</div>
);
});
子窗口
const Child = observer(() => {
const [store, setStore] = useLocalStorage('store', null);
return (
<div>
<h1 onClick={() => {
store.count ++
}}>I am Child Window</h1>
<div>store.count = {store.count}</div>
</div>
);
});
效果图
demo 链接:
1
zsj1029 2023-03-15 16:41:25 +08:00
https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API
hook 是不是基于这个 storage 事件实现 |
2
ruxuan1306 2023-03-15 16:51:59 +08:00
思路有意思学习了。但看起来 useLocalStorage 少返回一个 setStore ,我猜是引入 mobx 后例程忘改了。
|
3
travisyang OP @ruxuan1306 确实少返回了一个 setStore ,不过 mobx 支持直接修改成员变量触发 ui 更新,所以返回一个值也够了
|
4
travisyang OP @zsj1029 是的
|
5
snowKing66 2023-04-19 09:45:15 +08:00
思路很棒,但是如果要实际运用到工程项目中,我还有点疑问,如果采用这种方式作为窗口通信,不知道效率上跟 ipc 相比如何?因为安全性方便应该是不如 ipc
|
6
travisyang OP @snowKing66 效率上还没考虑过。其实用 ipc 的话也可以用同样的方式封装成一个 hook 。我一开始只是觉得 ipc 太麻烦了
|