反应路由器和快递冲突

Posted

技术标签:

【中文标题】反应路由器和快递冲突【英文标题】:React Router & Express Conflicts 【发布时间】:2017-10-03 00:57:40 【问题描述】:

我有我希望 React Router 处理的路径,并且我还有一个 express API 后端,我从 React 应用程序调用它来执行一些安全的 API 调用。

/#/ - 想要在这里提供应用程序/#/:id - 应用程序的唯一 URL,我使用 ID 从 React 调用某些快速端点。* - 所有快速 REST 端点

快递 app.js:

app.use(middleware);
app.use(require('webpack-hot-middleware')(compiler, 
  log: console.log
));
app.use('/api', [router_invokeBhApi]);
app.get('/#/*', function response(req, res) 
  res.write(middleware.fileSystem.readFileSync(path.join(__dirname, 'dist/index.html')));
  res.end();
);
app.use(express.static(path.join(__dirname, '/dist')))

我的 React 路由组件:

export default (
  <Route path="/" component=App>
    <IndexRoute component=HomePage />
    <Route path="/:id" component=ConsentForm something="dope"/>
  </Route>
);

这就是正在发生的事情: - 转到 localhost:8000 使用 HomePage 组件为应用程序提供服务 - 转到 localhost:8000/#/ 也为应用程序提供 HomePage 组件 - 去localhost:8000/example 给我Cannot GET /example 这意味着快递正在工作 - 转到localhost:8000/api 给了我一个测试 JSON 对象,这是我从 express 发送的,这是正确的。 - 转到localhost:8000/#/somehashcode 仍然给我HomePage 组件,而它应该给我ConsentForm 组件。

我使用 React 开发工具检查了路由器组件: - RouterContext 组件有一个名为routes 的对象,在routes[0] 内有一个childRoutes,它的路径为/:idroutes[0] 也有一个路径 / 告诉我 React Router 正确加载了所有路由??

好困惑……

我在其中渲染整个应用程序的 React 文件:

import 'babel-polyfill';

import React from 'react';
import ReactDOM from 'react-dom';
import  Router, browserHistory  from 'react-router';

import Routes from './shared/components/Routes';

import './shared/base.css';
import './shared/customInput.css';


const ROOT_ELEMENT = 'app';

ReactDOM.render((
  <Router history=browserHistory>
    Routes
  </Router>
), document.getElementById(ROOT_ELEMENT));

【问题讨论】:

你能提供更多关于你正在使用的 react-router 版本的信息吗?根据他们最新的文档,您必须从他们的一个包中使用 HashRouter,而不仅仅是 Route。 reacttraining.com/react-router/web/api/HashRouter @Michael "react": "^0.14.7", "react-bootstrap": "^0.28.3", "react-dom": "^0.14.7", "react-路由器”:“^2.0.0”,“react-router-dom”:“^4.1.1”, App 的渲染方法是什么样的?你有正确渲染子组件的地方吗? @gravityplanx 我已经用它更新了问题 仍然不包括我要求的信息。我专门询问名为App 的反应组件。它的渲染方法是否包含子组件的空间? 【参考方案1】:

我终于明白了!

在 React Router 组件中,将 :id 路由更改为:

<Route path="/redirect/:id" component=ConsentForm something="dope"/>

在 Express 中,app.js 将 React 服务更改为:

app.get('/redirect/*', function response(req, res) 
  res.write(middleware.fileSystem.readFileSync(path.join(__dirname, 'dist/index.html')));
  res.end();
);

从中学到 2 件事: - 在路由中使用 # 不起作用。不知道为什么。 - 在 React 端也明确说明路由。

很奇怪,或者我可能是在使用一些半生不熟的知识。任何能够为我指明正确方向的资源都会非常棒。

很确定其他人在同时使用 Express 和 React 时会遇到这种情况。

【讨论】:

【参考方案2】:

发现你的问题。

您在配置中使用BrowserHistory。这个选项(目前推荐的)在uri中没有使用hash,而是直接与浏览器集成。

尝试通过localhost:8000/somehashcode 访问您的应用,看看您会得到什么。

【讨论】:

http://localhost:8000/somehashcode 给我 'Cannot GET /somehashcode' 意思是 express 正在处理那条路线,对吗? 听起来很像,这意味着您的路由工具之间存在冲突。要解决这个问题,你应该 1;在 express 中设置通配符路由,以便任何不匹配的 get 请求呈现您的反应应用程序或 2;将 react-router 的 BrowserHistory 换成 HashHistory,这将使用原始问题中的 uri。 我只是想要一种方法让某些 URL 由 express 和某些由 React 处理。有没有办法让他们不这样冲突?当我明确指定仅以 /#/* 开头的 URL 由 React 处理时,我什至不明白为什么它们首先会发生冲突。我用 HashHistory 测试一下,给我几分钟时间 使用HashHistory 之类的作品(能够使用URL访问Form组件和Home组件,但仍然无法访问快速路由。 我认为您的问题源于对哈希参数的误解。哈希参数类似于普通参数(例如localhost:8000/?hasparam=somehashcode),除了*它们没有传递给服务器)。因此,您指定 app.get('/#/*'... 的快速配置实际上没有任何意义。

以上是关于反应路由器和快递冲突的主要内容,如果未能解决你的问题,请参考以下文章

如何从快递控制反应路由器

反应路由和django url冲突

尽管所有反应路由器版本冲突,如何在反应中进行服务器端渲染?

反应路由器和setState冲突

快递路线参数条件

javascript 路由器生成器快递