DEV Community

Cover image for Make our component's Tailwind class names more understandable in React's JSX
Nick Vu
Nick Vu

Posted on

Make our component's Tailwind class names more understandable in React's JSX

Background

Have you ever seen a long list of class names with barely knowing which components we try to debug?

I cannot deny that Tailwind helps our web development faster, especially, with styling, but when we try to use many of its utility class names within a single element. As a result, we cannot see the actual identity of that component and it may become a guessing game.

One of the solutions is that we can add a unique id or class name to identify that component

Added class name c_NPLButton

but I'd admit as a developer that sometimes, I'm too lazy to put it, or copy/paste components somewhere and forget to change their class name identities.

Solution

To solve the above problem programmatically, I implemented a higher-order component

const withComponentClassName = (WrappedComponent) => {
  const WrapperComponent = (props) => {
    const componentName =
      WrappedComponent.displayName || WrappedComponent.name;

    const className = componentName ? `c-${componentName}` : '';

    return (
      <div className={className}>
        <WrappedComponent {...props} />
      </div>
    );
  };

  return WrapperComponent;
};

export default withComponentClassName;
Enter fullscreen mode Exit fullscreen mode

And then use it in components

export default withComponentClassName(MyComponent);
Enter fullscreen mode Exit fullscreen mode

After that, it generates JSX like below

<div className="c-MyComponent">
   <MyComponent {...props} />
</div>
Enter fullscreen mode Exit fullscreen mode

Now every single component will have this pattern in DOM. We can clearly see where those elements are from.

The only trade-off with this approach is that we have an extra div element wrapping our component that increases our DOM size, but in the long run, it has boosted my team's development as well as UI debugging.


3 questions I stumped upon when I developed this approach:

We still can forget to place it in our components, how to prevent that?

We implemented a custom ESLint rule to verify export default of our components with withComponentClassName usage (I'll share it with more detail in another post)

Can we embed that class name into the component's elements directly instead of adding an extra div?

The solution is more complicated and actually, it may make unexpected re-renderings due to class name prop/state updates, so we've accepted this simpler solution

Can we hide that class name addition layer on production?

Yes, we can add a condition in withComponentClassName like below

const withComponentClassName = (WrappedComponent) => {
  //production variable depends on your codebase setup
  if(production === true) {
     return WrappedComponent;
  }

  const WrapperComponent = (props) => {...};

  return WrapperComponent;
};

export default withComponentClassName;
Enter fullscreen mode Exit fullscreen mode

Top comments (0)