【问题标题】:React Native - BackHandler with AlertReact Native - 带有警报的 BackHandler
【发布时间】:2018-11-09 20:05:38
【问题描述】:

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

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 不是函数

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

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

但实际发生的是:

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

我注意到我的handleBackPress() 中没有return true;,所以我补充说:

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(),由于堆叠导航)并向后导航,后退按钮的行为如下:

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

我正在导航到的屏幕的后退按钮被覆盖,并且似乎无法很好地适应这种替代生命周期。将尝试在所有后续屏幕上实施不同的方法;看看它是否正常运行。

【问题讨论】:

    标签: javascript android react-native react-navigation


    【解决方案1】:

    使用文档中的生命周期替代方案 (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();
    }
    

    【讨论】:

    • 谢谢你!你的解决方案仍然有效:)
    猜你喜欢
    • 1970-01-01
    • 2019-06-29
    • 1970-01-01
    • 2019-02-23
    • 1970-01-01
    • 2021-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多