React Native navigator ref属性

时间:2015-12-02 18:07:07

标签: facebook google-oauth react-native navigator

我正在尝试按照本机站点上的示例(https://github.com/facebook/react-native/tree/master/Examples/UIExplorer/Navigator)来设置我的导航器,但我似乎无法让它工作。现在我在使用ref属性时遇到问题,就像调用_setNavigatorRef时一样,我收到一条错误,它在下面的代码中找不到property _navigator of null。它适用于示例,但我不确定原因:

index.ios.js

'use strict';
var React = require('react-native');
var DataEntry = require('./app/DataEntry');
var PasswordView = require('./app/PasswordView');
var GoogSignIn = require('./app/GoogSignIn');


var {
    AppRegistry,
    Image,
    StyleSheet,
    Text,
    View,
    Navigator,
    TouchableOpacity,
} = React;

class PasswordRecovery extends React.Component {
  render() {
    return (
      <Navigator
        ref={this._setNavigatorRef}
        style={styles.container}
        initialRoute={{id: 'GoogSignIn', name: 'Index'}}
        renderScene={this.renderScene}
        configureScene={(route) => {
          if (route.sceneConfig) {
            return route.sceneConfig;
          }
          return Navigator.SceneConfigs.FloatFromRight;
        }} />
    );
  }

  renderScene(route, navigator) {
    switch (route.id) {
    case 'GoogSignIn':
      return <GoogSignIn navigator={navigator} />;
    case 'DataEntry':
      return <DataEntry navigator={navigator} />;
    case 'PasswordView':
      return <PasswordView navigator={navigator} />;
    default:
      return this.noRoute(navigator);
  }

  noRoute(navigator) {
    return (
      <View style={{flex: 1, alignItems: 'stretch', justifyContent: 'center'}}>
        <TouchableOpacity style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}
            onPress={() => navigator.pop()}>
          <Text style={{color: 'red', fontWeight: 'bold'}}>ERROR: NO ROUTE DETECTED</Text>
        </TouchableOpacity>
      </View>
    );
  }

  _setNavigatorRef(navigator) {
    if (navigator !== this._navigator) {
      this._navigator = navigator;

      if (navigator) {
        var callback = (event) => {
          console.log(
            `TabBarExample: event ${event.type}`,
            {
              route: JSON.stringify(event.data.route),
              target: event.target,
              type: event.type,
            }
          );
        };
        // Observe focus change events from the owner.
        this._listeners = [
          navigator.navigationContext.addListener('willfocus', callback),
          navigator.navigationContext.addListener('didfocus', callback),
        ];
      }
    }
  }

  componentWillUnmount() {
    this._listeners && this._listeners.forEach(listener => listener.remove());
  }
}

var styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
});


AppRegistry.registerComponent('PasswordRecovery', () => PasswordRecovery);

我只想尝试这一切,以便我可以显示Google登录场景,然后从那里导航。到目前为止,该场景的代码在这里:

GoogSignIn.js

'use strict';

var React = require('react-native');
var { NativeAppEventEmitter } = require('react-native');
var GoogleSignin = require('react-native-google-signin');
var cssVar = require('cssVar');
var { Icon } = require('react-native-icons');

var {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  TouchableOpacity,
  TouchableHighlight,
  PixelRatio,
  Navigator,
} = React;

var NavigationBarRouteMapper = {

  LeftButton: function(route, navigator, index, navState) {
    if (index === 0) {
      return null;
    }

    var previousRoute = navState.routeStack[index - 1];
    return (
      <TouchableOpacity
        onPress={() => navigator.pop()}
        style={styles.navBarLeftButton}>
        <Text style={[styles.navBarText, styles.navBarButtonText]}>
          {previousRoute.title}
        </Text>
      </TouchableOpacity>
    );
  },

  RightButton: function(route, navigator, index, navState) {
    return (
      null
    );
  },

  Title: function(route, navigator, index, navState) {
    return (
      <Text style={[styles.navBarText, styles.navBarTitleText]}>
        GOOGLE SIGN IN
      </Text>
    );
  },

};

