Итак, вот маршруты, с которыми я работаю:
<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>
, и это BackHandler из моего NavDrawer
:
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, подсветка вкладки не перемещается обратно в Home, потому что setState ({currentTab: 'Home'}) никогда не выполнялся.
Любая идея о том, как отключить обработчик по умолчанию илисделать обходной путь, не добавляя отдельных BackHandler для каждой дочерней сцены в ящике?
ОБНОВЛЕНИЕ: оказывается, эта проблема возникает, только когда я автоматически вошел в систему (то есть пропустил стек Auth
и сразу в Main
stack), кажется, что-то пошло не так между перезагрузкой и componentWillUnmount
или componentDidMount
, когда не вызывается, и BackHandlers из предыдущих перезагрузок как-то конфликтуют.
Потому что, если я попробую этот сценарий:
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:
Теперь я могу подтвердить, что проблема заключается в горячей перезагрузке, когда приложение перезагружается, componentWillUnmount
никогда не вызывается, и при его загрузке componentDidMount
вызывается сноваи теперь у нас есть 2 BackHandler, которые обрабатывают одно и то же событие (и я не знаю, как они должны себя вести в этом случае, но это заставляет использовать обработчик с Actions.pop()
вместо того, который я определил).
Вот почему, когда я выхожу из системы (и componentWillUnmount
вызывал и удалял BackHandler) и снова захожу (который затем загружает новый BackHandler на чистую доску с помощью componentDidMount
), все работает нормально.
Теперь мой новый вопрос: вызовет ли это проблему, если не было горячей перезагрузки, а пользователь просто закрыл приложение и снова открыл его (когда приложение фактически установлено, не загружается через expo, как сейчас)?