title: Get dimensions of image with React
body: <p>I need to get the dimensions of an image with React.  I found a library called <a href="https://github.com/souporserious/react-measure" rel="noreferrer">react-measure</a> that computes measurements of React components.  It works, but I can't get it to fire when the image has loaded.  I need to get it to fire when the image loads so I get accurate dimensions and not 0 x 157 or something like that.</p>
  
  <p>I tried using the <code>onLoad</code> Image Event  to detect when the image has loaded, but I didn't get satisfactory results.  Essentially what I've done is when the image has loaded (<code>handleImageLoaded()</code> has been called), change the <code>hasLoaded</code> state property to <code>true</code>.  I know for a fact that <code>hasLoaded</code> has been changed to <code>true</code> because it says so: <code>Image Loaded: true</code>.</p>
  
  <p>What I noticed is that I can calculate the dimensions for only images that have been cached...</p>
  
  <p><strong>Here is a demo video</strong>: cl.ly/250M2g3X1k21</p>
  
  <p>Is there a better, more concise way of retrieving dimensions properly with React?  </p>
  
  <p>Here is the code:</p>
  
  <pre><code>import React, {Component} from 'react';
  import Measure from '../src/react-measure';
  class AtomicImage extends Component {
  
      constructor() {
          super();
          this.state = {
              hasLoaded: false,
              dimensions: {}
          };
          this.onMeasure = this.onMeasure.bind(this);
          this.handleImageLoaded = this.handleImageLoaded.bind(this);
      }
  
      onMeasure(dimensions) {
          this.setState({dimensions});
      }
  
      handleImageLoaded() {
          this.setState({hasLoaded: true});
      }
  
      render() {
  
          const {src} = this.props;
          const {hasLoaded, dimensions} = this.state;
          const {width, height} = dimensions;
  
          return(
              &lt;div&gt;
                  &lt;p&gt;Dimensions: {width} x {height}&lt;/p&gt;
                  &lt;p&gt;Image Loaded: {hasLoaded ? 'true' : 'false'}&lt;/p&gt;
                  &lt;Measure onMeasure={this.onMeasure} shouldMeasure={hasLoaded === true}&gt;
                      &lt;div style={{display: 'inline-block'}}&gt;
                          &lt;img src={src} onLoad={this.handleImageLoaded}/&gt;
                      &lt;/div&gt;
                  &lt;/Measure&gt;
              &lt;/div&gt;
          );
      }
  }
  
  export default AtomicImage;
  </code></pre>
  
  <p>Here is the parent code.  It's not really important—just passes <code>src</code> to the <code>AtomicImage</code> element:</p>
  
  <pre><code>import React, {Component} from 'react';
  import ReactDOM from 'react-dom';
  import AtomicImage from './AtomicImage';
  
  class App extends Component {
  
    constructor() {
      super();
      this.state = {src: ''}
      this.handleOnChange = this.handleOnChange.bind(this);
    }
  
    handleOnChange(e) {
      this.setState({src: e.target.value});
    }
  
    render() {
  
      const {src} = this.state;
      return (
        &lt;div&gt;
          &lt;div&gt;
            &lt;input onChange={this.handleOnChange} type="text"/&gt;
          &lt;/div&gt;
          &lt;AtomicImage src={src} /&gt;
        &lt;/div&gt;
      )
    }
  
  }
  
  ReactDOM.render(&lt;App /&gt;, document.getElementById('app'));
  </code></pre>