React Native物理back返回鍵的使用

b10l07發表於2017-03-22

直接使用通用程式碼就好了

componentWillMount() {
        if (Platform.OS === 'android') {
            BackAndroid.addEventListener('hardwareBackPress', this.onBackAndroid);
        }
    }
    componentWillUnmount() {
        if (Platform.OS === 'android') {
            BackAndroid.removeEventListener('hardwareBackPress', this.onBackAndroid);
        }
    }

    onBackAndroid = () => {
        const  navigator  = this.refs.navigator;
const { navigator } = this.props;  
        const routers = navigator.getCurrentRoutes();
        console.log('當前路由長度:'+routers.length);
        if (routers.length > 1) {
            navigator.pop();
            return true;//接管預設行為
        }
        return false;//預設行為

    };

注意匯入 Platform 和 BackAndroid 。
這裡的 const { navigator } = this.props; 要看你具體的 navigator 是在哪裡,這裡是因為我的navigator 已經繫結了 ref="navigator",所以我直接改為 this.refs.navigator就可以了。

需要注意的是,不論是bind還是箭頭函式,
每次被執行都返回的是一個新的函式引用,
因此如果你還需要函式的引用去做一些別的事情(譬如解除安裝監聽器),那麼你必須自己儲存這個引用

// 錯誤的做法

class PauseMenu extends React.Component{
    componentWillMount(){
        AppStateIOS.addEventListener('change', this.onAppPaused.bind(this));
    }
    componentDidUnmount(){
        AppStateIOS.removeEventListener('change', this.onAppPaused.bind(this));
    }
    onAppPaused(event){
    }
}

// 正確的做法1

class PauseMenu extends React.Component{
    constructor(props){
        super(props);
        this._onAppPaused = this.onAppPaused.bind(this);
    }
    componentWillMount(){
        AppStateIOS.addEventListener('change', this._onAppPaused);
    }
    componentDidUnmount(){
        AppStateIOS.removeEventListener('change', this._onAppPaused);
    }
    onAppPaused(event){
    }
}

// 正確的做法2

class PauseMenu extends React.Component{
    componentWillMount(){
        AppStateIOS.addEventListener('change', this.onAppPaused);
    }
    componentDidUnmount(){
        AppStateIOS.removeEventListener('change', this.onAppPaused);
    }
    onAppPaused = (event) => {
        //把方法直接作為一個arrow function的屬性來定義,初始化的時候就繫結好了this指標
    }
}

BackAndroid在iOS平臺下是一個空實現,所以理論上不做這個Platform.OS === 'android'判斷也是安全的。如果所有事件監聽函式中,沒有任何一個返回真值,就會預設呼叫預設行為特別注意:navigator是同一個,這個事件在最外層註冊就行(不是initialRoute的元件,是AppRegistry的元件),否則會呼叫多次pop的,這個程式碼接管的是整個應用的後退鍵放到initialRoute裡會有問題,你兩三個頁面測不出來,頁面層次多了元件會unmount,然後事件就丟了addEventListener()第三個引數useCapture (Boolean)詳細解析:
•true 的觸發順序總是在 false 之前;
•如果多個均為 true,則外層的觸發先於內層;
•如果多個均為 false,則內層的觸發先於外層。

相關文章