react-native处理复杂的后退按钮功能

时间:2017-12-14 07:29:46

标签: react-native

我想知道推荐的方法(如果有的话)在处理android平台时处理react-native中的后退按钮。

我知道我可以在每个屏幕上注册监听器,但由于导航的工作方式,在导航时没有明确的绑定或取消绑定事件监听器的流程。

到目前为止,我有两个想法。

1)我可以注册一个单一的监听器,并让处理程序根据我的redux存储做出决定。这意味着如果我有一个屏幕,我有一个弹出窗口,我想用后退按钮关闭,我必须将它暴露给商店。基本上我的应用程序中任何想要受后退按钮影响的东西都必须连接到商店。凌乱

2)我可以在每个屏幕上注册一个监听器。根据我之前所说的,没有可靠的生命周期钩子来处理这个,所以它必须是我的手动,即我应该总是知道什么动作将导航到新的屏幕并在导航之前取消绑定特定屏幕上的监听器。

这解决了问题的一半。当导航回屏幕时,它应该重新绑定它的监听器。除了搞乱componentWillRecieveProps和其他人之外,不知道如何做到这一点。仍然看起来很混乱。

2 个答案:

答案 0 :(得分:3)

react-navigation无需任何工作即可为您处理基本的后退按钮功能。

如果您想要一些自定义处理,可以尝试使用react-navigation-addons库,它会为您提供2个要收听的事件:focusblur,以便您注册/取消注册back button listeners当这些事件发生时。

这是策略2)从你的问题,你可以使用它而不是缺少生命周期钩子。 但要小心这个库它是一个实验,所以在使用之前请阅读说明。它看起来像这样:

class Screen extends Component {
    handleBack = () => {
    ...
    }

    screenFocus = () => {
        // add back button listener or any other code you want to execute on screen focus
        BackHandler.addEventListener('hardwareBackPress', this.handleBack);
    }

    screenBlur = () => {
        // remove back button listener or add any other code you want to execute on screen blur
        BackHandler.removeEventListener('hardwareBackPress', this.handleBack);
    }

    componentDidMount() {
        this.props.navigation.addListener('focus', this.screenFocus);
        this.props.navigation.addListener('blur', this.screenBlur);
    }

    componentWillUnmount() {
        this.props.navigation.removeListener('focus', this.screenFocus);
        this.props.navigation.removeListener('blur', this.screenBlur);
    }
    ...
}

答案 1 :(得分:1)

React-native有一个api用于处理Android和AppleTV上的硬件后退操作。您将eventListender添加到BackHandler组件。 Docs

如果您使用的是react-navigation,则可以将此事件侦听器放在呈现堆栈的组件中。然后,您可以在堆栈中找到与导航状态对应的屏幕,并调用leftButton onPress。这是一个粗略的例子 -

const _RootContainer = (props) => {
  const navigation = addNavigationHelpers({
    dispatch: props.dispatch,
    state: props.nav,
  })
  BackHandler.addEventListener('hardwareBackPress', function() {
  const route = navigation.state.routes[navigation.state.index]
  const screen = stack[route].screen
  const navOptions = screen.navigationOptions({navigation})
      if (navOptions.headerLeft) {
    navOptions.headerLeft.props.onPress()
  }
      return true;
  });
  return (<View style={{ flex: 1 }}>
    <AppNavigator
      navigation={navigation}
    />
  </View>
)}