How do I bind a function outside of scope in React Native? I'm getting the errors:
undefined is not an object evaluating this.state
&
undefined is not an object evaluating this.props
I'm using the render method to evoke renderGPSDataFromServer()
when the data has been loaded. The problem is, I'm trying to use _buttonPress()
and calcRow()
inside of renderGPSDataFromServer()
, but I'm getting those errors.
I've added
constructor(props) {
super(props);
this._buttonPress = this._buttonPress.bind(this);
this.calcRow = this.calcRow.bind(this);
to my constructor and I've changed _buttonPress() {
to _buttonPress = () => {
and still nothing.
I think I understand the problem but I don't know how to fix it:
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>
)
}};
How do I go about fixing this and in this case what is the problem?
This is happening because, the function inside the
map
method creates a different context. You can use arrow functions as the callback in themap
method for lexical binding. That should solve the issue you are having.not sure if this is the problem, but I think is code is wrong, and may be potentially causing your issue.
specifically this line
onPress={this._buttonPress().bind(this)}>
you are invoking the function and binding it at the same time.The correct way to do this would be so
this way the function will be called only onPress.
You are going in the right direction, but there is still a minor issue. You are passing a
function
to yourmap
callback that has a different scope (this
) than your component (because it is not an arrow function), so when you dobind(this)
, you are rebinding your callback to use the scope frommap
. I think this should work, it basically turns the callback that you pass tomap
into an arrow function. Also, since youbind
your function in the constructor, you do not need to do it again:React docs - component and props
And therefore a component shouldn't try a to modify them let alone mutate them as you are doing here:
I'd suggest using state instead:
Regarding your binding issue:
the
.map
method takes a 2nd argument that is used to set the value ofthis
when the callback is invoked.In the context of your question, you just need to pass
this
as the 2nd argument to you.map
method to bind the components scope'sthis
to it.