如何将 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> </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
中。
我不清楚你为什么要从.open
Drawer
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 动态链接结合使用?