React Design Patterns (Part 1)
Tags: javascript, react, webdev, design
Published: 2021-01-23 12:57:42

![alt text](https://bugfender.com/wp-content/uploads/2020/12/Featured-React-Design-Patterns-scaled.jpg)

This article originally appeared at bugfender.com: [React Design Patterns (Part 1)](https://bugfender.com/blog/react-design-patterns-part-1/).

Having studied React for several months, one of the subjects I've paid particularly close attention to is design patterns. In this article, I'll share my key findings.

**Note:** Some of the patterns focus on state management concepts, but we can avoid `Redux,` `Mobx` and other third-party state management tools because they're not related to the subject of this article.

## Render Props

Abounding to [React docs](https://reactjs.org/docs/render-props.html):

> The term “render prop” refers to a technique for sharing code between React components using a prop whose value is a function.

In simple words, **it's just a prop with a function value. The function is a component that needs to be rendered**. Maybe you've seen it in `React Router`:

```jsx
<Route
  path='/about'
  render={(props) => (
    <About {...props} isLoad={true} />
  )}
/>
```

The primary purpose of this pattern **is to update props of sibling components**. It makes the components more reusable and helps us to implement the "[separation of concerns](https://en.wikipedia.org/wiki/Separation_of_concerns)" more easily.

Let's take the following scenario as an example:

- We need to develop a `Form` component.
- Inside the `From` we have `p` and `input`.
- The `input` is the input for the user.
- The `p` shows what the user writes.

We can simply create something like this:

```jsx
import React, { useState } from "react";
export default function Input(props) {
  return (
    <>
      <input
        type="text"
        value={props.value}
        onChange={props.onChange}
      />
    </>
  );
}

export default function Form() {
  const [value, setValue] = useState("");
  return (
    <form>
      <Input onChange={e => setValue(e.target.value)}/>
      <p>{value}</p>
    </form>
  );
}
```

There are two issues with this approach:

1. We don't use the "septate of concern" concept in this case because the `Input` should control the `Value` and not the `Form`.

2. Our components are not so reusable and flexible.

We can refactor the code and use **Render Props** like this:

```jsx
import React, { useState } from "react";

function Input(props) {
  const [value, setValue] = useState("");
  return (
    <>
      <input
        type="text"
        value={value}
        onChange={(e) => setValue(e.target.value)}
      />
      {props.render && props.render(value)}
    </>
  );
}

export default function Form() {
  return (
    <form>
      <Input render={(value) => <p>{value}</p>} />
    </form>
  );
}
```

In this way the `Input` component controls the value, and it is much more reusable (the same functionality can be implemented with different elements).

## HOC - Higher-Order Components

`Higher-Order Components` are basically a function that receive a component as an argument and return a new component with specific business logic inside. You maybe saw this in 'Redux':

```jsx
export default connect(mapStateToProps , mapDispatchToProps)(From);
```

With `Higher-Order Components`, you can write a separate functionality to your app's commons (global) functions and reuse it on diffident components in your project.

Let's take another scenario:

- We need to develop two `menu` components.
- Inside the first component, we have a `button` that needs to block the menu click event.
- The second component is also a `button`, but this time we need to *work with* the menu click event.

The problem is that **we need two kinds of menus - one with `stopPropagation` ability and the second without it.**

We can use `Higher-Order Components` like this:

```jsx
import React from "react";
import "./style.css";

function stopPropagation(WrappedComponent) {
  return function(){
    const handleClick = event => {
      event.stopPropagation();
      WrappedComponent.handleClick()
    };
     return <WrappedComponent onClick={handleClick} />;
  }
}

function Button(props){
  const handleClick = () => console.log("button clicked!");
  Button.handleClick = handleClick; 
  return <button onClick={props.onClick || handleClick}>Click Me</button>;
}

function Menu(props) {
  const openMenu = () => console.log("menu opened!");
  return (
    <div onClick={openMenu} className="menu">
      <h1>Menu</h1>
      {props.children}
    </div>
  );
}

export default function App() {
  const ButtonPropagation = stopPropagation(Button);
  return (
    <div>
      <Menu>
        <ButtonPropagation />
      </Menu>
      <Menu>
        <Button />
      </Menu>
    </div>
  );
}
```

[Link to the demo](https://stackblitz.com/edit/react-hfen5s?file=src/App.js)

Let's analyze this code:

- The `App` component reads the two `Menus` we mentioned.
- The `Menu` component reads the title and the children (in this case, the `Button`).
- `Button` has a button element with a click event. `**handleClick` is the basic functionality of the event.** We need to export this function using `Button.handleClick= handleClick` (in the class component you can do it with  `static`).
- **The `stopPropagation` is the Higher-Order Component**. It receives a component (`Button` in our case) and sends back the component with new ability (in our case `stopPropagation`).

This is a simple example of the use of `Higher-Order Components`. We can use `stopPropagation` and don't need to rewrite again on different components. Even more importantly, we can create other "button" HOCs like preventDefault and queueClick.

Ok, that's all for part one of the article. In the second part, I will discuss the `Context` pattern, the`Presentational and Container Components` pattern and the `compound components` pattern.

Thank you for reading. I hope you enjoyed the tutorial and learned something new. If you have something to add, please leave a comment. And if you would like more information, here are some excellent resources on the subject:

- [Master React Design Patterns 🔥 (render prop & HOC)](https://www.youtube.com/watch?v=axL59Dc5rZA&ab_channel=CoderOne) - In this video, you will find an explanation of `render prop` and `HOC` patterns.
- [React Context & Hooks Tutorial](https://www.youtube.com/playlist?list=PL4cUxeGkcC9hNokByJilPg5g9m2APUePI) - It's a playlist of 21 videos that explain React Context and React Context in hooks (there are some videos that explain hooks in general - you can skip them if you know hooks).
- [React Design Patterns: Presentational and Container Components](https://youtu.be/NazjKgJp7sQ) - This video explains what Presentational and Container Components (known also as "smart and dumb components") are.
- [Building Flexible Components with React Hooks](https://hashnode.com/post/building-flexible-components-with-react-hooks-cjth4fdlk000jzls1krpou422) - An excellent blog post that explains the compound components pattern. If you want an even more advanced resource about the subject, you can watch this video [React Hooks: Refactor compound components to hooks](https://youtu.be/415EfGPuhSo).