2

I am getting well known error undefined is not an object when trying to call this.refs from the context of navigationOptions.

Better if I explain with code:

 static navigationOptions = ({ navigation, screenProps }) => ({
        headerTitle: 'my app',
        title: 'my app',
        headerTitleStyle: {
            textAlign: "center",
            flex: 1,
        },
        headerLeft:
            <TouchableOpacity style={{padding: 15, marginLeft: 5}} onPress={() => { navigation.state.params.goBack(navigation.state.params.canGoBack) }}>
                {navigation.state.params.canGoBack ? <Text>back</Text>: <Text>close</Text>}
            </TouchableOpacity>,
    });


    componentDidMount() {
            this.props.navigation.setParams({goBack: this.onBack});
            this.props.navigation.setParams({canGoBack: this.state.canGoBack});
            Keyboard.dismiss();
        }

   onBack(canGoBack) {
        console.log(canGoBack);
        if(canGoBack){
            this.refs[WEBVIEW_REF].goBack(); // here is the error happening, somehow I can access this.refs.
        }
    }

    onNavigationStateChange(navState) {
        this.setState({
            canGoBack: navState.canGoBack
        });
        this.props.navigation.setParams({
            canGoBack: this.state.canGoBack,
        });
        console.log("some action happened: " + this.state.canGoBack);

    }

Anyone knows how to solve this?

Mizlul
  • 1
  • 7
  • 41
  • 100
  • 2
    It's not bound and being called outside of the object's context. – Dave Newton May 23 '18 at 11:22
  • 1
    You can use arrow function in order to get correct context: `onBack = (canGoBack) => { }` – Raeesaa May 23 '18 at 11:24
  • You can even assign a constant as `const instance = this;` in the start of your function and use `instance.refs`. It's occurring because scope of `this` is undefined in callback functions. So define a variable containing `this` and use it in callback function :) – Aseem Upadhyay May 23 '18 at 11:26
  • @User97 thnx, it worked! – Mizlul May 23 '18 at 11:29

1 Answers1

3

The issue is that you are losing the context when using this.onBack

You need to make sure that this.onBack is called with your component context, and you can do this by either:

  • Using arrow functions: this.props.navigation.setParams({goBack: (e) => this.onBack(e)});

  • Bind this to your function: this.props.navigation.setParams({goBack: this.onBack.bind(this)});

Hamza El Aoutar
  • 5,292
  • 2
  • 17
  • 23