【问题标题】:Universal routing with express and react router. Understanding history behaviour使用 express 和 react 路由器的通用路由。了解历史行为
【发布时间】:2017-08-19 10:21:49
【问题描述】:

我正在使用 React Router 4.0 和 Express 4.14 创建一个混合了单页应用 (SPA) 和多页应用 (MPA) 的应用。我不知道这是否是好的做法,但这不是重点。我实际上是为了学习而不是为了一个真实世界的应用程序。这个想法来自于您在应用程序中具有高度分离的部分的场景,例如博客和作品集。

客户端

所以,当我想作为 SPA 导航时,我使用来自 react-router-dom 的 Link 组件,例如 <Link to="/reactrouter-route">。如果我想向服务器处理的路由发出请求,我使用<a href="/server-route">。

服务器端

我有一个中间件记录我的服务器收到的任何请求的路径。我定义了两条路线,每条路线都服务于一个完整的 SPA。为了与博客/投资组合示例保持一致,假设我有以下内容

const express = require('express');
const app = express();

app.use((req, res, next) => {
  console.log(req.path);
  next();
});

app.get('/', (req, res) => {
  res.sendFile('blog.html');
});
app.get('/portfolio', (req, res) => {
  res.sendFile('portfolio.html');
});

行为

当我转到 / 时,博客将作为 SPA 加载,我可以在需要时转到导航回 / 的不同帖子。一切都按预期工作。 SPA 中的所有导航都由 React Router 管理,服务器只获取到/ 的第一个请求。

想象一下,从一个特定的帖子,比如/posts/some-post,我有一个投资组合的链接。如果我单击它,我会在服务器上收到一个请求,它会以投资组合 SPA 进行响应。我可以在投资组合 SPA 中导航,但无法返回 /posts/some-post。我收到以下错误:

无法获取 /posts/some-post

我以为错误是服务器抛出的,但令人惊讶的是,我返回时没有收到任何请求。我只在通过链接前进时在服务器上收到请求(仅限<a>)。

我一直在做测试,如果我从/portfolio 回到/ 没有问题。这按预期工作。

变得有趣

我在我的服务器中定义了一个路由,其规则与我在 React Router 路由中的规则相同。我在这条新路线中匹配的路径是/posts/:postid。我将此路由设置为重定向到/。现在,如果我从posts/some-post 转到/portfolio 并尝试返回,我会遇到同样的错误。这并不奇怪,因为服务器没有收到请求。如果我通过在浏览器中输入 URL 直接访问 /posts/some-post,则访问 / 也是正常的。

但是,一旦我手动转到/posts/some-post,我可以从/portfolio 转到/posts/some-post 而不会出现错误。现在它的行为就像调用了服务器一样。事实上,我在服务器中收到一个获取静态文件的请求。但是,我没有收到对/posts/some-post 和/ 的请求。

即便如此,如果从 /posts/some-other-post 转到 /portfolio 并尝试返回,我也会收到错误消息。

问题

我猜这与缓存有关,但我不知道那里发生了什么。 React Router 处理什么时候恢复?服务器什么时候处理呢?这个过程中缓存是如何参与的?

【问题讨论】:

  • 你有没有想过这个问题?下面的答案有帮助吗?
  • 我还是有同样的疑问。您的回答解释了如何解决问题,但我的问题是了解问题发生的原因。它有助于解决它,但我仍然有同样的问题。
  • 您是否尝试过 create-react-app 并阅读了有关如何与节点 API 后端集成的链接?

标签: react-router browser-cache browser-history history.js


【解决方案1】:

听起来您需要一个更清晰的 SPA 中服务器和客户端角色的思维模型。 “单页”是重要的部分。

使用 React 构建的客户端永远不应该从服务器加载页面。它应该是一个“单页”。换句话说,您根本不应该在您的客户端应用程序中使用<a href="/server-route">。客户端应该只使用类似fetch (https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) 的方式从服务器获取(JSON)数据。

我强烈建议您查看Create React App,它还解释了如何在开发过程中使用integrate with a node API backend。基本上,您希望您的所有客户端路由都类似于/post/:postid,它将由 React Router 处理,然后该 React 组件将使用fetch 从/api/posts/10 之类的东西中获取数据。如果您使用 /api 将所有请求作为前缀添加到服务器,它应该有助于您的心理模型。

【讨论】:

    猜你喜欢
    • 2017-06-11
    • 2018-05-18
    • 2020-11-30
    • 1970-01-01
    • 1970-01-01
    • 2021-11-01
    • 2017-10-07
    • 2017-08-03
    • 2020-06-14
    相关资源
    最近更新 更多