React useComponent pattern
Tags: react, javascript, typescript, designpattern
Published: 2020-02-05 23:47:41

---
title: React useComponent pattern
published: true
description: Introduction to the `useComponent` React design pattern
tags: react, javascript, typescript, DesignPattern
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tn9owqmad1dj8hxuq4p8.png
---

I'd like to introduce the `useComponent` pattern, something that has seen a lot of traction in the components we have been building lately.

# Objectives
Some common objectives for good React components: 

* Components should be reusable.
* Components should be controllable by the container.

# Pattern
You provide two items: 

* `Component` : the component that you want to be reusable. This will be used by the parent to render the component.
* `useComponent` : a custom hook that returns everything that the component needs in order to function. This is meant to be consumed by the parent that wants to use the component.

# Motivation Example 
Consider the humble `Counter` component:

```tsx
function Counter() {
  // Some hooks the component needs
  const [count, setCount] = useState(0);

  // The rendering of the component
  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}
```

This component although functional is not really reusable as it locks its logic within the render function. Say you wanted to use two counters and display the total count, then you are 💩 out of luck.

# Motivation Solution
Solution: Move any logic the `Counter` component needs into a `useCounter` custom hook function.

Here is the `useCounter` / `Counter` (and inferred TypeScript `CounterProps` 🌹) combo:

```tsx
// Some hooks the component needs
export function useCounter() {
  const [count, setCount] = useState(0);
  return {count, setCount};
}

// Infer the props
export type CounterProps = {
  use: ReturnType<typeof useCounter>
}

// The rendering of the component
export function Counter({ use }: CounterProps) {

  return (
    <div>
      <p>You clicked {use.count} times</p>
      <button onClick={() => use.setCount(use.count + 1)}>
        Click me
      </button>
    </div>
  );
}
```

# Demonstration of reuse
Say you wanted to use two counters and display the total count. Easy peasy: 

```tsx
export function App() {

  const counterOne = useCounter();
  const counterTwo = useCounter();

  return (
    <div>
      <Counter use={counterOne}/>
      <Counter use={counterTwo}/>
      
      {/* Able to use the counters for any additional logic */}
      <div>Total Count: {counterOne.count + counterTwo.count}</div>
    </div>
  );
}
```

Note that the `useCounter` function can easily take initial values. You can also create local functions in the `App` component that can intercept any calls made by the individual `Counter`s.

# Reasons for its popularity
There are two reasons why its so popular:

* Easy to understand: You are writing the component as would naturally, just splitting it into logic and rendering functions. This also makes it easy to deal with while developing and doing code review for *business logic* and *how it looks*. 
* Uses only React: Your components function without any third party library dependency. This allows much greater reuse across teams.

PS: a video on comparing mobx and hooks : https://www.youtube.com/watch?v=MtVGDAnveuY