Executando verificação de segurança...
6
Kadu
3 min de leitura ·

Você não precisa sempre criar um estado no React!! 🤯

Olá, sou o Kadu e hoje venho tentar passar um conhecimento sobre o state do React!

Hoje finalizei um projeto em grupo onde tinha uma página que precisava que um botão estivesse desabilitado, dependendo do Estado de um elemento da página.

    function App() {
      const [texto, setTexto] = useState('OK');
      const toggleTexto = (value) => setStatus(value)

      return (
        <>
          <h1>{texto}</h1>
          <div>
           <button type="button" onClick={() => toggleTexto('OK')}>OK</button>
           <button type="button" onClick={() => toggleTexto('Não OK')}>Não OK</button>
          </div>
          <button>Enviar</button>
        </>
      );
    }

Esse componente é um exemplo do que quero explicar, o desfio era simples o botão tinha que está desabilitado quanto o estado estivesse 'OK', e desabilitado quando não estivesse 'OK'.
Foi aí que minha parceira de grupo já estava indo fazer um novo State para armazenar valor de quando o botão pode ficar habilitado, deixando o código mais ou menos assim.

    function App() {
      const [texto, SetTexto] = useState("OK");
      const toggleTexto = (value) => SetTexto(value);

      const [buttonDisabled, setButtonDisabled] = useState(true);

      useEffect(() => {
        texto === "OK" ? setButtonDisabled(false) : setButtonDisabled(true);
      }, [texto]);

      return (
        <>
          <h1>{texto}</h1>
          <div>
            <button type="button" onClick={() => toggleTexto("OK")}>
              OK
            </button>
            <button type="button" onClick={() => toggleTexto("Não OK")}>
              Não OK
            </button>
          </div>
          <button disabled={buttonDisabled}>Enviar</button>
        </>
      );
    }

Se você comentou que o problema era as renderizações, você está certo! Uma coisa que pode deixar sua aplicação lenta são várias renderizações feitas desnecessariamente e se você conhece bem o react, sabe que toda alteração de 'ESTADO!' causa uma nova renderização.

Então se contarmos teremos duas atualizações no componente, a 1.º quando clicar no botão 'OK' ou 'Não OK' e o estado do texto muda e isso faz com que a função useEffect seja chamada e atualizando novamente o componente quando mudarmos o estado do botão de enviar, isso em uma aplicação grande pode ser um problema, mas no nosso caso não era, mas quiz passar esse conhecimento parar o meu grupo!

Então se for contar teremos duas atualização no componente, a 1° quando clicar no botão e o status do texto muda e isso faz como a função o useEffect ceja chamada e atualizando novamente o compomenete quando mudarmos o status do botão ativo, isso em uma aplicação grande pode ser um problema.

E como corrigimos isso? 😕

Componentes funcionais trouxeram o poder de tornar as coisas mais simples e uma delas é criar variáveis dentro da função do componente e é com isso que resolveremos o problema, ficando assim o componente ⬇️.

    export default function App() {
      const [texto, SetTexto] = useState("OK");
      const toggleTexto = (value) => SetTexto(value);

      const buttonDisabled = texto === "Não OK";

      return (
        <>
          <h1>{texto}</h1>
          <div>
            <button type="button" onClick={() => toggleTexto("OK")}>
              OK
            </button>
            <button type="button" onClick={() => toggleTexto("Não OK")}>
              Não OK
            </button>
          </div>
          <button disabled={buttonDisabled}>Enviar</button>
        </>
      );
    }

Percebam que não mudou muita coisa, somente retiramos o useEffect e em vez de um estado craimos uma com constante para armazenar o valor se o botão está ativo ou não. e sempre que alteramos o estado do texto a constante buttonDisabled vai ser recalculada e desabilitando o botão corratemente sem gerar uma nova renderização do componente. 😄

FIM


Espero que tenham entendido e qualquer dúvida deixe seu comentário. Estou sempre aberto para novos aprendizados, então se tiver outra opinião ou algo a acrescentar só comentar também.

Eu não sei se essa abordagem tem um nome e nem de onde eu tirei isso mas acho que algo muito valido a se fazer e envitando de usar um Estado desnecessairiamente.

Contatos:

GitHub: https://github.com/kaduh15
LinkedIn: https://www.linkedin.com/in/kaduh15/

Carregando publicação patrocinada...
2

Eae Kadu, beleza? Parabéns, é isso ai mesmo. Acho que se a pessoa não consegue identificar/entender este erro, é porque ela não entendeu ainda o funcionamento do React.

Vou deixar um vídeo aqui que o pessoal da Rocketseat fez, falando justamente deste ponto. Abraço: https://www.youtube.com/watch?v=kCpca2z2cls

Uma coisa que eu percebi é que se você está utilizando o useEffect para atualizar o valor de um estado com base no valor de outro estado, provavelmente você está cometendo esse erro de ter várias renderizações sem necessidade.

1
2

como o Matheus falou, quando aprendemos os principais hooks ( useState / useEffect ) achamos que é a solução pra tudo pq é bem mais simples, mas algumas vezes pode ser desnecessário por não saber o real motivo de usá-los.

1

É normal quando você aprende os hooks useState e useEffect querer sair usando por todo o código, sem entender realmente qual o objetivo deles. Como eu disse, se você entende o fluxo de renderização do React, em quais momentos ele vai recalcular e renderizar o componente novamente e atualizar os dados, dificilmente você vai cair nesses problemas, ou se cair, vai identificar rapidamente.

2

Ótima dica! Kent C. Dodds chama essa abordagem de "estado derivado" e recomenda que sempre se use estado derivado quando possível em vez de encher um componente de setStates e useEffects desnecessários.

Link do artigo dele sobre o assunto: Don't Sync State. Derive It!

Claro que, pelo menos pra mim que sou um reles júnior, esse tipo de coisa exige um pouco de prática. Ainda sou meio viciado em useEffect, mesmo quando ele cria uma mega complexidade difícil de lidar. Mas eu espero que em breve eu consiga superar isso.

1

eu também sou um mero Júnior, mas é assim mesmo tem coisa mais simples que demoro pra entender e colocar em prática.

Mas o que me levou a entenfer esse assunto é me perguntar quando quero ( preciso) que alguma parte do meu comportamento seja atualizado?
depois de responder essa pergunta eu sei se devo usar um useState/useEffect ou não.

mas com o tempo a tendência é melhorar 😄

1

dica maneira demais cara, confesso que desde que comecei a estudar React, nunca tinha parado para pensar nessa criação de renderizações desnecessárias. Com certeza depois desse post terei outra forma de olhar para o código.

1

Inicialmente pensei na solução:

<button disabled={texto === "OK"}>Enviar</button>

Não sei se há alguma diferença de performance ou execução.

1

não muda nada em performance, seria mais uma questão de organização de código e agora vejo que poderia tirar aquela ternário da variável.

muito obrigado pela sua visão!😄