Split fat component into smaller flexible components in React
Tags: react, functional, javascript, currying
Published: 2018-02-19 16:34:50

---
title: Split fat component into smaller flexible components in React
published: true
description: How currying in functional programming can help you to write more granular react component
tags: React, fp, javascript, currying
---

When writing React component, one of the common thing that happen is that the component that you write has became a big fat chunk, causing it harder to read and understand.

When that happens, it is always advised for you to split the big component into few smaller component so it is easier to understand. Besides, the smaller components could be reused elsewhere.

Sometimes, it is quite obvious how to do it by just moving your code into another component. But sometimes it is not so obvious what is the best way to split the code.

For instance, a scenario that can make splitting component more complicated is that your `onClick` handler for your child component need to know the id of the parent, which is a common requirement when you have some nested data structure.

In those case, currying may help you to split the component in a clean way.

# What is currying

Currying is a functional programming technique to transform a function that takes multiple arguments into a sequence of functions.

For instance, a typical add function and usage looks like below:
```js
const add = (x, y) => {
    return x + y;
}
add(2, 3); // 5
```

Using currying, the add function can be rewrited as below:
```js
const add = x => y => {
    return x + y;
}
add(2)(3); // 5
```

Now you understand what is currying, let's see how it can help us in splitting component.

# Intro to Example

To help you understand how currying may help, assuming you have the data structure below.

```js
data = [
    {
        id: 1,
        name: "Parent 1",
        sublist: [
            {
                id: 11,
                name: "Child 1",
 
            },
            {
                id: 12,
                name: "Child 2",
 
            }
        ]
    },
    {
        id: 2,
        name: "Parent 2",
        sublist: [
            {
                id: 21,
                name: "Child 3",
 
            },
            {
                id: 22,
                name: "Child 24",
 
            }
        ]
    }
];
```

And the initial components looks like this: (I know it is not so big in this example, just imagine the data structure is longer and you need to display more data in the component)

```jsx
const FatComponent = ({ data }) => {
  const updateItem = (parentId, childId) => {
    someFunction(parentId, childId);
  };

  return data.map(parent => (
      <div>
        <span>name: {parent.name}</span>
        <div>
          {parent.sublist.map(item => (
            <div>
              <span>{item.name}</span>
              <button onClick={() => this.updateItem(parent.id, item.id)}>remove</button>
            </div>
          ))}
        </div>
      </div>
    ));
}
```

# Attempt to split the component

We can split the component like below:

```jsx
const FatComponent = ({ data }) => {
  const updateItem = (parentId, itemId) => {
    someFunction(parentId, childId);
  };

  return data.map(parent => <Parent updateItem={updateItem} {...parent} />);
};

const Parent = ({ id, name, sublist, updateItem }) => (
  <div>
    <span>{name}</span>
    <div>
      {sublist.map(item => <Item updateItem={updateItem} parentId={id} {...item} />)}
    </div>
  </div>
);

const Item = ({ name, id, updateItem, parentId }) => (
  <div>
    <span>{name}</span>
    <button onClick={() => updateItem(parentId, id)}>remove</button>
  </div>
);
```
However, this solution is not clean because it makes `Item` become tightly coupled to the parent, as the parent component must pass down `updateItem` and `parentId` props to `Item` component. 

Ideally, `Item` should accept `buttonOnClick` props and attach it to the button `onClick` handler, like below:
```jsx
const Item = ({ name, id, buttonOnClick }) => (
  <div>
    <span>{name}</span>
    <button onClick={buttonOnClick}>remove</button>
  </div>
);
```
This would makes Item flexible and more likely to be reused for other components.

# Solution - Using currying
By using currying, we would able to achieve that:
```jsx
const FatComponent = ({ data }) => {
  const updateItem = parentId => itemId => () => {
    someFunction(parentId, itemId);
  };

  return data.map(parent => <Parent updateItem={updateItem(parent.id)} {...parent} />);
};

const Parent = ({ name, sublist, updateItem }) => (
  <div>
    <span>{name}</span>
    <div>
      {sublist.map(item => <Item buttonOnClick={updateItem(item.id)} parentId={id} {...item} />)}
    </div>
  </div>
);

const Item = ({ name, id, buttonOnClick }) => (
  <div>
    <span>{name}</span>
    <button onClick={buttonOnClick}>remove</button>
  </div>
);
```
Clean and sweet!

# Final Words

Even though functional programming is not required for you to coding in React, however, learning more of functional programming would help you to write cleaner and better React code.

Happy coding!