导航属性参考
应用中的每个 screen
组件都会自动提供 navigation
属性。该属性包含各种用于调度导航操作的便利功能。它看起来像这样:
¥Each screen
component in your app is provided with the navigation
prop automatically. The prop contains various convenience functions that dispatch navigation actions. It looks like this:
-
navigation
-
navigate
- 转到给定的屏幕,根据导航器的不同,其行为也会有所不同¥
navigate
- go to the given screen, this will behave differently based on the navigator -
goBack
- 返回上一个屏幕,当在堆栈中使用时,这将弹出当前屏幕¥
goBack
- go back to the previous screen, this will pop the current screen when used in a stack -
reset
- 将导航器的导航状态替换为给定状态¥
reset
- replace the navigation state of the navigator with the given state -
setParams
- 将新参数合并到路由的参数中¥
setParams
- merge new params onto the route's params -
dispatch
- 发送一个动作对象来更新 导航状态¥
dispatch
- send an action object to update the navigation state -
setOptions
- 更新屏幕的选项¥
setOptions
- update the screen's options -
isFocused
- 检查屏幕是否聚焦¥
isFocused
- check whether the screen is focused -
canGoBack
- 检查是否可以从当前屏幕返回¥
canGoBack
- check whether it's possible to go back from the current screen -
getState
- 获取导航器的导航状态¥
getState
- get the navigation state of the navigator -
getParent
- 获取父屏幕的导航对象(如果有)¥
getParent
- get the navigation object of the parent screen, if any -
addListener
- 订阅屏幕事件¥
addListener
- subscribe to events for the screen -
removeListener
- 取消订阅屏幕事件¥
removeListener
- unsubscribe from events for the screen
-
需要强调的是,navigation
属性并未传递给所有组件;只有 screen
组件会自动接收此属性!React Navigation 在这里并没有发挥任何作用。例如,如果你要定义 MyBackButton
组件并将其渲染为屏幕组件的子组件,则你将无法访问其上的 navigation
属性。但是,如果你希望在任何组件中访问 navigation
属性,则可以使用 useNavigation
钩子。
¥It's important to highlight the navigation
prop is not passed in to all components; only screen
components receive this prop automatically! React Navigation doesn't do any magic here. For example, if you were to define a MyBackButton
component and render it as a child of a screen component, you would not be able to access the navigation
prop on it. If, however, you wish to access the navigation
prop in any of your components, you may use the useNavigation
hook.
setParams
/setOptions
等只能在useEffect
/useLayoutEffect
/componentDidMount
/componentDidUpdate
等中调用。不能在渲染期间或构造函数中调用。¥
setParams
/setOptions
etc. should only be called inuseEffect
/useLayoutEffect
/componentDidMount
/componentDidUpdate
etc. Not during render or in constructor.
依赖于导航器的功能
¥Navigator-dependent functions
根据当前导航器的类型,navigation
属性上存在一些附加功能。
¥There are several additional functions present on navigation
prop based on the kind of the current navigator.
如果导航器是堆栈导航器,则提供了 navigate
和 goBack
的多种替代方案,你可以使用你喜欢的任何一个。其功能是:
¥If the navigator is a stack navigator, several alternatives to navigate
and goBack
are provided and you can use whichever you prefer. The functions are:
-
navigation
-
replace
- 将当前屏幕替换为新屏幕¥
replace
- replace the current screen with a new one -
push
- 将新屏幕推入堆栈¥
push
- push a new screen onto the stack -
pop
- 返回到堆栈中¥
pop
- go back in the stack -
popToTop
- 转到堆栈顶部¥
popToTop
- go to the top of the stack
-
有关这些方法的更多详细信息,请参阅 堆栈导航器助手 和 原生堆栈导航器辅助程序。
¥See Stack navigator helpers and Native Stack navigator helpers for more details on these methods.
如果导航器是选项卡导航器,则还可以使用以下内容:
¥If the navigator is a tab navigator, the following are also available:
-
navigation
-
jumpTo
- 转到选项卡导航器中的特定屏幕¥
jumpTo
- go to a specific screen in the tab navigator
-
有关这些方法的更多详细信息,请参阅 底部选项卡导航助手、Material 顶部选项卡导航助手 和 材质底部选项卡导航助手。
¥See Bottom Tab navigator helpers, Material Top Tab navigator helpers and Material Bottom Tab navigator helpers for more details on these methods.
如果导航器是抽屉式导航器,还可以使用以下内容:
¥If the navigator is a drawer navigator, the following are also available:
-
navigation
-
jumpTo
- 转到抽屉式导航器中的特定屏幕¥
jumpTo
- go to a specific screen in the drawer navigator -
openDrawer
- 打开抽屉¥
openDrawer
- open the drawer -
closeDrawer
- 关上抽屉¥
closeDrawer
- close the drawer -
toggleDrawer
- 切换状态,即。从关闭切换到打开,反之亦然¥
toggleDrawer
- toggle the state, ie. switch from closed to open and vice versa
-
有关这些方法的更多详细信息,请参阅 抽屉导航助手。
¥See Drawer navigator helpers for more details on these methods.
常用 API 参考
¥Common API reference
你与 navigation
属性的绝大多数互动将涉及 navigate
、goBack
和 setParams
。
¥The vast majority of your interactions with the navigation
prop will involve navigate
, goBack
, and setParams
.
navigate
navigate
方法允许我们导航到应用中的另一个屏幕。它需要以下参数:
¥The navigate
method lets us navigate to another screen in your app. It takes the following arguments:
navigation.navigate(name, params)
-
name
- 已在某处定义的路由的目的地名称¥
name
- A destination name of the route that has been defined somewhere -
params
- 要传递到目标路由的参数。¥
params
- Params to pass to the destination route.
function HomeScreen({ navigation: { navigate } }) {
return (
<View>
<Text>This is the home screen of the app</Text>
<Button
onPress={() =>
navigate('Profile', { names: ['Brent', 'Satya', 'Michaś'] })
}
title="Go to Brent's profile"
/>
</View>
);
}
在 原生堆栈导航器 中,使用屏幕名称调用 navigate
将根据屏幕是否已存在而导致不同的行为。如果该屏幕已存在于堆栈历史记录中,它将返回到该屏幕并删除此后的所有屏幕。如果屏幕不存在,它将推送一个新屏幕。
¥In a native stack navigator, calling navigate
with a screen name will result in different behavior based on if the screen is already present or not. If the screen is already present in the stack's history, it'll go back to that screen and remove any screens after that. If the screen is not present, it'll push a new screen.
例如,如果你有一个历史记录为 Home > Profile > Settings
的堆栈,并且调用 navigate(Profile)
,则结果屏幕将为 Home > Profile
,因为它会返回到 Profile
并删除 Settings
屏幕。
¥For example, if you have a stack with the history Home > Profile > Settings
and you call navigate(Profile)
, the resulting screens will be Home > Profile
as it goes back to Profile
and removes the Settings
screen.
默认情况下,屏幕通过其名称进行标识。但你也可以使用 getId
属性对其进行自定义以将参数考虑在内。
¥By default, the screen is identified by its name. But you can also customize it to take the params into account by using the getId
prop.
例如,假设你为 Profile
屏幕指定了 getId
属性:
¥For example, say you have specified a getId
prop for Profile
screen:
<Tab.Screen
name={Profile}
component={ProfileScreen}
getId={({ params }) => params.userId}
/>
现在,如果你有一个历史记录为 Home > Profile (userId: bob) > Settings
的堆栈,并且调用 navigate(Profile, { userId: 'alice' })
,则结果屏幕将为 Home > Profile (userId: bob) > Settings > Profile (userId: alice)
,因为它会添加一个新的 Profile
屏幕,因为找不到匹配的屏幕。
¥Now, if you have a stack with the history Home > Profile (userId: bob) > Settings
and you call navigate(Profile, { userId: 'alice' })
, the resulting screens will be Home > Profile (userId: bob) > Settings > Profile (userId: alice)
since it'll add a new Profile
screen as no matching screen was found.
goBack
goBack
方法让我们返回到导航器中的上一个屏幕。
¥The goBack
method lets us go back to the previous screen in the navigator.
默认情况下,goBack
将从调用它的屏幕返回:
¥By default, goBack
will go back from the screen that it is called from:
function ProfileScreen({ navigation: { goBack } }) {
return (
<View>
<Button onPress={() => goBack()} title="Go back from ProfileScreen" />
</View>
);
}
从特定屏幕返回
¥Going back from a specific screen
考虑以下导航堆栈历史记录:
¥Consider the following navigation stack history:
navigation.navigate({ name: SCREEN, key: SCREEN_KEY_A });
navigation.navigate({ name: SCREEN, key: SCREEN_KEY_B });
navigation.navigate({ name: SCREEN, key: SCREEN_KEY_C });
navigation.navigate({ name: SCREEN, key: SCREEN_KEY_D });
现在你位于屏幕 D 上,想要返回屏幕 A(弹出 D、C 和 B)。然后你可以使用 navigate
:
¥Now you are on screen D and want to go back to screen A (popping D, C, and B).
Then you can use navigate
:
navigation.navigate({ key: SCREEN_KEY_A }); // will go to screen A FROM screen D
或者,由于屏幕 A 是堆栈的顶部,因此你可以使用 navigation.popToTop()
。
¥Alternatively, as screen A is the top of the stack, you can use navigation.popToTop()
.
reset
reset
方法让我们用新状态替换导航器状态:
¥The reset
method lets us replace the navigator state with a new state:
navigation.reset({
index: 0,
routes: [{ name: 'Profile' }],
});
reset
中指定的状态对象将现有的 导航状态 替换为新的,即删除现有屏幕并添加新屏幕。如果你想在更改状态时保留现有屏幕,可以使用 CommonActions.reset
和 dispatch
代替。
¥The state object specified in reset
replaces the existing navigation state with the new one, i.e. removes existing screens and add new ones. If you want to preserve the existing screens when changing the state, you can use CommonActions.reset
with dispatch
instead.
将导航器的状态对象视为内部对象,并且可能会在次要版本中发生更改。避免使用除 index
和 routes
之外的 导航状态 状态对象的属性,除非你确实需要它。如果某些功能在不依赖状态对象的结构的情况下无法实现,请提出问题。
¥Consider the navigator's state object to be internal and subject to change in a minor release. Avoid using properties from the navigation state state object except index
and routes
, unless you really need it. If there is some functionality you cannot achieve without relying on the structure of the state object, please open an issue.
setParams
setParams
方法让我们更新当前屏幕的参数(route.params
)。setParams
的工作方式类似于 React 的 setState
- 它将提供的参数对象与当前参数浅层合并。
¥The setParams
method lets us update the params (route.params
) of the current screen. setParams
works like React's setState
- it shallow merges the provided params object with the current params.
function ProfileScreen({ navigation: { setParams } }) {
return (
<Button
onPress={() =>
setParams({
friends:
route.params.friends[0] === 'Brent'
? ['Wojciech', 'Szymon', 'Jakub']
: ['Brent', 'Satya', 'Michaś'],
title:
route.params.title === "Brent's Profile"
? "Lucy's Profile"
: "Brent's Profile",
})
}
title="Swap title and friends"
/>
);
}
setOptions
setOptions
方法允许我们在组件内设置屏幕选项。如果我们需要使用组件的 props、状态或上下文来配置屏幕,这非常有用。
¥The setOptions
method lets us set screen options from within the component. This is useful if we need to use the component's props, state or context to configure our screen.
function ProfileScreen({ navigation, route }) {
const [value, onChangeText] = React.useState(route.params.title);
React.useEffect(() => {
navigation.setOptions({
title: value === '' ? 'No title' : value,
});
}, [navigation, value]);
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<TextInput
style={{ height: 40, borderColor: 'gray', borderWidth: 1 }}
onChangeText={onChangeText}
value={value}
/>
<Button title="Go back" onPress={() => navigation.goBack()} />
</View>
);
}
此处指定的任何选项都会与定义屏幕时指定的选项浅层合并。
¥Any options specified here are shallow merged with the options specified when defining the screen.
使用 navigation.setOptions
时,我们建议在屏幕的 options
属性中指定占位符并使用 navigation.setOptions
更新它。这可确保用户不会注意到更新选项的延迟。它还使其可以与延迟加载的屏幕一起使用。
¥When using navigation.setOptions
, we recommend specifying a placeholder in the screen's options
prop and update it using navigation.setOptions
. This makes sure that the delay for updating the options isn't noticeable to the user. It also makes it work with lazy-loaded screens.
你还可以使用 React.useLayoutEffect
来减少更新选项的延迟。但如果你支持 Web 并进行服务器端渲染,我们建议你不要这样做。
¥You can also use React.useLayoutEffect
to reduce the delay in updating the options. But we recommend against doing it if you support web and do server side rendering.
navigation.setOptions
旨在提供必要时更新现有选项的能力。它不能替代屏幕上的 options
属性。确保仅在绝对必要时才谨慎使用 navigation.setOptions
。
¥navigation.setOptions
is intended to provide the ability to update existing options when necessary. It's not a replacement for the options
prop on the screen. Make sure to use navigation.setOptions
sparingly only when absolutely necessary.
导航事件
¥Navigation events
屏幕可以使用 addListener
方法在 navigation
属性上添加监听器。例如,监听 focus
事件:
¥Screens can add listeners on the navigation
prop with the addListener
method. For example, to listen to the focus
event:
function Profile({ navigation }) {
React.useEffect(() => {
const unsubscribe = navigation.addListener('focus', () => {
// do something
});
return unsubscribe;
}, [navigation]);
return <ProfileContent />;
}
有关可用事件和 API 使用的更多详细信息,请参阅 导航事件。
¥See Navigation events for more details on the available events and the API usage.
isFocused
这个方法让我们检查屏幕当前是否聚焦。如果屏幕获得焦点,则返回 true
,否则返回 false
。
¥This method lets us check whether the screen is currently focused. Returns true
if the screen is focused and false
otherwise.
const isFocused = navigation.isFocused();
当值更改时,此方法不会重新渲染屏幕,主要在回调中有用。你可能想使用 useIsFocused 而不是直接使用它,它将返回一个布尔值 a 属性来指示屏幕是否聚焦。
¥This method doesn't re-render the screen when the value changes and mainly useful in callbacks. You probably want to use useIsFocused instead of using this directly, it will return a boolean a prop to indicating if the screen is focused.
高级 API 参考
¥Advanced API Reference
dispatch
函数不太常用,但如果你无法使用 navigate
、goBack
等可用方法执行所需操作,则这是一个很好的逃生口。除非绝对必要,否则我们建议避免经常使用 dispatch
方法。
¥The dispatch
function is much less commonly used, but a good escape hatch if you can't do what you need with the available methods such as navigate
, goBack
etc. We recommend to avoid using the dispatch
method often unless absolutely necessary.
dispatch
dispatch
方法让我们发送一个导航操作对象,该对象确定 导航状态 将如何更新。所有导航功能(例如 navigate
)都在幕后使用 dispatch
。
¥The dispatch
method lets us send a navigation action object which determines how the navigation state will be updated. All of the navigation functions like navigate
use dispatch
behind the scenes.
请注意,如果你想分派操作,你应该使用此库中提供的操作创建器,而不是直接编写操作对象。
¥Note that if you want to dispatch actions you should use the action creators provided in this library instead of writing the action object directly.
有关可用操作的完整列表,请参阅 导航操作文档。
¥See Navigation Actions Docs for a full list of available actions.
import { CommonActions } from '@react-navigation/native';
navigation.dispatch(
CommonActions.navigate({
name: 'Profile',
params: {},
})
);
分派操作对象时,你还可以指定一些附加属性:
¥When dispatching action objects, you can also specify few additional properties:
-
source
- 应被视为操作源的路由的键。例如,replace
操作将用给定的键替换路由。默认情况下,它将使用调度操作的路由的键。你可以显式传递undefined
来覆盖此行为。¥
source
- The key of the route which should be considered as the source of the action. For example, thereplace
action will replace the route with the given key. By default, it'll use the key of the route that dispatched the action. You can explicitly passundefined
to override this behavior. -
target
- 应应用操作的 导航状态 的键。默认情况下,如果导航器未处理,操作将冒泡到其他导航器。如果指定了target
,则如果具有相同键的导航器未处理该操作,该操作将不会冒泡。¥
target
- The key of the navigation state the action should be applied on. By default, actions bubble to other navigators if not handled by a navigator. Iftarget
is specified, the action won't bubble if the navigator with the same key didn't handle it.
示例:
¥Example:
import { CommonActions } from '@react-navigation/native';
navigation.dispatch({
...CommonActions.navigate('Profile'),
source: 'someRoutekey',
target: 'someStatekey',
});
自定义动作创建者
¥Custom action creators
还可以将动作创建器函数传递给 dispatch
。该函数将接收当前状态并需要返回一个导航操作对象以供使用:
¥It's also possible to pass a action creator function to dispatch
. The function will receive the current state and needs to return a navigation action object to use:
import { CommonActions } from '@react-navigation/native';
navigation.dispatch((state) => {
// Add the home route to the start of the stack
const routes = [{ name: 'Home' }, ...state.routes];
return CommonActions.reset({
...state,
routes,
index: routes.length - 1,
});
});
你可以使用此功能来构建你自己的助手,以便在你的应用中使用。下面是一个示例,它实现了在最后一个屏幕之前插入一个屏幕:
¥You can use this functionality to build your own helpers that you can utilize in your app. Here is an example which implements inserting a screen just before the last one:
import { CommonActions } from '@react-navigation/native';
const insertBeforeLast = (routeName, params) => (state) => {
const routes = [
...state.routes.slice(0, -1),
{ name: routeName, params },
state.routes[state.routes.length - 1],
];
return CommonActions.reset({
...state,
routes,
index: routes.length - 1,
});
};
然后像这样使用它:
¥Then use it like:
navigation.dispatch(insertBeforeLast('Home'));
canGoBack
此方法返回一个布尔值,指示当前导航器或任何父导航器中是否有可用的导航历史记录。你可以使用它来检查是否可以调用 navigation.goBack()
:
¥This method returns a boolean indicating whether there's any navigation history available in the current navigator, or in any parent navigators. You can use this to check if you can call navigation.goBack()
:
if (navigation.canGoBack()) {
navigation.goBack();
}
不要使用此方法来渲染内容,因为这不会触发重新渲染。这仅适用于回调、事件监听器等内部。
¥Don't use this method for rendering content as this will not trigger a re-render. This is only intended for use inside callbacks, event listeners etc.
getParent
此方法从当前导航器嵌套的父导航器返回导航属性。例如,如果你有一个堆栈导航器和一个嵌套在堆栈内的选项卡导航器,那么你可以在选项卡导航器的屏幕内使用 getParent
来获取从堆栈导航器传递的导航属性。
¥This method returns the navigation prop from the parent navigator that the current navigator is nested in. For example, if you have a stack navigator and a tab navigator nested inside the stack, then you can use getParent
inside a screen of the tab navigator to get the navigation prop passed from the stack navigator.
它接受一个可选的 ID 参数来引用特定的父导航器。例如,如果你的屏幕在抽屉导航器下的某处进行了多层嵌套,且 id
属性为 "LeftDrawer"
,则你可以直接引用它,而无需多次调用 getParent
。
¥It accepts an optional ID parameter to refer to a specific parent navigator. For example, if your screen is nested with multiple levels of nesting somewhere under a drawer navigator with the id
prop as "LeftDrawer"
, you can directly refer to it without calling getParent
multiple times.
要使用导航器的 ID,首先传递一个唯一的 id
属性:
¥To use an ID for a navigator, first pass a unique id
prop:
<Drawer.Navigator id="LeftDrawer">{/* .. */}</Drawer.Navigator>
然后当使用 getParent
时,而不是:
¥Then when using getParent
, instead of:
// Avoid this
const drawerNavigation = navigation.getParent().getParent();
// ...
drawerNavigation?.openDrawer();
你可以做:
¥You can do:
// Do this
const drawerNavigation = navigation.getParent('LeftDrawer');
// ...
drawerNavigation?.openDrawer();
这种方法允许组件不必知道导航器的嵌套结构。所以强烈建议在使用 getParent
的同时使用 id
。
¥This approach allows components to not have to know the nesting structure of the navigators. So it's highly recommended that use an id
when using getParent
.
如果没有匹配的父导航器,此方法将返回 undefined
。使用此方法时,请务必始终检查 undefined
。
¥This method will return undefined
if there is no matching parent navigator. Be sure to always check for undefined
when using this method.
getState
将导航器的状态对象视为内部对象,并且可能会在次要版本中发生更改。避免使用除 index
和 routes
之外的 导航状态 状态对象的属性,除非你确实需要它。如果某些功能在不依赖状态对象的结构的情况下无法实现,请提出问题。
¥Consider the navigator's state object to be internal and subject to change in a minor release. Avoid using properties from the navigation state state object except index
and routes
, unless you really need it. If there is some functionality you cannot achieve without relying on the structure of the state object, please open an issue.
此方法返回包含屏幕的导航器的状态对象。在极少数情况下获取导航器状态可能很有用。你很可能不需要使用此方法。如果你这样做,请确保你有充分的理由。
¥This method returns the state object of the navigator which contains the screen. Getting the navigator state could be useful in very rare situations. You most likely don't need to use this method. If you do, make sure you have a good reason.
如果你需要渲染内容的状态,你应该使用 useNavigationState
而不是此方法。
¥If you need the state for rendering content, you should use useNavigationState
instead of this method.