Writing Clean Component Code

Every codebase I have joined had the same two kinds of components: the ones anybody could change on a Friday afternoon, and the ones nobody touched without booking a meeting first. The difference is almost never cleverness. It is whether the file tells you, in order, what it needs, what it decides, and what it renders.

Start with the boundaries. A component that reads from four contexts, fetches its own data, formats currency and animates on mount is really four components wearing a trench coat. Splitting it is not about file count; it is about giving each piece a single reason to change. When the design team renames a label, you should be editing markup, not untangling a fetch.

Naming does more work than any pattern. items tells me nothing; visibleInvoices tells me the list is already filtered and what is in it. The same goes for booleans: isLoading is fine, flag is a small act of sabotage. If a name needs a comment to be understood, the name is the thing that should change.

Be suspicious of premature abstraction. Two components that look alike today may diverge next quarter, and the shared version will grow a variant prop, then a variant prop with exceptions, then a switch statement nobody can delete. Duplicate first, extract on the third occurrence, and only when the three cases genuinely share a reason to exist.

Finally, keep the expensive work outside the render path. Sorting a list, building a formatter, parsing a date — do it once, above the markup, and let the template stay boring. The snippet below is a small grid I use as a background: the geometry is computed once, the palette is picked once, and the render loop does nothing but place elements.

Code Snippet

const TILES = ['sky', 'rose', 'mint', 'amber', 'violet'];

/** Deterministic pick so the pattern is identical on every render. */
function tileFor(row, column) {
  return TILES[(row * 7 + column * 3) % TILES.length];
}

export function TileGrid({ rows = 24, columns = 16 }) {
  const cells = [];

  for (let row = 0; row < rows; row += 1) {
    for (let column = 0; column < columns; column += 1) {
      cells.push({
        key: `${row}-${column}`,
        tile: tileFor(row, column),
        marked: row % 2 === 0 && column % 2 === 0,
      });
    }
  }

  return (
    <div className="tile-grid" style={{ '--columns': columns }}>
      {cells.map((cell) => (
        <span key={cell.key} className={`tile tile--${cell.tile}`} data-marked={cell.marked} />
      ))}
    </div>
  );
}

Nothing in there is clever, and that is the point. The loop is flat, the colour choice is a named function, and the markup is one element repeated. Six months from now, the person who has to add a hover state will find the one place to add it — and will not have to read a single line to understand what the component is for.

2026 — Built by Mila Vance