user1354934 user1354934 - 1 month ago 15
Javascript Question

Not sure what I am doing wrong - getting is not a function errors

I am not sure what I am doing wrong, but I have a few functions inside my component. However, I'm not able to pass one of those functions down as a prop, I receive a

this.nextScene
is not a function.

Here's a snippet from my component, and I have commented out where I am having the issue:

nextScene() {
this.refs.navigator.push('browse');
}

renderNavigationView() {
return (
<View style={styles.drawer}>
<Touchable
onPress={this.nextScene()} //issue here, "this.nextScene is not a function"
>
<View style={styles.container}>
<Text style={styles.title}>Browse</Text>
</View>
</Touchable>
<Touchable>
<View style={styles.container}>
<Text style={styles.title}>Button</Text>
</View>
</Touchable>
</View>
);
}

render() {
return (
<DrawerLayoutAndroid
ref="drawer"
drawerWidth={300}
drawerPosition={DrawerLayoutAndroid.positions.Left}
renderNavigationView={this.renderNavigationView}>
<Navigator
ref="navigator"
configureScene={(route) => {
if (Platform.OS === 'android') {
return Navigator.SceneConfigs.FloatFromBottomAndroid;
}
} }
initialRoute={{}}
renderScene={this.renderScene}
/>
</DrawerLayoutAndroid>
);
}


Thanks!

Answer

If you take a look at the component you are rendering, and at the renderNavigationView prop:

renderNavigationView={this.renderNavigationView}

It seems fine, but since the this context in functions is window by default, this refers to window in renderNavigationView. Consider your onPress event handler:

onPress={this.nextScene()}

Since you use this.nextScene() and this refers to window in a function, you're effectively trying to do window.nextScene which does not exist, thus throwing the error. (Also note that that is an invocation - not a reference. Remove the parentheses).


So if I try this.nextScene.bind(this), I get a cannot read property 'bind' of undefined

This is because the function is undefined because window.nextScene doesn't exist. To fix this, use Function.prototype.bind to bind the this correctly on both renderNavigationView and nextScene:

renderNavigationView={this.renderNavigationView.bind(this)}

What bind does in this situation is set the this context in the function. Since this here refers to the class, the class will be used to execute the nextScene method which should work correctly. You must also use bind on nextScene because inside nextScene we want this to refer to the class, not window:

onPress={this.nextScene.bind(this)} 
Comments