electron 如何使用带有电子的React路由器?

n7taea2i  于 2023-02-10  发布在  Electron
关注(0)|答案(9)|浏览(334)

this boilerplate为参考,我创建了一个Electron应用程序,它使用webpack捆绑脚本,使用express server托管脚本。
Webpack配置实际上与this和服务器this相同。
Electron的脚本加载:
mainWindow.loadURL('file://' + __dirname + '/app/index.html');
index.html加载服务器托管的脚本:
<script src="http://localhost:3000/dist/bundle.js"></script>
我运行electron index.js来构建应用程序,运行node server来启动服务器,服务器使用webpack捆绑脚本。
它工作正常,我的React组件应用程序已经安装。但我如何集成React路由器到这一点?
我以与浏览器应用相同的方式实现了它。我得到了这个错误:
[react-router] Location "/Users/arjun/Documents/Github/electron-app/app/index.html" did not match any routes
它是以文件路径作为路由的。浏览锅炉板代码没有帮助。我遗漏了什么?

gfttwv5a

gfttwv5a1#

必须将BrowserRouter替换为HashRouter

import {
  HashRouter,
  Route
} from "react-router-dom";

然后在我的index.js或电子应用程序的入口文件中,我有这样的内容:

<HashRouter>
  <div>
    <Route path="/" exact     component={ Home } />
    <Route path="/firstPage"  component={ FirstPage } />
    <Route path="/secondPage" component={ SecondPage } />
  </div>
</HashRouter>

然后一切都好了。
理由是:BrowserRouter用于基于请求的环境,而HashRouter用于基于文件的环境。
在此阅读更多信息:

qq24tv8q

qq24tv8q2#

另一个选择是使用hashHistory,实际上,在你引用的repo中你可以看到他们使用的是hashHistory,尝试一下并回发如何?

ymzxtsji

ymzxtsji3#

我使用的是React Router v4,不想回退到HashRouter,所以我用以下方法解决了这个问题:

import { Redirect, BrowserRouter } from 'react-router-dom';

const App = () => (
  <BrowserRouter>
    <div>
      {window.location.pathname.includes('index.html') && <Redirect to="/" />}
    </div>
  </BrowserRouter>
);
jdg4fx2g

jdg4fx2g4#

在回答这个问题的时候,最好的选择是使用MemoryRouter,对我很有效:)

9o685dep

9o685dep5#

简单地使用Switch将默认值设置为“/”怎么样?

<Switch>
  <Route path="/" exact component={Home}/>
  <Route path="/foo" component={Foo}/>
  <Route path="/bar" component={Bar}/>
  <Route render={() => <Redirect to="/"/>}/>
</Switch>

这样,“/index.html”将重定向到“/”

eufgjt7s

eufgjt7s6#

(当前)React路径文件称:
一般而言,如果您有回应要求的伺服器,则应使用;如果您使用的是静态档案伺服器,则应使用。
电子应用程序基本上是一个静态文件服务器。
MemoryRouter也可以工作,只要所有路由都来自应用的React部分。只有当您想从Browser进程导航到特定页面时,它才会福尔斯,例如,您想弹出一个新窗口并直接导航到“常规首选项”页面。在这种情况下,您可以使用HashRouter:

prefsWindow.loadURL(`file://${__dirname}/app/index.html#/general-prefs`);

我不认为有一种方法可以用MemoryRouter(从浏览器进程)做到这一点。

798qvoo8

798qvoo87#

同意Niekert的观点,但我认为在进行任何路线管理之前,最好先这样处理。

if ( window.location.pathname.includes('index.html') ) {
    location.pathname = ROUTES.ROOT;
}
zysjyyx4

zysjyyx48#

这完全取决于您传递给mainWindow.loadURL的URL类型。

一米一分一秒

如果直接通过file://协议加载index.html,例如

mainWindow.loadURL('file://' + path.join(__dirname, '../index.html#/home'))

则需要使用HashRouter

<HashRouter>
  <Routes>
    <Route path='/home' element={<MyHomeScreen/>}>
  </Routes>
</HashRouter>

请注意,index.html#/home中的#非常重要!
为什么?
想象一下如果你写index.html/home会发生什么。你的计算机会试图检索index.html目录中的home文件。#阻止了这一点,因此我们需要使用HashRouter。

一米十一分

如果从localhost:3000之类的服务器加载index.html,则有两种选择:

  • 包括#,如
mainWindow.loadURL('http://localhost:3000#/home')

中所示,并完全按照上面所述使用HashRouter

    • 或**
  • 不要像
mainWindow.loadURL('http://localhost:3000/home')

那样包含#,并按如下方式使用BrowserRouter

<BrowserRouter>
  <Routes>
    <Route path='/home' element={<MyHomeScreen/>}>
  </Routes>
</BrowserRouter>

在这种情况下,许多人更喜欢使用BrowserRouter,因为它避免了使用#使URL复杂化。

6za6bjd0

6za6bjd09#

main进程中:

mainWindow.loadURL(resolveHtmlPath('index.html'));

renderer进程中:

import { HashRouter as Router, Routes, Route } from 'react-router-dom';

//...

<Router>
  <Routes>
    <Route path="/" element={<Home />} />
    <Route path="/search" element={<Search />} />
    <Route
      exact="true"
      path="/library"
      element={<Library />}
      />
  </Routes>
</Router>

resolveHtmlPath的调用消除了我使用hashtags的需要,使用开箱即用的BrowserRouter在开发工具中给了我警告消息。
此函数位于您引用的Electron React Boilerplate项目中:

import { URL } from 'url';
import path from 'path';

export function resolveHtmlPath(htmlFileName: string) {
  if (process.env.NODE_ENV === 'development') {
    const port = process.env.PORT || 1212;
    const url = new URL(`http://localhost:${port}`);
    url.pathname = htmlFileName;
    return url.href;
  }
  return `file://${path.resolve(__dirname, '../renderer/', htmlFileName)}`;
}

相关问题