跳至主要内容
版本: 6.x

屏幕焦点改变时调用函数

在本指南中,我们将调用函数或在屏幕聚焦时渲染内容。这对于在用户重新访问标签导航器中的特定屏幕时进行额外的 API 调用,或在用户点击应用程序时跟踪用户事件很有用。

我们有多种方法可供选择

  1. 使用事件监听器监听 'focus' 事件。
  2. 使用 react-navigation 提供的 useFocusEffect 钩子。
  3. 使用 react-navigation 提供的 useIsFocused 钩子。

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

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

使用这种方法,我们只能在屏幕获得焦点时调用操作。这对于执行诸如记录屏幕视图以进行分析之类的操作很有用。

示例

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 的更多详细信息,请参阅 导航事件指南

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

使用 useFocusEffect 钩子触发操作

React Navigation 提供了一个 钩子,它在屏幕获得焦点时运行一个效果,并在屏幕失去焦点时清理它。这对于诸如添加事件监听器、在屏幕获得焦点时使用 API 调用获取数据或任何其他需要在屏幕进入视图时发生的任何操作等情况很有用。

当我们尝试在页面失去焦点时停止某些操作时,这尤其方便,例如停止视频或音频文件播放,或停止跟踪用户的地理位置。

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 文档。

使用 useIsFocused 钩子重新渲染屏幕

React Navigation 提供了一个 钩子,它返回一个布尔值,指示屏幕是否处于焦点状态。

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

useIsFocused 钩子将在我们聚焦和取消聚焦屏幕时导致我们的组件重新渲染。使用此钩子组件可能会导致不必要的组件重新渲染,因为屏幕进出焦点。这可能会导致问题,具体取决于我们在聚焦时调用的操作类型。因此,我们建议仅在您需要触发重新渲染时使用此钩子。对于诸如订阅事件或获取数据之类的副作用,请使用上面描述的方法。

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 文档 中有记录。