在非组件的屏幕之间进行本机导航 class

react-native navigating between screens from non component class

我正在尝试从我的后端 class 像这样在 React 本机屏幕之间导航:

var self = this;
firebase.auth().onAuthStateChanged((user) => {
  if (user) {
    self.setState({
      userID: user.uid,
    })
  } else{
      self.props.navigation.navigate("Login");
      }
});

我的后端 class 不是一个组件,因此没有导入到我正在使用的堆栈导航器中。我收到一条错误消息 'self.props.navigation is not an object'.

有人知道我可以解决这个问题吗?谢谢

一个不太好的做法是将 Navigator 定义为 App 实例的 static/class 变量:

const MyNavigator = StackNavigator(...);

export default class MyApp extends Component {
    render() {
        return <MyNavigator ref={(ref) => MyApp.Navigator = ref}/>
    }
}

然后您就可以在任何您想要的地方访问您的导航器及其道具和功能! (例如发送一个返回事件):

import MyApp from '...';
MyApp.Navigator.dispatch(NavigationActions.back());

我个人不喜欢发生在该级别的导航操作,但有时这是必要的。扩展@Dusk 的答案,我知道了一个有助于解决这个问题的模式。你可以在这里找到它
https://github.com/react-community/react-navigation/issues/1439#issuecomment-303661539

我们的想法是您创建一个服务来保存导航器的引用。现在,您可以从应用程序的任何位置导入该服务并访问您的导航器。它保持简洁。

如果您使用的是 react-navigation,那么您可以通过 Navigation Service 实现此目的

创建一个名为 NavigationService 的文件并在其中添加以下代码

      import { NavigationActions, StackActions } from 'react-navigation';

  let navigator;

  function setTopLevelNavigator(navigatorRef) {
    navigator = navigatorRef;
  }

  function navigate(routeName, params) {
    navigator.dispatch(
      NavigationActions.navigate({
        routeName,
        params
      })
    );
  }

  function goBack(routeName, params) {
    navigator.dispatch(
      StackActions.reset({
        index: 0,
        actions: [
          NavigationActions.navigate({
            routeName,
            params
          })
        ]
      })
    );
  }

  function replace(routeName, params) {
    navigator.dispatch(
      StackActions.replace({
        index: 0,
        actions: [
          NavigationActions.navigate({
            routeName,
            params
          })
        ]
      })
    );
  }

  function pop() {
    navigator.dispatch(StackActions.pop());
  }

  function popToTop() {
    navigator.dispatch(StackActions.popToTop());
  }

  // add other navigation functions that you need and export them

  export default {
    navigate,
    goBack,
    replace,
    pop,
    popToTop,
    setTopLevelNavigator
  };

现在将此文件导入您的 app.js 并设置 TopLevelNavigator,您的 app.js 将看起来像这样

    import React, { Component } from 'react';
    import NavigationService from './routes/NavigationService';

    export default class App extends Component {
    constructor() {
        super();
    }

    render() {
        return (
            <View style={{ flex: 1, backgroundColor: '#fff' }}>
            <AppNavigator
                ref={navigatorRef => {
                NavigationService.setTopLevelNavigator(navigatorRef);
                }}
            />
            </View>
        );
    }
   }

现在一切顺利,您可以在任何地方导入 NavigationService,您可以在任何组件和非组件文件中像这样使用它

import NavigationService from 'path to the NavigationService file';

/* you can use any screen name you have defined in your StackNavigators
 * just replace the LogInScreen with your screen name and it will work like a  
 * charm
 */
NavigationService.navigate('LogInScreen'); 


/*  
 * you can also pass params or extra data into the ongoing screen like this
 */
NavigationService.navigate('LogInScreen',{
  orderId: this.state.data.orderId
});