如何与Electron一起使用React路由器
How to use React Router with Electron?
使用这个样板作为参考,我创建了一个Electron应用程序。它使用webpack来捆绑脚本和express服务器来托管它
Webpack配置实际上与此和服务器配置相同。
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
它以文件路径作为路由。仔细检查锅炉铭牌代码也无济于事。我错过了什么?
必须用HashRouter
替换BrowserRouter
import {
HashRouter,
Route
} from "react-router-dom";
然后在我的index.js
或Electron应用程序的输入文件中,我有这样的东西:
<HashRouter>
<div>
<Route path="/" exact component={ Home } />
<Route path="/firstPage" component={ FirstPage } />
<Route path="/secondPage" component={ SecondPage } />
</div>
</HashRouter>
然后一切都正常了。
理由是:BrowserRouter
适用于基于请求的环境,而HashRouter
适用于基于文件的环境。
点击此处阅读更多:
- https://github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/docs/api/HashRouter.md
另一个选项是使用hashHistory。事实上,在您引用的回购中,您可以看到他们正在使用hashHistory,不如尝试一下并发布回去?
我使用的是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>
);
在回答这个问题时,最好的选择是使用MemoryRouter,对我有用:)
(当前)反应路由器文档说:
一般来说,您应该使用<浏览器路由器>如果您具有响应请求的服务器,并且<哈希路由器>如果您使用的是静态文件服务器。
Electron应用程序基本上是一个静态文件服务器。
MemoryRouter也可以工作,只要所有路由都源于应用程序的React部分。只有当您想从浏览器进程导航到特定页面时,它才会下降,例如,您想弹出一个新窗口并直接导航到"常规首选项"页面。在这种情况下,可以使用HashRouter:
prefsWindow.loadURL(`file://${__dirname}/app/index.html#/general-prefs`);
我认为MemoryRouter(从浏览器进程)没有办法做到这一点。
简单地使用Switch默认为"/",如下所示:
<Switch>
<Route path="/" exact component={Home}/>
<Route path="/foo" component={Foo}/>
<Route path="/bar" component={Bar}/>
<Route render={() => <Redirect to="/"/>}/>
</Switch>
这样,"/index.html"将重定向到"/"
同意Niekert的意见。但我相信,在进行任何路线管理之前,最好先这样处理。
if ( window.location.pathname.includes('index.html') ) {
location.pathname = ROUTES.ROOT;
}
这完全取决于传递给mainWindow.loadURL
的URL类型。
file://...
如果通过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
文件。#
防止了这种情况,因此我们需要使用Hash路由器。
http://localhost:3000
如果从localhost:3000
等服务器加载index.html
,则有两个选项:
- 包括
#
,如
并且完全如上所述使用CCD_ 27mainWindow.loadURL('http://localhost:3000#/home')
或
- 不包括
#
,如
并像这样使用CCD_ 29:mainWindow.loadURL('http://localhost:3000/home')
<BrowserRouter> <Routes> <Route path='/home' element={<MyHomeScreen/>}> </Routes> </BrowserRouter>
在这种情况下,许多人更喜欢使用BrowserRouter
,因为它避免了#
使URL复杂化。
在您的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
path="/library"
element={<Library />}
/>
</Routes>
</Router>
对resolveHtmlPath
的调用消除了对我使用标签的需要。在开发工具中使用开箱即用的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)}`;
}
- 如何使用带有Preact的React路由器
- 如何在react路由器的组件中使用参数
- React路由器服务器端渲染和ajax获取数据
- react路由器使用简单的javascript路由器配置来处理不匹配的路径
- React路由器错误-'无法调用方法'getRouteAtDepth'的未定义'
- 有条件地与react路由器链接
- 如何使用服务器上的react路由器处理所有可能的路由
- React.js-React路由器内容未更改
- 使用react路由器隐藏组件
- React 路由器 activeClassName 不会为子路由设置活动类
- react路由器(-redux)未匹配路由
- 从使用react路由器的网络应用程序解析物理URL
- React 路由器和任意查询参数:页面在加载时无意中刷新
- 如何使用react路由器的正常锚链接
- 未捕获的类型错误:hook.apply不是在react路由器中使用onEnter时的函数
- 我可以让react路由器只覆盖一些url,并将其余的url正常传递给服务器吗
- Meteor's Accounts.onEmailVerificationLink与React和React路由器
- React路由器仅模式路由
- 当react路由器更改时,我们可以取消api响应吗
- React,Flux,React路由器调度错误-可能的批更新解决方案