<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: judsonkerller</title>
    <description>The latest articles on DEV Community by judsonkerller (@judsonkerller).</description>
    <link>https://dev.to/judsonkerller</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1211400%2Fdcf30fba-d7c8-4076-ba02-8ec9a84c3812.png</url>
      <title>DEV Community: judsonkerller</title>
      <link>https://dev.to/judsonkerller</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/judsonkerller"/>
    <language>en</language>
    <item>
      <title>Finite State Machines no React: Gerenciado Estados de Forma Elegante</title>
      <dc:creator>judsonkerller</dc:creator>
      <pubDate>Mon, 07 Apr 2025 21:07:27 +0000</pubDate>
      <link>https://dev.to/judsonkerller/finite-state-machines-no-react-gerenciado-estados-de-forma-elegante-m7b</link>
      <guid>https://dev.to/judsonkerller/finite-state-machines-no-react-gerenciado-estados-de-forma-elegante-m7b</guid>
      <description>&lt;p&gt;Gerenciar estados complexos no React pode rapidamente se tornar um desafio, especialmente quando lidamos com múltiplas transições e regras de fluxo. Uma abordagem poderosa para resolver esse problema é o uso de Finite State Machines (FSMs), que ajudam a estruturar estados e transições de maneira previsível e fácil de manter.&lt;/p&gt;

&lt;p&gt;Neste artigo, vamos explorar o conceito de FSMs, entender como elas podem melhorar nosso código e criar uma implementação prática sem o uso de bibliotecas externas.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;O que são Finite State Machines?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;São modelos matemáticos que definem um sistema baseado em estados finitos e suas transições. De forma simples, um componente pode estar em um único estado por vez e só pode mudar para um novo estado através de uma transição definida.&lt;/p&gt;

&lt;p&gt;Vamos usar uma situação em que temos uma interface que nela contém um componente de card que faz uma requisição para uma api que retorna os dados para serem exibidos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Estado 1: &lt;code&gt;erro&lt;/code&gt; (em casos que a api falha)&lt;/li&gt;
&lt;li&gt;Estado 2: &lt;code&gt;carregando&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Estado 3: &lt;code&gt;sucesso&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As transições entre os estados estão bem definidas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Se a requisição falhar, mudamos para &lt;code&gt;erro&lt;/code&gt; e podemos exibir uma mensagem de erro.&lt;/li&gt;
&lt;li&gt;Em caso de não falha, mudamos o estado para &lt;code&gt;carregando&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Se a requisição for bem-sucedida, mudamos para &lt;code&gt;sucesso&lt;/code&gt; e exibimos os dados.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Essa previsibilidade evita estados inesperados e facilita a manutenção do código.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Visualizando a FSM&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A imagem abaixo ilustra a máquina de estados finitos para esse cenário de busca:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5wlmbn2rd5dj45fuf7s6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5wlmbn2rd5dj45fuf7s6.png" alt="Image description" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Quais os benefícios de usarmos as FSMs no React?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;✅ Previsibilidade: Cada estado e transição são claramente definidos, reduzindo erros inesperados.&lt;br&gt;
✅ Facilidade de Depuração: Como todas as mudanças de estados são controladas, fica mais fácil de entender e depurar bugs.&lt;br&gt;
✅ Melhoria na Manutenção: Componentes tornam-se mais organizados, facilitando a leitura e evolução do código.&lt;br&gt;
✅ Melhor Controle de Fluxo: Evita estados inválidos, garantindo que o componente sempre esteja em uma condição válida.&lt;/p&gt;


&lt;h2&gt;
  
  
  &lt;strong&gt;Implementando uma FSM no React com useReducer!&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Aqui está um componente aonde utilizamos o useReducer para controlar os estados:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useEffect, useReducer } from "react";
import { reducer } from "../utils/reducer";
import { ACTIONS, STATES } from "../utils/constants";
import './DataCard.css';

