跳到主要内容
版本: 7.x

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

在本指南中,我们将介绍如何在屏幕获得焦点时调用函数或渲染内容。这对于在用户重新访问 Tab Navigator 中的特定屏幕时进行额外的 API 调用,或者在用户点击我们的应用时跟踪用户事件非常有用。

我们有多种方法可用

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

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

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

通过这种方法,我们只能在屏幕获得焦点时调用操作。这对于执行诸如记录屏幕浏览量以进行分析等操作非常有用。

示例

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

function ProfileScreen() {
const navigation = useNavigation();

React.useEffect(() => {
const unsubscribe = navigation.addListener('focus', () => {
alert('Screen is focused');
// 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 />;
}
Snack 上尝试

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

在大多数情况下,建议使用 useFocusEffect Hook 而不是手动添加监听器。请参阅下文了解详细信息。

使用 useFocusEffect Hook 触发操作

React Navigation 提供了一个 Hook,该 Hook 在屏幕获得焦点时运行一个 effect,并在屏幕失去焦点时清理它。这对于诸如添加事件监听器、在屏幕获得焦点时通过 API 调用获取数据,或任何其他需要在屏幕进入视图后发生的操作非常有用。

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

function ProfileScreen() {
useFocusEffect(
React.useCallback(() => {
alert('Screen was focused');
// Do something when the screen is focused
return () => {
alert('Screen was unfocused');
// Do something when the screen is unfocused
// Useful for cleanup functions
};
}, [])
);

return <View />;
}
Snack 上尝试

请参阅 useFocusEffect 文档了解更多详细信息。

使用 useIsFocused Hook 重新渲染屏幕

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

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

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

function ProfileScreen() {
const isFocused = useIsFocused();

return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>{isFocused ? 'focused' : 'unfocused'}</Text>
</View>
);
}
Snack 上尝试

此示例也在 useIsFocused API 文档中进行了文档化。