导航状态参考
导航状态是 React Navigation 用于存储应用程序导航结构和历史记录的状态。如果您需要执行高级操作(例如 重置状态、提供自定义初始状态 等),了解导航状态的结构非常有用。
它是一个 JavaScript 对象,看起来像这样
const state = {
type: 'stack',
key: 'stack-1',
routeNames: ['Home', 'Profile', 'Settings'],
routes: [
{ key: 'home-1', name: 'Home', params: { sortBy: 'latest' } },
{ key: 'settings-1', name: 'Settings' },
],
index: 1,
stale: false,
};
每个导航状态对象中都有一些属性
type
- 状态所属的导航器的类型,例如stack
、tab
、drawer
。key
- 用于标识导航器的唯一键。routeNames
- 在导航器中定义的屏幕名称。这是一个包含每个屏幕字符串的唯一数组。routes
- 导航器中渲染的路由对象(屏幕)列表。它也代表了堆栈导航器中的历史记录。此数组中至少应存在一个项目。index
-routes
数组中聚焦的路由对象的索引。history
- 已访问项目的列表。这是一个可选属性,并非所有导航器中都存在。例如,它仅存在于核心中的标签和抽屉导航器中。history
数组中项目的形状可能因导航器而异。此数组中至少应存在一个项目。stale
- 除非显式将stale
属性设置为false
,否则导航状态被认为是过时的。这意味着状态对象需要进行 "重新水合"。
routes
数组中的每个路由对象可能包含以下属性
key
- 屏幕的唯一键。在导航到此屏幕时自动创建或添加。name
- 屏幕的名称。在导航器组件层次结构中定义。params
- 一个可选对象,包含在导航时定义的参数,例如navigate('Home', { sortBy: 'latest' })
。state
- 一个可选对象,包含嵌套在此屏幕内的子导航器的导航状态。
例如,包含嵌套在其主屏幕内的标签导航器的堆栈导航器可能具有如下导航状态对象
const state = {
type: 'stack',
key: 'stack-1',
routeNames: ['Home', 'Profile', 'Settings'],
routes: [
{
key: 'home-1',
name: 'Home',
state: {
key: 'tab-1',
routeNames: ['Feed', 'Library', 'Favorites'],
routes: [
{ key: 'feed-1', name: 'Feed', params: { sortBy: 'latest' } },
{ key: 'library-1', name: 'Library' },
{ key: 'favorites-1', name: 'Favorites' },
],
index: 0,
},
},
{ key: 'settings-1', name: 'Settings' },
],
index: 1,
};
需要注意的是,即使存在嵌套导航器,route
对象上的 state
属性也不会在导航发生之前添加,因此无法保证其存在。
部分状态对象
之前提到了导航状态中的 stale
属性。过时的导航状态意味着状态对象需要重新水合或修复,例如添加缺失的键、删除无效的屏幕等,然后才能使用。作为用户,您无需担心,React Navigation 会自动修复状态对象中的任何问题,除非 stale
设置为 false
。如果您正在编写 自定义路由器,则 getRehydratedState
方法允许您编写自定义重新水合逻辑来修复状态对象。
这也适用于 index
属性:index
应该是堆栈中的最后一个路由,如果指定了不同的值,React Navigation 会对其进行修复。例如,如果您想将应用程序的导航状态重置为显示 Profile
路由,并在返回时显示 Home
路由,并执行以下操作,
navigation.reset({
index: 0,
routes: [{ name: 'Home' }, { name: 'Profile' }],
});
React Navigation 会将 index
修正为 1,并按预期显示路由并执行导航。
此功能在执行诸如 重置、提供初始状态 等操作时非常有用,因为您可以安全地省略导航状态对象中的许多属性,并依赖 React Navigation 为您添加这些属性,从而使您的代码更简洁。例如,您只需提供一个 routes
数组,而无需任何键,React Navigation 会自动添加所有使其正常工作所需的元素
const state = {
routes: [{ name: 'Home' }, { name: 'Profile' }],
};
重新水合后,它将看起来像这样
const state = {
type: 'stack',
key: 'stack-1',
routeNames: ['Home', 'Profile', 'Settings'],
routes: [
{ key: 'home-1', name: 'Home' },
{ key: 'settings-1', name: 'Settings' },
],
index: 1,
stale: false,
};
在这里,React Navigation 填补了缺失的部分,例如键、路由名称、索引等。
也可以提供无效数据,例如不存在的屏幕,它将自动修复。虽然不建议编写包含无效状态对象的代码,但如果你做一些事情,例如 状态持久化,其中配置的屏幕可能在更新后发生变化,这可能会导致问题,如果 React Navigation 没有自动修复状态对象。
如果你希望 React Navigation 修复无效状态,你需要确保状态对象中没有 stale: false
。具有 stale: false
的状态对象被认为是有效的状态对象,React Navigation 不会尝试修复它们。
当你提供 initialState
中的状态对象时,React Navigation 将始终假设它是一个陈旧的状态对象,这确保了诸如状态持久化之类的事情能够顺利运行,而无需对状态对象进行额外的操作。