const DataCard = () =&amp;gt; {
  const [state, dispatch] = useReducer(reducer, STATES.LOADING);

  useEffect(() =&amp;gt; {
    if (state === STATES.LOADING) {
      const timeout = setTimeout(() =&amp;gt; {
        fetch('https://jsonplaceholder.typicode.com/posts/1')
        .then((response) =&amp;gt; {
          if (!response.ok) throw new Error('Failed to fetch');
          return response.json();
        })
        .then(() =&amp;gt; dispatch(ACTIONS.SUCCESS))
        .catch(() =&amp;gt; dispatch(ACTIONS.ERROR));
      }, 2000);

      return () =&amp;gt; clearTimeout(timeout);
    }
  }, [state]);

  return (
    &amp;lt;div className='card'&amp;gt;
      {state === STATES.LOADING &amp;amp;&amp;amp; &amp;lt;div className="loading"&amp;gt;Loading card...&amp;lt;/div&amp;gt;}
      {state === STATES.SUCCESS &amp;amp;&amp;amp; (
        &amp;lt;div className='success'&amp;gt;
          &amp;lt;h2&amp;gt;FSMs&amp;lt;/h2&amp;gt;
          &amp;lt;p&amp;gt;Simulated API content (request successful)&amp;lt;/p&amp;gt;
          &amp;lt;button onClick={() =&amp;gt; dispatch(ACTIONS.LOAD)}&amp;gt;Reload&amp;lt;/button&amp;gt;
        &amp;lt;/div&amp;gt;
      )}
      {state === STATES.ERROR &amp;amp;&amp;amp; (
        &amp;lt;div className='error'&amp;gt;
          &amp;lt;p&amp;gt;Error loading data!&amp;lt;/p&amp;gt;
          &amp;lt;button onClick={() =&amp;gt; dispatch(ACTIONS.LOAD)}&amp;gt;Try again&amp;lt;/button&amp;gt;
        &amp;lt;/div&amp;gt;
      )}
    &amp;lt;/div&amp;gt;
  );
};

export { DataCard };

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;Teste na Prática!&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Quer ver o conceito de FSMs funcionando na prática? Criei um repositório para que você possa clonar e testar por conta própria. Acesse o repositório no GitHub e siga as instruções:&lt;br&gt;
🔗 &lt;a href="https://github.com/judsonkerller/fsm-react" rel="noopener noreferrer"&gt;Repositório FSM React&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/judsonkerller/fsm-react.git
&lt;span class="nb"&gt;cd &lt;/span&gt;fsm-react
npm &lt;span class="nb"&gt;install
&lt;/span&gt;npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Experimente fazer alterações no código e observe como os estados e transições são gerenciados!&lt;/p&gt;




&lt;h3&gt;
  
  
  Conclusão
&lt;/h3&gt;

&lt;p&gt;Finite State Machines são uma ferramenta poderosa para gerenciar estados de forma estruturada no React. Com bibliotecas como o &lt;strong&gt;XState&lt;/strong&gt; ou implementações manuais usando &lt;code&gt;useReducer&lt;/code&gt;, podemos tornar nosso código mais previsível, modular e fácil de testar.&lt;/p&gt;

&lt;p&gt;E aí, já usou FSMs em seus projetos? Se sim, como foi a experiência? Se não, pretende experimentar? Me conta nos comentários! 🚀&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>frontend</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Criação de Hooks Personalizados no React: Reutilização de Lógica de Forma Inteligente</title>
      <dc:creator>judsonkerller</dc:creator>
      <pubDate>Mon, 03 Feb 2025 00:37:15 +0000</pubDate>
      <link>https://dev.to/judsonkerller/criacao-de-hooks-personalizados-no-react-reutilizacao-de-logica-de-forma-inteligente-3cap</link>
      <guid>https://dev.to/judsonkerller/criacao-de-hooks-personalizados-no-react-reutilizacao-de-logica-de-forma-inteligente-3cap</guid>
      <description>&lt;p&gt;Se você já trabalhou em projetos React, provavelmente percebeu que algumas lógicas são repetidas em diferentes componentes. Isso pode tornar o código menos manutenível e mais propenso a erros.&lt;br&gt;
Imagine que você precise implementar um comportamento de debounce em múltiplos componentes para otimizar chamadas a uma API. Em vez de copiar e colar o mesmo código, você pode criar um custom hook (hook personalizado), centralizando a lógica e reaproveitando-a de forma elegante.&lt;/p&gt;

