导航状态参考
导航状态是 React Navigation 存储应用的导航结构和历史记录的状态。如果你需要执行 重置状态、提供自定义初始状态 等高级操作,了解导航状态的结构很有用。
¥The navigation state is the state where React Navigation stores the navigation structure and history of the app. It's useful to know about the structure of the navigation state if you need to do advanced operations such as resetting the state, providing a custom initial state etc.
它是一个 JavaScript 对象,如下所示:
¥It's a JavaScript object which looks like this:
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,
};
每个导航状态对象中都存在一些属性:
¥There are few properties present in every navigation state object:
-
type- 状态所属导航器的类型,例如stack、tab、drawer。¥
type- Type of the navigator that the state belongs to, e.g.stack,tab,drawer. -
key- 用于识别导航器的唯一密钥。¥
key- Unique key to identify the navigator. -
routeNames- 导航器中定义的屏幕名称。这是一个包含每个屏幕字符串的唯一数组。¥
routeNames- Name of the screens defined in the navigator. This is an unique array containing strings for each screen. -
routes- 在导航器中渲染的路由对象(屏幕)列表。它还代表堆栈导航器中的历史记录。该数组中应该至少存在一项。¥
routes- List of route objects (screens) which are rendered in the navigator. It also represents the history in a stack navigator. There should be at least one item present in this array. -
index-routes数组中焦点路由对象的索引。¥
index- Index of the focused route object in theroutesarray. -
history- 已访问项目的列表。这是一个可选属性,并非所有导航器中都存在。例如,它仅存在于核心的选项卡和抽屉导航器中。history数组中项目的形状可能因导航器而异。该数组中应该至少存在一项。¥
history- A list of visited items. This is an optional property and not present in all navigators. For example, it's only present in tab and drawer navigators in the core. The shape of the items in thehistoryarray can vary depending on the navigator. There should be at least one item present in this array. -
stale- 导航状态被假定为过时的,除非stale属性显式设置为false。这意味着状态对象需要是 "rehydrated"。¥
stale- A navigation state is assumed to be stale unless thestaleproperty is explicitly set tofalse. This means that the state object needs to be "rehydrated".
routes 数组中的每个路由对象可能包含以下属性:
¥Each route object in a routes array may contain the following properties:
-
key- 屏幕的唯一键。自动创建或在导航到此屏幕时添加。¥
key- Unique key of the screen. Created automatically or added while navigating to this screen. -
name- 屏幕名称。在导航器组件层次结构中定义。¥
name- Name of the screen. Defined in navigator component hierarchy. -
params- 包含在导航时定义的参数的可选对象,例如navigate('Home', { sortBy: 'latest' })。¥
params- An optional object containing params which is defined while navigating e.g.navigate('Home', { sortBy: 'latest' }). -
state- 一个可选的对象,包含嵌套在此屏幕内的子导航器的 过时的导航状态。¥
state- An optional object containing the stale navigation state of a child navigator nested inside this screen.
例如,包含嵌套在其主屏幕内的选项卡导航器的堆栈导航器可能具有如下导航状态对象:
¥For example, a stack navigator containing a tab navigator nested inside it's home screen may have a navigation state object like this:
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 属性,因此不能保证它存在。
¥It's important to note that even if there's a nested navigator, the state property on the route object is not added until a navigation happens, hence it's not guaranteed to exist.
过期状态对象
¥Stale state objects
之前提到过导航状态中的 stale 属性。如果 stale 属性设置为 true 或缺失,则假定状态已过时。过时的导航状态意味着状态对象可能不完整,例如缺少键或路由、包含无效路由或可能不是最新的。过时的状态可能是 深层链接、r从持久化状态恢复 等造成的。
¥Earlier there was a mention of stale property in the navigation state. If the stale property is set to true or is missing, the state is assumed to be stale. A stale navigation state means that the state object may be partial, such as missing keys or routes, contain invalid routes, or may not be up-to-date. A stale state can be a result of deep linking, restoring from a persisted state etc.
如果你使用内置 API(例如 useNavigationState()、navigation.getState() 等)访问导航器的导航状态,则状态对象保证完整且未过期。但是,如果你尝试使用 route 对象上的 state 属性访问子导航器的状态,则该状态对象可能已过期或不完整。因此,不建议直接使用此属性。
¥If you're accessing the navigation state of a navigator using the built-in APIs such as useNavigationState(), navigation.getState() etc., the state object is guaranteed to be complete and not stale. However, if you try to access a child navigator's state with the state property on the route object, it maybe a stale or partial state object. So it's not recommended to use this property directly.
使用 ref.getRootState() API 将始终返回当前导航树(包括任何嵌套的子导航器)的完整且最新的状态对象。
¥Using the ref.getRootState() API will always return a complete and up-to-date state object for the current navigation tree, including any nested child navigators.
当 React Navigation 遇到过时或不完整的状态时,它会在使用前自动修复它。这包括添加缺失的键、移除任何无效路由、确保 index 正确等等。修复过时状态的过程称为“重新水合”(rehydration)。如果你正在编写 定制路由,则可以使用 getRehydratedState 方法编写自定义的重新水合逻辑来修复状态对象。
¥When React Navigation encounters stale or partial state, it will automatically fix it up before using it. This includes adding missing keys, removing any invalid routes, ensuring the index is correct etc. This process of fixing stale state is called rehydration. If you're writing a custom router, the getRehydratedState method lets you write custom rehydration logic to fix up state objects.
例如,index 应该是路由栈中的最后一个路由,如果指定了不同的值,React Navigation 会自动修复。例如,如果你想要重置应用的导航状态,使其显示 Profile 路由,并在返回时显示 Home 路由,并分发以下操作:
¥For example, index should be the last route in a stack, and if a different value was specified, React Navigation fixes it. For example, if you wanted to reset your app's navigation state to have it display the Profile route, and have the Home route displayed upon going back, and dispatched the following action:
navigation.reset({
index: 0,
routes: [{ name: 'Home' }, { name: 'Profile' }],
});
React Navigation 会在显示路由之前将 index 更正为 1。
¥React Navigation would correct index to 1 before the routes are displayed.
在执行诸如 reset、提供初始状态 等操作时,此功能非常方便,因为你可以安全地省略导航状态对象中的许多属性,并依靠 React Navigation 为你添加这些属性,从而使你的代码更简单。例如,你只能提供一个没有任何键的 routes 数组,React Navigation 将自动添加使其工作所需的所有内容:
¥This feature comes handy when doing operations such as reset, providing a initial state etc., as you can safely omit many properties from the navigation state object and relying on React Navigation to add those properties for you, making your code simpler. For example, you can only provide a routes array without any keys and React Navigation will automatically add everything that's needed to make it work:
const state = {
routes: [{ name: 'Home' }, { name: 'Profile' }],
};
补水后,它会看起来像这样:
¥After rehydration, it'll look something like this:
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 填充了缺失的部分,例如键、路由名称、索引等。
¥Here, React Navigation filled in the missing bits such as keys, route names, index etc.
还可以提供无效数据,例如不存在的屏幕,它会自动修复。虽然不建议使用无效的状态对象编写代码,但如果你执行诸如 状态持续性 之类的操作,那么它会非常有用,其中配置的屏幕可能在更新后发生更改,如果 React Navigation 没有自动修复状态对象,这可能会导致问题。
¥It's also possible to provide invalid data such as non-existent screens and it'll be fixed automatically. While it's not recommended to write code with invalid state objects, it can be super useful if you do things like state persistence, where the configured screens might have changed after an update, which could cause problems if React Navigation didn't fix the state object automatically.
如果你希望 React Navigation 修复无效状态,你需要确保状态对象中没有 stale: false。带有 stale: false 的状态对象被假定为有效的状态对象,React Navigation 不会尝试修复它们。
¥If you want React Navigation to fix invalid state, you need to make sure that you don't have stale: false in the state object. State objects with stale: false are assumed to be valid state objects and React Navigation won't attempt to fix them.
当你在 initialState 中提供状态对象时,React Navigation 会始终假定它是一个过时的状态对象,因为导航配置可能自上次以来已经发生更改。这确保了像 状态持续性 这样的功能能够流畅运行,而无需对状态对象进行额外的操作。
¥When you're providing a state object in initialState, React Navigation will always assume that it's a stale state object, since navigation configuration may have changed since the last time. This makes sure that things like state persistence work smoothly without extra manipulation of the state object.