首页 > 解决方案 > react-navigation:检测屏幕,标签栏何时激活/出现/聚焦/模糊

问题描述

以前当我想在屏幕打开时做一些动作时,我把它们放在里面componentDidMount。例如,我可以获取一些数据。

像这样。

componentDidMount() {
  this.updateData();
}

但是react-navigation componentDidMount当用户第一次打开屏幕时只发生一次,如果以后用户再次打开这个页面,它不会触发componentDidMount。

检测页面(屏幕)何时激活并执行操作的正确方法是什么?

标签: react-nativereact-hooksreact-navigationonfocusviewdidappear

解决方案


反应导航 v6

当屏幕成为焦点时使用 API 调用获取数据

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

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

function ProfileScreen() {
  useFocusEffect(
    React.useCallback(() => {

      alert('Screen was focused');

      return () => {

        alert('Screen was unfocused');
        // Useful for cleanup functions

      };
    }, [])
  );

  return <View />;
}

一个布尔值,指示屏幕是否聚焦

React Navigation 提供了一个钩子,它返回一个布尔值,指示屏幕是否聚焦。当屏幕聚焦时,钩子将返回 true,当我们的组件不再聚焦时,钩子将返回 false。这使我们能够根据用户是否在屏幕上来有条件地渲染某些东西。

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

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

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

参考 v6.x:https ://reactnavigation.org/docs/function-after-focusing-screen/


年长者:

使用react-navigation,您可以分两步完成:

  1. componentDidMount在or中添加侦听componentWillMount器以挂钩事件

  2. 删除监听componentWillUnmount 器,避免意外调用

API 参考文档 v3.x、v4.x、v5.x

反应导航 v3.x、v4.x

addListener- 订阅导航生命周期的更新

React Navigation 向订阅它们的屏幕组件发出事件:

  • willFocus- 屏幕将聚焦
  • didFocus- 屏幕聚焦(如果有过渡,则过渡完成)
  • willBlur- 屏幕将不聚焦
  • didBlur- 屏幕失焦(如果有过渡,则过渡完成)

React-navigation 3.x、4.x示例:

const didBlurSubscription = this.props.navigation.addListener(
  'didBlur',
  payload => {
    console.debug('didBlur', payload);
  }
);

// Remove the listener when you are done
didBlurSubscription.remove();

参考 v4.x https://reactnavigation.org/docs/4.x/navigation-prop/#addlistener---subscribe-to-updates-to-navigation-lifecycle

更新的 v5.x

v5.x 中的事件已更改

屏幕可以像在 React Navigation 中一样在导航道具上添加侦听器。默认情况下,有 2 个事件可用:

  • focus - 当屏幕成为焦点时发出此事件
  • blur - 当屏幕失焦时发出此事件
  • state (advanced) - 当导航器的状态改变时触发此事件

来自 reactnavigation.org 的示例代码

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

  componentWillUnmount() {
    this._unsubscribe();
  }

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

与钩子一起使用

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

    return unsubscribe;
  }, [navigation]);

  return <ProfileContent />;
}

屏幕上的听众道具

<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');
    },
  })}
/>

参考 v5.x:https ://reactnavigation.org/docs/navigation-events


推荐阅读