Search code examples
javascriptreactjses6-promise

react component this.value is null even when it's populated


Here a simplified version of a React component I have:

class Example extends Component {
    constructor(props) {
        super(props);
        this.state = {key : 10 };
        this.value = null;
    }

    componentDidMount() {
        this.fetchValueFromServer();
        this.fetchSecondValueFromServer();
    }

    fetchValueFromServer() {
        fetch_value_from_server(this.state.key).then( (value) => {
            this.value = value;     
        }); 
    }

    fetchSecondValueFromServer() {
        is_ready(this.value).then(() => {
            console.log("there");       
        }); 
    }

}

I expect to see the console.log("there") printed but this.value always remains null, even thou is set in the fetchValueFromServer. Why is this? if you are curious to how is_ready looks it's a simple promise:

function is_ready(variable) {

    return new Promise((resolve, reject) => {
        let interval = setInterval(() => 
        { 
            if (variable) {
                clearInterval(interval);
                resolve();
            }

        }, 100);
    });
}

Solution

  • The problem is with the logic of the is_ready function. It looks like you want that function to repeatedly check if that value is there, then resolve when it is. However, because of how closures in JS work, that variable argument will only ever have one value in the context of that function's body, even after this.value changes. Look at this small example:

    let secret = 'not found yet'
    
    function checkSecret(secretArg) {
      setInterval(() => {
        console.log(secretArg)
      }, 500)
    }
    
    checkSecret(secret)
    setTimeout(() => { secret = 'secret found!' }, 1000)

    This code will always print 'not found yet', because it's checking the secretArg variable that's been assigned locally, and not the secret variable directly.