Skip to main content
Version: 7.x

Web 上的 React 导航

React Navigation 内置了对 Web 平台的支持。这允许你在 React Native 应用和 Web 上使用相同的导航逻辑。导航器需要使用 面向 Web 的 React Native 才能在网络上工作。

¥React Navigation has built-in support for the Web platform. This allows you to use the same navigation logic in your React Native app as well as on the web. The navigators require using React Native for Web to work on the web.

先决条件

¥Pre-requisites

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

¥While Web support works out of the box, there are some things to configure to ensure a good experience on the web:

  1. 配置链接

    ¥Configure linking

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

    ¥Configuring linking allows React Navigation to integrate with the browser's URL bar. This is crucial for web apps to have proper URLs for each screen.

  2. 使用按钮或链接组件

    ¥Use Button or Link components

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

    ¥You may be familiar with using navigation.navigate to navigate between screens. But it's important to avoid using it when supporting the web. Instead, use the Link or Button components to navigate between screens. This ensures that an anchor tag is rendered which provides the expected behavior on the web.

  3. 服务端渲染

    ¥Server rendering

    目前,React Navigation 最适合完全客户端渲染的应用。但是,服务器端渲染支持最少。因此,你可以选择服务器渲染你的应用。

    ¥Currently, React Navigation works best with fully client-side rendered apps. However, minimal server-side rendering support is available. So you can optionally choose to server render your app.

注意

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

¥In React Navigation 4, it was necessary to install a separate package called @react-navigation/web to use web integration. This package is no longer needed in recent versions of React Navigation. If you have it installed, make sure to uninstall it to avoid conflicts.

延迟加载屏幕

¥Lazy loading screens

默认情况下,屏幕组件打包在主包中。如果你有许多屏幕,这可能会导致较大的打包包大小。为了加快加载时间,重要的是在网络上保持较小的包大小。

¥By default, screen components are bundled in the main bundle. This can lead to a large bundle size if you have many screens. It's important to keep the bundle size small on the web for faster loading times.

要减小包大小,你可以将 动态 import()React.lazy 一起使用以延迟加载屏幕:

¥To reduce the bundle size, you can use dynamic import() with React.lazy to lazy load screens:

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')),
},
},
});
Try on Snack

这会将屏幕组件拆分为单独的块(取决于你的打包器),这些块在渲染屏幕时按需加载。这可以显著减少初始打包包大小。

¥This will split the screen components into separate chunks (depending on your bundler) which are loaded on-demand when the screen is rendered. This can significantly reduce the initial bundle size.

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

¥In addition, you can use the screenLayout to wrap your screens in a <Suspense> boundary. The suspense fallback can be used to show a loading indicator and will be shown while the screen component is being loaded.

特定于 Web 的行为

¥Web-specific behavior

与原生平台相比,某些导航器在网络上的行为有所不同:

¥Some of the navigators have different behavior on the web compared to native platforms:

  1. 原生堆栈导航器

    ¥Native Stack Navigator

    Native Stack Navigator 使用平台的原语来处理原生平台上的动画和手势。但是,Web 不支持动画和手势。

    ¥Native Stack Navigator uses the platform's primitives to handle animations and gestures on native platforms. However, animations and gestures are not supported on the web.

  2. 堆栈导航器

    ¥Stack Navigator

    Stack Navigator 使用 react-native-gesture-handler 处理原生平台上的滑动手势。但是,Web 不支持手势。

    ¥Stack Navigator uses react-native-gesture-handler to handle swipe gestures on native platforms. However, gestures are not supported on the web.

    此外,默认情况下,Web 上的屏幕转换是禁用的。你可以通过在导航器的选项中设置 animationEnabled: true 来启用它们。

    ¥In addition, screen transitions are disabled by default on the web. You can enable them by setting animationEnabled: true in the navigator's options.

  3. 抽屉导航器

    ¥Drawer Navigator

    Drawer Navigator 使用 react-native-gesture-handler 处理滑动手势,使用 react-native-reanimated 处理原生平台上的动画。但是,Web 不支持手势,动画使用 CSS 过渡处理。

    ¥Drawer Navigator uses react-native-gesture-handler to handle swipe gestures and react-native-reanimated for animations on native platforms. However, gestures are not supported on the web, and animations are handled using CSS transitions.

此外,导航器在可能的情况下在 Web 上渲染超链接,例如在抽屉侧边栏、标签栏、堆栈导航器的后退按钮等。

¥In addition, navigators render hyperlinks on the web when possible, such as in the drawer sidebar, tab bar, stack navigator's back button, etc.

由于 react-native-gesture-handlerreact-native-reanimated 未在 Web 上使用,请避免在你自己的代码中导入它们以减少包大小,除非你的组件需要它们。你可以将 .native.js.native.ts 扩展用于特定于原生平台的代码。

¥Since react-native-gesture-handler and react-native-reanimated are not used on the web, avoid importing them in your own code to reduce the bundle size unless you need them for your components. You can use .native.js or .native.ts extensions for code specific to native platforms.

配置托管提供商

¥Configuring hosting providers

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

¥React Navigation is designed for Single Page Applications (SPAs). This usually means that the index.html file needs to be served for all routes.

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

¥During development, the bundler such as Webpack or Metro automatically handles this. However, when deploying the site, you may need to configure redirects to ensure that the index.html file is served for all routes to avoid 404 errors.

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

¥Here are instructions for some of the popular hosting providers:

Netlify

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

¥To handle redirects on Netlify, add the following in the netlify.toml file at the root of your project:

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

Vercel

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

¥To handle redirects on Vercel, add the following in the vercel.json file at the root of your project:

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

GitHub 页面

¥GitHub Pages

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

¥GitHub Pages doesn't support such redirection configuration for SPAs. There are a couple of ways to work around this:

  • 将你的 index.html 重命名为 404.html。这将为所有路由提供 404.html 文件。但是,这将导致所有路由都返回 404 状态代码。因此它不适合 SEO。

    ¥Rename your index.html to 404.html. This will serve the 404.html file for all routes. However, this will cause a 404 status code to be returned for all routes. So it's not ideal for SEO.

  • 编写一个脚本,将 index.html 文件复制到构建输出中的所有路由。例如,如果你的应用有路由 //about/contact,你可以将 index.html 文件复制到 about.htmlcontact.html

    ¥Write a script that copies the index.html file to all routes in the build output. For example, if your app has routes /, /about, and /contact, you can copy the index.html file to about.html and contact.html.