React Navigation 2.0
文档现已在 reactnavigation.org 上线,v1 版本在此处。
重大 breaking changes
以下更改被认为是“重大”的,因为它们无法通过搜索和替换或类似机械的方式修复。
StackNavigator 中的 navigate(routeName)
“不那么激进”
在 1.x 版本中,navigate(routeName)
和 push(routeName)
非常相似:每次调用 navigate(routeName)
都会将新路由推送到堆栈。现在,navigate(routeName)
将首先尝试查找路由的现有实例,如果存在则跳转到该实例,否则将路由推送到堆栈。
要为这个更改更新您的应用程序,您可能需要在每次想要推送新路由的地方将 navigate
更改为 push
。或者,您可以考虑使用 key
:navigate({routeName: ‘MyRoute’, key: data.uniqueId, params: data})
。 阅读更多关于使用键进行导航的信息。
在 RFC 4 和 commit 7a978b1 中阅读更多相关信息。
push
现在像 navigate
一样在路由器之间传播
以前,push
仅应用于最深层的活动堆栈路由器。这意味着,如果您有 Stack A > Stack B 并且 Stack B 触发了 push(‘MyRoute’)
,即使 Stack B 没有名为 ’MyRoute’
的路由,而 Stack A 有,屏幕也不会被推送。我们做出此更改是为了适应“不那么激进”的 navigate 行为。
更新您的应用程序时,您可能需要仔细检查您使用 push
的位置,以确保这不会影响您应用程序的预期行为。
浅层导航选项
对于使用 React Navigation 的开发人员来说,一个常见的困惑来源是 navigationOptions
的解析。例如,如果您有一个带有 header 的堆栈导航器,以及该堆栈内的 drawer,那么在某些情况下,每次您在 drawer 中更改屏幕时,堆栈的标题都会更改。这是因为堆栈导航器会爬入子导航器并从最深层的活动屏幕中提取 navigationOptions
。从 2.0 版本开始,这种情况不再发生:导航器将只查看其直接子项的 navigationOptions
。
在 RFC 5 中阅读更多关于此理由的信息。另请参阅新的文档页面 导航选项解析以了解更多信息。
用于创建导航器的新 API
现在可以更轻松地创建和维护自定义导航器。新的 createNavigator
API 完全将导航视图与路由器分离。关于每个屏幕的信息都可以在单个“描述符”上获得,包括预先计算的子导航属性,让您可以专注于自定义导航视图。
自定义导航器现在可以为其屏幕提供操作助手。例如,新的 drawer 导航器现在允许在其屏幕组件中使用 props.navigation.openDrawer()
。
这不会影响大多数用户 - 除非您在应用程序中使用自定义导航器,否则您无需为此进行任何更改。在 RFC 2 中阅读更多关于更改的信息。另请阅读自定义导航器文档。您还可以观看本次演讲中的 “创建导航器”部分以了解更多信息。
微不足道的 breaking changes
以下更改被认为是“微不足道”的,因为您只需要进行简单的机械更改即可更新您的应用程序以适应它们。
Drawer 路由已被操作替换
现在,您可以使用 navigation.openDrawer()
而不是使用 navigation.navigate(‘DrawerOpen’)
打开 drawer。其他方法包括 closeDrawer()
和 toggleDrawer()
。请参阅 pull 3618。
导航操作 API 大修
实际上,除了下面提到的一个案例外,此更改不太可能对您的应用程序产生任何影响。
在 1.x 版本中,navigation
上的函数不是上下文相关的 - 无论您的屏幕是在 drawer、堆栈、标签导航器等内部,它们都是相同的。在 2.0 版本中,navigation
属性上可用的函数取决于它对应的导航器。如果您的屏幕同时位于堆栈和 drawer 导航器内部,您将同时拥有两者的助手 - 例如 push
和 openDrawer
。
鉴于我们在 1.x 版本中仅公开了通用助手(navigate
、goBack
)和特定于堆栈的助手,如果您尝试从堆栈外部使用堆栈助手,这将只会影响您。例如,如果您有一个标签导航器,其中标签 A 中有一个堆栈,而标签 B 中只有一个普通屏幕,然后尝试从标签 B 中的屏幕推送路由,则 push
将不可用。如果您的应用程序遵循这种类型的结构,请在更新您的应用程序时记住这一点。
您从中获得的一大改进是,您现在可以将自己的助手添加到 navigation
属性中!在 RFC 6 和 pull 3392 中阅读更多信息。
NavigationActions 不再具有 toString()
实现(相关)
此更改旨在简化操作的实现。但是,我们可能会对此进行修改,如果这种调整给您带来麻烦,我们提前道歉。
NavigationActions 根据路由器拆分
如果您正在使用 NavigationActions.push
或其他特定于堆栈的操作,您需要导入 StackActions
并改用 StackActions.push
。
弃用
XNavigator(...) 现在是 createXNavigator(...)
StackNavigator
、TabNavigator
和 DrawerNavigator
现在已被弃用,取而代之的是 createStackNavigator
、createTabNavigator
和 createDrawerNavigator
,它们在功能上是相同的,但更清楚地表明它们是函数并且它们返回一个组件。XNavigator
样式将在 3.0 版本中删除。
Tab navigator 拆分为单独的组件
以前,TabNavigator
会在 Android 屏幕顶部和 iOS 屏幕底部渲染一个导航栏。我们现在已经将这些导航器分开,因此您可以根据需要显式使用 createBottomTabNavigator
和 createMaterialTopTabNavigator
。您可以使用 createTabNavigator
来获得与以前相同的行为,但它将在 3.0 版本中删除。
此外,值得注意的是,createBottomTabNavigator
与通过 TabNavigator
提供的底部标签导航器不同,因为它不支持 animationEnabled
或 swipeEnabled
属性。
增强功能
- navigation 属性上的
dangerouslyGetParent
和dismiss
助手 (3669) - 状态持久性 - 在应用程序重新启动时自动保存状态并重新加载 (3716)
- 平滑过渡 Stack 中的 header 可见性 (3821)
- 为 StackRouter 添加
initialRouteKey
(3540) - 使 StackNavigator 具有键盘感知能力 - 当您开始向后滑动时,它会自动隐藏,如果您取消向后滑动操作,它会重新聚焦 (3951)
- 允许修改 header 中的 SafeAreaView 属性 (3496)
- 添加
createMaterialBottomTabNavigator
以实现 material design 风格的标签栏。(请参阅 react-navigation-tabs)。 - 在 StateUtils 中使用
findIndex
而不是map/indexOf
(commit) - 当用户有多个有状态的导航容器时发出警告 (commit)
- 删除几乎所有对 React 16 弃用的生命周期方法的使用 (commit)
- 为 DrawerItem 添加
activeLabelStyle
和inactiveLabelStyle
(commit)
Bug修复
- 避免不必要的导航完成调度 (3902)
- 使用
Header.HEIGHT
而不是测量以避免闪烁 (3940) - 在
SwitchRouter
上实现路径 (commit)。 SwitchRouter
现在在幂等导航时返回null
(commit)。
最终说明
此版本中的 breaking changes 和弃用解决了用户遇到的许多问题,这些问题被认为是 bug,但在技术上是预期行为。我们认为我们已经大大提高了新用户和经验丰富的用户的库人体工程学,请在 Twitter 上告诉我们您的想法。
我们已经开始计划 3.0 版本。请通过在 Canny 上发布您的功能请求、打开 RFC 或通过组织良好的 issue 让我们知道 bug 来参与进来!