如何在不使用电子锻造重定向到根目录的情况下进行热重装并做出反应

Posted

技术标签:

【中文标题】如何在不使用电子锻造重定向到根目录的情况下进行热重装并做出反应【英文标题】:How to hot reload without being redirected to root with electron-forge and react 【发布时间】:2021-10-21 05:40:43 【问题描述】:

我在电子锻造方面遇到问题,我想这是一个常见问题,但我似乎找不到答案。

我已经使用npx create-electron-app 创建了一个新项目,并且我已经安装并设置了 react,一切正常。

我遇到的问题是热重载。我正在使用react-router-dom 进行路由,并且显然我使用了MemoryRouter,我没有运行电子应用程序的URL。热重新加载开箱即用,但每次重新加载时,我都会导航回应用程序的入口点,我想留在当前页面上。烦人的事情是,在我导航回根目录之前,我通常可以在一瞬间看到当前页面更新。有什么地方可以防止这种情况发生吗?

感谢任何帮助。

【问题讨论】:

你能用内存路由器发布一个沙盒回购吗?这将有助于解决问题 您也可以尝试在重新加载之间记录、window.history 并查看它们返回的内容 你在后台用什么? 这是内存路由器使用的要点gist.github.com/DrLazer/b555ff7226907d0123d97b5fa4d6e8a4 【参考方案1】:

肯定会导致这种情况的两件事,

<Switch>
   <Route path="/" component=RootComponent />
   <Route path="/test" component=TestComponent />
</Switch>
    检查你的路线,你有没有exact关键字的基本路线吗?

以上将匹配到根路由的所有路由,并将您置于根组件中。需要加exact

<Route exact path="/" component=RootComponent />
    package.json 中的homepage: "."index.html 中是否设置了&lt;base href="/"&gt;?如果是,请删除它们。

Homepage: '.' 将默认从根服务。

你在 MemoryRouter 中使用了哪些 props?如 initialIndexinitialEntries 等等?

你试过Hot module replacement吗?我不建议将此作为解决此问题的方法,但这是一个很好的解决方法Electron-forge doc for HMR

 entryPoints: [
          rhmr: 'react-hot-loader/patch', // react hot module replacement
          name: 'main_window',
          html: './src/renderer/index.html',
          js: './src/renderer/index.js'
        ]

Electron-forge doc 表示无法在渲染器中进行 HMR,您可以尝试上述方法吗?它在 webpack 应用程序中对我有用。

如果上述方法没有帮助,请提供一个最小的可重现代码 repo/codesandbox 来帮助您解决问题。最重要的是,需要在您的应用中查看MemoryRouter 的使用情况。

针对评论进行更新:

Yes, electron forge does hot reload by default,只有对 CSS 文件的更改会被热重新加载(不刷新),对 JS 文件的更改需要刷新,在这两种情况下,文件都会被监视更改。您可以在 webpack-dev-server 配置中看到注释(下面的快照)

MemoryRouter 上查看您的要点,我建议进行以下更改

    向路由器提供memory history prop

        import createMemoryHistory from 'history';
    
        const history = createMemoryHistory();
    
        <Router history=history>
          <Switch>
            <Route path='/dash' exact component=Dash />
            <Route path='/wallet' exact component=Wallet />
            <Route path='/service' exact component=ServiceStatus />
            <Route path='/' exact component=SignIn />
            <Route component=SignIn /> // would suggest protected routes 
          </Switch>
        </Router>
    

    exact从除基础路由之外的其他路由中移除并放置基础 以上登录。

如果问题依旧,建议你开启热模块 替换(无需重新加载即可更新您的应用)

Here is an elaborate writeup on Hot Module Replacement 被 redux 和 create-react-app 的共同创造者鼓掌。

HMR 上的 gif 取自上面的帖子(没有刷新,因此每次更改都不会登陆根路由,但应用程序已更新):

An example app 看看它的实际效果。

Electron forge HMR solution

Electron forge react example project

【讨论】:

感谢您的回答,这是一个很好的清单。 - 我在基本根目录上使用了确切的关键字 - package.json 中没有主页 - index.html 中没有 标记 - MemoryRouter 上没有附加属性 关于 MHR。我的印象是这是与电子锻造捆绑在一起的?我的意思是它确实会在保存时更新并重新加载,然后它会将我带到根目录。 我已根据您的评论更新了答案。谢谢 由于更新登陆时的重新加载很烦人,因此 devserver (forge.config.js) 中的 HMR 将是一个很好的解决方法。 再次感谢您的更新,所有明智的建议。现在向路由器提供历史记录,按照建议重新排序,从除根链接之外的所有链接中完全删除。 (是的,我将添加受保护的路线,一旦我走到那一步。)目前的结果相同。我会试试 HMR 路线。【参考方案2】:

您可以在开发过程中使用 electron-reloader 来实现这一点。 如果在主进程上进行了更改,则主进程将得到更新。 如果对渲染器进程进行了更改,则渲染器进程将得到更新 https://www.npmjs.com/package/electron-reloader

另一种方法是在渲染过程中记录当前路由并将其保存在本地存储中。然后,您可以在页面重新加载时转到该路线。如果要保留状态,可能需要在记录路由时保存状态。

localStorage.setItem('current_route', route)
localStorage.setItem('current_state, the_entire_state)

你可以使用必要的生命周期,去到需要的路由并设置状态

【讨论】:

在没有将错误信息喷入控制台的情况下,无法让电子重新加载器工作 :( 本地存储是一个有趣的想法,但对于应该可以工作的东西来说,它确实感觉像是一种黑客/解决方法。此外,如果项目在 dev 中运行,我需要添加逻辑以避免它在 prod 中运行

以上是关于如何在不使用电子锻造重定向到根目录的情况下进行热重装并做出反应的主要内容,如果未能解决你的问题,请参考以下文章

如何在不更改浏览器中的 URL 的情况下使用 htaccess 进行重定向

是否可以在不使用 WooCommerce 重定向到 PayPal 网站的情况下进行 PayPal 付款?

如何在不重新加载页面的情况下将用户重定向到 redux saga 上的另一个页面

是否可以在不重定向到外部登录页面的情况下进行 SPA 身份验证

如何在不使用 React Native 中的堆栈导航器的情况下重定向到页面?

如何在不使用 Javascript 的情况下最好地重定向网页?