DEV Community

loading...

A guide for Skeletons in React.

alexandprivate profile image Alex Suarez ・2 min read

Hi there developers! In this article, I will be sharing my experience in implementing skeletons components. Why using skeletons on loading states, how to implement them, and when and how to use them. Let's go.

Why

Skeletons or placeholders are very powerful for loading states, it's proven that reduce the user anxiety during the application loading process, and that is because it shows to the user the upcoming content structure(at least is intended), also gives the idea that the app is working, it is almost like "We have everything ready but the text and the images just wait a sec", so the user feels the app is about to show up the final content but structurally we already delivered the UI.

Implementation

In short, the easiest way to implement and skeleton screen is by using an SVG (using Figma for example) and add some animations to it, but if you have the time and the skills, you can create a responsive as a JSX component (using tailwindcss of course ) :)

HOC, In-component conditional rendering or composition

Well, it depends, I think HOC are meant for auth wrapper nowadays, since functional components and hooks solved many of the problems HOC use to solve in the past, with that said if you want to keep your JSX cleaner as possible, the way to go is... Composition of course. Let's take a look at it.

Let's create a simple skeleton component that just returns "loading..." when the "on" prop is true

function Skeletons({children, on}) {
  return on ? <p>Loading...</p> : <>{children}</>
}
Enter fullscreen mode Exit fullscreen mode

In your component...

import Skeletons from 'components/skeletons'

export default function App() {
  // useFetch is a custom hooks for data fetching
  const [data, loading, error] = useFetch(URL)
  return (
    <Skeletons on={loading}>
      <div className="App">
        {data.map(data => 
          <div key={data.id}>{data.name}</div>
        )}
      </div>
    </Skeletons>
  );
}
Enter fullscreen mode Exit fullscreen mode

The above method is far better than creating the Skeleton component with no render condition on it.

function Skeletons({children}) {
  return <p>Loading...</p>
}
Enter fullscreen mode Exit fullscreen mode

An then handle the conditional rendering on every single component to show the Skeletons ...

import Skeletons from 'components/skeletons'

export default function App() {
  // useFetch is a custom hooks for data fetching
  const [data, loading, error] = useFetch(URL)

  if(loading) return <Skeletons />
  return (
    <Skeletons on={loading}>
      <div className="App">
        {data.map(data => 
          <div key={data.id}>{data.name}</div>
        )}
      </div>
    </Skeletons>
  );
}
Enter fullscreen mode Exit fullscreen mode

So compositions wins this fight, and if you ask me is the best way to implement Skeletons screens for your components loading states, it's easy to scalable and reusable.

So what's yours?

Discussion (0)

pic
Editor guide