react-native在非组件类的屏幕之间导航

时间:2017-08-31 11:29:34

标签: firebase react-native firebase-authentication react-navigation stack-navigator

我正试图在我的Backend类的反应原生屏幕之间导航,如下所示:

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

我的后端类不是组件,因此不会导入我正在使用的堆栈导航器中。我收到一条错误,说'self.props.navigation不是一个对象'。

有谁知道我能解决这个问题吗?感谢

3 个答案:

答案 0 :(得分:1)

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

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());

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

如果您使用的是反应导航,则可以通过导航服务实现

创建一个名为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
});