React Native-带警报的BackHandler

时间:2018-11-09 20:05:39

标签: javascript android react-native react-navigation

我试图覆盖屏幕上的后退按钮,并提示注销。请参阅以下内容:

import React, { Component } from "react";
import { Alert, BackHandler } from "react-native";

export default class Dashboard extends Component {

    constructor(props) {
        super(props);
    }

    componentDidMount() {

        BackHandler.addEventListener("hardwareBackPress",this.handleBackPress);
    }

    componentWillUnmount() {
        BackHandler.removeEventListener("hardwareBackPress", this.handleBackPress);
    }

    handleBackPress() {
        Alert.alert(
            "Logout",
            "Are you sure you want to logout?",
            [
                {
                    text: "Cancel",
                    onPress: () => {
                        console.log("Cancel Pressed");
                    },
                    style: "cancel"
                },
                { text: "Logout", onPress: () => this.handleLogout() }
            ],
            { cancelable: false }
        );
    }

    handleLogout() {
        this.props.navigation.navigate("Login");
    }
}

如您所见,在进行更改时,我将“ hardwareBackPress”绑定并取消绑定到this.handleBackPress。请注意,我必须使用.bind(this),否则会得到

  

_this2.handleLogout不是函数

在警报中按注销时。预期的功能是:

  • 按下后退按钮
  • 功能已禁用(无法导航)
  • 显示警告
  • 按下确定
  • 向后导航
  • 上一个屏幕上的“后退”按钮具有默认操作

但是实际发生的是:

  • 按下后退按钮
  • 向后导航
  • 显示警告
  • (后续步骤无关紧要)

我注意到return true;的任何地方都没有handleBackPress(),所以我添加了:

handleBackPress() {
    Alert.alert(
        "Logout",
        "Are you sure you want to logout?",
        [
            {
                text: "Cancel",
                onPress: () => {
                    console.log("Cancel Pressed");
                },
                style: "cancel"
            },
            {
                text: "Logout",
                onPress: () => {
                    return this.handleLogout();
                }
            }
        ],
        { cancelable: false }
    );

    return true;
}

但是现在发生的是:

  • 按下后退按钮
  • 功能已禁用(无法导航)
  • 显示警告
  • 按下确定
  • 向后导航
  • 在上一个屏幕上按
  • 返回按钮会显示警报

我已确认调用了componentDidUnmount(),但似乎并未删除事件监听器。

以前有人遇到过此问题吗?现在,我只是通过在应用程序的入口点添加此处理程序来全局禁用后退按钮,但这不是一个长期解决方案。

编辑:我注意到有一个生命周期替代方案,因此我尝试实现该方案:

componentDidMount() {
    this.backHandler = BackHandler.addEventListener("hardwareBackPress", () => {
        Alert.alert("Logout", "Are you sure you want to logout?", [{ text: "Cancel", onPress: () => {}, style: "cancel" }, { text: "Logout", onPress: () => this.handleLogout() }], { cancelable: false });
        return true;
    });
}

componentWillUnmount() {
    this.backHandler.remove();
}

尽管这使它工作(以某种方式),但它还有另一个副作用。一旦我向前导航(由于堆叠导航,不会触发componentDidUnmount())并向后导航,后退按钮的行为如下:

  • 按下后退按钮
  • 功能已禁用(无法导航)
  • 未显示警报

我正在浏览的屏幕已覆盖了“后退”按钮,并且在此替代生命周期中似乎无法正常使用。将尝试在所有后续屏幕上实施不同的方法;看看它是否正常运行。

1 个答案:

答案 0 :(得分:0)

使用文档(https://facebook.github.io/react-native/docs/backhandler)中的生命周期替代方法似乎可以处理Alert和return true;的异常行为:

Dashboard.js

componentDidMount() {
    this.backHandler = BackHandler.addEventListener("hardwareBackPress", () => {
        Alert.alert("Logout", "Are you sure you want to logout?", [{ text: "Cancel", onPress: () => {}, style: "cancel" }, { text: "Logout", onPress: () => this.handleLogout() }], { cancelable: false });
        return true;
    });
}

componentWillUnmount() {
    this.backHandler.remove();
}

handleLogout() {
    global.screenName = "Dashboard";
    return this.props.navigation.navigate("Login");
}

只要需要覆盖后退按钮的所有后续屏幕也使用相同的逻辑:

Detail.js(堆栈导航器中的后续屏幕):

componentDidMount() {
    this.backHandler = BackHandler.addEventListener("hardwareBackPress", () => {
        return this.props.navigation.navigate("Dashboard");
    });
}

componentWillUnmount() {
    this.backHandler.remove();
}