javascriptreactjsreact-loading-skeleton

How to Make React Skeleton Loader Responsive with Different Line Counts for Desktop and Mobile?


I'm currently working on a React project where I'm using react-loading-skeleton to implement loading skeletons. I would like to make the skeleton responsive so that it displays a different number of lines depending on the screen size. Specifically, I want to show:

This is to maintain the content's height and avoid any sudden layout shifts when the actual content loads.

Here is a simplified version of my code:

{loading ? (
  <SkeletonTheme baseColor="#222222" highlightColor="#000">
    <Skeleton height="24px" count={3} width="100%" borderRadius="4px" />
  </SkeletonTheme>
) : (
  <MyText>
    Lorem ipsum dolor sit amet consectetur, adipisicing elit. Suscipit, dolor. Lorem ipsum 
    dolor sit amet consectetur, adipisicing elit. Suscipit, dolor. Lorem ipsum dolor sit 
    amet consectetur, adipisicing elit. Suscipit, dolor?
  </MyText>
)}

How can I modify the skeleton loader to display 3 lines on desktop and 5 lines on mobile while maintaining the content's height to avoid jumping content?


Solution

  • Since you are wanting to control a prop value you'll need to check the view size outside the Skeleton component in order to pass in different count prop values.

    Here's an example implementation that uses a window.resize listener to test the view is greater than a specified width.

    import { useEffect, useState } from 'react';
    
    const useIsViewWidth = (width = 0) => {
      const [innerWidth, setInnerWidth] = useState(0);
    
      useEffect(() => {
        const handleResize = () => {
          setInnerWidth(window.innerWidth);
        };
    
        handleResize();
    
        window.addEventListener("resize", handleResize, true);
    
        return () => {
          window.removeEventListener("resize", handleResize, true);
        };
      }, []);
    
      return innerWidth > width;
    };
    
    const isDesktop = useIsViewWidth(768);
    
    ...
    
    {loading ? (
      <SkeletonTheme baseColor="#222222" highlightColor="#000">
        <Skeleton
          height="24px"
          count={isDesktop ? 3 : 5} // <-- pass correct count value here
          width="100%"
          borderRadius="4px"
        />
      </SkeletonTheme>
    ) : (
      <MyText>
        Lorem ipsum dolor sit amet consectetur, adipisicing elit. Suscipit, dolor. Lorem ipsum 
        dolor sit amet consectetur, adipisicing elit. Suscipit, dolor. Lorem ipsum dolor sit 
        amet consectetur, adipisicing elit. Suscipit, dolor?
      </MyText>
    )}
    

    Edit how-to-make-react-skeleton-loader-responsive-with-different-line-counts-for-desk