Cleaning Up Our JavaScript Code by Refactoring Them — Encapsulation
Tags: webdev, programming, javascript, codequality
Published: 2021-01-25 03:17:53

**Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62**

**Subscribe to my email list now at http://jauyeung.net/subscribe/**

JavaScript is an easy to learn programming language. It’s easy to write programs that run and does something. However, it’s hard to write a piece of clean JavaScript code.

In this article, we’ll look at ways to refactor our code by encapsulating our API calls in their own React component, and use factory functions to provide polymorphism in our JavaScript code.

### Encapsulate APIs in Our React Components

To decouple API calls from our components, we can call one API per component.

This way, if one API changes, it won’t break other components. It also keeps components simple because at most they use one API.

For instance, we can create components and use them as follows:

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

const Person = () => {
  const [person, setPerson] = useState({});
  const getData = async () => {
    const res = await fetch("https://api.agify.io?name=michael");
    const p = await res.json();
    setPerson(p);
  };
  useEffect(() => {
    getData();
  }, []);

  return <p>{person.name}</p>;
};

const Dog = () => {
  const [dog, setDog] = useState({});
  const getData = async () => {
    const res = await fetch("https://dog.ceo/api/breeds/image/random");
    const d = await res.json();
    setDog(d);
  };
  useEffect(() => {
    getData();
  }, []);

  return <img src={dog.message} alt="" />;
};

export default function App() {
  return (
    <div className="App">
      <Person />
      <Dog />
    </div>
  );
}
```

In the code above, we have 2 components, each of which calls a single. The `Person` component calls one and `Dog` calls another. They only render something simple.

Then in `App` , we use them both at the same level. This way, we can combine them into one place without creating one large component.

If we have to share data between these components, then we can use some state management solutions like Redux or Mobx to share data in a centralized place in a way that’s decoupled from the component.

### Replace Conditional with Polymorphism

Polymorphism is a provision of creating a single interface of entities to different types.

In JavaScript, there’re no interfaces, but we can still use this principle to let us create functions that returns objects of different class instances that have the same methods that we can call by calling one function instead of instantiating multiple classes ourselves and calling the methods ourselves.

For instance, we can create a factory function that instantiates multiple classes and return one by checking the arguments that we pass into the factory function.

Instead of writing:

```
const meow = (animal) => {
  //...
};
const bark = (animal) => {
  //...
};
if (animal === 'cat') {
  meow(animal);
}

if (animal === 'dog') {
  bark(animal);
}
```

We can instead create classes and instantiate them with a factory function as follows:

```
class Cat {
  speak() {}
}

class Dog {
  speak() {}
}

const Animal = (type) => {
  if (type === 'cat') {
    return new Cat();
  } else if (type === 'dog') {
    return new Dog();
  }
}

const cat = Animal('cat');
const dog = Animal('dog');
cat.speak();
dog.speak();
```

In the code above, we have 2 classes, `Cat` and `Dog` . They have the same `speak` method instead of the `meow` and `bark` functions.

Then we created an `Animal` class, which has the `type` parameter to let us specify the type of animal to instantiate. If the `type` is `'cat'` , then we return a new `Cat` instance. If the `type` is `'Dog'` , then we return a new `Dog` instance.

After that, we can use the same `Animal` function to create these 2 class instances and call the `speak` method on the returned object.

This way, we only have to depend on the `Animal` function rather than a bunch of different functions. So we don’t have to worry about anything other than `Animal` having breaking changes.

This is a commonly used principle to reduce coupling. We reduce the number of dependencies that we have to rely on to reduce coupling so that we have fewer chances of breaking our code when anything changes.

This makes our code more robust.

### Conclusion

To keep our React components simple, we should break them up so that they only do one thing. One way to do that is to only have each component call a maximum of one API.

Polymorphism is also a good way to reduce coupling. We can create a factory function that instantiates classes for us and have the class include the same method names so that they implement one interface and we don’t have to worry about the implementation of those classes.

Even though JavaScript has no interfaces, we can still make sure that classes have the same methods included.