thebedroomprogrammer
thebedroomprogrammer

Reputation: 129

Not able to get access to a function is nested calls (React)

import React,{ Component } from 'react';
import Login from './login';
import ChatScreen from './chatscreen'

export default class App extends Component{
    constructor(props){
        super(props)
        this.state = {
            isLoggedIn :false
        }
    }

    getLoginStatus(status){
        this.setState({isLoggedIn:status});
    }

    showScreen(){
      
        if(this.state.isLoggedIn)
            return (
             <ChatScreen checkStatus={(status)=>{this.getLoginStatus(status)}}/>)
        else if(this.state.isLoggedIn===false)
        return (
            <Login checkStatus={(status)=>{this.getLoginStatus(status)}} />
            )
            
            
    }
   
	render(){
        return this.showScreen()
    }

}


     
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

So, My probelem is this. I have used google's signin api to detect whether user has signed in or not. When he has signed in he sees his main page with a signout button.

When he clicks on the signout button his instance is grabbed and signOut function is called on that instance and the user is signed out.

Now, in order to go back to the login screen, I have defined the state of parent component and passed a function call back to each of the login and logged in screen from where when they call the function using this.props.checkStatus(). The state of parent component is changed and the parent is re-rendered showing login screen or the logged in screen based on its state.

I got it right for the login screen. But when I am signing the user out I am not able to call the callback using this.props as I am calling it inside nested callbacks.

Please provide me a way to call this.props.checkstatus(false) as soon as the singOut() is called.

import React,{ Component } from 'react';


export default class App extends Component{


 componentDidMount(){
     document.getElementById("signOut").addEventListener("click",this.logOut.bind(this));
    
}

    logOut(status){
        var auth2 = gapi.auth2.getAuthInstance();
        auth2.signOut().then(function () {
            console.log("outlog");
             this.props.checkStatus(false);
          });
         
     }
    

	render(){
        return <button id="signOut">out</button>
        
    }

}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

Solution watch this video to understand how this works https://www.youtube.com/watch?v=QQ4__W9nELc

what I used was ecmascript 6 feature or binded the this context like this.

Using ES6 Arrow function

logOut(){
        
        var auth2 = gapi.auth2.getAuthInstance();
        auth2.signOut().then(()=>{
            this.props.checkStatus(false);
        });
        
     }

or using BIND

logOut(){
        
        var auth2 = gapi.auth2.getAuthInstance();
        auth2.signOut().then(function(){
            this.props.checkStatus(false);
        }.bind(this));
        
     }

warning

avoid saving your context like

var that = this;

Upvotes: 0

Views: 312

Answers (1)

Prabodh M
Prabodh M

Reputation: 2252

import React, { Component } from 'react';

export default class App extends Component {

    componentDidMount() {
        document.getElementById("signOut").addEventListener("click", this.logOut.bind(this));
    }

    logOut(status) {
        // Supposing your checkStatus method is in props
        var me = this; //Saving Context of your Component here
        var auth2 = gapi.auth2.getAuthInstance();
        auth2.signOut().then(function() {
            // this here points to the callback method after signOut
            // has performed its task. So this will point to that
            // context. 
            console.log("outlog");
            me.props.checkStatus(false); // Here we used the context saved 
            //above so we can access the required method.
        });

    }

    render() {
        return <button id = "signOut" > out < /button>
    }
}

Just save the context of your App before calling the checkStatus.

Upvotes: 1

Related Questions