Skip to main content
Version: 6.x

导航事件

你可以监听 React Navigation 发出的各种事件以获取某些事件的通知,并在某些情况下覆盖默认操作。有一些核心事件,例如 focusblur 等(如下所述)适用于每个导航器,以及仅适用于某些导航器的导航器特定事件。

¥You can listen to various events emitted by React Navigation to get notified of certain events, and in some cases, override the default action. There are few core events such as focus, blur etc. (documented below) that work for every navigator, as well as navigator specific events that work only for certain navigators.

除了核心事件之外,每个导航器都可以发出自己的自定义事件。例如,堆栈导航器发出 transitionStarttransitionEnd 事件,选项卡导航器发出 tabPress 事件等。你可以在各个导航器的文档中找到有关发出的事件的详细信息。

¥Apart from the core events, each navigator can emit their own custom events. For example, stack navigator emits transitionStart and transitionEnd events, tab navigator emits tabPress event etc. You can find details about the events emitted on the individual navigator's documentation.

核心活动

¥Core events

以下是每个导航器中可用的事件:

¥Following are the events available in every navigator:

focus

当屏幕聚焦时会发出此事件。

¥This event is emitted when the screen comes into focus.

对于大多数情况,useFocusEffect 钩子可能比手动添加监听器更合适。请参阅 本指南 了解更多详细信息,以决定你应该使用哪个 API。

¥For most cases, the useFocusEffect hook might be appropriate than adding the listener manually. See this guide for more details to decide which API you should use.

blur

当屏幕失去焦点时会发出此事件。

¥This event is emitted when the screen goes out of focus.

state

当导航器的状态更改时会发出此事件。该事件接收事件数据 (event.data.state) 中的导航器状态。

¥This event is emitted when the navigator's state changes. This event receives the navigator's state in the event data (event.data.state).

beforeRemove

当用户离开屏幕时会发出此事件,有机会 阻止用户离开

¥This event is emitted when the user is leaving the screen, there's a chance to prevent the user from leaving.

监听事件

¥Listening to events

有多种方法可以监听来自导航器的事件。每个注册为事件监听器的回调都会接收一个事件对象作为其参数。事件对象包含几个属性:

¥There are multiple ways to listen to events from the navigators. Each callback registered as an event listener receives an event object as its argument. The event object contains few properties:

  • data - 有关导航器传递的事件的附加数据。如果没有传递数据,则可以是 undefined

    ¥data - Additional data regarding the event passed by the navigator. This can be undefined if no data was passed.

  • target - 应接收事件的屏幕的路由键。对于某些事件,如果事件与特定屏幕无关,则这可能是 undefined

    ¥target - The route key for the screen that should receive the event. For some events, this maybe undefined if the event wasn't related to a specific screen.

  • preventDefault - 对于某些事件,事件对象上可能有 preventDefault 方法。调用此方法将阻止事件执行的默认操作(例如在 tabPress 上切换选项卡)。对阻止操作的支持仅适用于某些事件(例如 tabPress),并不适用于所有事件。

    ¥preventDefault - For some events, there may be a preventDefault method on the event object. Calling this method will prevent the default action performed by the event (such as switching tabs on tabPress). Support for preventing actions are only available for certain events like tabPress and won't work for all events.

你可以使用以下 API 监听事件:

¥You can listen to events with the following APIs:

在屏幕内,你可以使用 addListener 方法在 navigation 属性上添加监听器。addListener 方法有 2 个参数:事件的类型,以及要在该事件上调用的回调。它返回一个可以调用以取消订阅事件的函数。

¥Inside a screen, you can add listeners on the navigation prop with the addListener method. The addListener method takes 2 arguments: type of the event, and a callback to be called on the event. It returns a function that can be called to unsubscribe from the event.

示例:

¥Example:

const unsubscribe = navigation.addListener('tabPress', (e) => {
// Prevent default action
e.preventDefault();
});

通常,你会在 React.useEffect 中为函数组件添加事件监听器。例如:

¥Normally, you'd add an event listener in React.useEffect for function components. For example:

function Profile({ navigation }) {
React.useEffect(() => {
const unsubscribe = navigation.addListener('focus', () => {
// do something
});

return unsubscribe;
}, [navigation]);

return <ProfileContent />;
}

