仅在特定屏幕中对物理后退按钮按下执行缩减器操作以响应本机

perform a reducer action on physical back button press in react native only in a specific screen

我有一个案例,我的应用程序中有一个底部选项卡导航器。第一个底部选项卡是一个堆栈导航器,由主屏幕和 siteDetail Screen 组成。用户可以从主屏幕导航到 SiteDetail 屏幕。同样,底部选项卡中还有其他元素。

只要用户在 SiteDetail 屏幕中按下后退按钮,他就会被引导回到主主页(这是显而易见的)。但在此之前我需要更新减速器。所以我实现了一个 BackHandler 监听器:

constructor(props){
super(props);
//.........
   this.handleBackButtonClick = this.handleBackButtonClick.bind(this);
}       

componentDidMount() {
    
    this.fetchSiteDetail();
    BackHandler.addEventListener('hardwareBackPress', this.handleBackButtonClick);
}

handleBackButtonClick() {
   
    if (this.props.isRestroDetailPage) {// doesn't  work of course
        this.props.unselectSite();
    }
}

componentWillUnmount() {
    BackHandler.removeEventListener('hardwareBackPress');
}

后处理者的话如预期的那样。但是,当我遍历其他底部选项卡并按下后退按钮时,它也有效。我轻松定制了软后退按钮,但对于硬后退按钮,听者会听到来自底部选项卡的所有按键。

我确实理解这种行为,但是我如何才能让程序仅在我在 SiteDetail 屏幕上按下后退按钮时才应用 this.props.unselectSite()。 我正在使用 React Navigation v5,如果它有帮助的话。

您可以在执行操作之前使用条件,react-native 有一个道具来验证屏幕是否 select。 一个例子:

handleBackButtonPressAndroid = () => {
    let { navigation } = this.props;
    if (navigation.isFocused()) {
      //execute what you want.
    };
}

你的情况:

handleBackButtonClick() {
    let { navigation } = this.props;
    if(navigation.isFocused()) {
      if (this.props.isRestroDetailPage) {// doesn't  work of course
          this.props.unselectSite();
      }
    }
}

文档:https://reactnavigation.org/docs/navigation-prop/

React-Navigation 刚刚添加了一个新方法,应该可以帮助您,beforeRemove

像这样:

React.useEffect(
    () =>
      navigation.addListener('beforeRemove', (e) => {
        if (!props.isRestroDetailPage) {
          // If we don't have unsaved changes, then we don't need to do anything
          return;
        }

        // Prevent default behavior of leaving the screen
        e.preventDefault();

        this.props.unselectSite();
        navigation.dispatch(e.data.action)
      }),
    [navigation, props.isRestroDetailPage]
  );