React Scaffold Components

Image of Author
April 10, 2022 (last updated September 21, 2022)

A scaffold component is a component containing the "layout elements" and css of a component hierarchy. This is often a "page" component but can also live anywhere within a hierarchy of components in so far that it represents the layout of it's children components.

The utility of thinking of a component as a scaffold component is that it can guide you on where to cleave your components apart, where to break them down into smaller components. Consider the following element hierarchy inspired by the layout of an article page. Consider, as you read, that you likely want to refactor out an <AuthorCardComponent />. Where do you cleave?

function ArticlePage({ ... }) {
  return (
    <div>
      <div>
        <div>
          <img />
          <div>
            <div>
              <div>
                <a>{authorName}</a>
              </div>
              <div>
                <a>
                  <SocialIcon />
                </a>
              </div>
            </div>
            <div>{datePublished}</div>
          </div>
        </div>
      </div>
      <ArticleComponent />
    </div>
  )
}

You cleave where the page layout ends, and the (eventual) <AuthorCardComponent /> begins. Candidate cleave points begin at the sibling div to the <ArticleComponent />. But, the actual sibling div is likely a layout div, responsible for the position of the author card within the greater page. As such, it belongs in the scaffold, and the cleave would occur lower in the hierarchy. Each child component is then only responsible for its own, internal layout.

Component extraction too high in the hierarchy is a common mistake. It results in a component whose CSS and HTML only make sense in the context of its parent. That means the the component is not really reusable. Forcing it to be reusable often requires strange HTML layouts or strange CSS, both within itself and in its parents. The solution is to move that context-dependent CSS and HTML back into the parent, where the scaffolding belongs. A funny way of thinking of it is to "raise your children to be selfish". Don't give them extra responsibilities.

function ArticlePage() {
  return (
    <div>
      <div>
        <AuthorCardComponent />
      </div>
      <ArticleComponent />
    </div>
  );
}

Don't fall prey to the false aesthetic of forcing your children components to be sibling elements. Focus on discerning where layout ends, and component begins.

Deeply nested elements in a large component can definitely be a bad sign. A bad sign that refactors are needed. A bad sign that all the complexity of the component is being smashed together in a single place, interweaving its spaghetti strands into a tangled web that will be hard to disentangle later. But, at the same time, deeply nested elements are an inevitability of a sufficiently complex application. Avoid adding too many elements to a page, but don't be disgusted when there are many. Instead, develop of practice of when and were it is okay to have them. A scaffold component is one such practice.