基于文件路由的核心概念
了解 Expo Router 的基本规则以及它与其他代码的关系。
在深入研究如何使用 Expo Router 构建应用的导航树之前,让我们首先了解构成 Expo Router 中基于文件路由基础的核心概念,以及 Expo Router 项目在结构上与其他 React Native 项目有何不同。
¥Before diving into how to construct your app's navigation tree with Expo Router, let's first understand the core concepts that make up the foundation of file-based routing in Expo Router, and how an Expo Router project might differ in structure from other React Native projects.
Expo Router 规则
¥The rules of Expo Router
1. 所有屏幕/页面都是应用目录中的文件
¥ All screens/pages are files inside of app directory
应用中的所有导航路由均由应用目录中的文件和子目录定义。app 目录下的每个文件都有一个默认导出,用于定义应用中的不同页面(特殊的 _layout 文件除外)。
¥All navigation routes in your app are defined by the files and sub-directories inside the app directory. Every file inside the app directory has a default export that defines a distinct page in your app (except for the special _layout files).
因此,应用内的目录将相关屏幕组合在一起定义为堆栈、选项卡或其他排列方式。
¥Accordingly, directories inside app define groups of related screens together as stacks, tabs, or in other arrangements.
2. 所有页面都有一个 URL
¥ All pages have a URL
所有页面的 URL 路径都与应用目录中文件的位置匹配,可用于在网页地址栏中导航到该页面,或在原生移动应用中用作特定于应用的深层链接。这就是 Expo Router 支持 "通用深度链接" 的含义。无论使用哪个平台,都可以通过 URL 导航到应用中的所有页面。
¥All pages have a URL path that matches the file's location in the app directory, which can be used to navigate to that page in the address bar on the web, or as an app-specific deep link in a native mobile app. This is what is meant by Expo Router supporting "universal deep-linking". All pages in your app can be navigated to with a URL, regardless of the platform.
3. 第一个 index.tsx 是初始路由
¥ First index.tsx is the initial route
使用 Expo Router,你无需在代码中定义初始路由或首屏。相反,当你打开应用时,Expo Router 会查找第一个与 /
URL 匹配的 index.tsx 文件。这可以是 app/index.tsx 文件,但并非必须如此。如果用户默认从导航树的更深层位置启动,你可以使用 路由组(名称用括号括起来的目录),这将不计入 URL 的一部分。如果你希望第一个屏幕是一组标签页,你可以将所有标签页放在 app/(tabs) 目录中,并将默认标签页定义为 index.tsx。通过这种安排,/
URL 会将用户直接带到 app/(tabs)/index.tsx 文件。
¥With Expo Router, you do not define an initial route or first screen in code. Rather, when you open your app, Expo Router will look for the first index.tsx file matching the /
URL. This could be an app/index.tsx file, but it doesn't have to be. If the user should start by default in a deeper part of your navigation tree, you can use a route group (a directory where the name is surrounded in parenthesis), and that will not count as part of the URL. If you want your first screen to be a group of tabs, you might put all of the tab pages inside the app/(tabs) directory and define the default tab as index.tsx. With this arrangement, the /
URL will take the user directly to app/(tabs)/index.tsx file.
4. 根 _layout.tsx 替换 App.jsx/tsx
¥ Root _layout.tsx replaces App.jsx/tsx
每个项目都应该在 app 目录中直接包含一个 _layout.tsx 文件。此文件会在应用中的任何其他路由之前渲染,你可以在此处放置之前可能已在 App.jsx 文件中定义的初始化代码,例如加载字体或与启动画面交互。
¥Every project should have a _layout.tsx file directly inside the app directory. This file is rendered before any other route in your app and is where you would put the initialization code that may have previously gone inside an App.jsx file, such as loading fonts or interacting with the splash screen.
5. 非导航组件位于应用目录之外
¥ Non-navigation components live outside of app directory
在 Expo Router 中,app 目录专门用于定义应用的路由。应用的其他部分,例如组件、钩子、实用程序等,应放置在其他顶层目录中。如果你将非路由内容放在应用目录中,Expo Router 将尝试将其视为路由。
¥In Expo Router, the app directory is exclusively for defining your app's routes. Other parts of your app, like components, hooks, utilities, and so on, should be placed in other top-level directories. If you put a non-route inside of the app directory, Expo Router will attempt to treat it like a route.
或者,你可以创建一个 顶层 src 目录 文件,并将路由放在 src/app 目录中,将非路由组件放在 src/components、src/utils 等文件夹中。这是 Expo Router 唯一能识别的其他目录结构。
¥Alternatively, you can create a top-level src directory and put your routes inside the src/app directory, with non-route components going in folders like src/components, src/utils, and so on. This is the only other directory structure that Expo Router will recognize.
6. 底层仍然是 React Navigation
¥ It's still React Navigation under the hood
虽然这听起来与 React Navigation 有很大不同,但 Expo Router 实际上是建立在 React Navigation 之上的。你可以将 Expo Router 视为 Expo CLI 的优化,它将你的文件结构转换为你之前在代码中定义的 React Navigation 组件。
¥While this may sound quite a bit different from React Navigation, Expo Router is actually built on top of React Navigation. You can think of Expo Router as an Expo CLI optimization that translates your file structure into React Navigation components that you previously defined in your own code.
这也意味着你可以经常参考 React Navigation 文档来了解如何设置或配置导航,因为默认的堆栈导航器和标签导航器使用完全相同的选项。
¥This also means that you can often refer to React Navigation documentation for how to style or configure navigation, as the default stack and tab navigators use the exact same options.
Expo Router 规则的应用
¥The rules of Expo Router applied
让我们运用 Expo Router 的基本规则来快速识别以下项目文件结构的关键元素:
¥Let's apply these foundational rules of Expo Router to quickly identify key elements of the following project file structure:
app
index.tsx
home.tsx
_layout.tsx
profile
friends.tsx
components
TextField.tsx
Toolbar.tsx
-
app/index.tsx 是初始路由,当你打开应用或导航到 Web 应用的根 URL 时,它将首先显示。
¥app/index.tsx is the initial route, and will appear first when you open the app or navigate to your web app's root URL.
-
app/home.tsx 是一个包含路由
/home
的页面,因此你可以在浏览器中使用类似yourapp.com/home
的 URL 导航到该页面,在原生应用中使用myapp://home
的 URL 导航到该页面。¥app/home.tsx is a page with the route
/home
, so you can navigate to it with a URL likeyourapp.com/home
in the browser, ormyapp://home
in a native app. -
app/_layout.tsx 是根布局。你之前在 App.jsx 中编写的任何初始化代码都应在此处放置。
¥app/_layout.tsx is the root layout. Any initialization code you may have previously put in App.jsx should go here.
-
app/profile/friends.tsx 是一个包含路由
/profile/friends
的页面。¥app/profile/friends.tsx is a page with the route
/profile/friends
. -
TextField.tsx 和 Toolbar.tsx 不在应用目录中,因此它们不会被视为页面。它们没有 URL,也不能成为导航操作的目标。但是,它们可以用作应用目录内页面中的组件。
¥TextField.tsx and Toolbar.tsx are not in the app directory, so they will not be considered pages. They will not have a URL, and they cannot be the target of a navigation action. However, they can be used as components in the pages inside of the app directory.