Composition in React
Tags: react, javascript, programming
Published: 2021-04-18 18:58:43

React implements a unidirectional pattern for data flow for building components. The pattern itself is not unique to react but followed strictly in react.

>__Unidirectional data flow means that data can only flow in one way alone.__

Following the definition and if experienced with react, you would have noticed that the child component cannot pass data to the parent component; hence, data only flows in one way, “__FROM__ the parent __TO__ the child.”

If we need to modify the child that influences the parent or share state between two child components, we use props.

Let’s see a trivial example.

```javascript
import React from "react";

import { Header } from "./components/header";

export default function App() {
  const [loggedIn, setLoggedIn] = React.useState(false);

  const handleSetLoggedIn = () => {
    setLoggedIn(!loggedIn);
  };

  return <Header loggedIn={loggedIn} handleSetLoggedIn={handleSetLoggedIn} />;
}
```

In the example above, we make some assumptions that the App function is responsible for handling login, and it passes the _“loggedIn”_ state and the _“handleSetLoggedIn”_ function to Header.

Let’s investigate the Header component and see how it makes use of these props.

```javascript
import React from "react";
import { Profile } from "./profile";

function Header({ loggedIn, handleSetLoggedIn }) {
  return (
    <>
      <Profile loggedIn={loggedIn} handleSetLoggedIn={handleSetLoggedIn} />
    </>
  );
}

export { Header };
```

Above, we can see that the Header component doesn't make use of the props but passes them to the Profile component that makes use of them. This situation is known as props drilling.

##Props drilling

Props drilling is passing props to a child component that doesn’t need the props but helps to pass it down to its own child component, which might pass it to its own child component because it doesn’t need it as well till it gets to the child that really needs the props.

The problem with props drilling is that things get messy, and debugging might become difficult quickly.

A good solution might be to reach out for the context API or Redux, but that is not needed to solve this problem.

We could use composition (component composition) to our advantage. In fact, the React team says:

>[If you only want to avoid passing some props through many levels, the component composition is often a simpler solution than context.
— React Team] (https://reactjs.org/docs/context.html#before-you-use-context)

##What is composition?
Composition is the act of assembling components or elements to build a whole.

React gives a powerful tool that helps with composition, which is children-props.

We can easily refactor our Header component like this.

```javascript
import React from "react";

function Header({children}) {
  return (
    <>
      {children}
    </>
  );
}

export { Header };
```

The children’s prop is available on every component. It contains the content between the opening and closing tags of a component.

Now, our Header component is a wrapper for the children we choose to render in it.

This gives us the power to refactor our App component render in _“App.js.”_

```javascript
import React from "react";

import { Header } from "./components/header";
import { Profile } from "./components/profile";

export default function App() {
  const [loggedIn, setLoggedIn] = React.useState(false);

  const handleSetLoggedIn = () => {
    setLoggedIn(!loggedIn);
  };

  return (
    <Header>
      <Profile loggedIn={loggedIn} handleSetLoggedIn={handleSetLoggedIn} />
    </Header>
  );
}
```
We have solved the issue with props drilling by making use of composition.

This pattern also gives us the power to build more scalable reusable components, especially when building a tool, a library, or components used by a large number of people with varying needs.

The next article will build a card component and see how composition can be an exciting pattern to think about and use often.

Thank you for reading.