React Native React导航Redux处理Android后退按钮

时间:2018-09-07 13:25:04

标签: reactjs react-native redux react-navigation

当我使用与redux集成的react导航时,我正在关注试图处理Android后退按钮的文档。

当前按后退按钮可在您按任意位置退出整个应用程序。我尝试通过在根组件上添加处理程序来按照指南处理后退操作:

 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 :(得分:0)

由于我没有足够的代表,因此我必须将其发布为答案。

请仔细阅读以下内容:

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

答案 1 :(得分:0)

您可以通过将其传递给有权访问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>
    )
  }
}