&lt;p&gt;No nosso papo de hoje, vamos explorar o conceito de custom hooks, como criá-los, boas práticas, como vivem, o que comem (essas duas últimas foram zueira pessoal rsrs), e um exemplo real de um hook de debounce. Então pegue seu cafézin e rumbora aprender mais sobre hooks.&lt;/p&gt;
&lt;h2&gt;
  
  
  O que são Hooks Personalizados?
&lt;/h2&gt;

&lt;p&gt;São funções JavaScript que utilizam os hooks padrões do React para encapsular e reutilizar lógica compartilhada entre componentes. Eles seguem a convenção de nome começando com "use" ("useDebounce").&lt;br&gt;
Eles permitem separar preocupações, melhorar a legibilidade e reduzir redundância no seu código.&lt;/p&gt;
&lt;h2&gt;
  
  
  Criando um Hook Personalizado: useDebounce
&lt;/h2&gt;

&lt;p&gt;Vamos criar um hook que atrasa a execução de uma função até que o usuário pare de digitar por um tempo determinado.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useState, useEffect } from 'react';

function useDebounce&amp;lt;T&amp;gt;(value: T, delay: number): T {
  const [debounceValue, setDebounceValue] = useState(value);

  useEffect(() =&amp;gt; {
    const handler = setTimeout(() =&amp;gt; {
     setDebounceValue(value);
    }, delay)

    return () =&amp;gt; {
      clearTimeout(handler);
    };
  }, [value, delay]);

  return debounceValue;
}

export { useDebounce };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora, podemos usar o hook personalizado que acabamos de criar, dentro de um componente para otimizar chamadas a uma API de pesquisas, sem que seja feito uma chamada a cada vez que o usuário digitar algo no input, por exemplo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useState } from "react";
import useDebounce from "./useDebounce";

function SearchInput() {
  const [searchTerm, setSearchTerm] = useState("");
  const debouncedSearchTerm = useDebounce(searchTerm, 500);

  useEffect(() =&amp;gt; {
    if (debouncedSearchTerm) {
      console.log("Buscando por:", debouncedSearchTerm);
      // Aqui você pode chamar uma API, por exemplo
    }
  }, [debouncedSearchTerm]);

  return (
    &amp;lt;input
      type="text"
      placeholder="Digite sua pesquisa..."
      value={searchTerm}
      onChange={(e) =&amp;gt; setSearchTerm(e.target.value)}
    /&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Boas práticas ao criar Hooks Personalizados
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Nomeie corretamente&lt;/strong&gt;: Comece sempre com o &lt;code&gt;use&lt;/code&gt; para garantir que o React reconheça como um hook.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Evite dependências desnecessárias&lt;/strong&gt;: Utilize apenas os estados e useEffect's se realmente forem necessários para evitar re-renderizações inesperadas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mantenha genérico e reutilizável&lt;/strong&gt;: Evite hardcodes dentro do hook. Prefira passar valores via props.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Escreva testes para seus hooks&lt;/strong&gt;: Utilize Jest e React Testing Library para validar o comportamento esperado.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Extra: Adote a prática de por testes em todo código que você fizer, pois assim você garante o funcionamento para o qual o mesmo foi criado.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Pra finalizarmos, os hooks personalizados são uma forma poderosa de organizar e reutilizar lógica dentro do React. No exemplo que vimos hoje, transformamos uma lógica repetitiva em um hook que podemos utilizar em diversos componentes que aguardam esse comportamento, e ficou bem estruturado, falaê!? rsrs&lt;/p&gt;

&lt;p&gt;Se você quiser se aprofundar, tente criar outros hooks personalizados, observe no seu dia a dia alguma lógica que se repete no projeto que você esteja atualmente e tente implementar - se possível, claro, dependendo do time e contexto que você esteja inserido - garanto que isso só vai trazer benefícios para você e principalmente pro seu time.&lt;/p&gt;

&lt;p&gt;Curtiu o artigo? Curtiu o papo? Que outro hook personalizado você gostaria de ver? Deixe seu comentário!🚀&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>javascript</category>
      <category>react</category>
      <category>learning</category>
    </item>
  </channel>
</rss>
