如何将 ES6 与 React Native 结合使用

Posted

技术标签:

【中文标题】如何将 ES6 与 React Native 结合使用【英文标题】:how to use ES6 with react native 【发布时间】:2016-06-18 03:43:27 【问题描述】:

使用 React-Native 并尝试学习 ES6 语法。我昨天遇到了类似的问题并得到了解决方案。我加了

.bind(这个)

到我的函数调用,问题就解决了。我在另一个函数调用中再次遇到了同样的问题,我无法追踪发生了什么。错误信息是一样的。

undefined 不是一个对象(评估 'this.props.drawer.open')

函数是:

    onClickMenu () 
    this.props.drawer.open();
  

它是用这个来调用的:

onPress=this.onClickMenu.bind(this)

这是完整的代码。如果您发现除此问题之外的其他看起来不正确的问题,请告诉我! *注意我已将“var”替换为“let”。从我读过的内容来看,在任何地方都这样做是正确的 ES6 语法吗?

    'use strict';

const React = require('react-native');
const 
  Text,
  View,
  Component,
  StyleSheet,
  Switchandroid
 = React;

import  Button  from 'react-native-material-design';
import Store from 'react-native-simple-store';
import Underscore from 'underscore';
import RNGMap from 'react-native-gmaps';
import Polyline from 'react-native-gmaps/Polyline';
import Icon from 'react-native-vector-icons/Ionicons';
import SettingsService from './../settings/settings.service';
//import subdivisions from './subdivisions.json';
import commonStyles from './../common/styles';

let accessToken = null;
let userId = null;
let routeId = null;
let subdivisionId = null;

SettingsService.init('Android');

