使用Electron-Forge与React开发时,如何实现热重载且不跳转到根路由?
我之前在Electron-Forge + React + MemoryRouter的项目里也碰到过这个烦人的问题!每次热重载明明能看到当前页面更新了一下,结果瞬间跳回首页,调试的时候真的很打断思路。
问题根源其实很清楚:MemoryRouter的路由状态完全存在内存里,而Electron-Forge的热重载本质是重启了渲染进程——进程一重启,内存里的状态就全没了,所以React会重新用默认的根路由初始化MemoryRouter。你能短暂看到当前页面,是因为HMR先更新了组件,但随后整个应用重新挂载,路由状态重置了。
给你几个亲测有效的解决方案,从简单到进阶:
方案1:用localStorage持久化路由状态(最快捷)
这是我最常用的方法,实现起来最简单,不需要额外依赖。核心思路就是把当前路由路径存在localStorage里,每次应用初始化时从localStorage读取上次的路径作为MemoryRouter的初始路由,同时监听路由变化实时更新存储。
具体代码示例:
import { useEffect, useState } from 'react'; import { MemoryRouter, Routes, Route, useLocation } from 'react-router-dom'; // 工具函数:保存/读取路由路径 const saveLastRoute = (path) => localStorage.setItem('electron-react-last-route', path); const getLastRoute = () => localStorage.getItem('electron-react-last-route') || '/'; // 监听路由变化并保存的组件 const RoutePersister = () => { const location = useLocation(); useEffect(() => { // 每次路由切换时保存当前路径 saveLastRoute(location.pathname); }, [location.pathname]); return null; }; function App() { // 初始化时读取上次保存的路由 const [initialRoute, setInitialRoute] = useState(getLastRoute()); // 处理热重载前的最后一次保存(避免进程重启时丢失最新状态) useEffect(() => { const handleBeforeReload = () => { // 这里通过React内部状态获取当前路由,确保保存最新路径 const rootContainer = document.querySelector('#root')?._reactRootContainer; if (rootContainer?.._internalRoot?.pendingProps?.children?._location) { saveLastRoute(rootContainer._internalRoot.pendingProps.children._location.pathname); } }; window.addEventListener('beforeunload', handleBeforeReload); return () => window.removeEventListener('beforeunload', handleBeforeReload); }, []); return ( <MemoryRouter initialEntries={[initialRoute]}> <RoutePersister /> <Routes> <Route path="/" element={<Home />} /> <Route path="/dashboard" element={<Dashboard />} /> <Route path="/settings" element={<Settings />} /> {/* 你的其他路由 */} </Routes> </MemoryRouter> ); } export default App;
方案2:用Electron的主进程存储路由状态(更可靠)
如果担心localStorage被清理,或者需要跨窗口同步路由状态,可以把路由状态存在Electron主进程的app.getPath('userData')目录下的JSON文件里。
大致步骤:
- 在渲染进程里,路由变化时通过
ipcRenderer发送消息给主进程,保存当前路径 - 应用初始化时,通过
ipcRenderer从主进程读取上次保存的路径 - 主进程负责读写文件(用
fs.promises即可)
这个方案稍微复杂一点,但适合更复杂的场景。
额外注意事项
- 如果开发时偶尔需要回到根路由,可以手动清除localStorage:打开开发者工具,在Application面板里找到localStorage,删除对应的键即可
- 可以加环境变量判断,只在开发环境启用路由持久化,生产环境不需要:
然后在保存和读取的时候加个判断就行。const shouldPersistRoute = process.env.NODE_ENV === 'development';
亲测这个方法能完美解决热重载跳转的问题,现在我每次热重载都能停在当前页面,舒服多了!
内容的提问来源于stack exchange,提问作者DrLazer
相关产品推荐
相关产品推荐

