Undefined 不是评估 this.state/this.props 的对象
Undefined is not an object evaluating this.state/this.props
如何在 React Native 中绑定作用域外的函数?我收到错误:
undefined is not an object evaluating this.state
&
undefined is not an object evaluating this.props
我正在使用 render 方法在数据加载后调用 renderGPSDataFromServer()
。问题是,我试图在 renderGPSDataFromServer()
中使用 _buttonPress()
和 calcRow()
,但我遇到了这些错误。
我添加了
constructor(props) {
super(props);
this._buttonPress = this._buttonPress.bind(this);
this.calcRow = this.calcRow.bind(this);
到我的构造函数,我已经将 _buttonPress() {
更改为 _buttonPress = () => {
但仍然没有。
我想我明白了这个问题,但我不知道如何解决它:
renderLoadingView() {
return (
<View style={[styles.cardContainer, styles.loading]}>
<Text style={styles.restData}>
Loading ...
</Text>
</View>
)
}
_buttonPress = () => {
this.props.navigator.push({
id: 'Main'
})
}
renderGPSDataFromServer =() => {
const {loaded} = this.state;
const {state} = this.state;
return this.state.dataArr.map(function(data, i){
return(
<View style={[styles.cardContainer, styles.modularBorder, styles.basePadding]} key={i}>
<View style={styles.cardContentLeft}>
<TouchableHighlight style={styles.button}
onPress={this._buttonPress().bind(this)}>
<Text style={styles.restData}>View Video</Text>
</TouchableHighlight>
</View>
<View style={styles.cardContentRight}>
<Text style={styles.restData}>{i}</Text>
<View style={styles.gpsDataContainer}>
<Text style={styles.gpsData}>
{Number(data.lat).toFixed(2)}</Text>
<Text style={styles.gpsData}>{Number(data.long).toFixed(2)}</Text>
</View>
<Text style={styles.gpsData}>
{this.calcRow(55,55).bind(this)}
</Text>
</View>
</View>
);
});
}
render = ()=> {
if (!this.state.loaded) {
return this.renderLoadingView();
}
return(
<View>
{this.renderGPSDataFromServer()}
</View>
)
}};
我该如何解决这个问题?在这种情况下,问题是什么?
不确定这是否是问题所在,但我认为是代码有误,可能会导致您的问题。
<View style={styles.cardContentLeft}>
<TouchableHighlight style={styles.button}
onPress={this._buttonPress().bind(this)}>
<Text style={styles.restData}>View Video</Text>
</TouchableHighlight>
</View>
特别是这一行onPress={this._buttonPress().bind(this)}>
您正在调用该函数并同时绑定它。
正确的做法应该是这样
onPress={this._buttonPress.bind(this)}>
这样函数只会在 onPress 时被调用。
你的方向是正确的,但还有一个小问题。您正在将 function
传递给 map
回调,该回调的作用域 (this
) 与您的组件不同(因为它不是箭头函数),所以当您执行 bind(this)
,您正在重新绑定回调以使用来自 map
的范围。我认为这应该可行,它基本上将您传递给 map
的回调变成了箭头函数。另外,由于你 bind
你的函数在构造函数中,你不需要再做一次:
// The constructor logic remains the same
// ....
renderLoadingView() {
return (
<View style={[styles.cardContainer, styles.loading]}>
<Text style={styles.restData}>
Loading ...
</Text>
</View>
)
}
_buttonPress = () => {
this.props.navigator.push({
id: 'Main'
})
}
renderGPSDataFromServer =() => {
const {loaded} = this.state;
const {state} = this.state;
return this.state.dataArr.map((data, i) => {
return(
<View style={[styles.cardContainer, styles.modularBorder, styles.basePadding]} key={i}>
<View style={styles.cardContentLeft}>
<TouchableHighlight style={styles.button}
onPress={this._buttonPress}>
<Text style={styles.restData}>View Video</Text>
</TouchableHighlight>
</View>
<View style={styles.cardContentRight}>
<Text style={styles.restData}>{i}</Text>
<View style={styles.gpsDataContainer}>
<Text style={styles.gpsData}>
{Number(data.lat).toFixed(2)}</Text>
<Text style={styles.gpsData}>{Number(data.long).toFixed(2)}</Text>
</View>
<Text style={styles.gpsData}>
{this.calcRow(55,55).bind(this)}
</Text>
</View>
</View>
);
});
}
render = ()=> {
if (!this.state.loaded) {
return this.renderLoadingView();
}
return(
<View>
{this.renderGPSDataFromServer()}
</View>
)
}};
发生这种情况是因为 map
方法中的函数创建了不同的上下文。您可以使用箭头函数作为 map
方法中的回调来进行词法绑定。这应该可以解决您遇到的问题。
renderGPSDataFromServer =() => {
const {loaded} = this.state;
const {state} = this.state;
return this.state.dataArr.map((data, i) => {
return(
<View style={[styles.cardContainer, styles.modularBorder, styles.basePadding]} key={i}>
<View style={styles.cardContentLeft}>
<TouchableHighlight style={styles.button}
onPress={this._buttonPress().bind(this)}>
<Text style={styles.restData}>View Video</Text>
</TouchableHighlight>
</View>
<View style={styles.cardContentRight}>
<Text style={styles.restData}>{i}</Text>
<View style={styles.gpsDataContainer}>
<Text style={styles.gpsData}>
{Number(data.lat).toFixed(2)}</Text>
<Text style={styles.gpsData}>{Number(data.long).toFixed(2)}</Text>
</View>
<Text style={styles.gpsData}>
{this.calcRow(55,55).bind(this)}
</Text>
</View>
</View>
);
});
}
Also, once you've used arrow functions in the class function definition you
don't need to bind them in constructor like:
constructor(props) {
super(props);
this._customMethodDefinedUsingFatArrow = this._customMethodDefinedUsingFatArrow.bind(this)
}
Also, once you have defined class functions as arrow functions, you
don't need to use the arrow functions while calling them either:
class Example extends React.Component {
myfunc = () => {
this.nextFunc()
}
nextFunc = () => {
console.log('hello hello')
}
render() {
// this will give you the desired result
return (
<TouchableOpacity onPress={this.myFunc} />
)
// you don't need to do this
return (
<TouchableOpacity onPress={() => this.myFunc()} />
)
}
}
this.props are read-only
React docs - component and props
因此,组件不应该尝试修改它们,更不用说像您在这里所做的那样改变它们了:
_buttonPress = () => {
this.props.navigator.push({
id: 'Main'
})
}
我建议改为使用状态:
_buttonPress = () => {
this.setState = {
...this.state,
navigator: {
...this.state.navigator,
id: 'Main'
}
}
}
关于您的绑定问题:
.map
方法采用第二个参数,用于在调用回调时设置 this
的值。
在您问题的上下文中,您只需要将 this
作为第二个参数传递给 .map
方法以将组件范围的 this
绑定到它。
如何在 React Native 中绑定作用域外的函数?我收到错误:
undefined is not an object evaluating this.state
&
undefined is not an object evaluating this.props
我正在使用 render 方法在数据加载后调用 renderGPSDataFromServer()
。问题是,我试图在 renderGPSDataFromServer()
中使用 _buttonPress()
和 calcRow()
,但我遇到了这些错误。
我添加了
constructor(props) {
super(props);
this._buttonPress = this._buttonPress.bind(this);
this.calcRow = this.calcRow.bind(this);
到我的构造函数,我已经将 _buttonPress() {
更改为 _buttonPress = () => {
但仍然没有。
我想我明白了这个问题,但我不知道如何解决它:
renderLoadingView() {
return (
<View style={[styles.cardContainer, styles.loading]}>
<Text style={styles.restData}>
Loading ...
</Text>
</View>
)
}
_buttonPress = () => {
this.props.navigator.push({
id: 'Main'
})
}
renderGPSDataFromServer =() => {
const {loaded} = this.state;
const {state} = this.state;
return this.state.dataArr.map(function(data, i){
return(
<View style={[styles.cardContainer, styles.modularBorder, styles.basePadding]} key={i}>
<View style={styles.cardContentLeft}>
<TouchableHighlight style={styles.button}
onPress={this._buttonPress().bind(this)}>
<Text style={styles.restData}>View Video</Text>
</TouchableHighlight>
</View>
<View style={styles.cardContentRight}>
<Text style={styles.restData}>{i}</Text>
<View style={styles.gpsDataContainer}>
<Text style={styles.gpsData}>
{Number(data.lat).toFixed(2)}</Text>
<Text style={styles.gpsData}>{Number(data.long).toFixed(2)}</Text>
</View>
<Text style={styles.gpsData}>
{this.calcRow(55,55).bind(this)}
</Text>
</View>
</View>
);
});
}
render = ()=> {
if (!this.state.loaded) {
return this.renderLoadingView();
}
return(
<View>
{this.renderGPSDataFromServer()}
</View>
)
}};
我该如何解决这个问题?在这种情况下,问题是什么?
不确定这是否是问题所在,但我认为是代码有误,可能会导致您的问题。
<View style={styles.cardContentLeft}>
<TouchableHighlight style={styles.button}
onPress={this._buttonPress().bind(this)}>
<Text style={styles.restData}>View Video</Text>
</TouchableHighlight>
</View>
特别是这一行onPress={this._buttonPress().bind(this)}>
您正在调用该函数并同时绑定它。
正确的做法应该是这样
onPress={this._buttonPress.bind(this)}>
这样函数只会在 onPress 时被调用。
你的方向是正确的,但还有一个小问题。您正在将 function
传递给 map
回调,该回调的作用域 (this
) 与您的组件不同(因为它不是箭头函数),所以当您执行 bind(this)
,您正在重新绑定回调以使用来自 map
的范围。我认为这应该可行,它基本上将您传递给 map
的回调变成了箭头函数。另外,由于你 bind
你的函数在构造函数中,你不需要再做一次:
// The constructor logic remains the same
// ....
renderLoadingView() {
return (
<View style={[styles.cardContainer, styles.loading]}>
<Text style={styles.restData}>
Loading ...
</Text>
</View>
)
}
_buttonPress = () => {
this.props.navigator.push({
id: 'Main'
})
}
renderGPSDataFromServer =() => {
const {loaded} = this.state;
const {state} = this.state;
return this.state.dataArr.map((data, i) => {
return(
<View style={[styles.cardContainer, styles.modularBorder, styles.basePadding]} key={i}>
<View style={styles.cardContentLeft}>
<TouchableHighlight style={styles.button}
onPress={this._buttonPress}>
<Text style={styles.restData}>View Video</Text>
</TouchableHighlight>
</View>
<View style={styles.cardContentRight}>
<Text style={styles.restData}>{i}</Text>
<View style={styles.gpsDataContainer}>
<Text style={styles.gpsData}>
{Number(data.lat).toFixed(2)}</Text>
<Text style={styles.gpsData}>{Number(data.long).toFixed(2)}</Text>
</View>
<Text style={styles.gpsData}>
{this.calcRow(55,55).bind(this)}
</Text>
</View>
</View>
);
});
}
render = ()=> {
if (!this.state.loaded) {
return this.renderLoadingView();
}
return(
<View>
{this.renderGPSDataFromServer()}
</View>
)
}};
发生这种情况是因为 map
方法中的函数创建了不同的上下文。您可以使用箭头函数作为 map
方法中的回调来进行词法绑定。这应该可以解决您遇到的问题。
renderGPSDataFromServer =() => {
const {loaded} = this.state;
const {state} = this.state;
return this.state.dataArr.map((data, i) => {
return(
<View style={[styles.cardContainer, styles.modularBorder, styles.basePadding]} key={i}>
<View style={styles.cardContentLeft}>
<TouchableHighlight style={styles.button}
onPress={this._buttonPress().bind(this)}>
<Text style={styles.restData}>View Video</Text>
</TouchableHighlight>
</View>
<View style={styles.cardContentRight}>
<Text style={styles.restData}>{i}</Text>
<View style={styles.gpsDataContainer}>
<Text style={styles.gpsData}>
{Number(data.lat).toFixed(2)}</Text>
<Text style={styles.gpsData}>{Number(data.long).toFixed(2)}</Text>
</View>
<Text style={styles.gpsData}>
{this.calcRow(55,55).bind(this)}
</Text>
</View>
</View>
);
});
}
Also, once you've used arrow functions in the class function definition you don't need to bind them in constructor like:
constructor(props) {
super(props);
this._customMethodDefinedUsingFatArrow = this._customMethodDefinedUsingFatArrow.bind(this)
}
Also, once you have defined class functions as arrow functions, you don't need to use the arrow functions while calling them either:
class Example extends React.Component {
myfunc = () => {
this.nextFunc()
}
nextFunc = () => {
console.log('hello hello')
}
render() {
// this will give you the desired result
return (
<TouchableOpacity onPress={this.myFunc} />
)
// you don't need to do this
return (
<TouchableOpacity onPress={() => this.myFunc()} />
)
}
}
this.props are read-only
React docs - component and props
因此,组件不应该尝试修改它们,更不用说像您在这里所做的那样改变它们了:
_buttonPress = () => {
this.props.navigator.push({
id: 'Main'
})
}
我建议改为使用状态:
_buttonPress = () => {
this.setState = {
...this.state,
navigator: {
...this.state.navigator,
id: 'Main'
}
}
}
关于您的绑定问题:
.map
方法采用第二个参数,用于在调用回调时设置 this
的值。
在您问题的上下文中,您只需要将 this
作为第二个参数传递给 .map
方法以将组件范围的 this
绑定到它。