了解如何创建链接以在页面之间移动。
Expo Router 使用 "links" 在应用的页面之间移动。这在概念上类似于网络如何使用 <a>
标签和 href
属性。
¥Expo Router uses "links" to move between pages in the app. This is conceptually similar to how the web works with <a>
tags and the href
attribute.
app
index.tsx
about.tsx
user
[id].tsx
在以下示例中,有两个导航到不同路由的 <Link />
组件。
¥In the following example, there are two <Link />
components which navigate to different routes.
import { View } from 'react-native';
import { Link } from 'expo-router';
export default function Page() {
return (
<View>
<Link href="/about">About</Link>
{/* ...other links */}
<Link href="/user/bacon">View user</Link>
</View>
);
}
¥Buttons
默认情况下,Link 组件将子组件封装在 <Text>
组件中,这对于可访问性很有用,但并不总是需要的。你可以通过传递 asChild
属性来自定义组件,这会将所有属性转发到 Link
组件的第一个子组件。子组件必须支持 onPress
和 onClick
属性,href
和 role
也会被传递下去。
¥The Link component wraps the children in a <Text>
component by default, this is useful for accessibility but not always desired. You can customize the component by passing the asChild
prop, which will forward all props to the first child of the Link
component. The child component must support the onPress
and onClick
props, href
and role
will also be passed down.
import { Pressable, Text } from 'react-native';
import { Link } from 'expo-router';
export default function Page() {
return (
<Link href="/other" asChild>
<Pressable>
<Text>Home</Text>
</Pressable>
</Link>
);
}
¥Understanding native navigation
Expo Router 使用基于堆栈的导航方法。你导航到的每条新路由都会添加到堆栈中。如果你导航到堆栈中已有的路由,则堆栈将展开回该现有路由。
¥Expo Router uses a stack-based navigation approach. Each new route you navigate to gets added to a stack. If you navigate to a route already in the stack, the stack unwinds back to that existing route.
例如,当你从 /feed
导航到 /profile
时,堆栈包含 /feed
和 /profile
。如果你随后导航到 /settings
,堆栈将包含 /feed
、/profile
和 /settings
。如果你随后导航回 /feed
,堆栈将回退至 /feed
。
¥For example, when you navigate from /feed
to /profile
, the stack contains /feed
and /profile
. If you then navigate to /settings
, the stack contains /feed
, /profile
, and /settings
. If you then navigate back to /feed
, the stack unwinds back to /feed
.
要导航到不展开堆栈的路由,你可以在 <Link>
组件上使用 push
属性。这总是将路由推入堆栈,即使它已经存在。
¥To navigate to a route without the stack unwinding, you can use the push
prop on the <Link>
component. This always pushes the route onto the stack, even if it already exists.
相比之下,replace
方法将导航堆栈中的当前路由替换为新路由,从而有效地用新路由替换当前屏幕,而不添加到堆栈中。
¥In contrast, the replace
method substitutes the current route in the navigation stack with a new one, effectively replacing the current screen with the new one without adding to the stack.
要进行导航,你可以提供完整路径 (/profile/settings
)、相对路径 (../settings
) 或通过传递对象 ({ pathname: 'profile', params: { id: '123' } }
)。
¥To navigate, you can provide a full path (/profile/settings
), a relative path (../settings
), or by passing an object ({ pathname: 'profile', params: { id: '123' } }
).
名称 | 描述 |
---|---|
navigate | 在导航状态下导航至最近的路由。如果新路由不同(不包括搜索参数或哈希),navigate 仅推送新屏幕。否则,当前屏幕将使用新参数重新渲染。如果你导航到历史记录中的路由,堆栈将关闭该路由的屏幕。 |
push | 始终推送新路由,并且从不弹出或替换现有路由。你可以多次推送当前路由或使用新参数。 |
replace | 从历史记录中删除当前路由并将其替换为指定的 URL。这对于重定向很有用。 |
¥Relative navigation
relativeToDirectory
将在expo-router
的下一个版本中发布。
相对 URL 是带有 ./
的 URL 前缀,例如 ./article
或 ./article/
。相对 URL 是相对于当前渲染的屏幕解析的。
¥A relative URL is a URL prefix with ./
, such as ./article
, or ./article/
. Relative URLs are resolved relative to the current rendered screen.
当前屏幕的 URL 是文档 URL(没有尾部斜杠的 URL),因此相对 URL 将相对于目录进行解析。当当前屏幕由 index
文件渲染时,这可能会造成混淆,因为相对 URL 是从 URL 的目录而不是文件系统解析的。通过使用 relativeToDirectory
选项,Expo Router 将把当前 URL 视为目录 URL。
¥The URL of the current screen is a document URL (a URL without a trailing slash), so relative URLs will be resolved relative to the directory. This can be confusing when the current screen is rendered by an index
file as the relative URL is resolved from the URL's directory, not the file system. By using the relativeToDirectory
option, Expo Router will instead treat the current URL as a directory URL.
Href | 当前 URL | relativeToDirectory | 结果 |
---|---|---|---|
./article | /route/v1 | /route/article | |
./article | /route/v1 | true | /route/v1/article |
../article | /route/v1 | /article | |
../article | /route/v1 | true | /route/article |
// Using `relativeToDirectory` with Link
<Link href="./article" relativeToDirectory>Go to article</Link>
// Using `relativeToDirectory` with the imperative API
router.push("./article", { relativeToDirectory: true })
router.navigate("./article", { relativeToDirectory: true })
router.replace("./article", { relativeToDirectory: true })
不支持不带./
前缀的相对 URL,例如article
。
¥Linking to dynamic routes
动态路由和查询参数可以静态提供,也可以使用方便的 Href 对象提供。
¥Dynamic routes and query parameters can be provided statically or with the convenience Href object.
import { Link } from 'expo-router';
import { View } from 'react-native';
export default function Page() {
return (
<View>
<Link
href={{
pathname: '/user/[id]',
params: { id: 'bacon' }
}}>
View user
</Link>
</View>
);
}
¥Pushing screens
默认情况下,通过推送新路由或展开到现有路由,将 navigate
链接到导航堆栈中最近的路由。你可以使用 push
属性始终将路由推入堆栈。
¥By default, links navigate
to the nearest route in the navigation stack, either by pushing a new route or unwinding to an existing route. You can use the push
prop to always push the route onto the stack.
import { Link } from 'expo-router';
export default function Page() {
return (
<View>
<Link push href="/feed">Login</Link>
</View>
);
}
¥Replacing screens
默认情况下,将 "push" 路由链接到导航堆栈。它遵循与 navigation.navigate()
相同的规则。这意味着当用户返回时,上一个屏幕将可用。你可以使用 replace
属性替换当前屏幕,而不是推送新屏幕。
¥By default, links "push" routes onto the navigation stack. It follows the same rules as navigation.navigate()
. This means that the previous screen will be available when the user navigates back. You can use the replace
prop to replace the current screen instead of pushing a new one.
import { Link } from 'expo-router';
export default function Page() {
return (
<View>
<Link replace href="/feed">Login</Link>
</View>
);
}
使用 router.replace()
强制替换当前屏幕。
¥Use router.replace()
to replace the current screen imperatively.
原生导航并不总是支持 replace
。例如在 X 上,你无法直接从配置文件 "replace" 到推文,这是因为 UI 需要一个后退按钮才能返回到提要或其他顶层选项卡屏幕。在这种情况下,替换将切换到提要选项卡,并将推文路由推到其顶部,或者如果你在提要选项卡内的其他推文上,它将用新推文替换当前推文。通过使用 unstable_settings
,可以在 Expo Router 中获得这种确切的行为。
¥Native navigation does not always support replace
. For example on X, you wouldn't be able to "replace" directly from a profile to a tweet, this is because the UI requires a back button to return to the feed or other top-level tab screen. In this case, replace would switch to the feed tab, and push the tweet route on top of it, or if you were on a different tweet inside the feed tab, it would replace the current tweet with the new tweet. This exact behavior can be obtained in Expo Router by using unstable_settings
.
¥Imperative navigation
你还可以使用 router
对象进行命令式导航。当你需要在 React 组件之外执行导航操作时(例如在事件处理程序或实用程序函数中),这很有用。
¥You can also navigate imperatively using the router
object. This is useful when you need to perform a navigation action outside a React component, such as in an event handler or a utility function.
import { router } from 'expo-router';
export function logout() {
router.replace('/login');
}
router
对象是不可变的,包含以下函数:
¥The router
object is immutable and contains the following functions:
导航:(href: Href) => void
。执行 navigate
操作。
¥navigate: (href: Href) => void
. Perform a navigate
action.
推:(href: Href) => void
。执行 push
操作。
¥push: (href: Href) => void
. Perform a push
action.
代替:(href: Href) => void
。执行 replace
操作。
¥replace: (href: Href) => void
. Perform a replace
action.
后退:() => void
。导航回之前的路由。
¥back: () => void
. Navigate back to previous route.
可以返回:() => boolean
如果存在有效的历史堆栈并且 back()
函数可以弹出,则返回 true
。
¥canGoBack: () => boolean
Returns true
if a valid history stack exists and the back()
function can pop back.
设置参数:(params: Record<string, string>) => void
更新当前所选路由的查询参数。
¥setParams: (params: Record<string, string>) => void
Update the query params for the currently selected route.
¥Autocomplete
Expo Router 可以自动为应用中的所有路由生成静态 TypeScript 类型。这允许你对 href
使用自动补齐功能,并在使用无效链接时收到警告。了解更多:静态类型路由。
¥Expo Router can automatically generate static TypeScript types for all routes in your app. This allows you to use autocomplete for href
s and get warnings when invalid links are used. Learn more: Statically Typed Routes.
¥Web behavior
Expo Router 在网络上运行时支持标准 <a>
元素,但这将执行全页服务器导航。这比较慢并且没有充分利用 React。相反,Expo Router <Link>
组件将执行客户端导航,这将保留网站的状态并更快地导航。
¥Expo Router supports the standard <a>
element when running on web, however this will perform a full-page server-navigation. This is slower and doesn't take full advantage of React. Instead, the Expo Router <Link>
component will perform client-side navigation, which will preserve the state of the website and navigate faster.
还支持仅 Web 属性 target
、rel
和 download
。当在网络上运行时,这些将被传递到 <a>
元素。
¥The web-only attributes target
, rel
, and download
are also supported. These will be passed to the <a>
element when running on web.
客户端导航适用于单页应用和 静态渲染。
¥Client-side navigation works with both single-page apps, and static rendering.
¥Usage in simulators
请参阅 测试网址 指南,了解如何在 Android 模拟器和 iOS 模拟器中模拟深层链接。
¥See the testing URLs guide to learn how you can emulate deep links in Android Emulators and iOS Simulators.