导航状态参考
导航状态是 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
属性。过时的导航状态意味着状态对象需要重新水合或修复或整理,例如添加缺少的键、删除无效屏幕等,然后才能使用。作为用户,您无需担心它,除非 stale
设置为 false
,否则 React Navigation 会自动修复状态对象中的任何问题。如果您正在编写自定义路由器,则 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 将始终假定它是过时的状态对象,这确保了状态持久化等功能可以顺利运行,而无需额外操作状态对象。