Как я могу отключить BackHandler по умолчанию, не переопределяя его в отдельной сцене? - PullRequest
0 голосов
/ 22 мая 2018

Итак, вот маршруты, с которыми я работаю:

<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, как сейчас)?

1 Ответ

0 голосов
/ 22 мая 2018

В вашем EventListener BackHandler попробуйте это.Пожалуйста, не забудьте поместить это в корневой компонент

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;
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...