react-navigation升級3.x 問題解決方案

背景

  • 最近把以前的RN項目更新了,react-native升級到了0.58,react-navigation升級到了3.3.0。
  • 咱們項目結構是TabNavigation,有A/B/C三個Tab,根據用戶的權限來決定展現幾個Tab,會有四種狀況,ABC、AC、BC、C(C是一直存在的)。用createAppContainer建立了四個TabNavigation

升級

  • 按照舊版本的實現,建立三個StackNavigator,按照權限再建立四個TabNavigator,根據權限來決定展現哪一個。新版本升級後,統一使用createXXXNavigator生成,而後經過createAppContainer導出才行。

遇到的問題

  • 修改成新版本的寫法後,發現進入二級頁面tabbar不隱藏了,以前的參數無論用了。查閱文檔後,官方給出了建議的寫法:把TabNavigator當作StackNavigator的一部分,push時二級頁面整個蓋到TabNavigator上。reactnavigation.org/docs/en/nav…
  • 以前跳轉二級頁面時寫的是this.props.navigation.navigate('XXX'),按照上面官方建議修改以後發現很差使了…緣由是this.props.navigation獲取到的是當前頁面的navigation,可是咱們外面包了一層TabNavigator,此時應該用TabNavigator的navigation去navigate('XXX')。好比頁面A和頁面B,在TabC上,在頁面A上navigate('D'),可是頁面A的StackNavigator裏沒有D哇,而且咱們要把Tab蓋住哇,因此要用TabC的this.props.navigation去navigate('D')才能夠。若是頁面A的StackNavigator裏有D,navigate時tabbar還會在,隱藏不了,就又回到了上一個問題。個人解決辦法是:在跳轉二級頁面時發個通知,用TabC接收,而後再TabC裏進行頁面跳轉。有點笨,可是想不到其它好辦法了…
  • 還有就是安卓物理返回鍵的問題。這個問題真的很尷尬啊,在第一個Tab進二級頁面,按返回鍵能夠很棒的返回,然而在第二個和第三個Tab進二級頁面後,按一下返回沒反應,按兩下就直接到第一個Tab了!!!Oh my god~~~~而後找解決方案,官方文檔給出了reactnavigation.org/docs/en/cus…,我是想在一個地方寫而後全局均可用,來來回試了不少次也沒弄好,只能每一個頁面都寫了一次,具體實現看下面的代碼。

具體實現

  1. 咱們項目結構是TabNavigation,有A/B/C三個Tab,根據用戶的權限來決定展現幾個Tab,會有四種狀況,ABC、AC、BC、C(C是一直存在的)。用createAppContainer建立了四個TabNavigation
const ABCTabbar = createBottomTabNavigator({
    'ANav': {screen: ANav,},
    'BNav': {screen: BNav,},
    'CNav': {screen: CNav,},
});
const ACTabbar = createBottomTabNavigator({
    'ANav': {screen: ANav,},
    'CNav': {screen: CNav,},
});
const BCTabbar = createBottomTabNavigator({
    'BNav': {screen: BNav,},
    'CNav': {screen: CNav,},
});
const CTabbar = createBottomTabNavigator({
    'CNav': {screen: CNav,},
});

const ABCTabNavigator = createAppContainer(ABCTabbar);
const ACTabNavigator = createAppContainer(ACTabbar);
const BCTabNavigator = createAppContainer(BCTabbar);
const CTabNavigator = createAppContainer(CTabbar);
export { ABCTabNavigator, ACTabNavigator, BCTabNavigator, CTabNavigator };
複製代碼
  1. 新建MainNavigation.js,在這個文件裏判斷用戶有哪些權限,而後展現相應的TabNavigator
class MainNav extends Component {
	render() {
	  if (this.state.permission === 'ABC') {
	    return (<ABCTabNavigator/>);
	  } else if (this.state.permission == 'AC') {
	    return (<ACTabNavigator/>);
	  } else if (this.state.permission == 'BC') {
	    return (<BCTabNavigator/>);
	  } else {
	    return (<CTabNavigator/>);
	  }
	}
}
複製代碼
  1. 在MainNavigation.js裏,生成一個MainNavigation,在入口render裏配置成就OK了
const Main = createStackNavigator({
    MainNav: {screen: MainNav},
    DPage: {screen: DPage},
});
const MainNavigation = createAppContainer(Main);
export default MainNavigation;
複製代碼
  1. 安卓物理返回鍵問題。從網上找了個工具類AndroidBackAction.js,修改了一下
import {BackHandler} from 'react-native';

const handleAndroidBackButton = callback => {
  BackHandler.addEventListener('hardwareBackPress', callback);
};

const removeAndroidBackButtonHandler = (callback) => {
  BackHandler.removeEventListener('hardwareBackPress', callback);
}

export {handleAndroidBackButton, removeAndroidBackButtonHandler};
複製代碼

頁面上的實現:html

import {handleAndroidBackButton, removeAndroidBackButtonHandler} from '../../Util/AndroidBackAction.js'; 	// 你本身的路徑

export default class D extends Component {

    constructor(props) {
        super(props);
        handleAndroidBackButton(this.onBackAndroid);	// 必定要在這裏寫
    }

    componentWillUnmount() {
        removeAndroidBackButtonHandler(this.onBackAndroid);	// 必定要在這裏寫
    }

    onBackAndroid = () => {
        this.props.navigation.goBack();
        return true;
    };
}

複製代碼

還有個按兩下退出應用的,我是寫在了入口的地方(就配置的地方),監聽的方式是同樣的,就是onBackAndroid實現不同react

onBackAndroid = () => {
    if (this.lastBackPressed && this.lastBackPressed + 2000 >= Date.now()) {
        //最近2秒內按過back鍵,能夠退出應用。
        return false;
    }
    this.lastBackPressed = Date.now();
    ToastAndroid.show('再按返回退出應用', ToastAndroid.SHORT);
    return true;
};
複製代碼

好啦,大功告成~~~android

結束~撒花~~~react-native

相關文章
相關標籤/搜索