class Map extends Component 
  constructor(props) 
    super(props)
    this.state = 
      odometer: 0,
      mapWidth: 300,
      mapHeight: 300,
      enabled: false,
      isMoving: false,
      currentLocation: undefined,
      locationManager: undefined,
      paceButtonIcon: 'Start Trip',
      navigateButtonIcon: 'navigate',
      paceButtonStyle: commonStyles.disabledButton,
      // mapbox
      center: 
        lat: 40.7223,
        lng: -73.9878
      ,
      zoom: 10,
      markers: []
    
  

  componentDidMount() 
    Store.get('token').then((token) => 
      accessToken = token.access_token;
      userId = token.userId;
    );
    let me = this,
      gmap = this.refs.gmap;

    this.locationManager = this.props.locationManager;

    // location event
    this.locationManager.on("location", function(location) 
      console.log('- location: ', JSON.stringify(location));
      me.setCenter(location);
      gmap.addMarker(me._createMarker(location));

      me.setState(
        odometer: (location.odometer / 1000).toFixed(1)
      );

      // Add a point to our tracking polyline
      if (me.polyline) 
        me.polyline.addPoint(location.coords.latitude, location.coords.longitude);
      
    );
    // http event
    this.locationManager.on("http", function(response) );
    // geofence event
    this.locationManager.on("geofence", function(geofence) );
    // error event
    this.locationManager.on("error", function(error) 
      console.log('- ERROR: ', JSON.stringify(error));
    );
    // motionchange event
    this.locationManager.on("motionchange", function(event) 
      me.updatePaceButtonStyle();
    );

    // getGeofences
    this.locationManager.getGeofences(function(rs) 
    , function(error) 
      console.log("- getGeofences ERROR", error);
    );

    SettingsService.getValues(function(values) 
      values.license = "eddbe81bbd86fa030ea466198e778ac78229454c31100295dae4bfc5c4d0f7e2";
      values.orderId = 1;
      values.stopTimeout = 0;
      //values.url = 'http://192.168.11.120:8080/locations';

      me.locationManager.configure(values, function(state) 
        me.setState(
          enabled: state.enabled
        );
        if (state.enabled) 
          me.initializePolyline();
          me.updatePaceButtonStyle()
        
      );
    );

    this.setState(
      enabled: false,
      isMoving: false
    );
  
  _createMarker(location) 
    return 
      title: location.timestamp,
      id: location.uuid,
      icon: require("image!transparent_circle"),
      anchor: [0.5, 0.5],
      coordinates: 
        lat: location.coords.latitude,
        lng: location.coords.longitude
      
    ;
  

  initializePolyline() 
    // Create our tracking Polyline
    let me = this;
    Polyline.create(
      width: 12,
      points: [],
      geodesic: true,
      color: '#2677FF'
    , function(polyline) 
      me.polyline = polyline;
    );
  

  onClickMenu () 
    this.props.drawer.open();
  

  onClickEnable() 
    let me = this;
    if (!this.state.enabled) 
      this.locationManager.start(function() 
        me.initializePolyline();
      );
     else 
      this.locationManager.resetOdometer();
      this.locationManager.stop();
      this.setState(
        markers: [],
        odometer: 0
      );
      this.setState(
        markers: []
      );
      if (this.polyline) 
        this.polyline.remove(function(result) 
          me.polyline = undefined;
        );
      
    

    this.setState(
      enabled: !this.state.enabled
    );
    this.updatePaceButtonStyle();
  

  onClickPace() 
    if (!this.state.enabled) 
      return;
    
    let isMoving = !this.state.isMoving;
    this.locationManager.changePace(isMoving);

    this.setState(
      isMoving: isMoving
    );
    this.updatePaceButtonStyle();
  

  onClickLocate() 
    let me = this;

    this.locationManager.getCurrentPosition(
      timeout: 30
    , function(location) 
      me.setCenter(location);
    , function(error) 
      console.error('ERROR: getCurrentPosition', error);
      me.setState(
        navigateButtonIcon: 'navigate'
      );
    );
  

  onRegionChange() 

  setCenter(location) 
    this.setState(
      navigateButtonIcon: 'navigate',
      center: 
        lat: location.coords.latitude,
        lng: location.coords.longitude
      ,
      zoom: 16
    );
  

  onLayout() 
    let me = this,
      gmap = this.refs.gmap;

    this.refs.workspace.measure(function(ox, oy, width, height, px, py) 
      me.setState(
        mapHeight: height,
        mapWidth: width
      );
    );
  

  updatePaceButtonStyle() 
    let style = commonStyles.disabledButton;
    if (this.state.enabled) 
      style = (this.state.isMoving) ? commonStyles.redButton : commonStyles.greenButton;
    
    this.setState(
      paceButtonStyle: style,
      paceButtonIcon: (this.state.enabled && this.state.isMoving) ? 'Stop Trip' : 'Start Trip'
    );
  

  render() 
    return (
      <View style=commonStyles.container>
        <View style=commonStyles.topToolbar>
          <Icon.Button name="android-options" onPress=this.onClickMenu.bind(this) backgroundColor="transparent" size=30 color="#000" style=styles.btnMenu underlayColor="transparent" />
          <Text style=commonStyles.toolbarTitle>Background Geolocation</Text>
          <SwitchAndroid onValueChange=this.onClickEnable.bind(this) value=this.state.enabled />
        </View>
        <View ref="workspace" style=styles.workspace onLayout=this.onLayout.bind(this)>

          <RNGMap
            ref='gmap'
            style=width: this.state.mapWidth, height: this.state.mapHeight
            markers=this.state.markers
            zoomLevel=this.state.zoom
            onMapChange=(e) => console.log(e)
            onMapError=(e) => console.log('Map error --> ', e)
            center=this.state.center />

        </View>
        <View style=commonStyles.bottomToolbar>
          <Icon.Button name=this.state.navigateButtonIcon onPress=this.onClickLocate.bind(this) size=25 color="#000" underlayColor="#ccc" backgroundColor="transparent" style=styles.btnNavigate />
          <Text style=fontWeight: 'bold', fontSize: 18, flex: 1, textAlign: 'center'>this.state.odometer km</Text>
          <Button raised=true 
                  text=this.state.paceButtonIcon 
                  onPress=this.onClickPace.bind(this)
                  overrides=backgroundColor:"#e12429",textColor:"#ffffff" 
                  style=this.state.paceButtonStyle></Button>
          <Text>&nbsp;</Text>
        </View>
      </View>
    );
  
