跳到主要内容
版本: 7.x

React Navigation 在 Web 上的应用

React Navigation 内置了对 Web 平台的支持。这使你可以在 React Native 应用以及 Web 上使用相同的导航逻辑。这些导航器需要在 Web 上使用 React Native for Web 才能工作。

前提条件

虽然 Web 支持开箱即用,但仍有一些事项需要配置以确保在 Web 上获得良好的体验

  1. 配置链接

    配置链接允许 React Navigation 与浏览器的 URL 栏集成。这对于 Web 应用为每个屏幕设置正确的 URL 至关重要。

  2. 使用 Button 或 Link 组件

    你可能熟悉使用 navigation.navigate 在屏幕之间导航。但在支持 Web 时,重要的是要避免使用它。相反,使用 LinkButton 组件在屏幕之间导航。这确保了渲染一个锚标记,从而在 Web 上提供预期的行为。

  3. 服务端渲染

    目前,React Navigation 在完全客户端渲染的应用中效果最佳。但是,也提供了最基本的服务端渲染支持。因此,你可以选择性地服务端渲染你的应用。

注意

在 React Navigation 4 中,需要安装一个名为 @react-navigation/web 的单独包才能使用 Web 集成。在最近版本的 React Navigation 中,不再需要此包。如果你已安装它,请确保卸载它以避免冲突。

懒加载屏幕

默认情况下,屏幕组件捆绑在主 bundle 中。如果你有很多屏幕,这可能会导致 bundle 尺寸过大。在 Web 上保持 bundle 尺寸较小对于更快的加载时间非常重要。

为了减小 bundle 尺寸,你可以将 dynamic import()React.lazy 结合使用来懒加载屏幕

import { Suspense, lazy } from 'react';

const MyStack = createNativeStackNavigator({
screenLayout: ({ children }) => (
<Suspense fallback={<Loading />}>{children}</Suspense>
),
screens: {
Home: {
component: lazy(() => import('./HomeScreen')),
},
Profile: {
component: lazy(() => import('./ProfileScreen')),
},
},
});
Snack 上尝试

这将把屏幕组件拆分成单独的代码块(取决于你的 bundler),这些代码块会在屏幕渲染时按需加载。这可以显著减小初始 bundle 尺寸。

此外,你可以使用 screenLayout 将你的屏幕包裹在 <Suspense> 边界中。suspense fallback 可用于显示加载指示器,并在屏幕组件加载时显示。

Web 特有行为

与原生平台相比,某些导航器在 Web 上具有不同的行为

  1. 原生栈导航器

    原生栈导航器使用平台的原生组件来处理原生平台上的动画和手势。但是,Web 上不支持动画和手势。

  2. 栈导航器

    栈导航器使用 react-native-gesture-handler 来处理原生平台上的滑动 gestures。但是,Web 上不支持手势。

    此外,Web 上默认禁用屏幕过渡动画。你可以在导航器的选项中设置 animationEnabled: true 来启用它们。

  3. 抽屉导航器

    抽屉导航器使用 react-native-gesture-handler 来处理滑动 gestures,并使用 react-native-reanimated 来处理原生平台上的动画。但是,Web 上不支持手势,动画使用 CSS 过渡来处理。

此外,导航器在 Web 上尽可能渲染超链接,例如在抽屉侧边栏、标签栏、栈导航器的返回按钮等中。

由于 react-native-gesture-handlerreact-native-reanimated 未在 Web 上使用,因此除非你的组件需要它们,否则请避免在自己的代码中导入它们以减小 bundle 尺寸。你可以为特定于原生平台的代码使用 .native.js.native.ts 扩展名。

配置托管服务提供商

React Navigation 专为单页应用程序 (SPA) 设计。这通常意味着 index.html 文件需要为所有路由提供服务。

在开发过程中,诸如 Webpack 或 Metro 之类的 bundler 会自动处理此问题。但是,在部署站点时,你可能需要配置重定向以确保为所有路由提供 index.html 文件,以避免 404 错误。

以下是一些流行托管服务提供商的说明

Netlify

要在 Netlify 上处理重定向,请在项目根目录的 netlify.toml 文件中添加以下内容

[[redirects]]
from = "/*"
to = "/index.html"
status = 200

Vercel

要在 Vercel 上处理重定向,请在项目根目录的 vercel.json 文件中添加以下内容

{
"rewrites": [{ "source": "/(.*)", "destination": "/index.html" }]
}

GitHub Pages

GitHub Pages 不支持 SPA 的此类重定向配置。有几种方法可以解决这个问题

  • 将你的 index.html 重命名为 404.html。这将为所有路由提供 404.html 文件。但是,这将导致所有路由都返回 404 状态代码。因此,这对 SEO 来说并不理想。
  • 编写一个脚本,将 index.html 文件复制到构建输出中的所有路由。例如,如果你的应用具有路由 //about/contact,你可以将 index.html 文件复制到 about.htmlcontact.html