Dependency Inversion Principle in React
Tags: react, typescript, javascript, learning
Published: 2023-10-14 14:54:01

## D (Dependency Inversion Principle)

> _High-level modules should not depend on low-level modules, but rather both should depend on abstractions_

![UNO Reverse](https://i.gifer.com/Qh16.gif)

Dependency Inversion in React involves ensuring that high-level components don't directly depend on low-level components. Instead, both should rely on abstractions, like props or context, to foster flexibility and maintainability. This promotes modularity, simplifies testing, and allows for easier code maintenance.

Adhering to the Dependency Inversion Principle in React leads to a more scalable architecture with better separation of concerns. It simplifies unit testing by enabling easy mockup of low-level components, enhancing control and precision in testing high-level components.

![Solid](https://media.tenor.com/_pqZjEJYLcgAAAAM/pretty-solid.gif)

```typescript
const CreateBookForm = () => {
  const handleCreateBookForm = async (e: FormEvent<HTMLFormElement>) => {
    try {
      const formData = new FormData(e.currentTarget);
      await axios.post("https://myapi.com/books", formData);
    } catch (err) {
      console.error(err.message);
    }
  };

  return (
    <form onSubmit={handleCreateBookForm}>
      <input name="title" />
      <input name="author" />
      <input name="bookType" />
    </form>
  );
};
```

The component above shows a form for handling create book by rendering a form and send the submitted data to an api.

Let's imagine if there's another form to edit the book with 100% same ui and differs only from logic. The dependency to the logic of sending data to the API is what makes the form unreusable, so we have to make a component that doesn't depend on a low-level module.

```typescript
const BookForm = ({ onSubmit }) => {
  return (
    <form onSubmit={onSubmit}>
      <input name="title" />
      <input name="author" />
      <input name="bookType" />
    </form>
  );
};
```

We have removed the dependency from the form and we can pass the logic through props.

Now let's use the form!

```typescript
const CreateBookForm = () => {
  const handleCreateBook = async (e: FormEvent<HTMLFormElement>) => {
    try {
      const formData = new FormData(e.currentTarget);
      await axios.post("https://myapi.com/books", formData);
    } catch (err) {
      console.error(err.message);
    }
  };
  return <BookForm onSubmit={handleCreateBook} />;
};
```

```typescript
const EditBookForm = () => {
  const handleEditBook = async (e: FormEvent<HTMLFormElement>) => {
    try {
      // Another logic
    } catch (err) {
      console.error(err.message);
    }
  };
  return <BookForm onSubmit={handleEditBook} />;
};
```

See now that we have implemented Dependency Inversion Principle, we have a great separation of concerns by abstracting the dependency

## What's next?

This is the last part of our [Apply SOLID in React series](https://dev.to/mikhaelesa/series/24919). Now that you have a good understanding of SOLID, it's time for you to implement these principles and see how powerful and impactful your codes can be.

Dadah~ 👋