前几天发了一个帖子关于如何实现 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 链接:
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.