javascriptjqueryreactjsjquery-deferredimagesloaded

React with imagesLoaded, and resolving a value for the final render


I have a class called PhotoTags that has a function called getScalePercent(). In getScalePercent I do a simple calculation involving the width and height of a displayed image, and return a value. In the render function of PhotoTags I use coordinate data to apply elements over a photo. This logic works fine only if the image has been loaded 100%. If I refresh the page enough times I can see that my logic is in fact setting the coordinates properly but only once the image has either been cached, or loaded quickly. Therefore I want to use imagesLoaded to check if the image has loaded, inorder to use the coordinates effectively.

My function looks like this:

getScalePercent(){
        var p =0;
        var targetWidth = $('.expanded-image').width();
        var targetHeight = $('.expanded-image').height();
        p = (targetWidth / 1920);
        return p;
}

And in my render function I am trying to use imagesLoaded to check if the image has been loaded before using getScalePercent():

render(){
   var p = 0;

   $('.expanded-image').imagesLoaded().done( function() {
        p = this.getScalePercent();
   });

   console.log(p); //But value is still 0

   //I then want to use p later in the render function

My variable p is not being manipulated within the .done event of imagesLoaded. I know it has something to do with asynchronous calls and what not, and I have tried putting imagesLoaded in getScalePercent() but to no avail. I have also tried doing a callback to getScalePercent() and many other variations but still to no avail. Basically what I want to do is fire getScalePercent() inside the .done() event of imagesLoaded. I then want to be able to use the value that getScalePercent() returns (when the image is fully loaded) inside the render function of PhotoTags. Any help is much appreciated.


Solution

  • Would you not be better just adding an onLoad event on your image, something like this:

    class Test extends Component {
        constructor (props){
            super(props);
            this.state = {
                imgLoaded:false
            }
        }
        handleImgLoaded (event){
            // Do stuff
            console.log(event.target);
            this.setState({
                imgLoaded:true
            });
        }
        render (){           
            <div className={'img-wrapper-class ' + (this.state.imgLoaded ? 'img-loaded' : 'img-loading')}>
                <img src={"somesrc.jpg"} onLoad={this.handleImgLoaded.bind(this)} />
            </div>
        }
    }