SOLID in React- OCP – Open-Closed Principle

solid-in-react-ocp-–-open-closed-principle

Embora tenha sido concebido para a programaรงรฃo orientada a objetos, os princรญpios do SOLID podem ser aplicados em outros contextos como em componentes React.

  • Este post aborda o “O” do S[O]LID
  • Criado com Next 13 + React 18
  • Codepen no final do post
  • A aplicaรงรฃo inicia com o SRP aplicado

OCP – Open-Closed Principle

O Open Closed Principle (Princรญpio Aberto/Fechado) preconiza que uma entidade de software (classe, mรณdulo, funรงรฃo, etc.) deve estar aberta para extensรฃo (ou seja, deve ser possรญvel adicionar novos comportamentos ou funcionalidades sem modificar o cรณdigo existente) e fechada para modificaรงรฃo (ou seja, o cรณdigo existente nรฃo deve ser modificado para adicionar novos comportamentos ou funcionalidades).

Suponha que temos uma lista de usuรกrios que podem ser exibidos em um componente em nossa aplicaรงรฃo. Inicialmente, exibimos apenas o primeiro nome e o gรชnero do usuรกrio com um รญcone ao lado do nome, sendo azul para usuรกrios masculinos e vermelho para usuรกrios femininos.

No contexto de componentes, o princรญpio Aberto/Fechado nรฃo estรก sendo aplicado ao cรณdigo fornecido. Isso ocorre porque o componente ListUsersBefore precisa ser alterado se houver a necessidade de adicionar um filtro de usuรกrios, componentes ou propriedades dentro dele. Isso viola o princรญpio, pois o componente deve estar aberto para extensรฃo e fechado para modificaรงรฃo.

/**
 * ocp
 *  ListUsersBefore
 *    hooks
 *      useUsers
 *        index.ts
 *    index.tsx
 *    styles.ts
 */

Componente principal:

//ocp/ListUsersBefore/index.tsx

import { FaFemale, FaMale } from 'react-icons/fa';
import { useUsers } from './hooks/useUsers';
import { S } from './styles';

export const ListUsersBefore = () => {
  const { data, isLoading } = useUsers();

  return (
    <>
      {isLoading && <div>Loading...div>}

      {data.map((user) => (
        <S.Div 
          gender={user.gender} 
          key={user.email}
        >
          {(user.gender === 'female' && <FaFemale />) || <FaMale />}
          <span>{user.name.first}span>
        S.Div>
      ))}
    
  );
};

Estilos do componente principal:

//ocp/ListUsersBefore/styles.ts

type StyledUserProps = {
  gender: 'male' | 'female';
};

export const S = {
  Div: styled.div<StyledUserProps>`
    color: ${(props) => (props.gender === 'male' ? 'blue' : 'red')};
    border: 1px solid;
    max-width: 200px;
    padding: 0.2rem;
    margin-bottom: 0.2rem;
    border-radius: 4px;
  `
};

Hook que fornece os dados:

//ocp/ListUsersBefore/hooks/useUsers/index.tsx

import axios from 'axios';
import { useEffect, useState } from 'react';

type User = {
  name: {
    first: string;
  };
  email: string;
  gender: 'male' | 'female';
};

type useUsersReponse = {
  data: User[];
  isLoading: true | false;
  error: null | string;
};

export const useUsers = (): useUsersReponse => {
  const [data, setData] = useState<User[]>([]);
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState<null | string>(null);

  const handleFetch = async () => {
    setIsLoading(true);

    try {
      const url = `https://randomuser.me/api/?results=5`;
      const res = await axios.get(url);

      setError(null);
      setData(res.data.results);
    } catch (err) {
      setError('Error get Users!');
    }

    setIsLoading(false);
  };

  useEffect(() => {
    handleFetch();
  }, []);

  return {
    data,
    isLoading,
    error
  };
};

Total
0
Shares
Leave a Reply

Your email address will not be published. Required fields are marked *

Previous Post
5-reasons-why-command-line-interface-(cli)-is-more-efficient-than-gui

5 Reasons Why Command Line Interface (CLI) is More Efficient Than GUI

Next Post
how-to-convert-string-to-integer-in-java

How to convert String to Integer in java

Related Posts