class GoogSignin extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      user: null
    };
  }

  componentWillMount() {
var navigator = this.props.navigator;
var callback = (event) => {
  console.log(
    `NavigationBarSample : event ${event.type}`,
    {
      route: JSON.stringify(event.data.route),
      target: event.target,
      type: event.type,
    }
  );
};

// Observe focus change events from this component.
this._listeners = [
  navigator.navigationContext.addListener('willfocus', callback),
  navigator.navigationContext.addListener('didfocus', callback),
];
  }

  componentWillUnmount() {
    this._listeners && this._listeners.forEach(listener => listener.remove());
  }

  componentDidMount() {
    this._configureOauth(
      '105558473349-7usegucirv10bruohtogd0qtuul3kkhn.apps.googleusercontent.com'
    );
  }

  renderScene(route, navigator) {
      console.log("HERE");
      return (
        <View style={styles.container}>
          <TouchableHighlight onPress={() => {this._signIn(); }}>
            <View style={{backgroundColor: '#f44336', flexDirection: 'row'}}>
              <View style={{padding: 12, borderWidth: 1/2, borderColor: 'transparent', borderRightColor: 'white'}}>
                <Icon
                  name='ion|social-googleplus'
                  size={24}
                  color='white'
                  style={{width: 24, height: 24}}
                />
              </View>
              <Text style={{color: 'white', padding: 12, marginTop: 2, fontWeight: 'bold'}}>Sign in with Google</Text>
            </View>
          </TouchableHighlight>
        </View>
      );
  }

  render() {
    return (
      <Navigator
      debugOverlay={false}
      style={styles.appContainer}
      renderScene={this.renderScene}
      navigationBar={
        <Navigator.NavigationBar
          routeMapper={NavigationBarRouteMapper}
          style={styles.navBar}/>
      }/>
    );
  }

  _configureOauth(clientId, scopes=[]) {
    console.log("WE HERE")
    GoogleSignin.configure(clientId, scopes);

    NativeAppEventEmitter.addListener('googleSignInError', (error) => {
      console.log('ERROR signin in', error);
    });

    NativeAppEventEmitter.addListener('googleSignIn', (user) => {
      console.log(user);
      this.setState({user: user});
    });

    return true;
  }

  _signIn() {
    GoogleSignin.signIn();
  }

  _signOut() {
    GoogleSignin.signOut();
    this.setState({user: null});
  }
};

var styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  messageText: {
    fontSize: 17,
    fontWeight: '500',
    padding: 15,
    marginTop: 50,
    marginLeft: 15,
  },
  button: {
    backgroundColor: 'white',
    padding: 15,
    borderBottomWidth: 1 / PixelRatio.get(),
    borderBottomColor: '#CDCDCD',
  },
  buttonText: {
    fontSize: 17,
    fontWeight: '500',
  },
  navBar: {
    backgroundColor: 'white',
  },
  navBarText: {
    fontSize: 16,
    marginVertical: 10,
  },
  navBarTitleText: {
    color: cssVar('fbui-bluegray-60'),
    fontWeight: '500',
    marginVertical: 9,
  },
  navBarLeftButton: {
    paddingLeft: 10,
  },
  navBarRightButton: {
    paddingRight: 10,
  },
  navBarButtonText: {
    color: cssVar('fbui-accent-blue'),
  },
  scene: {
    flex: 1,
    paddingTop: 20,
    backgroundColor: '#EAEAEA',
  },
});



module.exports = GoogSignin;

1 个答案:

答案 0 :(得分:1)

我怀疑这是一个背景问题。在Navigator组件上,尝试从以下转换:

ref={this._setNavigatorRef}

对此:

ref={(navigator) => this._setNavigatorRef(navigator)}(更漂亮的恕我直言)

或者这个:

ref={this._setNavigatorRef.bind(this)}