React Native реагирует на навигационную избыточную ручку Android кнопку назад - PullRequest
0 голосов
/ 07 сентября 2018

Я слежу за документами, пытающимися обработать кнопку возврата Android при использовании реагирующей навигации, интегрированной с redux.

В настоящее время нажатие кнопки возврата завершает работу всего приложения, где бы вы его ни нажимали. Я попытался обработать нажатие назад, следуя инструкциям, добавив обработчик в компонент Root:

 const persistConfig = {
      key: 'root',
      storage,
      blacklist: ['nav'],
    };

    const AppNavigator = createStackNavigator(
      {
        SelectScreen,
        PageScreen,
        SettingsScreen,
      },
      {
        initialRouteName: 'SelectScreen',
      },
    );

    const navReducer = createNavigationReducer(AppNavigator);
    const appReducer = combineReducers({
      nav: navReducer,
      theme: themeReducer,
      page: pageReducer,
    });
    const persistedReducer = persistReducer(persistConfig, appReducer);

    const middleware = createReactNavigationReduxMiddleware('root', state => state.nav);

    const App = reduxifyNavigator(AppNavigator, 'root');
    const mapStateToProps = state => ({
      state: state.nav,
    });
    const AppWithNavigationState = connect(mapStateToProps)(App);

    const store = createStore(persistedReducer, applyMiddleware(middleware));
    const persistor = persistStore(store);

    class Root extends React.Component {

componentDidMount() {
    BackHandler.addEventListener("hardwareBackPress", this.onBackPress);
  }

  componentWillUnmount() {
    BackHandler.removeEventListener("hardwareBackPress", this.onBackPress);
  }

  onBackPress = () => {
    const { dispatch, nav } = this.props;
    if (nav.index === 0) {
      return false;
    }

    dispatch(NavigationActions.back());
    return true;
  };
      render() {
        return (
          <Provider store={store}>
            <PersistGate loading={null} persistor={persistor}>
              <AppWithNavigationState />
            </PersistGate>
          </Provider>
        );
      }
    }

    AppRegistry.registerComponent(appName, () => Root);

Однако я получаю сообщение об ошибке, поскольку в корневом компоненте не существует навигационных реквизитов. Я знаю, что это, вероятно, ошибка из-за моего непонимания, поэтому я очень признателен за помощь в том, как заставить это работать!

Спасибо

Ответы [ 2 ]

0 голосов
/ 07 сентября 2018

Вы можете сделать это, передав его другому компоненту, который имеет доступ к Provider store.

AppNavigation.js

const PrimaryNav = createStackNavigator(
      {
        SelectScreen,
        PageScreen,
        SettingsScreen,
      },
      {
        initialRouteName: 'SelectScreen',
      },
 );

export const appNavigatorMiddleware = createReactNavigationReduxMiddleware(
  'root',
  state => state.nav
); //... Import it to your configure store file, to apply the middleware

const AppNavigator = reduxifyNavigator(PrimaryNav, 'root');

export default AppNavigator

ReduxNavigation.js

import React from 'react'
import { BackHandler, Platform } from 'react-native'
import { connect } from 'react-redux'
import AppNavigation from './AppNavigation' //... Import from AppNavigation.js

class ReduxNavigation extends React.Component {
  ...// Add your BackHandler Code here

  render () {
    return <AppNavigation state={this.props.nav}  dispatch={this.props.dispatch}/>
  }
}

const mapStateToProps = state => ({ nav: state.nav })
export default connect(mapStateToProps)(ReduxNavigation)

App.js

class App extends Component {
  render () {
    return (
      <Provider store={store}>
        <PersistGate loading={null} persistor={persistor}>
         <RootContainer />
        </PersistGate>
      </Provider>
    )
  }
}
0 голосов
/ 07 сентября 2018

Поскольку у меня недостаточно репутации, я должен опубликовать это как ответ.

Прочитайте это:

https://reactnavigation.org/docs/en/custom-android-back-button-handling.html

Посмотрите пример, но посмотрите на слушателя в конструкторе:

this._didFocusSubscription = props.navigation.addListener('didFocus', payload =>
  BackHandler.addEventListener('hardwareBackPress', this.onBackButtonPressAndroid)
);

Похоже, вы на правильном пути, вам просто нужно добавить слушателя к props.navigation

...