如何从反应原生javascript语法切换到es6

时间:2016-03-03 20:31:06

标签: javascript reactjs ecmascript-6 react-native

我正在重写一些代码到es6语法,我遇到了麻烦。这是我的第一个反应原生项目,所以我不熟悉一些事情。我从这个演示开始rn-background-geolocation-demo 我在登录界面添加了导航。当我登录并切换视图时,我收到此错误

 onLayout() {
var me = this,
  gmap = this.refs.gmap;

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

undefined不是对象(评估'this.refs')

这是整个文件。如果您需要更多信息,请告诉我!感谢

Map.js

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

  componentDidMount() {

    var 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) {
      console.log('- http ' + response.status);
      console.log(response.responseText);
    });
    // geofence event
    this.locationManager.on("geofence", function(geofence) {
      console.log('- onGeofence: ', JSON.stringify(geofence));
    });
    // error event
    this.locationManager.on("error", function(error) {
      console.log('- ERROR: ', JSON.stringify(error));
    });
    // motionchange event
    this.locationManager.on("motionchange", function(event) {
      console.log("- motionchange", JSON.stringify(event));
      me.updatePaceButtonStyle();
    });

    // getGeofences
    this.locationManager.getGeofences(function(rs) {
      console.log('- getGeofences: ', JSON.stringify(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) {
        console.log('- configure state: ', 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: this.locationIcon,
      anchor: [0.5, 0.5],
      coordinates: {
        lat: location.coords.latitude,
        lng: location.coords.longitude
      }
    };
  }

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

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

  onClickEnable() {
    var 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;
    }
    var isMoving = !this.state.isMoving;
    this.locationManager.changePace(isMoving);

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

  onClickLocate() {
    var me = this;

    this.locationManager.getCurrentPosition({
      timeout: 30
    }, function(location) {
      me.setCenter(location);
      console.log('- current position: ', JSON.stringify(location));
    }, function(error) {
      console.error('ERROR: getCurrentPosition', error);
      me.setState({
        navigateButtonIcon: 'navigate'
      });
    });
  }

  onRegionChange() {
    console.log('onRegionChange');
  }

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

  onLayout() {
    var me = this,
      gmap = this.refs.gmap;

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

  updatePaceButtonStyle() {
    var 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) ? 'pause' : 'play'
    });
  }

  render() {
    return (
      <View style={commonStyles.container}>
        <View style={commonStyles.topToolbar}>
          <Icon.Button name="android-options" onPress={this.onClickMenu} backgroundColor="transparent" size={30} color="#000" style={styles.btnMenu} underlayColor={"transparent"} />
          <Text style={commonStyles.toolbarTitle}>Background Geolocation</Text>
          <SwitchAndroid onValueChange={this.onClickEnable} value={this.state.enabled} />
        </View>
        <View ref="workspace" style={styles.workspace} onLayout={this.onLayout}>
          <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} 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>
          <Icon.Button name={this.state.paceButtonIcon} onPress={this.onClickPace} iconStyle={commonStyles.iconButton} style={this.state.paceButtonStyle}><Text>State</Text></Icon.Button>
          <Text>&nbsp;</Text>
        </View>
      </View>
    );
  }
};

module.exports = Map;

2 个答案:

答案 0 :(得分:2)

问题来自<View ref="workspace" style={styles.workspace} onLayout={this.onLayout}>行;您将onLayout函数的引用传递给了<View ref="workspace" style={styles.workspace} onLayout={this.onLayout.bind(this)}> 函数,但是当它被调用时,它会在没有上下文的情况下被调用。你想要做的是在传递引用之前绑定该函数。有many ways来做这件事,但最简单的是:

╔══════╦══════╗
║ Type ║ Data ║
╠══════╬══════╣
║    1 ║ a    ║
║    1 ║ b    ║
║    1 ║ c    ║
║    2 ║ d    ║
║    2 ║ e    ║
║    2 ║ f    ║
║    3 ║ g    ║
║    3 ║ h    ║
║    3 ║ i    ║
╚══════╩══════╝

答案 1 :(得分:0)

Arrow Functions词法绑定“this”,所以如果你像这样编写你的onLayout()函数:

onLayout = () => {
...
};

您将不再需要将其绑定到任何地方。