Writing cleaner react code
Tags: beginners, javascript, tutorial, react
Published: 2022-07-31 13:49:09

As a developer, you'll often hear the phrase **`Clean Code`**. So what does it mean? **`Clean Code`** is writing code that is **`D.R.Y`** (don't repeat yourself), **`understandable`** and **`maintainable`**. This is a skill that is crucial for every developer to master.

Inexperienced **`react`** developers fall victim to repetitive code when their projects scale. So here are some good practices for React!

## 1 - Self Closing

Avoid using react tags more than once.

For Example:

```javascript
<Example firstArg="example arg" secondArg="second arg"><Example>
```

Even if they have a child property like this:

```jsx
<Example>
  <h1>Text</h1>
</Example>
```

You can add it as a **`children`** argument.

```jsx
<Example children={<h1>Text</h1>} />
```

## 2 - Choosing the correct function type

### Use Arrow functions

Avoid using functions. In react, you'll be using variables (for example `const`, `let` or `var`) more often than not, so for the sake of consistency, use arrow functions.

Avoid using this.

```jsx
function ExampleFunction() {
  return <h1>Hello world</h1>;
}
```

Arrow functions allow you to skip a return statement for one line codes. Here is the same code as an arrow function:

```jsx
// Single Line
const ExampleFunction = () => <h1>Hello world</h1>;

// Multi Line
const ExampleFunction = () => (
  <>
    <h1>Hello world</h1>
    <h2>Hello example Code</h2>
  </>
);
```

### Does it need to be a function?

Not every block of code needs to be a function. In fact if you're not passing an argument and all that is being returned is a JSX element, why not just make the code block a variable?

For example:

```jsx
const ExampleFunction = () => <h1>Hello world</h1>;
const exampleCode = <h2>Hello example Code</h2>;

const codeBlock = (
  <>
    <ExampleFunction />
    {exampleCode}
  </>
);
```

## 3 - Deconstruction

When you pass arguments through a function, it will look like this:

```jsx
<HelloFunction firstName="John" lastName="Doe" age={18} />
```

When accessing those argument properties, you'll normally do something like this:

```jsx
const HelloFunction = (prop) => {
  return (
    <h1>
      Hello my name is {prop.firstName} {props.lastName}, I am {props.age}.
    </h1>
  );
};
```

But by deconstructing the arguments, you avoid the repetition of `props.`. Here are some examples:

```jsx
// Option 1 - deconstruct in the function argument
const HelloFunction = ({ firstName, lastName, age }) => (
  <h1>
    Hello my name is {firstName} {lastName}, I am {age}.
  </h1>
);

// Option 2 - deconstruct inside function
const HelloFunction = (props) => {
  const { firstName, lastName, age } = props;

  return (
    <h1>
      Hello my name is {firstName} {lastName}, I am {age}.
    </h1>
  );
};
```

## 4 - Spreading arguments

Your return statement should be as short as possible. Here is an example of a component function:

```jsx
<ExampleFunction
  firstName="John"
  lastName="Doe"
  age={18}
  address="123 example road"
  student={true}
/>
```

Instead of writing all of a component function's arguments, you can declare them before and spread them like so:

```jsx
const exampleArg = {
  firstName: "John",
  lastName: "Doe",
  age: 18,
  address: "123 example road",
  student: true
};

<ExampleFunction {...exampleArg} />;
```

By doing this, you'll reduce the size of the files return statement.

## 5 - Utilize Map functions to avoid repeating.

You should avoid repetition in your code whenever possible, let's say you have a number of tabs like this:

```jsx
const myTabs = () => (
  <Tabs>
    <Tab title="First Title">
      <h1>First content</h1>
    </Tab>
    <Tab title="Second Title">
      <h1>Second content</h1>
    </Tab>
    <Tab title="Third Title">
      <h1>Third content</h1>
    </Tab>
  </Tabs>
);
```

Each **`Tab`** in the example above has a title and child argument. To represent the data, we can just create an array of objects for each tab. By doing this, we can map function over that object and only return the unique values for each tab.

Here is an example of how to refactor it:

```jsx
const TabsData = [
  {
    title: "First Title",
    content: <h1>First content</h1>
  },
  {
    title: "Second Title",
    content: <h1>Second content</h1>
  },
  {
    title: "Third Title",
    content: <h1>Third content</h1>
  }
];

const displayedTabs = TabsData.map(({ title, content }, index) => (
  <Tab title={title} key={index}>
    <h1>{content}</h1>
  </Tab>
));

const myTabs = () => <Tabs>{displayedTabs}</Tabs>;
```

This reduces errors when having tens or hundreds of tabs cause we're only changing the unique values. It also becomes a lot easier to read.

## 6 - Remove unnecessary files, lines and packages

### Imports

If you're not using an import, comment out or remove it from your file. When you run npm start, clear any compiler warnings for example:

```node
Compiled with warnings.

[eslint]
src/App.js
  Line 1:8:  'logo' is defined but never used  no-unused-vars

Search for the keywords to learn more about each warning.
To ignore, add // eslint-disable-next-line to the line before.

WARNING in [eslint]
src/App.js
  Line 1:8:  'logo' is defined but never used  no-unused-vars

webpack compiled with 1 warning
```

When deploying, dead imports can become a nightmare, so remove or comment them out early.

```node
Compiled successfully!

You can now view my-app in the browser.

  Local:            http://localhost:3000
  On Your Network:  http://192.168.0.75:3000

Note that the development build is not optimized.
To create a production build, use npm run build.

webpack compiled successfully
```

### Packages

If you are not using a specific package, uninstall it:

```bash
npm uninstall package-name
```

This reduces the size of your project and which helps when collaborators clone/fork your project.

## 7 - Maintain a good folder structure

When your project begins to scale, it becomes harder to keep track of maintaining a good structure allow you and your colleagues to keep track of where everything is.

Here is my preferred folder structure:


![Folder image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7ugtcstzkye5tsbf7fo1.png)

### Folders

- **`components`** - This directory should store all your global reusable components such as tabs, tables and modals
- **`data`** - This directory should store static data (for example, your pages data)
- **`pages`** - This directory should store all the pages for your project
- **`services`** - This directory should store all of your data services such as api fetches
- **`styles`** - This directory should store all of your global stylesheets
- **`tests`** - This directory should store all of your tests

## Summary

I hope you've learned something from these tips, even if you take just one of these points on board, then you're already improving by 1%. Remember these are just recommendations, if you're coding as part of a team make sure you check what they consider as acceptable practices.

Happy coding!