Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to preload image in a React JS component?

I'm currently rendering a child component when a signInError occurs. The signInError is stored in the parent component and if it's not null, it renders the <SignInError/> component, as per the code below:

ParentComponent.js

  // Some code...

  render() {
    return(
      <div>
        <SignInForm
          doSignIn={this.doSignIn}
          resetSignInError={this.resetSignInError}
          signInError={this.state.signInError}
        />
        {this.state.signInError && <SignInError/>}
      </div>
    );
  }

So far, so good, here's the child component SignInError.js

import React from 'react';
import RoundImage from '../../../UI/Common/RoundImage';
import Newman from '../../../../assets/newman-min.png';

class SignInError extends React.Component {
  constructor(props){
    super(props);
  }

    componentDidMount(){
    const img = new Image();
    img.src = Newman;
  }

  render(){
    return(
      <div>
      <div>
        <RoundImage src={img.src}/> // <--- img is undefined here!!!
      </div>
      <div>
        Hello... Newman!
      </div>
    </div>
    );
  }
}

export default SignInError;

RoundImage.js

import React from 'react';

const RoundImage = (props) => {
  return (
    <div>
      <img src={props.src}/>
    </div>
  );
}

export default RoundImage;

How to preload images in React.js?

This question's answer (link above) here on Stack Over flow tells me to create the img object inside the componentDidMount() method to force the browser to load it. And so I did, as you can see from the code above. But now, when I try to pass it as a prop to my grand-child component inside my render method, I can't access the img, because it was defined inside of another method.

What's the best way around this? I just need the image to be loaded and to be displayed together with the error message. Otherwise the error message will show before the image, if your browser hasn't cached it yet. Thanks for the help.

like image 645
cbdeveloper Avatar asked Jan 08 '19 16:01

cbdeveloper


People also ask

How do I preload images in Reactjs?

To load the image into the class, we will simply declare a new Image instance, and will attach the image url to that instance. Then we will set the Promise's resolve attribute to the Image onload attribute and we will set the Promise's reject attribute to the Image onerror attribute.

Can we preload images?

Preload lets you tell the browser about critical resources that you want to load as soon as possible, before they are discovered in HTML. This is especially useful for resources that are not easily discoverable, such as fonts included in stylesheets, background images, or resources loaded from a script.

How do you preload components in React?

Preloading implementation Code for lazyWithPreload and PreloadableComponent is available down here: import { ComponentType } from 'react'; export type PreloadableComponent<T extends ComponentType<any>> = T & { preload: () => Promise<void>; };


1 Answers

Image download happens in the browser. Rendering to the DOM also happens in the browser.

By preloading, do you mean that you want that the component renders only when the image is ready?

If so, you could do something like this:

componentDidMount() {
  const img = new Image();
  img.onload = () => {
    // when it finishes loading, update the component state
    this.setState({ imageIsReady: true });
  }
  img.src = Newman; // by setting an src, you trigger browser download

}

render() {
  const { imageIsReady } = this.state;

  if (!imageIsReady) {
    return <div>Loading image...</div>; // or just return null if you want nothing to be rendered.
  } else {
    return <img src={Newman} /> // along with your error message here
  }
}
like image 58
Jackyef Avatar answered Sep 30 '22 06:09

Jackyef