我如何判断屏幕是否已通过 React Navigation 导航到

How can I tell if the screen is navigated to with ReactNavigation

我想在屏幕出现时在 React Native 应用程序中刷新屏幕上的数据 - 就像在 ViewWillAppear 方法中一样。我尝试使用 componentWillMount 方法,但看起来它在出现之前会触发一次,并且在再次导航到视图时不会再次触发。

查看此示例 https://reactnavigation.org/docs/guides/screen-tracking,我似乎可以在根导航的 onNavigationStateChange 方法上添加一个侦听器,但我想将逻辑保留在屏幕中如果我将那个屏幕的数据获取逻辑移到根导航器之外,就会感到困惑。

我已尝试按照示例并将该方法设置为我的 stacknavigation,但它似乎没有触发。

  <RootNavigation ref={nav => { this.navigator = nav; }}
    onNavigationStateChange={(prevState, currentState, action) => {

      // maybe here I can fire redux event or something to let screens
      // know that they are getting focus - however it doesn't fire so
      // I might be implementing this incorrectly

      const currentScreen = getCurrentRouteName(currentState);
      const prevScreen = getCurrentRouteName(prevState);

      if (prevScreen !== currentScreen) {
        console.log('navigating to this screen', currentScreen);
      }
    }}
  />

这是我的 navigator reducer。

function getCurrentRouteName(navState) {
  if (!navState) {
    return null;
  }

  const navigationState = (navState && navState.toJS && navState.toJS()) || navState;

  const route = navigationState.routes[navigationState.index];
  // dive into nested navigators
  if (route.routes) {
    return getCurrentRouteName(route);
  }

  return route.routeName;
}


export default function NavigatorReducer(state, action) {
  // Initial state
  if (!state) {
    return fromJS(AppNavigator.router.getStateForAction(action, state));
  }

  // Is this a navigation action that we should act upon?
  if (includes(NavigationActions, action.type)) {
    // lets find currentScreen before this action based on state
    const currentScreen = getCurrentRouteName(state);
    const nextState = AppNavigator.router.getStateForAction(action, state.toJS());
    // determine what the new screen will be after this action was performed
    const nextScreen = getCurrentRouteName(nextState);

    if (nextScreen !== currentScreen) {
      nextState.currentRoute = nextScreen;
      console.log(`screen changed, punk: ${currentScreen} -> ${nextScreen}`);
    }

    return fromJS(nextState);
  }

  return state;
}

然后我们必须将 module/route 连接到 redux 存储(sceneIsActive 是重要的一点):

export default connect(
  state => ({
    counter: state.getIn(['counter', 'value']),
    loading: state.getIn(['counter', 'loading']),
    sceneIsActive: state.getIn(['navigatorState', 'currentRoute']) === 'Counter',
  }),
  dispatch => {
    return {
      navigate: bindActionCreators(NavigationActions.navigate, dispatch),
      counterStateActions: bindActionCreators(CounterStateActions, dispatch),
    };
  },
)(CounterView);

然后在您的组件中,您可以在场景激活时查看 for/trigger 代码:

  componentWillReceiveProps(nextProps) {
    if (nextProps.sceneIsActive && (this.props.sceneIsActive !== nextProps.sceneIsActive)) {
      console.log('counter view is now active, do something about it', this.props.sceneIsActive, nextProps.sceneIsActive);
      doSomethingWhenScreenBecomesActive();
    }
  }

知道 componentWillReceiveProps 在初始安装时不会 运行。所以别忘了给你的 doSomethingWhenScreenBecomesActive 打电话。

下面是我如何使用 onNavigateStateChange.

      <RootNavigation
        ref={nav => { this.navigator = nav; }}
        uriPrefix={prefix}
        onNavigationStateChange={(prevState, currentState) => {
          const currentScreen = this.getCurrentRouteName(currentState);
          const prevScreen = this.getCurrentRouteName(prevState);
          if (prevScreen !== currentScreen) {
            this.props.emitActiveScreen(currentScreen);
            {/*console.log('onNavigationStateChange', currentScreen);*/}
          }
        }}
      />

并且在您的屏幕中,您可以检查您的视图是否会出现,请注意 MyPage 是导航对象中的路线名称。

  componentWillReceiveProps(nextProps) {
    if ((nextProps.activeScreen === 'MyPage' && nextProps.activeScreen !== this.props.activeScreen)) {
      // do your on view will appear logic here
    }
  }

您可以使用 focus/blur 事件侦听器(已演示 here and discussed here)。