Skip to main content
Version: 6.x

当焦点屏幕改变时调用函数

在本指南中,我们将调用一个函数或在屏幕聚焦上渲染某些内容。当用户重新访问选项卡导航器中的特定屏幕时,这对于进行额外的 API 调用很有用,或者在用户点击我们的应用时跟踪用户事件。

¥In this guide we will call a function or render something on screen focusing. This is useful for making additional API calls when a user revisits a particular screen in a Tab Navigator, or to track user events as they tap around our app.

我们可以采用多种方法:

¥There are multiple approaches available to us:

  1. 使用事件监听器监听 'focus' 事件。

    ¥Listening to the 'focus' event with an event listener.

  2. 使用 react-navigation 提供的 useFocusEffect 钩子。

    ¥Using the useFocusEffect hook provided by react-navigation.

  3. 使用 react-navigation 提供的 useIsFocused 钩子。

    ¥Using the useIsFocused hook provided by react-navigation.

使用 'focus' 事件监听器触发操作

¥Triggering an action with a 'focus' event listener

我们还可以使用事件监听器来监听 'focus' 事件。设置事件监听器后,我们还必须在屏幕卸载时停止监听该事件。

¥We can also listen to the 'focus' event with an event listener. After setting up an event listener, we must also stop listening to the event when the screen is unmounted.

通过这种方法,我们只能在屏幕聚焦时调用操作。这对于执行诸如记录屏幕视图以进行分析之类的操作非常有用。

¥With this approach, we will only be able to call an action when the screen focuses. This is useful for performing an action such as logging the screen view for analytics.

示例:

¥Example:

import * as React from 'react';
import { View } from 'react-native';

function ProfileScreen({ navigation }) {
React.useEffect(() => {
const unsubscribe = navigation.addListener('focus', () => {
// The screen is focused
// Call any action
});

// Return the function to unsubscribe from the event so it gets removed on unmount
return unsubscribe;
}, [navigation]);

return <View />;
}

有关事件监听器 API 的更多详细信息,请参阅 导航活动指南

¥See the navigation events guide for more details on the event listener API.

在大多数情况下,建议使用 useFocusEffect 钩子,而不是手动添加监听器。详情请参阅下文。

¥In most cases, it's recommended to use the useFocusEffect hook instead of adding the listener manually. See below for details.

使用 useFocusEffect 钩子触发操作

¥Triggering an action with the useFocusEffect hook

React Navigation 提供了一个 hook,它在屏幕聚焦时运行效果,并在屏幕失焦时清理它。这对于添加事件监听器、在屏幕聚焦时通过 API 调用获取数据或屏幕进入视图后需要执行的任何其他操作等情况非常有用。

¥React Navigation provides a hook that runs an effect when the screen comes into focus and cleans it up when it goes out of focus. This is useful for cases such as adding event listeners, for fetching data with an API call when a screen becomes focused, or any other action that needs to happen once the screen comes into view.

当我们试图在页面未聚焦时停止某些操作(例如停止播放视频或音频文件,或停止跟踪用户位置)时,这特别方便。

¥This is particularly handy when we are trying to stop something when the page is unfocused, like stopping a video or audio file from playing, or stopping the tracking of a user's location.

import { useFocusEffect } from '@react-navigation/native';

function Profile({ userId }) {
const [user, setUser] = React.useState(null);

useFocusEffect(
React.useCallback(() => {
const unsubscribe = API.subscribe(userId, (user) => setUser(data));

return () => unsubscribe();
}, [userId])
);

return <ProfileContent user={user} />;
}

有关更多详细信息,请参阅 useFocusEffect 文档。

¥See the useFocusEffect documentation for more details.

使用 useIsFocused 钩子重新渲染屏幕

¥Re-rendering screen with the useIsFocused hook

React Navigation 提供了 hook,它返回一个布尔值,指示屏幕是否获得焦点。

¥React Navigation provides a hook that returns a boolean indicating whether the screen is focused or not.

当屏幕聚焦时,钩子将返回 true;当我们的组件不再聚焦时,钩子将返回 false。这使我们能够根据用户是否在屏幕上有条件地渲染某些内容。

¥The hook will return true when the screen is focused and false when our component is no longer focused. This enables us to render something conditionally based on whether the user is on the screen or not.

当我们聚焦和取消聚焦屏幕时,useIsFocused 钩子将导致我们的组件重新渲染。当屏幕进入和离开焦点时,使用此钩子组件可能会导致不必要的组件重新渲染。这可能会导致问题,具体取决于我们呼吁关注的操作类型。因此,我们建议仅在需要触发重新渲染时才使用此钩子。对于订阅事件或获取数据等副作用,请使用上述方法。

¥The useIsFocused hook will cause our component to re-render when we focus and unfocus a screen. Using this hook component may introduce unnecessary component re-renders as a screen comes in and out of focus. This could cause issues depending on the type of action we're calling on focusing. Hence we recommend to use this hook only if you need to trigger a re-render. For side-effects such as subscribing to events or fetching data, use the methods described above.

import * as React from 'react';
import { Text } from 'react-native';
import { useIsFocused } from '@react-navigation/native';

function Profile() {
// This hook returns `true` if the screen is focused, `false` otherwise
const isFocused = useIsFocused();

return <Text>{isFocused ? 'focused' : 'unfocused'}</Text>;
}

该示例也记录在 useIsFocused API 文档

¥This example is also documented in the useIsFocused API documentation.