;

const styles = StyleSheet.create(
  workspace: 
    flex: 1
  
);

module.exports = Map;

更新: 通过终端中的 adb 调试显示相同的错误

所以这里是其余的代码。进行故障排除。我将项目文件添加到 plunker。这是我正在使用的演示项目。 plunker

    'use strict';

const React = require('react-native');
const 
  Text, 
  Component,
  StyleSheet, 
  AppRegistry
 = React;

import Map from './map/map';
import Drawer from 'react-native-drawer';
import Settings from './settings/settings.android';
import Icon from 'react-native-vector-icons/Ionicons';
import BackgroundGeolocation from 'react-native-background-geolocation-android';

global.bgGeo = BackgroundGeolocation;

class App extends Component 
  onClickMenu() 
    this.props.refs.drawer.open();
  

  render() 
    return (
      <Drawer ref="drawer" side="right" acceptPan=false content=<Settings drawer=this.refs.drawer locationManager=BackgroundGeolocation />>
        <Map drawer=this.refs.drawer locationManager=BackgroundGeolocation />    
      </Drawer>
    );
  
;

module.exports = App;

更新:

【问题讨论】:

我不认为你的代码显示了哪个props 被传递给你的组件,并且错误没有指定哪个部分是未定义的。您假设没有传递上下文,是否可能未定义 drawer(甚至 props)?一些日志记录会确认这一点。 好的,我怎样才能获得日志记录? 只是console.log,XCode在运行你的应用程序时会通过调试面板显示JS日志。 more info 当您在onClickMenu 中插入console.log( this )console.log( this.props ) 作为第一行时会发生什么? 哦,刚刚看到了更多编辑,我不确定确切的问题(因此缺乏答案),但无论如何你不能像在 React 中那样通过组件,充其量您将传递引用该组件的元素(不确定在 react-native 中如何发挥作用)。不过,您可以将函数传递给子代以调用 drawer.open()drawer.close() 【参考方案1】:

我认为您不能以这种方式将 refs 传递给组件, 当然它不会在React 中工作,我认为它不会工作 以这种方式在React-Native 中。

我不清楚你为什么要从.openDrawer Map 组件,因为它看起来像 Map 组件只能是 当Drawer 打开时访问,但是,如果你想访问父 孩子们的行为一个好的模式是通过函数 让孩子们执行(你可以说这实际上很糟糕 并且传递事件是一种更强大的模式)。

我从来没有使用过这个库,所以我并不完全清楚它的用法,但是 你可以像这样传递函数:

class Application extends Component 

  closeControlPanel = () => 
    this.refs.drawer.close()
  ;
  openControlPanel = () => 
    this.refs.drawer.open()
  ;
  render () 
    return (
      <Drawer
        ref="drawer"
        content=<ControlPanel />
        >
        <Map onMenuClose= this.closeControlPanel.bind( this )  />
      </Drawer>
    )
  
)

在这种情况下,this.props.onMenuClose 应该附加到一个动作,执行时会触发父函数并执行 this.refs.drawer.close 函数。

【讨论】:

好的。我现在不在电脑前,但会尽快插入。这实际上是我的第一个 react 原生项目,所以我边走边学。我把它作为一个演示项目,我想我会将它转换为 ES6 以与那里的大多数项目保持一致。使用演示项目来学习的问题是你永远不知道傻瓜是怎么做到的

以上是关于如何将 ES6 与 React Native 结合使用的主要内容,如果未能解决你的问题,请参考以下文章

是否可以将 React Native 与 socket.io 结合使用

将 Amazon SNS 与 React Native 结合使用

[RN][IOS]是不是可以将 React Native RCTLinking 与 RNFirebase 动态链接结合使用?

如何在 React Native 中的 setState 之前停止执行

React Native 的导入与导出

如何使用 Stripe (stripe.js) 和 react-native