如何判断屏幕是否通过ReactNavigation导航到

时间:2017-05-03 21:15:51

标签: react-native react-navigation

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

看一下这个例子https://reactnavigation.org/docs/guides/screen-tracking,看起来我可以在根导航上的onNavigationStateChange方法上添加一个监听器,但是我想将逻辑保留在屏幕上,因为它会让人感到困惑如果我将外部的一个scree的数据获取逻辑移到根导航器中。

我已经尝试按照示例将该方法设置为我的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);
      }
    }}
  />

3 个答案:

答案 0 :(得分:4)

所以,我是如何使用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
    }
  }

答案 1 :(得分:1)

这是我的导航器减速器。

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;
}

然后我们必须将模块/路由连接到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);

然后在组件内部,您可以在场景变为活动状态时观察/触发代码:

  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

答案 2 :(得分:1)

您可以使用焦点/模糊事件监听器(演示here并讨论here)。