My secret trick for writing great React components
Tags: react, webdev, discuss
Published: 2021-11-29 18:24:28

---
title: My secret trick for writing great React components
published: true
description: Single responsibility principle in React. The key of thinking and writing components in React.
tags: react, webdev, discuss
cover_image: https://images.pexels.com/photos/4587991/pexels-photo-4587991.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940
---

I have a confession to make. I do not write a single test for my React components. Yes, you read that right, not a single one. You might wonder how I keep track of complex React projects with many many components. Here's my trick:

## Always write React components that you can read without scrolling.

As a rule of thumb, if you cannot read a React component without scrolling, then I bet it does more than one thing. It has more than one responsibility, more than one single purpose.

## Thinking in React

> The first thing you’ll want to do is to draw boxes around every component (and subcomponent) in the mock and give them all names.

[This is an actual quote from the React docs](https://reactjs.org/docs/thinking-in-react.html#step-1-break-the-ui-into-a-component-hierarchy) that apparently everybody forgot to read.

![Thinking in React](https://reactjs.org/static/9381f09e609723a8bb6e4ba1a7713b46/90cbd/thinking-in-react-components.png)

If you follow this advice every component that you write will do one and only one thing, will serve only one purpose. If it ends up growing, it should be decomposed into smaller subcomponents.

What about complex functions that manipulate data? This is also simple: I just create a pure function with all the logic, save it in a file and just use it in my React components.

## Let's see some code

Let's assume I want to add React Context to one of my components.

```jsx
const AwesomeComponent = (props) => {
  const defaults = {
    mode: 'dark',
  };
  const cache = {
    mode: local.get('theme.mode'),
  };
  const initialTheme = merge(defaults, cache);
  const [theme, setTheme] = useState(initialTheme);

  return (
    <ThemeContext.Provider value={{ theme, setTheme }}>
      <div className="awesome-component">
        <div>everything else...</div>
      </div>
    </ThemeContext.Provider>
  );
};
```

The first part of the component uses the `useState` React hook. It also initializes the state with some default values taken from some options cached values.

### First improvement

The defaults can really grow over time to many other options, not just `mode`. Let's make a function that initializes the state. This function will have a single purpose: initializing the state.

```jsx
const AwesomeComponent = (props) => {
  const [theme, setTheme] = useState(themable());

  return (
    <ThemeContext.Provider value={{ theme, setTheme }}>
      <div className="awesome-component">
        <div>everything else...</div>
      </div>
    </ThemeContext.Provider>
  );
};
```

### Second improvement

The component still does more than it should. Let's move the hard-to-read React context code in a separate component and just implement it in our main component. This way we will not care how the context is initialized, we will care only that the context WAS initialized.

```jsx
const AwesomeComponent = (props) => {
  return (
    <Theme>
      <div className="awesome-component">
        <div>everything else...</div>
      </div>
    </Theme>
  );
};
```

### More improvements

If you start thinking this way in React you will notice these small changes everywhere in your projects. And your projects will become better and better.

## Final thoughts

**Code clutter**

We're all guilty of it. Junior devs, senior devs, fullstack devs. We all have written God classes in OOP or huge React components without splitting them by purpose. 

But this has to change, otherwise the complex project you are working on is going to become a complex monster project.

And it has to change fast. So next time you plan to write some React component, hook or just a plain function: why not split it in multiple files, each one with a single responsibility? The world of programming would be a much better place.