RN学习中关于物理返回键的随手记
记录下RN关于监听物理返回键的方法,及遇到的坑
首先我要实现的是在导航界面中实现点击两次退出应用,其他子界面的时候点击返回
键回到上一级界面。
首先记录下遇到的第一个坑
网上查找到的方法就是在componentDIDMount中注册BackHandler,我就在我的
bottomNavigator 中去实现了代码,这时能实现了点击两次退出应用,但是,当跳
转到子级界面时,返回键依然是点击两次退出应用,如果我在子级界面再去监听返回
键的时候,就又把导航页的返回事件覆盖掉了,而且这样写是获取不到navigation 和
navigator的,每次获取的都是undefined,基本到这我就放弃了
接下载在朋友的帮助下发现了一个正确的写法,但是依然会有个坑
开始贴上我的代码
App.js
import React, {Component} from 'react';
import LoginPage from './login/loginPage';
import Global from './base/Global';
import BottomNavigatView from './home/bottomNavigatView';
import {createSwitchNavigator} from 'react-navigation';
import WelcomPage from './login/welcomPage';
import PassLoginPage from './login/PassLoginPage';
import {Provider} from 'react-redux';
import {createStore, applyMiddleware, combineReducers} from 'redux';
import {
createReduxContainer,
createReactNavigationReduxMiddleware,
createNavigationReducer,
} from 'react-navigation-redux-helpers';
import ReduxNavigation from './navigation/ReduxNavigation';
const AppStrack = createSwitchNavigator(
{
WelcomPage: {
screen: WelcomPage,
},
LoginPage: {
screen: LoginPage,
},
PassLoginPage: {
screen: PassLoginPage,
},
BottomNavigatView: {
screen: BottomNavigatView,
navigationOptions: {
headerShown: false,
},
},
// stractNavigatior,
},
{
mode: 'modal',
headerMode: 'none',
},
);
const navReducer = createNavigationReducer(AppStrack);
const appReducer = combineReducers({
router: navReducer,
});
export const navigationMiddleware = createReactNavigationReduxMiddleware(
state => state.router,
'root',
);
export const App = createReduxContainer(AppStrack, 'root');
const store = createStore(appReducer, applyMiddleware(navigationMiddleware));
export default class Root extends React.Component {
render() {
return (
<Provider store={store}>
<ReduxNavigation />
</Provider>
);
}
};
ReduxNavigation代码,ReduxNavigation中官方是在componentDidMount中注册的
、BackHandler,这样写会有一个坑,只要两次点击退出应用后再次进入应用,进入子级
界面,这时的返回键也会变成两次点击退出应用,只有杀死应用进程后再次进入应用才会
正常,后来经过研究,我将BackHandler放到了UNSAFE_componentWillMount中注
册,顺利解决了坑
import React from 'react';
import {BackHandler} from 'react-native';
import {connect} from 'react-redux';
import {NavigationActions} from 'react-navigation';
import {App} from '../App';
import ToastUtil from '../base/ToastUtil';
class ReduxNavigation extends React.Component {
UNSAFE_componentWillMount() {
BackHandler.addEventListener('hardwareBackPress', this.onBackPress);
}
// componentWillMount() {
//
// }
componentWillUnmount() {
BackHandler.removeEventListener('hardwareBackPress', this.onBackPress);
}
onBackPress = () => {
const {dispatch, nav} = this.props;
if (nav.index === 3) {
var times = (new Date()).valueOf();
if (!this.firstClick || times - this.firstClick > 2000) {
this.firstClick = times;
ToastUtil.show('再按一次退出');
return true;
} else {
BackHandler.exitApp();
}
return true;
}
dispatch(NavigationActions.back());
return true;
};
render() {
const {nav, dispatch} = this.props;
return <App state={nav} dispatch={dispatch}/>;
}
}
const mapStateToProps = state => ({
nav: state.router,
});
export default connect(mapStateToProps)(ReduxNavigation);