unsubscribe 函数可以作为效果中的清理函数返回。

¥The unsubscribe function can be returned as the cleanup function in the effect.

对于类组件,可以在 componentDidMount 生命周期方法中添加事件,并在 componentWillUnmount 中取消订阅:

¥For class components, you can add the event in the componentDidMount lifecycle method and unsubscribe in componentWillUnmount:

class Profile extends React.Component {
componentDidMount() {
this._unsubscribe = navigation.addListener('focus', () => {
// do something
});
}

componentWillUnmount() {
this._unsubscribe();
}

render() {
// Content of the component
}
}

要记住的一件事是,你只能使用 addListener 监听来自直接导航器的事件。例如,如果你尝试在嵌套在选项卡中的堆栈内的屏幕中添加监听器,则它将不会获取 tabPress 事件。如果你需要监听来自父导航器的事件,你可以使用 navigation.getParent 来获取对父导航器的 navigation prop 的引用并添加监听器。

¥One thing to keep in mind is that you can only listen to events from the immediate navigator with addListener. For example, if you try to add a listener in a screen that's inside a stack that's nested in a tab, it won't get the tabPress event. If you need to listen to an event from a parent navigator, you may use navigation.getParent to get a reference to parent navigator's navigation prop and add a listener.

const unsubscribe = navigation
.getParent('MyTabs')
.addListener('tabPress', (e) => {
// Do something
});

这里 'MyTabs' 指的是你在要监听其事件的父级 Tab.Navigatorid 属性中传递的值。

¥Here 'MyTabs' refers to the value you pass in the id prop of the parent Tab.Navigator whose event you want to listen to.

Screen 上的 listeners 属性

¥listeners prop on Screen

有时,你可能希望从定义导航器的组件而不是屏幕内部添加监听器。你可以使用 Screen 组件上的 listeners 属性来添加监听器。listeners 属性采用一个对象,其中事件名称作为键,监听器回调作为值。

¥Sometimes you might want to add a listener from the component where you defined the navigator rather than inside the screen. You can use the listeners prop on the Screen component to add listeners. The listeners prop takes an object with the event names as keys and the listener callbacks as values.

示例:

¥Example:

<Tab.Screen
name="Chat"
component={Chat}
listeners={{
tabPress: (e) => {
// Prevent default action
e.preventDefault();
},
}}
/>

你还可以传递一个回调,该回调返回带有监听器的对象。它将接收 navigationroute 作为参数。

¥You can also pass a callback which returns the object with listeners. It'll receive navigation and route as the arguments.

示例:

¥Example:

<Tab.Screen
name="Chat"
component={Chat}
listeners={({ navigation, route }) => ({
tabPress: (e) => {
// Prevent default action
e.preventDefault();

// Do something with the `navigation` object
navigation.navigate('AnotherPlace');
},
})}
/>

导航器上的 screenListeners 属性

¥screenListeners prop on the navigator

你可以将名为 screenListeners 的 prop 传递给导航器组件,你可以在其中为该导航器的所有屏幕指定事件的监听器。如果你想要监听特定事件而不考虑屏幕,或者想要监听常见事件(例如发送到所有屏幕的 state),这可能很有用。

¥You can pass a prop named screenListeners to the navigator component, where you can specify listeners for events from all screens for this navigator. This can be useful if you want to listen to specific events regardless of the screen, or want to listen to common events such as state which is emitted to all screens.

示例:

¥Example:

<Stack.Navigator
screenListeners={{
state: (e) => {
// Do something with the state
console.log('state changed', e.data);
},
}}
>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Profile" component={ProfileScreen} />
</Stack.Navigator>

listeners 类似,你也可以将函数传递给 screenListeners。该函数将接收每个屏幕的 navigation 属性route 属性。如果你需要访问 navigation 对象,这会很有用。

¥Similar to listeners, you can also pass a function to screenListeners. The function will receive the navigation prop and the route prop for each screen. This can be useful if you need access to the navigation object.

<Tab.Navigator
screenListeners={({ navigation }) => ({
state: (e) => {
// Do something with the state
console.log('state changed', e.data);

// Do something with the `navigation` object
if (!navigation.canGoBack()) {
console.log("we're on the initial screen");
}
},
})}
>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Profile" component={ProfileScreen} />
</Tab.Navigator>