路由

当用户在您的网店域上发出请求时,它由在 pwa-kit-react-sdk/ssr/server/react-rendering 中定义的名为 render 的 Express.js 处理程序处理。处理程序选择要渲染的组件作为响应。这种类型的组件称为路由。可用于渲染的路由都在 app/routes.jsx 名为 routes 的对象数组中定义。

路由数组遵循 React 路由器定义的路由配置形状routes 数组中的每个对象都可以具有以下属性:

类型说明参考文档
路径Express 样式的字符串、字符串数组或正则表达式与传入请求路径进行比较以寻找潜在匹配的路径React Router API → 路由组件 → 路径
组件函数(导入 routes.jsx要呈现的组件(如果路径匹配请求)React Router API → 路由组件 → 组件
精确Boolean确定路径是否必须完全匹配React Router API → 路由组件 → 精确

新生成的项目已经在 routes 数组中包含许多标准电子商务页面的对象,例如主页、PLP 和 PDP。

但 React 应用程序如何为任何给定的请求选择要呈现的适当组件?我们使用 React Router 库依次搜索 routes 数组中的路由配置对象,直到找到与请求路径匹配的 path 字符串。

React Router 为您提供了许多构建 path 字符串的选项。您可以为同一个组件指定多个路径,并使用正则表达式来匹配遵循某种模式的路径。

React Router 也用于整个 Retail React App 来执行导航。例如,所有超链接都使用 React Router 的 Link 组件。React Router 提供其他组件,可让您访问浏览器历史记录、查询参数等。

要了解有关使用 React Router 的更多信息,请参阅官方文档。(坚持使用版本 5 的文档,因为其他版本使用不同的模式匹配系统。)

routes 数组中指定的每个组件都由 routeComponent 函数自动增强,这是 PWA Kit React SDK 中的高阶组件。用于构造 routeComponent 的基础类定义了几个静态方法,包括网店开发人员可以自定义的两个重要方法:getPropsshouldGetProps

getProps 方法用于将通过 props 对象从 API 请求中获取的数据提供给 routeComponent

routeComponent 增强 routes 数组中的组件时,它会在组件的属性中查找名为 getProps 的函数。如果您在该处定义一个函数,它将作为增强组件的方法公开。您不必为 routes 数组中的每个组件定义函数,只需针对在渲染之前获取数据的组件。

您定义的 getProps 函数应该返回一个 promise。当 promise 完成时,其解析值会在组件被渲染之前通过 props 对象传递给增强组件。

routes 数组中的组件被呈现时,该组件的 getProps 方法获得单个 JavaScript 对象。此对象具有以下属性,具体取决于渲染上下文:

类型说明可用性更多信息
params对象包含与 Express 样式路由字符串中的命名路由参数相对应的对象属性。示例:如果您有路由 /user/:name,则请求路径中的值 :name 可用作 params.name。默认值:{}客户端和服务器端Express API → Request → req.params
req对象由 Express 增强的 Node 请求对象的一个版本。表示 HTTP 请求并带有查询字符串、参数、正文、HTTP 标头等的属性。仅服务器端Express API → Request
res对象表示 Express 应用程序在收到 HTTP 请求时发送的 HTTP 响应。仅服务器端Express API → Response
location字符串请求的 URL。客户端和服务器端不是 Express API 的一部分

要处理 getProps 函数中的错误,您有两种选择。

第一种选择是抛出 HTTPError 对象,该对象可以从 pwa-kit-react-sdk/ssr/universal/errors 导入。当您抛出 HTTPError 时,会呈现一个专用 Error 组件。

第二种选择是使用道具将错误通知呈现组件,以便可以在自定义错误处理逻辑中使用它。

这是一个使用两种错误处理方法的示例:

getProps 返回的对象被序列化,并通过页面源中名为 __PRELOADED_STATE__ 的对象嵌入到呈现的 HTML 中。

要减小呈现的 HTML 的大小,请选择要在 getProps 中返回的数据。例如,尽可能避免从 API 请求返回整个响应。

要在浏览器中预览在服务器端呈现的页面版本,请附加到 ?__server_only URL。此查询参数停止 hydration 进程,以使浏览器不会接管呈现,在服务器端渲染之后页面保持不变。要查看 __PRELOADED_STATE__ 对象的高品质打印版本,请在查询字符串中添加 ?__server_only&__pretty_print

当用户在客户端渲染期间导航到后续页面时,页面会立即被渲染。由于 getProps 仍在获取数据时可能会进行渲染,因此请始终在组件中编写条件代码来处理未定义的道具。还要记得在未定义道具时呈现占位符组件(如 Chakra UI 中的 Skeleton)。

在客户端,组件的 render 方法在 getProps 解析之前和之后被调用。使用传递给组件的 isLoading 道具来决定是否渲染加载界面。

getProps 中发出多个 HTTP 请求时,尽量使其并行发送。如果您不能让它们并行,考虑将其移动到客户端渲染。

如果您只想在客户端获取数据,请在组件(而不是 getProps)中使用 React hooks

如果要对所有路由运行相同的代码,可以定义一个属于 App 组件的 getProps 函数,该组件是特殊组件之一。特殊组件用于添加跨多个路由共享的功能。要了解有关应用程序组件和其他特殊组件的更多信息,请参阅我们的特殊组件指南。

shouldGetProps 方法控制何时调用 getProps 方法。在服务器端渲染期间,shouldGetProps 仅调用一次。在客户端渲染期间,每次调用 React 有效周期 componentDidUpdate 方法时都会调用它。

默认情况下,每次 location.pathname 的值变化时,getProps 都会调用 getProps。您可以通过将自己的 routes 函数定义为组件的属性来覆盖 shouldGetProps 数组中每个组件的默认行为。您可以自定义 shouldGetProps 以检查请求并仅调用特定请求的 getProps

通过查看追踪代码来更深入地了解路由。以下是在 Retail React App 中检查的一些关键文件:

  • app/routes.jsx:演示用于路径匹配的 Express 样式语法,包括已命名路由参数。
  • app/pages/product-detail/index.jsx:PDP 的这个示例组件包括 getPropsshouldGetProps 的自定义函数。
  • app/components/_app_config/index.jsx:包括广泛的配置代码和应用程序范围的 getProps 函数。

在阅读 PWA Kit 文档时,不要错过 Retail React App 架构指南。