Recoil中atom状态发生变更时如何执行额外的自定义操作?
Recoil监听atom状态变更并执行副作用的实现方案
你需要的监听atom状态变更、自动执行持久化等额外操作的需求,有两种成熟的实现方案:
最优方案:使用Atom Effects(官方推荐)
Recoil从0.7.0版本开始提供了effects配置项,专门用来处理atom的副作用逻辑,包括状态变更监听、持久化、同步外部存储等,完全不需要修改业务层的状态更新代码,所有逻辑都在atom定义处统一维护。
修改你的themeState定义即可:
import { StrictMode } from "react"; import ReactDOM from "react-dom"; import { RecoilRoot, atom, useRecoilState } from "recoil"; type ThemeItem = "light" | "dark"; const themeState = atom<ThemeItem>({ key: "themeState", // 初始化时优先读取localStorage里的历史值,没有就用默认light default: (localStorage.getItem("theme") as ThemeItem) || "light", effects: [ ({ onSet }) => { // 监听状态所有变更事件,不管从哪里调用更新方法都会触发 onSet((newValue) => { localStorage.setItem("theme", newValue); // 还可以在这里扩展其他操作,比如同步修改页面根节点的主题标识 document.documentElement.dataset.theme = newValue; }); } ] }); function App() { const [theme, setTheme] = useRecoilState(themeState); function handleTheme(theme: ThemeItem) { return () => setTheme(theme); } return ( <> <h3>{theme}</h3> <button onClick={handleTheme("light")}>light</button> <button onClick={handleTheme("dark")}>dark</button> </> ); } ReactDOM.render( <StrictMode> <RecoilRoot> <App /> </RecoilRoot> </StrictMode>, document.getElementById("root") );
这个方案的优势:
- 逻辑完全解耦,状态的持久化等附加逻辑和业务层调用无关
- 不会遗漏任何状态更新入口,不管多少组件调用setTheme都会自动触发副作用
- 支持扩展多套副作用逻辑,只需要在effects数组里新增即可
备选方案:封装自定义Hooks
如果你使用的Recoil版本低于0.7.0不支持effects,可以封装自定义Hooks统一处理附加逻辑,后续所有组件都调用这个自定义Hooks来读写主题状态即可:
// 封装自定义Hooks,替代直接调用useRecoilState(themeState) function useThemeState() { const [theme, setRecoilTheme] = useRecoilState(themeState); const setTheme = (newTheme: ThemeItem) => { setRecoilTheme(newTheme); localStorage.setItem("theme", newTheme); }; return [theme, setTheme] as const; } // 组件中使用 function App() { const [theme, setTheme] = useThemeState(); // 剩余业务逻辑完全不需要修改 function handleTheme(theme: ThemeItem) { return () => setTheme(theme); } return ( <> <h3>{theme}</h3> <button onClick={handleTheme("light")}>light</button> <button onClick={handleTheme("dark")}>dark</button> </> ); }
内容的提问来源于stack exchange,提问作者Kyungeun Park
相关产品推荐
相关产品推荐

