Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Show a react-placeholder skeleton until a image loaded completely in a page

Tags:

reactjs

I'm Beginner in react, i want to show a skeleton placeholder until a image loads completely in my page so I used react-placeholder library for skeleton loader and set the loaded state to false so the skeleton loader shows. I then change the loaded to true by setState it on onLoad function on img tag but my problem is the state is not changing so the skeleton loader shows infinitely thus hiding the image.

how to fix this? what i done wrong here? Someone please help me solve this.

import React from 'react';
import ReactPlaceholder from 'react-placeholder';

class Home extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      loaded: false
    }
  }
  handleImageLoaded() {
    this.setState({ loaded: true });
  }
  render() {
    return ( 
    <React.Fragment>
      <ReactPlaceholder type = 'rect' ready = {this.state.loaded} style = {{height: 160}} >
        <div className = "imageHolder" >
          <img src ="http://someImage.png" alt = "" onLoad={this.handleImageLoaded.bind(this)} />
        </div> 
      </ReactPlaceholder> 
    
    </React.Fragment>
    )
  }
}
like image 571
Naga Nandhini Avatar asked Dec 06 '19 06:12

Naga Nandhini


People also ask

How do you load all images before showing the page in React?

You can ensure that an image is pre-downloaded 100% well before it gets displayed to the screen. Simply create an Image element and set its src property to the URL where the image is located. Then use the image's onload event to detect when it is ready for instant display.

How do you make skeleton loading in React?

React Loading Skeleton Besides Material UI Skeleton, there are other great alternatives, such as the react-loading-skeleton package. Then after a simple import, you can render a SkeletonTheme to style all Skeleton components under it or add props in individual Skeleton components to style them.

How do you use placeholder in React?

Use the placeholder prop to set a placeholder on an input field in React, e.g. <input type="text" placeholder="Your first name" /> . The placeholder text of an input field is shown until the user types something in the field. Copied!


1 Answers

"react-placeholder" is not rendering the image until state.loaded is true, so the onLoad callback will never be executed.

You should take the control of rendering the placeholder and control the image visibility by yourself, and do not use the "react-placeholder" component as it requires a children node, which is not the best election for this case.

import React, { Fragment } from "react";
import ImagePlaceholder from "./ImagePlaceholder";

class Image extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      loaded: false
    }
  }

  handleImageLoaded() {
    this.setState({ loaded: true });
  }

  render() {
    const { loaded } = this.state;
    const imageStyle = !loaded ? { display: "none" } : {};
    return ( 
      <div className = "imageHolder" >
        {!loaded && <ImagePlaceholder/> }
        <img src ="http://someImage.png" style={imageStyle} onLoad={this.handleImageLoaded.bind(this)} />
      </div>
    )
  }
}

Anyway, if you still want to continue using "react-placeholder", then you could solve it with something like:

import React, { Fragment } from "react";
import ReactPlaceholder from "react-placeholder";

class Image extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      loaded: false
    }
  }

  handleImageLoaded() {
    this.setState({ loaded: true });
  }

  render() {
    const { loaded } = this.state;
    const imageStyle = !loaded ? { display: "none" } : {};
    const image = <img src="http://someImage.png" style={imageStyle} onLoad={this.handleImageLoaded.bind(this)} />;
    return (
      <Fragment>
        <ReactPlaceholder type="rect" ready={this.state.loaded} style={{height: 160}} >
          <div className="imageHolder" >
            {image}
          </div> 
        </ReactPlaceholder>
        {!loaded && image}
      </Fragment>
    )
  }
}
like image 140
Javier Brea Avatar answered Nov 05 '22 03:11

Javier Brea