DEV Community

Cover image for How to add load Blur effect to images in React
Michael Chac贸n
Michael Chac贸n

Posted on

How to add load Blur effect to images in React

There is a problem that sometimes we dislike in Create React App, which is solving the loading of images, there are plugins for frameworks that provide solutions such as Gatsby or Next, but aha

驴if I am building a React application, can I use those plugins?

The answer is No, you could use it if you change your entire application to some of those frameworks that I mentioned, there are also some plugins that give you a lazy image. But we are going to do it with a quick script.

First, let's create a file at src/components/BlurImage.js and we'll create our script there:

import * as React from 'react';
import clsx from 'clsx';

function BlurImage({ img, ...rest }) {
  const [visible, setVisible] = React.useState(false);
  const imgRef = React.useRef(null);

  const { src, srcSet, sizes } = img.props;
  React.useLayoutEffect(() => {
    if (imgRef.current?.complete) setVisible(true);
  }, []);

  React.useEffect(() => {
    if (!imgRef.current) return;
    if (imgRef.current.complete) return;

    let current = true;
    imgRef.current.addEventListener('load', () => {
      if (!imgRef.current || !current) return;
      setTimeout(() => {
        setVisible(true);
      }, 950);
    });

    return () => {
      current = false;
    };
  }, [src, srcSet, sizes]);

  const imgEl = React.cloneElement(img, {
    ref: imgRef,
    key: img.props.src,
    className: clsx(
      img.props.className,
      ' w-full h-full object-cover transition-opacity',
      { 'opacity-0': !visible },
    ),
  });

  return (
    <>
      <div
        className={clsx(rest.className, 'w-full h-70')}
        style={
          visible === false
            ? {
                ...rest.style,
                backgroundSize: 'cover',
                backgroundColor: 'rgba(232, 74, 148, 0.8)',
                filter: `blur(3px)`,
              }
            : rest.style
        }
      >
        {imgEl}
      </div>
    </>
  );
}
export { BlurImage };
Enter fullscreen mode Exit fullscreen mode

I explain:
We create a state which will help us when the image appears and we use a useRef for when it is fully loaded it is shown, we will create two effects which will be attentive to the change of the images and a setTimeout to show in an estimated time if you want the image.

Then we create a clone of the img element which we will pass the ref and the classes to add style to our effect in my case I use tailwindcss but they can use css, now we return our component:

The same use clsx to apply logic to the css, we continue, then we tell it if the visibility is still in false show me my blur while loading.

We go through the props the img and ...rest in case we want to add a different style to our image when it is applied

Ok now we need to import our component in a place where we want to render the image.

We create a script where the result of the images is obtained, it could be src/components/Image.js

import * as React from 'react'
import {BlurImage} from './BlurImage';

function Image(){
return(
 <div>
 <BlurImage img={<img   src="https://res.cloudinary.com/mcljs/image/upload/v1593235813/sample.jpg" 
          alt="Placeholder"
          className="rounded-lg px-2 py-4  object-center w-full lg:h-72 md:h-3"
        />
 </div>
)}

Enter fullscreen mode Exit fullscreen mode

Finally I leave the example of images on websites used:

Blur

image-complete

You can follow me on my GitHub and see more of me and projects

Discussion (1)