所以这是我正在使用的路线:
<Router>
<Scene key="root" hideNavBar>
<Stack key="Auth" initial={!this.state.isLoggedIn}>
<Scene key="Login" hideNavBar component={Login} title="Login" />
</Stack>
<Stack key="Main" initial={this.state.isLoggedIn}>
<Scene drawer key="NavDrawer" hideNavBar contentComponent={() => <NavDrawer username={this.state.userName} />} type={ActionConst.REPLACE} panHandlers={null}>
<Scene key="homeTab" navBar={() => <PageHeader title='Home' />} drawerLockMode={'locked-closed'}>
<Scene tabs={true} tabBarComponent={ScrollableTabBar} tabBarPosition='top' lazy={true}>
<Scene key="Home" hideNavBar component={Home} title={"Home"} name='Home'/>
</Scene>
<Scene key="itemDescription" hideNavBar component={itemDescription} title="Item Description" back />
</Scene>
<Scene key="helpTab" navBar={() => <PageHeader title='Help' />} title="Help" drawerLockMode={'locked-closed'}>
<Scene>
<Scene key="Help" hideNavBar component={Help} title={"Help"} />
</Scene>
</Scene>
<Scene key="settingTab" navBar={() => <PageHeader title='Settings' />} title="Settings" drawerLockMode={'locked-closed'}>
<Scene>
<Scene key="Setting" hideNavBar component={Setting} title={"Setting"} />
</Scene>
</Scene>
<Scene key="QRTab" navBar={() => <PageHeader title='QR Scanner' />} title="QR" drawerLockMode={'locked-closed'}>
<Scene>
<Scene key="QRScanner" hideNavBar component={QRScanner} title={"QR Scanner"} />
</Scene>
</Scene>
</Scene>
</Stack>
</Scene>
</Router>
这是我NavDrawer
的BackHandler:
handleBackButton() {
if (Actions.currentScene === '_Home')
this.onSignOut()
else if (this.state.currentTab !== 'Home') {
this.setState({ currentTab: 'Home' })
Actions.homeTab();
}
else if (Actions.currentScene === 'Login')
{
BackHandler.exitApp();
}
else{
Actions.pop();
}
return true;
}
componentDidMount() {
BackHandler.addEventListener('hardwareBackPress', this.handleBackButton);
}
componentWillUnmount() {
BackHandler.removeEventListener('hardwareBackPress');
}
似乎RNRF抽屉已经为抽屉下任何新堆叠的场景实现了默认的BackHandler,默认行为为Actions.pop()
。
此时所有逻辑场景移动都按预期工作,但是,由于默认的BackHandler被调用而只是执行Actions.pop()
以返回主页,因此选项卡突出显示不会移回Home,因为setState ({currentTab:'Home'})从未执行过。
有关如何禁用默认处理程序或在不将单个BackHandler添加到抽屉中的每个子场景的情况下执行变通方法的任何想法?
更新:
事实证明这个问题只发生在我自动登录时(即跳过Auth
堆栈并直接进入Main
堆栈),重新加载和componentWillUnmount
之间似乎出错了componentDidMount
没有被调用,而之前重新加载的BackHandler以某种方式发生冲突。
因为如果我尝试这种情况:
login --> Setting/Help/QR tab --> hardware back to Home
它不会导致问题
但如果我这样做:
autoLogin(login using stored token) --> Setting/Help/QR tab --> hardware back to Home
将调用默认的BackHandler,但是如果我再次按回,则会调用所需的BackHandler并且我已经注销,然后如果我再次尝试登录,则一切正常!
UPDATE2:
我现在可以确认问题在于热重新加载,当app重新加载时,componentWillUnmount
从未被调用,并且当它被加载回来时,componentDidMount
再次被调用,现在我们有2个BackHandler,处理相同的事件(我不知道它们在这种情况下应该如何表现,但这会导致使用Actions.pop()
的处理程序而不是我定义的处理程序。
这就是为什么当我退出(并componentWillUnmount
调用并删除BackHandler)并再次登录(然后通过componentDidMount
在干净的平板上加载新的BackHandler)时一切正常。
现在我的新问题是,如果没有任何热重新加载并且用户只是关闭应用程序并再次打开它(当实际安装的应用程序没有像现在那样通过expo加载时)会导致问题吗?
答案 0 :(得分:0)
在你的BackHandler eventlistener中尝试这个。请确保将其放在根组件中
let routeName = this.props.navigation.state.routeName // If you're using react navigation
let routeName = Actions.currentScene // If you're using router flux
BackHandler.addEventListener('hardwareBackPress', function() {
if (routeName !== "Home") {
this.props.navigation.goBack() // or create go back custom function
Actions.pop() // If your're using router flux
return true;
}
return false;
});