Making Our ⚛ Components Reusable♻️
Tags: react, javascript, reusable, components
Published: 2020-08-01 20:30:54

React’s value add for frontend developers is that it makes single page web app development much easier by combining the well understood syntax of HTML with the scripting capabilities of JavaScript in an intuitive and convenient way.

One of React’s *most important* features that is easy for new developers to overlook is component reusability. We need to be building React components that are designed to be reused throughout the UI.

I get it though, it can be hard to see how a component can be reused. I hope to be able to pass on some tips that I’ve learned during my journey into React to help keep components reusable.

# Start with the planning stage
In the last post in the series, I broke down a series of wireframes into a component hierarchy. Detailed planning is the first step to identifying reusable components.

When looking at a mockup or a wireframe, it’s critical to identify parts of the UI which are identical to other parts of the UI or are extremely similar but with minor variations.


## Aristotle and UI
The Greek philosopher Aristotle formalized thought regarding an object’s essence. According to Aristotle, an object’s essence is the set of characteristics that make the object what it is and without which it would not be what it is.

For example, we could say that the essence of a button is its clickability. All buttons are clickable and perform some action when clicked. Similarly, if a part of a UI is never clickable, then we can say that it is not a button.

In contrast to an object’s essence, Aristotle held that objects also have “accidental” characteristics. Basically what Aristotle meant by the term “accidental” is “not essential”. That is, an accidental characteristic is something which can be removed from an object without making the object something other than what it is.

In our example, a button’s color, shape, or text would all be accidental characteristics because they can all be changed without making the button not a button. A red button is still a button.

> In Aristotle’s thought, an “accidental” characteristic is not one which occurs by chance, but rather a characteristic which can be altered without changing the object into a different kind of object.

## How does all this relate to reusability ♻️?
When identifying reusable components, first look for all the parts of the UI which share essential characteristics. Identify UI elements which are accidental characteristics of the components to which they belong, so that you can see all the features that it shares in common with similar components.

Reusable components share the same set of essential characteristics in **every** part of the UI, even though some of their accidental characteristics might change between parts of the UI.

# Building Reusable components
If you haven’t already, create a new react app for our forum project.
```bash
npx create-react-app
```
When it’s finished, navigate to the new project and install missing dependencies:
```bash
yarn add @mdi/js @mdi/react bulma rbx \
  react-router react-router-dom \ 
  graphql-request redux react-redux \ 
  immer easy-redux-reducers
```

Here’s a brief explanation of the dependencies

* [Bulma][bulma], [rbx][rbx]: npm packages to use the bulma framework with react
* `@mdi/js`, `@mdi/react`: packages to use the material design icon font with react
* `react-router`, `react-router-dom`: allows us to have multiple pages in one react app.
* `graphql-request`: allows us to easily query our GraphQL backend.
* [redux][redux], `react-redux`: helps us manage complex application state
* [immer][immer]: allows us to maintain immutability but also to modify state objects directly.
* [easy-redux-reducers][reducers]: a tiny package to eliminate the need for writing switch statements in redux reducers.

Once those are finished installing, we’re ready to begin building reusable components


# Delete unnecessary files
Remove the files `index.css`, `app.css`, `logo.svg`, `favicon.ico` and all the references to those files. We won’t need them and they’ll just get in the way.

# Creating our first reusable component
Let’s tackle the most reused component in our component hierarchy: `Field`. If you look back at the last post, you’ll see that this field is probably the most reused component in the whole hierarchy.

For clarity, I’m calling `Field` `FormField` in the actual code to reduce ambiguity since there is a `field` component in Bulma.

Here’s my code for `FormField`:
```jsx
// src/components/FormField.js

import React from 'react';

import {Field, Label, Control, Input} from 'rbx';

const FormField = props => {
    return <Field>
        <Label>{props.name}:</Label>
        <Control>
            <Input 
                type="text" 
                placeholder={props.name} 
                value={props.value}
                onChange={props.onChange}
            />
        </Control>
    </Field>
};

export default FormField;
```

The `Field`, `Label`, `Control`, and `Input` components are all components from `rbx` required to use Bulma styles and make sure that they stay consistent.

Notice that I have not actually passed any values (other than the “text” property) to any of the components. This is key to keeping a component reusable. We need to make sure it behaves predictably in whatever context we use it.

`FormField` does not maintain any state, but rather expects an `onChange` prop so that it’s parent component can keep track of state management. Since `FormField` is a functional component, getting the value of the `Input` component would have been challenging.

## The `TopicTitle` component
Let’s look at another example. Here’s my code for the `TopicTitle` component:
```jsx
import React from 'react';

import { withRouter } from 'react-router-dom';
import { Box, Title } from 'rbx';

const TopicTitle = props => {
    return <Box onClick={()=> props.history.push({pathname: props.to})}>
        <Title>{ props.text }</Title>
    </Box>
}

export default withRouter(TopicTitle);
```

This component displays the title of a topic and also acts as a link to the topic itself. Again, by using props, I can make this component highly reusable with minimal effort. I wrapped the whole component in `react-router`’s `withRouter()` function to enable it to properly integrate with the browser’s history API. 

# Go build some reusable♻️ components
I hope I have been able to give you some tips regarding how to make React components reusable. As always, feel free to ask me questions in the comments.

The code for this part of the series is available on [GitHub][repo]

{% github speratus/miniforum-frontend %}

[bulma]: https://bulma.io
[rbx]: https://github.com/dfee/rbx
[redux]: https://redux.js.org
[immer]: https://immerjs.github.io/immer/docs/introduction
[reducers]: https://github.com/speratus/easy-redux-reducers
[repo]: https://github.com/speratus/miniforum-frontend/tree/part1-reusability