如何从在顶层呈现的组件调用导航

How to call navigate from a component rendered at top level

根据有关 react-navigation 的文档,您可以使用以下方法从顶级组件调用 navigate:

import { NavigationActions } from 'react-navigation';

const AppNavigator = StackNavigator(SomeAppRouteConfigs);

class App extends React.Component {
  someEvent() {
    // call navigate for AppNavigator here:
    this.navigator && this.navigator.dispatch(
      NavigationActions.navigate({ routeName: someRouteName })
    );
  }
  render() {
    return (
      <AppNavigator ref={nav => { this.navigator = nav; }} />
    );
  }
}

但是,如果执行分派的逻辑位于与导航器处于同一级别的另一个组件中,我将如何做到这一点?在我的例子中,我创建了我的导航器(一个带有堆栈导航器和其他嵌套导航器的抽屉),然后我使用 <Drawer> 渲染它们。在同一级别上,我正在加载我的 <PushController> 组件来处理推送通知。 pushcontroller 实际上得到了我想要分派的事件。

我不知道如何将 ref 传递(?)到 pushcontroller 组件以便我可以使用它,目前以下方法不起作用。我收到控制台日志,告诉我 fcm.ACTION.OPEN_NOTIFICATION 已触发但没有派发。我想这可能是因为 ref 是在渲染期间创建的,并且在渲染发生时它还不能传递?但我也不确定您是否会这样做,以便让另一个组件访问在同一级别声明的 ref。提前感谢您的帮助!

Drawer + PushController渲染

  render(){
      return(
        <View style={{flex: 1}}>
          <Drawer ref={nav => { this.navigator = nav; }}/>
          <PushController user={this.props.user} navigator={this.navigator}/>
        </View>
      )
  }

PushController 片段:

import { NavigationActions } from 'react-navigation';

async doFCM() {
    FCM.getInitialNotification().then(notif => {
      console.log('Initial Notification', notif);
      if(notif.fcm.action === "fcm.ACTION.OPEN_NOTIFICATION"){
        console.log('fcm.ACTION.OPEN_NOTIFICATION triggered', notif);
        this.props.navigator && this.props.navigator.dispatch(NavigationActions.navigate({routename: 'Chat'}))
      }
    });
}

答案是将导航调用移动到渲染时定义的函数并将其传递给组件。

import { NavigationActions } from 'react-navigation';

...
//class definition omitted for brevity
  render(){
    const callNavigate = (routeName, params) => {
      console.log('Params', params);
      this.navigator.dispatch({
        type: NavigationActions.NAVIGATE,
        routeName: routeName,
        params: params
      }) 
    }

      return(
        <View style={{flex: 1}}>
          <Drawer ref={nav => this.navigator = nav }/>
          <PushController callNavigate={callNavigate}/>
        </View>
      )
  }

函数在 PushController 中调用如下:

  this.props.callNavigate('RouteName', params);