从 6.x 升级
React Navigation 7 专注于简化 API 以避免可能导致错误的模式。这意味着弃用一些出于向后兼容原因而保留的遗留行为。
¥React Navigation 7 focuses on streamlining the API to avoid patterns that can cause bugs. This means deprecating some of the legacy behavior kept for backward compatibility reasons.
本指南列出了从 React Navigation 6 升级时需要注意的 React Navigation 7 中的所有重大更改和新功能。
¥This guides lists all the breaking changes and new features in React Navigation 7 that you need to be aware of when upgrading from React Navigation 6.
最低要求
¥Minimum Requirements
-
react-native
>= 0.72.0 -
expo
>= 52(如果你使用 Expo Go)¥
expo
>= 52 (if you use Expo Go) -
typescript
>= 5.0.0(如果你使用 TypeScript)¥
typescript
>= 5.0.0 (if you use TypeScript)
重大变化
¥Breaking changes
对 navigate
操作的更改
¥Changes to the navigate
action
navigate
方法不再在嵌套子导航器中导航到屏幕
¥The navigate
method no longer navigates to screen in a nested child navigator
由于向后兼容性的原因,React Navigation 5 和 6 支持使用 navigation.navigate(ScreenName)
语法导航到嵌套子导航器中的屏幕。但这是有问题的:
¥Due to backward compatibility reasons, React Navigation 5 and 6 support navigating to a screen in a nested child navigator with navigation.navigate(ScreenName)
syntax. But this is problematic:
-
它仅在导航器已安装时才有效 - 使导航与其他逻辑耦合。
¥It only works if the navigator is already mounted - making navigation coupled to other logic.
-
它不适用于 TypeScript 类型。
¥It doesn't work with the TypeScript types.
由于这些问题,我们有一个特殊的 API 来导航到嵌套屏幕(navigation.navigate(ParentScreenName, { screen: ScreenName })
)。
¥Due to these issues, we have a special API to navigate to a nested screen (navigation.navigate(ParentScreenName, { screen: ScreenName })
).
从这些版本开始,这不再是默认行为。如果你在应用中依赖此行为,你可以将 navigationInChildEnabled
属性传递给 NavigationContainer
以保持该行为,直到你能够迁移:
¥From these release, this is no longer the default behavior. If you're relying on this behavior in your app, you can pass the navigationInChildEnabled
prop to NavigationContainer
to keep the behavior until you are able to migrate:
<NavigationContainer navigationInChildEnabled>{/* ... */}</NavigationContainer>
navigationInChildEnabled
prop 将在下一个主要版本中被删除。
¥The navigationInChildEnabled
prop will be removed in the next major.
有关更新用法,请参阅 navigate
。
¥See navigate
for updated usage.
navigate
方法不再返回,改用 popTo
¥The navigate
method no longer goes back, use popTo
instead
以前,如果屏幕已存在于堆栈中,则 navigate
方法会向后导航。我们看到很多人对这种行为感到困惑。
¥Previously, navigate
method navigated back if the screen already exists in the stack. We have seen many people get confused by this behavior.
为了避免这种混淆,我们从 navigate
中删除了返回行为,并添加了 新方法 popTo
以明确返回堆栈中的特定屏幕:
¥To avoid this confusion, we have removed the going back behavior from navigate
and added a new method popTo
to explicitly go back to a specific screen in the stack:
navigation.navigate('PreviousScreen', { foo: 42 });
navigation.popTo('PreviousScreen', { foo: 42 });
方法现在的行为如下:
¥The methods now behave as follows:
-
如果屏幕已经聚焦,则
navigate(screenName)
将停留在当前屏幕上,否则将新屏幕推送到堆栈中。¥
navigate(screenName)
will stay on the current screen if the screen is already focused, otherwise push a new screen to the stack. -
如果屏幕存在于堆栈中,则返回屏幕,否则弹出当前屏幕并将此屏幕添加到堆栈中。
¥
popTo(screenName)
will go back to the screen if it exists in the stack, otherwise pop the current screen and add this screen to the stack.
详细信息请参见 popTo
。
¥See popTo
for more details.
要实现与之前 navigate
类似的行为,你可以使用 getId
prop,在这种情况下,它将转到具有匹配 ID 的屏幕并相应地推送或弹出屏幕。
¥To achieve a behavior similar to before with navigate
, you can use the getId
prop in which case it'll go to the screen with the matching ID and push or pop screens accordingly.
为了帮助迁移,我们添加了一个名为 navigateDeprecated
的新方法,其行为与旧 navigate
方法类似。你可以用 navigateDeprecated
替换当前的 navigate
调用以逐步迁移到新行为:
¥To help with the migration, we have added a new method called navigateDeprecated
which will behave like the old navigate
method. You can replace your current navigate
calls with navigateDeprecated
to gradually migrate to the new behavior:
navigation.navigate('SomeScreen');
navigation.navigateDeprecated('SomeScreen');
navigateDeprecated
方法将在下一个主要版本中被删除。
¥The navigateDeprecated
method will be removed in the next major.
navigate
方法不再接受 key
选项
¥The navigate
method no longer accepts a key
option
以前,你可以指定要导航到的 key
路由,例如:
¥Previously, you could specify a route key
to navigate to, e.g.:
navigation.navigate({ key: 'someuniquekey' })`
这是有问题的,因为:
¥It's problematic since:
-
key
是一个内部实现细节,由库内部创建 - 这使其使用起来很奇怪。¥
key
is an internal implementation detail and created by the library internally - which makes it weird to use. -
其他任何操作都不支持此类用法。
¥None of the other actions support such usage.
-
指定
key
不是类型安全的,很容易导致错误。¥Specifying a
key
is not type-safe, making it easy to cause bugs.
在 React Navigation 5 中,我们添加了 getId
prop,可用于类似的用例 - 并给予用户完全控制权,因为他们提供 ID,并且它不是由库自动生成的。
¥In React Navigation 5, we added the getId
prop which can be used for similar use cases - and gives users full control since they provide the ID and it's not autogenerated by the
library.
因此,key
选项现在已从 navigate
操作中删除。
¥So the key
option is now being removed from the navigate
action.
有关更新用法,请参阅 navigate
。
¥See navigate
for updated usage.
对 NavigationContainer
的更改
¥Changes to NavigationContainer
NavigationContainer
上的 onReady
回调现在仅在渲染导航器时触发
¥The onReady
callback on NavigationContainer
now fires only when there are navigators rendered
以前,onReady
prop 和 navigationRef.isReady()
的工作方式略有不同:
¥Previously, the onReady
prop and navigationRef.isReady()
worked slightly differently:
-
当
NavigationContainer
完成安装并解析深层链接时,会触发onReady
回调。¥The
onReady
callback fired whenNavigationContainer
finishes mounting and deep links is resolved. -
navigationRef.isReady()
方法还检查是否有任何导航器已渲染 - 如果用户在NavigationContainer
内有条件地渲染导航器,则情况可能并非如此。¥The
navigationRef.isReady()
method additionally checks if there are any navigators rendered - which may not be true if the user is rendering their navigators conditionally inside aNavigationContainer
.
了解这一点很重要,因为如果没有渲染导航器,我们就无法分派任何导航操作,因为没有导航器来处理它们。但 onReady
和 navigationRef.isReady()
之间的不一致很容易引起问题和混淆。
¥This is important to know since if no navigator is rendered, we can't dispatch any navigation actions as there's no navigator to handle them. But the inconsistency between onReady
and navigationRef.isReady()
made it easy to cause issues and confusion.
这将 onReady
更改为与 navigationRef.isReady()
类似的工作方式。onReady
回调现在仅在渲染导航器时触发 - 反映 navigationRef.isReady()
的值。
¥This changes onReady
to work similar to navigationRef.isReady()
. The onReady
callback will now fire only when there are navigators rendered - reflecting the value of navigationRef.isReady()
.
此更改不会破坏大多数用户,因此你可能不需要执行任何操作。
¥This change is not breaking for most users, so you may not need to do anything.
有关用法,请参阅 onReady
。
¥See onReady
for usage.
NavigationContainer
上的 independent
属性已被删除,取而代之的是 NavigationIndependentTree
组件
¥The independent
prop on NavigationContainer
is removed in favor of NavigationIndependentTree
component
NavigationContainer
上的 independent
prop 被添加以支持在与应用其余部分不同的树中渲染导航器。这对于小程序等用例很有用。
¥The independent
prop on NavigationContainer
was added to support rendering navigators in a separate tree from the rest of the app. This is useful for use cases such as miniapps.
但是,这种方法存在问题:
¥However, there are issues with this approach:
-
当构建小程序时,添加此属性的责任在于小程序开发者,这并不理想,因为忘记它会导致问题。
¥When building a miniapp, the responsibility of adding this prop was on the miniapp developer, which isn't ideal since forgetting it can cause problems.
-
许多初学者错误地添加了这个 prop,并不明白为什么导航不起作用。
¥A lot of beginners mistakenly added this prop and were confused why navigation wasn't working.
因此,我们删除了这个 prop,而不是 NavigationIndependentTree
组件,你可以使用它来封装导航容器:
¥So we've removed this prop instead of a NavigationIndependentTree
component which you can use to wrap the navigation container:
<NavigationContainer independent>
{/* ... */}
</NavigationContainer>
<NavigationIndependentTree>
<NavigationContainer>
{/* ... */}
</NavigationContainer>
</NavigationIndependentTree>
这样,责任不再在于小应用开发者,而是在于父应用。初学者也很难意外添加它。
¥This way, the responsibility no longer lies on the miniapp developer, but on the parent app. It's also harder for beginners to accidentally add this.
有关用法,请参阅 独立导航容器。
¥See Independent navigation containers for usage.
theme
属性现在接受 fonts
属性
¥The theme
prop now accepts a fonts
property
以前,NavigationContainer
上的 theme
prop 接受 colors
属性来自定义 React Navigation 中各种 UI 元素使用的颜色。我们现在添加了一个 fonts
属性来自定义字体。如果你在 theme
属性中传递自定义主题,则需要更新它以包含 fonts
属性。
¥Previously, the theme
prop on NavigationContainer
accepted a colors
property to customize the colors used by various UI elements from React Navigation. We have now added a fonts
property to customize the fonts as well. If you are passing a custom theme in the theme
prop, you'll need to update it to include the fonts
property.
import { DefaultTheme } from '@react-navigation/native';
const theme = {
colors: {
// ...
},
fonts: DefaultTheme.fonts,
};
如果你想要自定义字体,请参阅 主题指南 了解更多详细信息。
¥If you want to customize the fonts, see the themes guide for more details.
对链接的更改
¥Changes to linking
路径位置中的参数编码现在更加宽松
¥Encoding of params in path position is now more relaxed
以前,在为屏幕生成链接(例如 Web 上的 URL)时,无论参数的位置如何(例如查询位置,如 ?user=jane
或路径位置,如 /users/jane
),参数始终使用 encodeURIComponent
进行 URL 编码。这使得在参数中使用特殊字符变得困难。
¥Previously, params were always URL encoded with encodeURIComponent
regardless of their position (e.g. query position such as ?user=jane
or path position such as /users/jane
) when generating a link for a screen (e.g. URL on the Web). This made it hard to use special characters in the params.
现在,只有查询位置的参数是 URL 编码的。对于路径位置中的参数,我们仅对路径位置中不允许的字符进行编码。
¥Now, only the params in the query position are URL encoded. For the params in the path position, we only encode the characters that are not allowed in the path position.
通过此更改,在路径中使用特殊字符(如 @
)会更容易。例如,要获得 profile/@username
之类的 URL,你可以在链接配置中使用以下内容:
¥With this change, it's easier to use special characters such as @
in the path. For example, to have a URL such as profile/@username
, you can use the following in the linking config:
const config = {
prefixes: ['https://mysite.com'],
config: {
screens: {
Profile: {
path: 'profile/:username',
parse: {
username: (username) => username.replace(/^@/, ''),
},
stringify: {
username: (username) => `@${username}`,
},
},
},
},
};
有关链接配置的用法,请参阅 配置链接。
¥See Configuring links for usage of the linking config.
Link
组件和 useLinkProps
钩子现在使用屏幕名称而不是路径
¥The Link
component and useLinkProps
hook now use screen names instead of paths
以前,Link
组件和 useLinkProps
钩子被设计为通过 to
prop 与路径字符串一起使用。但它有几个问题:
¥Previously, the Link
component and useLinkProps
hook were designed to work with path strings via the to
prop. But it had few issues:
-
路径字符串不是类型安全的,重构后很容易导致拼写错误和错误
¥The path strings are not type-safe, making it easy to cause typos and bugs after refactor
-
API 使得通过屏幕名称导航更加不方便,即使这是首选方法
¥The API made navigating via screen name more inconvenient, even if that's the preferred approach
现在,它们不再接受采用路径字符串的 to
属性,而是接受 screen
和 params
属性,以及可选的 href
属性来代替生成的路径:
¥Now, instead of the to
prop that took a path string, they now accept screen
and params
props, as well as an optional href
prop to use instead of the generated path:
<Link to="/details?foo=42">Go to Details</Link>
<Link screen="Details" params={{ foo: 42 }}>Go to Details</Link>
or
const props = useLinkProps({ to: '/details?foo=42' });
const props = useLinkProps({ screen: 'Details', params: { foo: 42 } });
通过此更改,如果你有 配置全局类型,则在使用 Link
组件时现在将具有完全的类型安全性。
¥With this change, you'd now have full type-safety when using the Link
component given that you have configured the global type.
有关用法,请参阅 Link
和 useLinkProps
。
¥See Link
and useLinkProps
for usage.
useLinkBuilder
钩子现在返回一个对象而不是一个函数
¥The useLinkBuilder
hooks now returns an object instead of a function
以前,useLinkBuilder
钩子返回一个函数来为屏幕构建 href
- 这主要用于构建自定义导航器。现在,它返回一个具有 buildHref
和 buildAction
方法的对象:
¥Previously, the useLinkBuilder
hooks returned a function to build a href
for a screen - which is primarily useful for building custom navigators. Now, it returns an object with buildHref
and buildAction
methods:
const { buildHref, buildAction } = useLinkBuilder();
const href = buildHref('Details', { foo: 42 }); // '/details?foo=42'
const action = buildAction('/details?foo=42'); // { type: 'NAVIGATE', payload: { name: 'Details', params: { foo: 42 } } }
buildHref
方法的作用与之前返回的函数相同。新的 buildAction
方法可用于从 href
字符串构建导航操作。
¥The buildHref
method acts the same as the previously returned function. The new buildAction
method can be used to build a navigation action from a href
string.
请注意,此钩子主要供自定义导航器使用,而不是终端用户使用。对于终端用户,Link
组件和 useLinkProps
是推荐的导航方式。
¥Note that this hook is intended to be primarily used by custom navigators and not by end users. For end users, the Link
component and useLinkProps
are the recommended way to navigate.
有关用法,请参阅 useLinkBuilder
。
¥See useLinkBuilder
for usage.
对导航器的更改
¥Changes to navigators
推到模态框顶部的屏幕现在在 Stack 和 Native Stack 导航器中显示为模态框
¥Screens pushed on top of modals are now shown as modals in the Stack and Native Stack navigators
以前,在 Stack 和 Native Stack 导航器中,推送到模态框顶部的屏幕显示为常规屏幕。这通常会导致 Stack Navigator 上的动画出现故障,并出现在 Native Stack Navigator 上的模式后面。如果用户从深层链接进入屏幕,这可能会特别令人困惑。
¥Previously, screens pushed on top of modals were shown as regular screens in the Stack and Native Stack navigators. This often caused glitchy animation on Stack Navigator and appeared behind the modal on Native Stack Navigator. This can be especially confusing if the user came to the screen from a deep link.
现在,推到模态框顶部的屏幕会自动显示为模态框,以避免这些问题。可以通过将 presentation
选项明确设置为 card
来禁用此行为:
¥Now, screens pushed on top of modals are automatically shown as modals to avoid these issues. This behavior can be disabled by explicitly setting the presentation
option to card
:
<Stack.Screen
name="MyModal"
component={MyModalScreen}
options={{
presentation: 'card',
}}
/>
¥See Stack Navigator and Native Stack Navigator docs for usage.
在 Stack 和 Native Stack 导航器中,headerBackTitleVisible
被删除,取而代之的是 headerBackButtonDisplayMode
¥headerBackTitleVisible
is removed in favor of headerBackButtonDisplayMode
in Stack and Native Stack navigators
以前,headerBackTitleVisible
可用于控制后退按钮标题是否显示在标题中。现在已将其删除,以支持提供更多灵活性的 headerBackButtonDisplayMode
。
¥Previously, headerBackTitleVisible
could be used to control whether the back button title is shown in the header. It's now removed in favor of headerBackButtonDisplayMode
which provides more flexibility.
可以通过将 headerBackButtonDisplayMode
设置为 default
和 minimal
来实现以前的行为,分别显示和隐藏后退按钮标题:
¥The previous behavior can be achieved by setting headerBackButtonDisplayMode
to default
and minimal
for showing and hiding the back button title respectively:
<Stack.Screen
name="Details"
component={DetailsScreen}
options={{
headerBackTitleVisible: false,
headerBackButtonDisplayMode: 'minimal',
}}
/>
在 Stack Navigator 中,animationEnabled
选项被删除,取而代之的是 animation
选项
¥animationEnabled
option is removed in favor of animation
option in Stack Navigator
以前,animationEnabled: false
用于禁用 Stack Navigator 中屏幕转换的动画。
¥Previously, animationEnabled: false
was used to disable the animation for the screen transition in Stack Navigator.
现在有一个新的 animation
属性来配置类似于 Native Stack 的动画。因此,你现在可以使用 animation: 'none'
来禁用动画:
¥There's now a new animation
prop to configure animations similar to the Native Stack. So you can now use animation: 'none'
to disable the animation instead:
<Stack.Screen
name="Details"
component={DetailsScreen}
options={{
animationEnabled: false,
animation: 'none',
}}
/>
有关用法,请参阅 Stack Navigator 动画。
¥See Stack Navigator animation for usage.
在 Native Stack Navigator 中,customAnimationOnGesture
被重命名为 animationMatchesGesture
¥customAnimationOnGesture
is renamed to animationMatchesGesture
in Native Stack Navigator
Native Stack Navigator 中的 customAnimationOnGesture
选项重命名为 animationMatchesGesture
,以更好地反映其用途。如果你在项目中使用 customAnimationOnGesture
,则可以将其重命名为 animationMatchesGesture
:
¥The customAnimationOnGesture
option in Native Stack Navigator is renamed to animationMatchesGesture
to better reflect its purpose. If you are using customAnimationOnGesture
in your project, you can rename it to animationMatchesGesture
:
<Stack.Navigator options={{ customAnimationOnGesture: true }}>
<Stack.Navigator options={{ animationMatchesGesture: true }}>
有关用法,请参阅 原生堆栈导航器。
¥See Native Stack Navigator for usage.
Native Stack 现在需要 react-native-screens
4
¥Native Stack now requires react-native-screens
4
@react-navigation/native-stack
现在需要 react-native-screens
4,使用早期版本时会中断。如果你在项目中使用 Native Stack Navigator,请确保将 react-native-screens
升级到版本 4。
¥@react-navigation/native-stack
now requires react-native-screens
4 and will break when using an earlier version. If you are using Native Stack Navigator in your project, make sure to upgrade react-native-screens
to version 4.
有关用法,请参阅 原生堆栈导航器。
¥See Native Stack Navigator for usage.
Material Top Tab Navigator 不再需要安装 react-native-tab-view
¥Material Top Tab Navigator no longer requires installing react-native-tab-view
以前,@react-navigation/material-top-tabs
需要在项目中安装 react-native-tab-view
作为依赖。我们现在已将此包移至 React Navigation monorepo,并能够协调发布,因此不再需要单独安装它。
¥Previously, @react-navigation/material-top-tabs
required installing react-native-tab-view
as a dependency in the project. We have now moved this package to the React Navigation monorepo and able to coordinate the releases together, so it's no longer necessary to install it separately.
如果你使用 @react-navigation/material-top-tabs
并且在项目中的其他任何地方都不使用 react-native-tab-view
,则可以在升级后将其从依赖中删除。
¥If you use @react-navigation/material-top-tabs
and don't use react-native-tab-view
anywhere else in your project, you can remove it from your dependencies after upgrading.
如果你出于某种原因需要强制执行特定版本的 react-native-tab-view
,我们建议使用 Yarn 分辨率 或 npm 覆盖 来执行此操作。
¥If you need to enforce a specific version of react-native-tab-view
for some reason, we recommend using Yarn resolutions or npm overrides to do so.
有关用法,请参阅 材质顶部选项卡导航器。
¥See Material Top Tab Navigator for usage.
在 Bottom Tab Navigator 和 Drawer Navigator 中,unmountOnBlur
选项已被删除,取而代之的是 popToTopOnBlur
¥The unmountOnBlur
option is removed in favor of popToTopOnBlur
in Bottom Tab Navigator and Drawer Navigator
在许多情况下,所需的行为是在失去焦点后返回嵌套在选项卡或抽屉导航器中的堆栈的第一个屏幕。以前,unmountOnBlur
选项用于实现此行为。但是,它存在一些问题:
¥In many cases, the desired behavior is to return to the first screen of the stack nested in a tab or drawer navigator after it's unfocused. Previously, the unmountOnBlur
option was used to achieve this behavior. However, it had some issues:
-
它破坏了堆栈中屏幕的本地状态。
¥It destroyed the local state of the screen in the stack.
-
在选项卡导航上重新安装嵌套导航器很慢。
¥It was slow to remount the nested navigator on tab navigation.
popToTopOnBlur
选项提供了一种替代方法 - 它会弹出嵌套堆栈上的屏幕以返回堆栈中的第一个屏幕,并且不会出现上述问题。
¥The popToTopOnBlur
option provides an alternative approach - it pops the screens on a nested stack to go back to the first screen in the stack and doesn't have the above issues.
¥See Bottom Tab Navigator and Drawer Navigator docs for usage.
仍然可以通过在屏幕中使用 useIsFocused 钩子来实现 unmountOnBlur
的旧行为:
¥It's still possible to achieve the old behavior of unmountOnBlur
by using the useIsFocused hook in the screen:
const isFocused = useIsFocused();
if (!isFocused) {
return null;
}
这也可以与新的 布局属性 结合使用,以在屏幕配置级别指定它。
¥This could also be combined with the new layout props to specify it at the screen configuration level.
在 Bottom Tab Navigator 和 Material Top Tab Navigator 中,tabBarTestID
选项已重命名为 tabBarButtonTestID
¥The tabBarTestID
option is renamed to tabBarButtonTestID
in Bottom Tab Navigator and Material Top Tab Navigator
@react-navigation/bottom-tabs
和 @react-navigation/material-top-tabs
中的 tabBarTestID
选项重命名为 tabBarButtonTestID
,以更好地反映其用途。如果你在项目中使用 tabBarTestID
,则可以将其重命名为 tabBarButtonTestID
:
¥The tabBarTestID
option in @react-navigation/bottom-tabs
and @react-navigation/material-top-tabs
is renamed to tabBarButtonTestID
to better reflect its purpose. If you are using tabBarTestID
in your project, you can rename it to tabBarButtonTestID
:
<Tab.Navigator tabBarOptions={{ tabBarTestID: 'test-id' }}>
<Tab.Navigator tabBarOptions={{ tabBarButtonTestID: 'test-id' }}>
有关用法,请参阅 底部选项卡导航器 和 材质顶部选项卡导航器 文档。
¥See Bottom Tab Navigator and Material Top Tab Navigator docs for usage.
从 Bottom Tab Navigator、Material Top Tab Navigator 和 Drawer Navigator 中移除 sceneContainerStyle
属性和选项,取而代之的是 sceneStyle
¥The sceneContainerStyle
prop and option are removed from Bottom Tab Navigator, Material Top Tab Navigator and Drawer Navigator in favor of sceneStyle
以前,Bottom Tab Navigator 和 Material Top Tab Navigator 接受 sceneContainerStyle
prop 来设置场景容器的样式。这不灵活,因为它不允许为不同的屏幕使用不同的样式。现在,sceneStyle
选项已添加到这些导航器中,以设置各个屏幕的样式。
¥Previously, the Bottom Tab Navigator and Material Top Tab Navigator accepted a sceneContainerStyle
prop to style the container of the scene. This was inflexible as it didn't allow different styles for different screens. Now, the sceneStyle
option is added to these navigators to style individual screens.
类似地,Drawer Navigator 中的 sceneContainerStyle
选项重命名为 sceneStyle
以保持一致性。
¥Similarly, the sceneContainerStyle
option in Drawer Navigator is renamed to sceneStyle
for consistency.
如果你使用 sceneContainerStyle
属性,则可以在 screenOptions
中传递 sceneStyle
以保持相同的行为:
¥If you are using sceneContainerStyle
prop, you can pass sceneStyle
in screenOptions
instead to keep the same behavior:
<Tab.Navigator sceneContainerStyle={{ backgroundColor: 'white' }}>
<Tab.Navigator screenOptions={{ sceneStyle: { backgroundColor: 'white' }}}>
Drawer Navigator 现在需要原生平台上的 Reanimated 2 或 3
¥Drawer Navigator now requires Reanimated 2 or 3 on native platforms
以前,@react-navigation/drawer
使用 useLegacyImplementation
选项支持 Reanimated 1 和 Reanimated 2 API。现在不再支持此功能,并且 useLegacyImplementation
选项已被删除。
¥Previously, @react-navigation/drawer
supported both Reanimated 1 and Reanimated 2 APIs with the useLegacyImplementation
option. This is now no longer supported and the useLegacyImplementation
option is removed.
如果你在项目中使用 Reanimated 1,则需要升级到 Reanimated 2 或 3 才能使用 @react-navigation/drawer
。
¥If you are using Reanimated 1 in your project, you'll need to upgrade to Reanimated 2 or 3 to use @react-navigation/drawer
.
如果你在 Web 上使用 Drawer Navigator,它现在将使用 CSS 转换而不是 Reanimated 来减小包大小。
¥If you're using Drawer Navigator on the Web, it'll now use CSS transitions instead of Reanimated for a smaller bundle size.
有关用法,请参阅 抽屉导航器。
¥See Drawer Navigator for usage.
弃用和删除
¥Deprecations and removals
Material Bottom Tab Navigator 现在位于 react-native-paper
包中
¥Material Bottom Tab Navigator now lives in react-native-paper
package
@react-navigation/material-bottom-tabs
软件包为 react-native-paper
的 BottomNavigation
组件提供了 React Navigation 集成。为了更轻松地使其与 react-native-paper
中的更改保持更新,我们现在已将其移至 react-native-paper
包。
¥The @react-navigation/material-bottom-tabs
package provided React Navigation integration for react-native-paper
's BottomNavigation
component. To make it easier to keep it updated with the changes in react-native-paper
, we have now moved it to the react-native-paper
package.
如果你在项目中使用 @react-navigation/material-bottom-tabs
,则可以将其从依赖中删除,然后将导入更改为 react-native-paper/react-navigation
:
¥If you are using @react-navigation/material-bottom-tabs
in your project, you can remove it from your dependencies and change the imports to react-native-paper/react-navigation
instead:
import { createMaterialBottomTabNavigator } from '@react-navigation/material-bottom-tabs';
import { createMaterialBottomTabNavigator } from 'react-native-paper/react-navigation';
有关用法,请参阅 材质底部选项卡导航器。
¥See Material Bottom Tab Navigator for usage.
flipper devtools 插件现已删除
¥The flipper devtools plugin is now removed
以前,我们为 React Navigation 添加了 Flipper 插件,使调试导航更容易。但是,它为我们增加了大量维护开销。Flipper 团队最近没有专注于 React Native,因此使用 Flipper 和 React Native 的整体体验很差。
¥Previously, we added a Flipper plugin for React Navigation to make debugging navigation easier. However, it has added significant maintenance overhead for us. The Flipper team hasn't been focused on React Native recently, so the overall experience of using Flipper with React Native has been poor.
目前,Flipper 团队一直专注于原生开发者体验,因此我们将重新开始。我们在团队中创建了一个专注于开发者体验的新支柱。我们目前正在研究 Hermes 团队改进的 Chrome 调试器协议支持,以及将调试体验从 Flipper 迁移到 Chrome DevTools,以便我们可以提供符合我们标准的调试体验。
¥Currently, the Flipper team has been focused on native developer experience, so we are going back to the drawing board. We have created a new pillar within our team focused on Developer Experience. We are currently investigating improved Chrome Debugger protocol support from the Hermes team as well as migrating the debugging experience from Flipper to Chrome DevTools so we can deliver a debugging experience that meets our standard.
react-native-community/discussions-and-proposals#546 (评论)
¥react-native-community/discussions-and-proposals#546 (comment)
由于 React Native 团队正在从 Flipper 迁移,因此我们花费额外资源继续支持它没有多大意义。因此,我们从 @react-navigation/devtools
中删除了 Flipper 插件。
¥Since the React Native team migrating away from Flipper, it doesn't make much sense for us to spend additional resources to keep supporting it. So we've removed the Flipper plugin from @react-navigation/devtools
.
或者,你可以使用以下开发者工具:
¥Alternatively, you can use the following developer tools:
-
如果你使用 Expo,则为 Expo 的 Devtools 插件。
¥Devtools plugin for Expo if you are using Expo.
各种弃用的 API 已被删除
¥Various deprecated APIs are removed
我们删除了所有以前弃用的 API。这些 API 在 React Navigation 6 中已弃用,使用时会显示警告。因此,请确保在升级之前已解决所有警告。
¥We have removed all of the previously deprecated APIs. These APIs were deprecated in React Navigation 6 and showed a warning when used. So make sure that you have addressed all the warnings before upgrading.
Full list of removed APIs
-
@react-navigation/stack
-
删除了
mode
属性 - 改用presentation
选项¥Removed
mode
prop - usepresentation
option instead -
删除了
headerMode
属性 - 改用headerMode
和headerShown
选项¥Removed
headerMode
prop - useheaderMode
andheaderShown
options instead -
删除了
keyboardHandlingEnabled
属性 - 改用keyboardHandlingEnabled
选项¥Removed
keyboardHandlingEnabled
prop - usekeyboardHandlingEnabled
option instead
-
-
@react-navigation/drawer
-
删除了
openByDefault
属性 - 改用defaultStatus
属性¥Removed
openByDefault
prop - usedefaultStatus
prop instead -
删除了
lazy
属性 - 改用lazy
选项¥Removed
lazy
prop - uselazy
option instead -
删除了包含以下选项的
drawerContentOptions
prop:¥Removed
drawerContentOptions
prop which contained following options:-
drawerPosition
- 改用drawerPosition
选项¥
drawerPosition
- usedrawerPosition
option instead -
drawerType
- 改用drawerType
选项¥
drawerType
- usedrawerType
option instead -
edgeWidth
- 改用swipeEdgeWidth
选项¥
edgeWidth
- useswipeEdgeWidth
option instead -
hideStatusBar
- 改用drawerHideStatusBarOnOpen
选项¥
hideStatusBar
- usedrawerHideStatusBarOnOpen
option instead -
keyboardDismissMode
- 改用keyboardDismissMode
选项¥
keyboardDismissMode
- usekeyboardDismissMode
option instead -
minSwipeDistance
- 改用swipeMinDistance
选项¥
minSwipeDistance
- useswipeMinDistance
option instead -
overlayColor
- 改用overlayColor
选项¥
overlayColor
- useoverlayColor
option instead -
statusBarAnimation
- 改用drawerStatusBarAnimation
选项¥
statusBarAnimation
- usedrawerStatusBarAnimation
option instead -
gestureHandlerProps
- 改用gestureHandlerProps
选项¥
gestureHandlerProps
- usegestureHandlerProps
option instead
-
-
-
@react-navigation/bottom-tabs
-
删除了
lazy
属性 - 改用lazy
选项¥Removed
lazy
prop - uselazy
option instead -
删除了包含以下选项的
tabBarOptions
prop:¥Removed
tabBarOptions
prop which contained following options:-
keyboardHidesTabBar
- 改用tabBarHideOnKeyboard
选项¥
keyboardHidesTabBar
- usetabBarHideOnKeyboard
option instead -
activeTintColor
- 改用tabBarActiveTintColor
选项¥
activeTintColor
- usetabBarActiveTintColor
option instead -
inactiveTintColor
- 改用tabBarInactiveTintColor
选项¥
inactiveTintColor
- usetabBarInactiveTintColor
option instead -
activeBackgroundColor
- 改用tabBarActiveBackgroundColor
选项¥
activeBackgroundColor
- usetabBarActiveBackgroundColor
option instead -
inactiveBackgroundColor
- 改用tabBarInactiveBackgroundColor
选项¥
inactiveBackgroundColor
- usetabBarInactiveBackgroundColor
option instead -
allowFontScaling
- 改用tabBarAllowFontScaling
选项¥
allowFontScaling
- usetabBarAllowFontScaling
option instead -
showLabel
- 改用tabBarShowLabel
选项¥
showLabel
- usetabBarShowLabel
option instead -
labelStyle
- 改用tabBarLabelStyle
选项¥
labelStyle
- usetabBarLabelStyle
option instead -
iconStyle
- 改用tabBarIconStyle
选项¥
iconStyle
- usetabBarIconStyle
option instead -
tabStyle
- 改用tabBarItemStyle
选项¥
tabStyle
- usetabBarItemStyle
option instead -
labelPosition
和adapative
- 改用tabBarLabelPosition
选项¥
labelPosition
andadapative
- usetabBarLabelPosition
option instead -
tabBarVisible
- 改用display: 'none'
tabBarStyle
选项¥
tabBarVisible
- usedisplay: 'none'
tabBarStyle
option instead
-
-
-
@react-navigation/material-top-tabs
-
删除了
swipeEnabled
属性 - 改用swipeEnabled
选项¥Removed
swipeEnabled
prop - useswipeEnabled
option instead -
删除了
lazy
属性 - 改用lazy
选项¥Removed
lazy
prop - uselazy
option instead -
删除了
lazyPlaceholder
属性 - 改用lazyPlaceholder
选项¥Removed
lazyPlaceholder
prop - uselazyPlaceholder
option instead -
删除了
lazyPreloadDistance
属性 - 改用lazyPreloadDistance
选项¥Removed
lazyPreloadDistance
prop - uselazyPreloadDistance
option instead -
删除了包含以下选项的
tabBarOptions
prop:*renderBadge
- 改用tabBarBadge
选项 -renderIndicator
- 改用tabBarIndicator
选项 -activeTintColor
- 改用tabBarActiveTintColor
选项 -inactiveTintColor
- 改用tabBarInactiveTintColor
选项 -pressColor
- 改用tabBarPressColor
选项 -pressOpacity
- 改用tabBarPressOpacity
选项 -showLabel
- 改用tabBarShowLabel
选项 -showIcon
- 改用tabBarShowIcon
选项 -allowFontScaling
- 改用tabBarAllowFontScaling
选项 -bounces
- 改用tabBarBounces
选项 -scrollEnabled
- 改用tabBarScrollEnabled
选项 -iconStyle
- 改用tabBarIconStyle
选项 -labelStyle
- 改用tabBarLabelStyle
选项 -tabStyle
- 改用tabBarItemStyle
选项 -indicatorStyle
- 改用tabBarIndicatorStyle
选项 -indicatorContainerStyle
- 改用tabBarIndicatorContainerStyle
选项 -contentContainerStyle
- 改用tabBarContentContainerStyle
选项 -style
- 改用tabBarStyle
选项¥Removed
tabBarOptions
prop which contained following options: -renderBadge
- usetabBarBadge
option instead -renderIndicator
- usetabBarIndicator
option instead -activeTintColor
- usetabBarActiveTintColor
option instead -inactiveTintColor
- usetabBarInactiveTintColor
option instead -pressColor
- usetabBarPressColor
option instead -pressOpacity
- usetabBarPressOpacity
option instead -showLabel
- usetabBarShowLabel
option instead -showIcon
- usetabBarShowIcon
option instead -allowFontScaling
- usetabBarAllowFontScaling
option instead -bounces
- usetabBarBounces
option instead -scrollEnabled
- usetabBarScrollEnabled
option instead -iconStyle
- usetabBarIconStyle
option instead -labelStyle
- usetabBarLabelStyle
option instead -tabStyle
- usetabBarItemStyle
option instead -indicatorStyle
- usetabBarIndicatorStyle
option instead -indicatorContainerStyle
- usetabBarIndicatorContainerStyle
option instead -contentContainerStyle
- usetabBarContentContainerStyle
option instead -style
- usetabBarStyle
option instead
-
杂项
¥Miscellaneous
各种 UI 元素现在遵循 Material Design 3 指南
¥Various UI elements now follow Material Design 3 guidelines
以前,React Navigation 中的 UI 元素(例如 iOS 以外平台上的标题、抽屉、Material 顶部选项卡等)遵循 Material Design 2 指南。我们现在已经更新它们以遵循 Material Design 3 指南。
¥Previously, the UI elements in React Navigation such as the header on platforms other than iOS, drawer, material top tabs etc. were following the Material Design 2 guidelines. We have now updated them to follow the Material Design 3 guidelines.
React Native Tab View 现在有一个新的 API 来指定各种选项
¥React Native Tab View now has a new API to specify various options
react-native-tab-view
中 TabView
和 TabBar
组件的 API 已得到改进。以前,TabBar
采用以下 props:
¥The API for the TabView
and TabBar
component in react-native-tab-view
has been revamped. Previously, the TabBar
took the following props:
-
getLabelText
-
getAccessible
-
getAccessibilityLabel
-
getTestID
-
renderIcon
-
renderLabel
-
renderBadge
这些属性已在 TabView
上被 commonOptions
和 options
属性取代:
¥These props have been replaced with commonOptions
and options
props on TabView
:
<TabView
commonOptions={{
icon: ({ route, focused, color }) => (
<Icon name={route.icon} color={color} />
),
}}
options={{
albums: {
labelText: 'Albums',
},
profile: {
labelText: 'Profile',
},
}}
/>
使用自定义标签栏时,它将在参数中接收 options
。
¥When using a custom tab bar, it will receive the options
in the arguments.
新的 API 将使我们更容易提高库中标签栏项目的重新渲染性能。
¥The new API will make it easier for us to improve re-rendering performance of the tab bar items in the library.
有关用法,请参阅 React Native 选项卡视图。
¥See React Native Tab View for usage.
自定义导航器现在需要更多类型信息
¥Custom navigators now require more type information
自定义导航器现在需要更多类型信息才能正常工作,以便我们在使用导航器时在 TypeScript 中提供更好的类型检查和自动补齐功能。
¥Custom navigators now require more type information to work correctly so that we can provide better type-checking and autocompletion in TypeScript when using the navigator.
export const createMyNavigator = createNavigatorFactory<
MyNavigationState<ParamListBase>,
MyNavigationOptions,
MyNavigationEventMap,
typeof MyNavigator
>(MyNavigator);
export function createMyNavigator<
const ParamList extends ParamListBase,
const NavigatorID extends string | undefined = undefined,
const TypeBag extends NavigatorTypeBagBase = {
ParamList: ParamList;
NavigatorID: NavigatorID;
State: TabNavigationState<ParamList>;
ScreenOptions: TabNavigationOptions;
EventMap: TabNavigationEventMap;
NavigationList: {
[RouteName in keyof ParamList]: TabNavigationProp<
ParamList,
RouteName,
NavigatorID
>;
};
Navigator: typeof TabNavigator;
},
const Config extends StaticConfig<TypeBag> = StaticConfig<TypeBag>,
>(config?: Config): TypedNavigator<TypeBag, Config> {
return createNavigatorFactory(MyNavigator)(config);
}
有关用法,请参阅 自定义导航器。
¥See Custom navigators for usage.
包现在使用 ESM 和包导出
¥Packages now use ESM and package exports
React Navigation 中的所有包现在都使用 ESM 导出。虽然它不会影响大多数用户,但仍有一些变化需要注意:
¥All the packages in React Navigation now use ESM exports. While it shouldn't affect most users, there are some changes to be aware of:
-
如果你从包中导入内部文件,它们现在可能受到打包器的限制,无法直接导入它们。你应该改用公共 API。
¥If you are importing internal files from the packages, they might now be restricted by your bundler and it won't be possible to import them directly. You should use the public API instead.
-
如果你使用
patch-package
、yarn patch
等修补软件包,则需要修补lib/
文件夹下的构建文件,而不是src/
下的源文件,因为源文件不再导出。¥If you're patching the packages using
patch-package
,yarn patch
etc., you'll need to patch the built files underlib/
folders instead of the source files undersrc/
as the source files are no longer exported. -
如果你使用的是 Webpack,可能需要将
resolve.fullySpecified
设置为false
才能使打包工作。¥If you're using Webpack, it maybe necessary to set
resolve.fullySpecified
tofalse
for bundling to work.
新功能
¥New features
静态配置 API
¥Static configuration API
React Navigation 5 引入了动态 API 来支持更灵活的用例。使用 React Navigation 7,我们重新引入了静态配置 API:
¥React Navigation 5 introduced a dynamic API to support more flexible use cases. With React Navigation 7, we are re-introducing a static configuration API:
import { createNativeStackNavigator } from 'react-native-screens/native-stack';
const MyStack = createNativeStackNavigator({
screens: {
Home: {
screen: HomeScreen,
options: {
title: 'My App',
},
},
Details: {
screen: DetailsScreen,
linking: 'details/:id',
},
},
});
静态配置 API 提供以下好处:
¥The static configuration API provides the following benefits:
-
使用 TypeScript 进行更简单的类型检查:没有必要单独指定屏幕及其参数。详细信息请参见 使用 TypeScript 进行类型检查。
¥Simpler type-checking with TypeScript: It's not necessary to specify screens and their params separately. See Type checking with TypeScript for more details.
-
更简单的深度链接设置:路径可以自动生成。可以在屏幕旁边定义链接配置以进行显式配置。详细信息请参见 配置链接。
¥Easier deep linking setup: Paths can be generated automatically. Linking configuration can be defined next to the screen for explicit configuration. See Configuring links for more details.
也可以混合使用静态和动态配置 API。例如,你可以将静态配置 API 用于顶层导航器,将动态配置 API 用于需要更多灵活性的嵌套导航器。
¥It's also possible to mix the static and dynamic configuration APIs. For example, you can use the static configuration API for the top-level navigators and the dynamic configuration API for the nested navigators where you need more flexibility.
静态配置 API 不会取代动态配置 API。这两个 API 都同样受支持,你可以选择更适合你用例的 API。
¥The static configuration API doesn't replace the dynamic configuration API. Both APIs are equally supported and you can choose the one that fits your use case better.
你可以通过在示例中选择相应的选项卡来查看文档中静态和动态配置 API 的示例。
¥You can see examples for both the static and dynamic configuration APIs in the documentation by selecting the appropriate tab in the examples.
转到 "你好 React 导航" 开始使用静态 API 编写一些代码。
¥Go to "Hello React Navigation" to start writing some code with the static API.
改进的 TypeScript 支持
¥Improved TypeScript support
以前,options
和 listeners
回调中收到的 navigation
对象被键入为 any
并需要手动类型注释。现在,navigation
对象根据其使用的导航器具有更准确的类型,并且不再需要类型注释。
¥Previously, the navigation
object received in options
and listeners
callbacks were typed as any
and required manual type annotation. Now, the navigation
object has a more accurate type based on the navigator it's used in, and the type annotation is no longer required.
我们还导出了一个新的 XOptionsArgs
(其中 X
是导航器名称,例如 StackOptionsArgs
、BottomTabOptionsArgs
等)类型,可用于键入 options
回调的参数。如果你想单独定义选项回调,这将很有用。
¥We also export a new XOptionsArgs
(where X
is the navigator name, e.g. StackOptionsArgs
, BottomTabOptionsArgs
etc.) type which can be used to type the arguments of the options
callback. This can be useful if you want to define the options callback separately.
const options = ({
route,
}: StackOptionsArgs<RootStackParamList, 'Details'>) => {
return {
title: route.params.title,
};
};
改进的 RTL 支持
¥Improved RTL support
以前,各种 UI 元素使用 I18nManager
API 来确定书写方向。但是,此 API 在 Web 上运行不佳,因为特定子树的写入方向可能不同,因此无法全局确定。
¥Previously, various UI elements used the I18nManager
API to determine the writing direction. However, this API doesn't work well on the Web as the writing direction can be different for a specific subtree and hence can't be determined globally.
NavigationContainer
现在接受 direction
prop 来指定布局的方向,而不是依赖 I18nManager
API。它还通过 useLocale
钩子公开此值以供你自己的组件使用。
¥The NavigationContainer
now accepts a direction
prop to specify the direction of the layout instead of relying on the I18nManager
API. It also exposes this value via useLocale
hook for use in your own components.
有关用法,请参阅 导航容器文档。
¥See the navigation container docs for usage.
options
回调获取 theme
¥The options
callback gets theme
options
回调现在接收 theme
对象以允许自定义选项中指定的 UI 元素:
¥The options
callback now receives the theme
object to allow customizing the UI elements specified in the options:
<Stack.Screen
name="Details"
component={DetailsScreen}
options={({ theme }) => ({
headerRight: () => (
<IconButton
icon="dots-horizontal"
onPress={() => {}}
color={theme.colors.primary}
/>
),
})}
/>
有关用法,请参阅 屏幕选项。
¥See Screen options for usage.
链接中的顶层 path
配置
¥Top-level path
in linking config
链接配置现在支持顶层 path
配置,以定义导航器中所有屏幕的基本路径:
¥The linking configuration now supports a top-level path
configuration to define the base path for all the screens in the navigator:
const linking = {
prefixes: ['https://mysite.com'],
config: {
path: 'app',
screens: {
Home: 'home',
Details: 'details/:id',
},
},
};
如果你的应用位于网络上的子路径下,这将很有用。例如,如果你的应用位于 https://mysite.com/app
下,你可以将 path
定义为 app
,并且 Details
屏幕将在 https://mysite.com/app/details/42
上可访问。
¥This can be useful if your app lives under a subpath on the web. For example, if your app lives under https://mysite.com/app
, you can define the path
as app
and the Details
screen will be accessible at https://mysite.com/app/details/42
.
有关用法,请参阅 配置链接。
¥See Configuring links for usage.
改进的 Web 集成
¥Improved Web integration
更多触发导航的内置 UI 元素现在在 Web 上渲染 a
标签,以实现更好的可访问性和 SEO。这包括:
¥More built-in UI elements that trigger navigation now render a
tags on the Web for better accessibility and SEO. This includes:
-
标题中的后退按钮
¥Back button in the header
-
Material 顶部选项卡导航器中的选项卡按钮
¥The tab buttons in material top tab navigator
UI 元素(例如底部选项卡栏和抽屉项目)已在 Web 上渲染 a
标签。
¥UI elements such as the bottom tab bar and drawer items already rendered a
tags on the Web.
新的 usePreventRemove
钩子
¥New usePreventRemove
hook
以前,防止屏幕从堆栈中移除的唯一方法是使用 beforeRemove
事件。这与 Native Stack Navigator 配合使用效果不佳。
¥Previously, the only way to prevent a screen from being removed from the stack was to use the beforeRemove
event. This didn't work well with the Native Stack Navigator.
新的 usePreventRemove
钩子是 beforeRemove
的替代品,可与 Native Stack Navigator 配合使用。
¥The new usePreventRemove
hook is an alternative to beforeRemove
that works with the Native Stack Navigator.
有关用法,请参阅 usePreventRemove
。
¥See usePreventRemove
for usage.
新的 layout
属性
¥New layout
props
对于导航器
¥For navigators
导航器现在支持 layout
属性。它可用于使用封装器为导航器增加额外的 UI。与添加常规封装器的区别在于,layout
回调中的代码可以访问导航器的状态、选项等:
¥Navigators now support a layout
prop. It can be useful for augmenting the navigators with additional UI with a wrapper. The difference from adding a regular wrapper is that the code in layout
callback has access to the navigator's state, options etc.:
<Stack.Navigator
layout={({ children, state, descriptors, navigation }) => (
<View style={styles.container}>
<Breadcrumbs />
{children}
</View>
)}
>
{/* ... */}
</Stack.Navigator>
有关用法,请参阅 导航器布局。
¥See Navigator layout for usage.
对于屏幕和组
¥For screens and groups
layout
prop 可以更轻松地为屏幕组提供诸如全局错误边界和悬念回退之类的功能,而无需为每个屏幕单独手动添加 HOC。
¥The layout
prop makes it easier to provide things such as a global error boundary and suspense fallback for a group of screens without having to manually add HOCs for every screen separately.
它可以与 layout
一起用于单个屏幕:
¥It can be used for a single screen with layout
:
<Stack.Screen
name="MyScreen"
component={MyScreenComponent}
layout={({ children }) => (
<ErrorBoundary>
<React.Suspense
fallback={
<View style={styles.fallback}>
<Text style={styles.text}>Loading…</Text>
</View>
}
>
{children}
</React.Suspense>
</ErrorBoundary>
)}
/>
或者使用 group 或 navigator 和 screenLayout
:
¥Or with a group or navigator with screenLayout
:
<Stack.Group
screenLayout={({ children }) => (
<ErrorBoundary>
<React.Suspense
fallback={
<View style={styles.fallback}>
<Text style={styles.text}>Loading…</Text>
</View>
}
>
{children}
</React.Suspense>
</ErrorBoundary>
)}
>
{/* screens */}
</Stack.Group>
预加载屏幕
¥Preloading screens
所有内置导航器现在都支持在导航到屏幕之前预加载屏幕。通过预加载用户可能接下来导航到的屏幕,这可以有助于提高应用的感知性能。预加载屏幕将使其在屏幕外渲染并执行其副作用,例如数据获取。
¥All built-in navigators now support preloading screens prior to navigating to them. This can be useful to improve the perceived performance of the app by preloading the screens that the user is likely to navigate to next. Preloading a screen will render it off-screen and execute its side-effects such as data fetching.
要预加载屏幕,你可以在导航对象上使用 preload
方法:
¥To preload a screen, you can use the preload
method on the navigation object:
navigation.preload('Details', { id: 42 });
有关用法,请参阅 preload
。
¥See preload
for usage.
导航器改进
¥Improvements to navigators
底部选项卡导航器现在可以在侧面和顶部显示选项卡
¥Bottom Tab Navigator can now show tabs on the side and top
@react-navigation/bottom-tabs
软件包现在支持在侧面显示选项卡。这将使构建响应式 UI 变得更加容易,你可以在较小的屏幕上在底部显示选项卡,并在较大的屏幕上切换到侧边栏。
¥The @react-navigation/bottom-tabs
package now supports showing tabs on the side. This will make it easier to build responsive UIs for where you want to show tabs on the bottom on smaller screens and switch to a sidebar on larger screens.
类似地,还支持在顶部显示选项卡,这对于 Android TV 或 Apple TV 应用很有用。
¥Similarly, showing tabs on the top is also supported which can be useful for Android TV or Apple TV apps.
你可以使用 tabBarPosition
选项自定义选项卡的位置:
¥You can use the tabBarPosition
option to customize the position of the tabs:
<Tab.Navigator
screenOptions={{
tabBarPosition: 'left',
}}
>
{/* ... */}
</Tab.Navigator>
有关用法,请参阅 底部选项卡导航器选项。
¥See Bottom Tab Navigator options for usage.
底部选项卡导航器现在支持动画
¥Bottom Tab Navigator now supports animations
@react-navigation/bottom-tabs
软件包现在支持动画。这是我们 Canny 板上最需要的功能之一:TabNavigator 自定义过渡。
¥The @react-navigation/bottom-tabs
package now supports animations. This was one of the most requested features on our Canny board: TabNavigator Custom Transition.
你可以使用 animation
选项自定义选项卡转换的动画:
¥You can use the animation
option to customize the animations for the tab transitions:
<Tab.Navigator
screenOptions={{
animation: 'fade',
}}
>
{/* ... */}
</Tab.Navigator>
有关用法,请参阅 底部选项卡导航器动画。
¥See Bottom Tab Navigator animation for usage.
Stack Navigator 现在支持 animation
选项
¥Stack Navigator now supports an animation
option
@react-navigation/stack
软件包现在支持 animation
选项,用于自定义屏幕转换的动画:
¥The @react-navigation/stack
package now supports an animation
option to customize the animations for the screen transitions:
<Stack.Navigator
screenOptions={{
animation: 'slide_from_right',
}}
>
{/* ... */}
</Stack.Navigator>
animation
选项是 TransitionPresets
API 的替代方案,旨在使 JS 堆栈和原生堆栈导航器之间的迁移更容易。
¥The animation
option is an alternative to the TransitionPresets
API, and is intended to make migrating between JS stack and native stack navigators easier.
有关用法,请参阅 Stack Navigator 动画。
¥See Stack Navigator animation for usage.
Native Stack Navigator 现在导出 useAnimatedHeaderHeight
钩子
¥Native Stack Navigator now exports a useAnimatedHeaderHeight
hook
@react-navigation/native-stack
包现在导出 useAnimatedHeaderHeight
钩子。它可用于根据标题高度变化为内容设置动画 - 例如当 iOS 上的大标题缩小为小标题时:
¥The @react-navigation/native-stack
package now exports a useAnimatedHeaderHeight
hook. It can be used to animate content based on the header height changes - such as when the large title shrinks to a small title on iOS:
const headerHeight = useAnimatedHeaderHeight();
return (
<Animated.View style={{ transform: { translateY: headerHeight }}}>
{/* ... */}
</Animated.View>
);
所有带标题的导航器现在都支持 headerSearchBarOptions
¥All navigators with headers now support headerSearchBarOptions
@react-navigation/elements
中的 Header
组件现在支持 headerSearchBarOptions
prop。这意味着所有使用 Header
组件的导航器现在在所有平台上都支持标题中的搜索栏。以前,这仅在 iOS 和 Android 上的 Native Stack Navigator 中可用。
¥The Header
component from @react-navigation/elements
now supports a headerSearchBarOptions
prop. This means all navigators that use the Header
component now support a search bar in the header as well on all platforms. Previously, this was only available in the Native Stack Navigator on iOS and Android.
React.useLayoutEffect(() => {
navigation.setOptions({
headerSearchBarOptions: {
placeholder: 'Search',
onChangeText: (text) => {
// Do something
},
},
});
}, [navigation]);
有关用法,请参阅 headerSearchBarOptions
。
¥See headerSearchBarOptions
for usage.
元素库中的新组件
¥New components in elements library
@react-navigation/elements
软件包现在包含可在你的应用中使用的新组件:
¥The @react-navigation/elements
package now includes new components that can be used in your app:
Button
Button
组件内置了对导航到屏幕的支持,并在用于导航时在 Web 上渲染锚标记:
¥The Button
component has built-in support for navigating to screens, and renders an anchor tag on the Web when used for navigation:
<Button screen="Profile" params={{ userId: 'jane' }}>
View Jane's Profile
<Button>
它也可以用作常规按钮:
¥It can also be used as a regular button:
<Button
onPress={() => {
/* do something */
}}
>
Do something
</Button>
按钮跟随 Material Design 3 指南。
¥The button follows the Material Design 3 guidelines.
有关用法,请参阅 Button
。
¥See Button
for usage.
HeaderButton
HeaderButton
组件可用于以适当的样式渲染标题中的按钮:
¥The HeaderButton
component can be used to render buttons in the header with appropriate styling:
headerRight: ({ tintColor }) => (
<HeaderButton
accessibilityLabel="More options"
onPress={() => {
/* do something */
}}
>
<MaterialCommunityIcons
name="dots-horizontal-circle-outline"
size={24}
color={tintColor}
/>
</HeaderButton>
),
有关用法,请参阅 HeaderButton
。
¥See HeaderButton
for usage.
Label
Label
组件可用于渲染标签文本,例如标签栏按钮中的标签:
¥The Label
component can be used to render label text, such as the label in a tab bar button:
<Label>Home</Label>
有关用法,请参阅 Label
。
¥See Label
for usage.
react-native-drawer-layout
包
¥react-native-drawer-layout
package
@react-navigation/drawer
中使用的抽屉实现现在可作为名为 react-native-drawer-layout
的独立包使用。即使你不使用 React Navigation,或者想要在没有导航器的情况下使用它,这也使使用抽屉实现变得更容易。
¥The drawer implementation used in @react-navigation/drawer
is now available as a standalone package called react-native-drawer-layout
. This makes it easier to use the drawer implementation even if you're not using React Navigation, or if you want to use it without a navigator.
你可以使用以下方法安装它:
¥You can install it with:
- npm
- Yarn
- pnpm
npm install react-native-drawer-layout
yarn add react-native-drawer-layout
pnpm add react-native-drawer-layout
有关用法,请参阅 react-native-drawer-layout
。
¥See react-native-drawer-layout
for usage.
useLogger
devtool
@react-navigation/devtools
包现在导出 useLogger
钩子。它可用于将导航操作记录到控制台:
¥The @react-navigation/devtools
package now exports a useLogger
hook. It can be used to log navigation actions to the console:
有关用法,请参阅 useLogger
。
¥See useLogger
for usage.