Dependency Injection

Dependency Injection

Let's learn how to apply this important concept in React.js!

Introduction

If you've ever faced the challenge of managing complex dependencies in your code, you've probably heard of dependency injection.

With dependency injection, it's possible to remove complexity from components and make them more independent and reusable. In this video, we'll cover everything you need to know about dependency injection and how to apply it in your code to create more robust and scalable applications.

With dependency injection, it's possible to remove complexity from components and make them more independent and reusable. In this video, we'll cover everything you need to know about dependency injection and how to apply it in your code to create more robust and scalable applications.

What is DI?

DI, or Dependency Injection, is a design pattern where a function receives the data it depends on, for example, through parameters.

By doing so, the function doesn't need to have everything it depends on within itself, which would make it bloated and lead to several issues, such as:

  • Difficulty in testing
  • Increased complexity of maintenance
  • Decreased reusability

This concept applies not only to functions but also to objects, which can receive other objects as dependencies.

What are the advantages? There are several advantages, such as:

  1. Separation of responsibility; Reduced coupling
  2. This way, each function doesn't need to know the implementation details of another function.
  3. It just needs to know the interface (connection).
  4. For example: You don't need to understand how a microwave works internally to use it, you just need to know the interface (the control panel/buttons).

And how to apply it in React.js?

This is the best part, React.js already has DI by default. Are you surprised?!

Think about React.js props (properties). Isn't the main purpose of props to allow a component to receive parameters from its parent component (passing information from parent to child)? Exactly!

Practical Example

Let's create a Header component, first in the "incorrect" way, and then we'll apply DI.

import * as S from './styles';
 
const Header = () => {
  const name = window.localStorage.getItem('name') ?? 'unknown';
  const email = window.localStorage.getItem('email') ?? 'unknown@email.com';
 
  return (
    <S.Container>
      <S.Content>
        <S.LogoContainer>
          <img src="logo.svg" alt="Logo" />
        </S.LogoContainer>
 
        <S.ProfileContainer>
          <S.ProfileName>{name}</S.ProfileName>
          <S.ProfileEmail>{email}</S.ProfileEmail>
        </S.ProfileContainer>
      </S.Content>
    </S.Container>
  );
};

Notice how many responsibilities the Header component has:

  • Retrieving the name and email from localStorage.

  • Handling whether the correct data exists in localStorage.

  • Styling the logo.

Does the Header component need to have all these responsibilities? No!

Let's improve this.

Correct approach

Creating the Logo component:

const Logo = () => {
  return (
    <S.LogoContainer>
      <img src="logo.svg" alt="Logo" />
    </S.LogoContainer>
  );
};

Creating the Profile component:

const Profile = ({ name, email }: { name: string; email: string }) => {
  return (
    <S.ProfileContainer>
      <S.ProfileName>{name}</S.ProfileName>
      <S.ProfileEmail>{email}</S.ProfileEmail>
    </S.ProfileContainer>
  );
};

Creating a function to retrieve data from localStorage:

const getItemLocalStorage = (key: string) => {
  return window.localStorage.getItem(key);
};

Now let's put the "pieces" together in our Header component:

const Header = () => {
  const name = getItemLocalStorage('name') ?? 'unknown';
  const email = getItemLocalStorage('email') ?? 'unknown@email.com';
 
  return (
    <S.Container>
      <S.Content>
        <Logo />
 
        <Profile name={name} email={email} />
      </S.Content>
    </S.Container>
  );
};

Conclusion

In this post, we have understood what Dependency Injection is, its advantages, and how to apply it in React.js using functional components.

I hope you have enjoyed the content. Thank you very much for reading this far, and see you next time!