Como alterar corretamente o estado com useState no React JS

Neste artigo você aprenderá a como alterar corretamente o estado com useState, um hook muito importante do React JS!

Pra alterar o estado com useState no React tu nunca mexe na variável direto, sempre chama a função set que veio no par do useState, tipo setCount(count + 1)

Se o novo valor depende do valor atual, usa a função atualizadora: setCount(n => n + 1)

Segundo a documentação oficial, a função set atualiza a variável de estado apenas para a próxima renderização, então ler a variável logo depois de chamar a função set devolve o valor antigo, o que ainda está na tela

O motivo é o agrupamento: o React junta as atualizações e só atualiza a tela depois que todos os manipuladores de evento terminam de rodar e chamarem suas funções set

Se tu precisa da tela atualizada antes, por exemplo pra acessar o DOM, existe o flushSync

alterar corretamente o estado com useState capa

Fala programador(a), beleza? Bora aprender mais sobre programação e React!

O React é uma biblioteca de JavaScript para criar interfaces de usuário, amplamente utilizado por sua simplicidade e flexibilidade.

Um dos principais conceitos em React é o estado, que permite que componentes mantenham e manipulem dados.

O Hook useState é uma das maneiras mais comuns de gerenciar o estado no React.

Entendendo o useState

No React, o estado é uma instância de dados que pode ser manipulada e renderizada no componente.

O Hook useState é uma função que permite que você adicione o estado ao componente funcional do React.

import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>Você clicou {count} vezes</p>
      <button onClick={() => setCount(count + 1)}>
        Clique aqui
      </button>
    </div>
  );
}

Neste exemplo, useState(0) é uma função que aceita o estado inicial como argumento (neste caso, 0) e retorna uma matriz com dois elementos: a primeira é a variável de estado atual (count) e a segunda é a função para atualizar o estado (setCount).

Atualizando o Estado Corretamente

Uma das coisas mais importantes a lembrar ao usar useState é nunca atualizar o estado diretamente.

Sempre use a função de atualização de estado (setCount no exemplo acima) fornecida por useState.

Isso ocorre porque o React depende do antigo estado para calcular o novo estado e renderizar a UI de acordo.

Estado Anterior

Em algumas situações, precisamos acessar o estado anterior para calcular o novo estado.

Nesse caso, podemos passar uma função para a função de atualização de estado.

Esta função recebe o estado anterior como argumento e retorna o novo estado.

import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>Você clicou {count} vezes</p>
      <button onClick={() => setCount(prevCount => prevCount + 1)}>
        Clique aqui
      </button>
    </div>
  );
}

Aqui, setCount recebe uma função que usa prevCount (o estado anterior de count) para calcular o novo estado.

Formação Vibe Coding
Formação Recomendada

Formação Vibe Coding

Do Prompt ao Produto: Crie Software Real com IA

  • 474 aulas
  • 20 projetos
  • 39h 27min

useState com Objetos e Arrays

Também podemos usar useState com objetos e arrays. No entanto, é importante lembrar que useState não faz a fusão de objetos ou arrays como this.setState faz em componentes de classe.

Em vez disso, ele substitui o estado anterior pelo novo estado.

import React, { useState } from 'react';

function Form() {
  const [form, setForm] = useState({ name: '', email: '' });

  const handleChange = e => {
    setForm(prevForm => ({
      ...prevForm,
      [e.target.name]: e.target.value,
    }));
  };

  return (
    <div>
      <input name="name" value={form.name} onChange={handleChange} />
      <input name="email" value={form.email} onChange={handleChange} />
    </div>
  );
}

Neste exemplo, estamos usando a função handleChange para atualizar o estado do formulário. Estamos usando o operador de propagação (...) para copiar todo o estado anterior e, em seguida, atualizamos apenas a propriedade que queremos.

O useState é Assíncrono

Uma coisa crucial para entender sobre o useState é que a atualização do estado é assíncrona. Isto significa que as chamadas setState são enfileiradas e executadas após a renderização do componente ter sido concluída.

import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  const handleClick = () => {
    setCount(count + 1);
    console.log(count); // Isto irá logar o estado anterior, não o novo estado
  };

  return (
    <div>
      <p>Você clicou {count} vezes</p>
      <button onClick={handleClick}>
        Clique aqui
      </button>
    </div>
  );
}

Neste exemplo, você pode esperar que o console.log registre o novo estado após o setCount, mas ele ainda irá registrar o estado anterior.

Isso ocorre porque a atualização do estado não ocorre imediatamente, mas é agendada para acontecer depois que a renderização atual é concluída.

Usando Múltiplos Estados

Uma das vantagens do Hook useState é que você pode usá-lo várias vezes em um único componente. Isso permite que você separe diferentes valores de estado em diferentes variáveis de estado, em vez de ter um único objeto de estado grande.

import React, { useState } from 'react';

function Form() {
  const [name, setName] = useState('');
  const [email, setEmail] = useState('');

  // ...

  return (
    <div>
      <input value={name} onChange={e => setName(e.target.value)} />
      <input value={email} onChange={e => setEmail(e.target.value)} />
    </div>
  );
}

Separar o estado desta maneira pode tornar seu código mais limpo e mais fácil de gerenciar, especialmente à medida que seu componente cresce e se torna mais complexo.

Estado Derivado

Em alguns casos, você pode querer derivar o estado de outra propriedade ou variável. Isso é chamado de estado derivado.

No entanto, tenha cuidado ao fazer isso, pois pode levar a bugs se não for gerenciado corretamente.

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

function UserName({ id }) {
  const [user, setUser] = useState(null);

  useEffect(() => {
    fetchUser(id).then(userData => setUser(userData));
  }, [id]);

  // ...

  return <div>{user ? user.name : 'Carregando...'}</div>;
}

Neste exemplo, o estado user é derivado do prop id. Sempre que id muda, a função fetchUser é chamada para atualizar o estado user.

Isso é feito usando o Hook useEffect, que permite executar efeitos colaterais (como buscar dados) em componentes funcionais.

Quer aprender mais sobre programação? Conheça nosso canal no YouTube:

Conclusão

E chegamos ao fim do artigo sobre como alterar corretamente o estado com useState!

O Hook useState é uma ferramenta poderosa para gerenciar o estado em componentes funcionais do React.

Ele oferece flexibilidade para trabalhar com vários tipos de dados e fornece um método fácil de manipular e renderizar dados de estado em sua aplicação.

Lembre-se sempre de não alterar o estado diretamente e usar a função de atualização de estado para garantir que o React possa acompanhar as mudanças e renderizar a interface do usuário de acordo.

Está buscando em evoluir como Programador? Confira o nossos cursos de programação.

A resposta curta: como alterar o estado com useState

Nunca mexe na variável direto, sempre chama a função set que veio junto no useState

Se o novo valor depende do valor atual, passa uma função atualizadora: setCount(n => n + 1)

E se liga nisso, que é onde quase todo mundo tropeça: a documentação oficial diz que a função set atualiza a variável de estado apenas para a próxima renderização, então se tu ler a variável logo depois de chamar a função set, ainda vem o valor antigo que está na tela

Isso acontece porque o React agrupa as atualizações e só atualiza a tela depois que todos os manipuladores de evento terminam de rodar e chamarem suas funções set

Precisa da tela atualizada na hora, por exemplo pra acessar o DOM? aí existe o flushSync

E quando eu preciso atualizar o mesmo estado duas vezes no mesmo clique?

Esse é o caso clássico que quebra a cabeça de quem tá começando

Se tu chama a função set três vezes usando a variável direto, o resultado não soma três, porque as três chamadas leem o mesmo valor daquela renderização

A documentação orienta o caminho: usa uma função atualizadora

function Counter() {

return (
<button onClick={() => {
setNumber(n => n + 1)
setNumber(n => n + 1)
setNumber(n => n + 1)
}}>
+3
</button>
)
}

Cada n aí é o valor que a fila já processou até então, e não o retrato congelado da renderização

Regra de bolso pra guardar: leu o valor atual pra calcular o novo? função atualizadora, sem medo

Por que o console.log mostra o valor antigo? (snapshot e agrupamento)

Que snapshot? calma que eu te explico

Quando o React chama o teu componente, ele entrega um retrato do estado daquela renderização específica

A variável count daquele clique é uma foto, ela não muda no meio do caminho

Por isso a documentação é bem direta: se tu ler a variável logo depois de chamar a função set, ainda recebe o valor antigo que estava na tela

Soma a isso o agrupamento: o React junta as atualizações e só atualiza a tela depois que todos os manipuladores de evento terminam de rodar

E tem um detalhe de versão que muita gente não sabe: antes do React 18, esse agrupamento acontecia só dentro dos manipuladores de evento do React

A partir do React 18, lançado em 29 de março de 2022, atualizações dentro de promises, setTimeout e eventos nativos também são agrupadas automaticamente

Quer forçar o React a atualizar a tela antes, por exemplo pra acessar o DOM na sequência? existe o flushSync pra isso

Tome cuidado: flushSync é exceção, não rotina

Três comportamentos do useState que economizam horas de debug

1) O valor inicial pode ser calculado só uma vez

Se tu passar uma função pro useState, o React só chama essa função quando precisa do valor inicial, ou seja, na primeira renderização do componente

Repara na diferença: useState(criarListaPesada()) roda a função em TODA renderização, useState(() => criarListaPesada()) roda uma vez

2) Setar o mesmo valor pode não redesenhar nada

Se o novo valor for idêntico ao estado atual segundo uma comparação com Object.is, o React pula a re-renderização do componente e dos filhos

Ou seja, aquele teu console.log que não apareceu talvez não seja bug, é otimização

3) Em desenvolvimento, a tua função atualizadora roda duas vezes

Em Strict Mode o React chama a função atualizadora duas vezes, de propósito, pra te ajudar a achar impurezas acidentais

É comportamento só de desenvolvimento e não afeta a produção

Já me deixou maluco procurando bug que não existia, então fica esperto 🙂

Antes de criar mais um estado, pergunta: dá pra calcular?

A documentação oficial é bem clara nesse ponto: quando algo pode ser calculado a partir das props ou do estado que já existem, não coloca em estado, calcula durante a renderização

Nome completo a partir de nome e sobrenome? calcula

Lista filtrada a partir da lista e do texto da busca? calcula

Menos estado, menos sincronização, menos bug

E quando o dado vem mesmo de fora, cuidado com a corrida

Buscar dado dentro de um Effect tem uma armadilha: as respostas de rede podem chegar fora de ordem

A documentação mostra o padrão de uma variável ignore, iniciada como false e marcada como true na limpeza do Effect

useEffect(() => {
let ignore = false

fetchUser(id).then(userData => {
if (!ignore) setUser(userData)
})

return () => { ignore = true }

Sem isso, uma resposta antiga chega depois e sobrescreve a nova, aí tu vê na tela o usuário errado

E a recomendação oficial pra buscar dados, se tu usa um framework, é usar o mecanismo de busca de dados dele

Sem framework, a documentação sugere usar ou construir um cache no cliente, citando TanStack Query, useSWR e React Router 6.4+

Como resetar o estado de um componente

Essa é a pergunta que aparece na sequência: montei o formulário, salvei, e agora, como limpo tudo?

Dá pra chamar a função set de cada campo, claro

Mas tem um caminho mais direto: o React mantém o estado enquanto o mesmo componente é renderizado na mesma posição

Então passar uma key diferente pro componente faz o React recriar ele do zero, resetando o estado

<Formulario key={usuarioSelecionadoId} />

Trocou o id, o React monta um componente novo e o estado nasce limpo

Simples e massa demais quando tu tem uma lista e um formulário do lado

Onde o useState está no React de hoje

O React andou bastante desde que esse artigo saiu, então vale o recado

O React 19 saiu estável em 5 de dezembro de 2024, trazendo useActionState, useOptimistic, useFormStatus e a API use()

Depois veio o React 19.2, publicado em 1 de outubro de 2025, com o componente Activity, o Hook useEffectEvent, cacheSignal, Performance Tracks, Partial Pre-rendering e revelação de Suspense em lote no server rendering

Em 7 de outubro de 2025 o React Compiler 1.0 saiu estável, com memoização automática

E teve mudança de casa também: React e React Native saíram da tutela da Meta e foram pra React Foundation, hospedada pela Linux Foundation, com Amazon, Callstack, Expo, Meta, Microsoft, Software Mansion e Vercel entre os membros fundadores e Seth Webster como diretor executivo

O React 19 é a major atual e a última versão estável é a 19.2.8, de 21 de julho de 2026

Os comportamentos que tu viu aqui em cima (função set, função atualizadora, agrupamento, snapshot) estão na referência atual do useState no react.dev

O que eu vi gravando a aula de useState do curso

Na aula 10 do nosso curso de React eu montei um formulário de cadastro do zero, com campo de nome e campo de senha, e liguei os dois no useState

E eu insisto nessa ordem por um motivo: dá pra pegar o valor do input selecionando o elemento na mão, via JavaScript puro

Dá, mas fica chato e cresce mal

Com o useState tu atrela o onChange do input à função set e pronto, o valor fica atualizado a cada caractere que o usuário digita

Esse é o ponto que mais destrava a galera na gravação: entender que estado é simplesmente o dado que o componente tá lidando, e o hook só te dá um jeito simples de consultar e modificar esse dado

Outra coisa que eu esbarrei ali ao vivo, montando as labels: em React tu usa htmlFor no lugar do for do HTML, porque for já é instrução do JavaScript

Bobo? é

Mas custa uns minutos de cara feia pra quem tá vindo do HTML puro 😀

E vale dizer: o onChange é a convenção em formulário, mas nada te impede de mudar o state a partir de um clique, funciona igual

Quer ver isso rodando de ponta a ponta? a aula tá no nosso canal no YouTube, dentro do curso de React

Perguntas frequentes

Por que o console.log depois do setState mostra o valor antigo?

Porque quando o React chama o teu componente ele entrega um snapshot do estado daquela renderização específica

A documentação oficial diz na lata: a função set atualiza a variável apenas para a próxima renderização, e ler a variável logo depois ainda devolve o valor antigo que estava na tela

Não é bug, é o modelo do React

Como atualizar o mesmo estado duas ou três vezes no mesmo clique?

Com função atualizadora

A documentação orienta usar o formato setNumber(n => n + 1) quando tu precisa atualizar o mesmo estado mais de uma vez dentro de um único evento

Assim cada chamada trabalha em cima do resultado da anterior, e não em cima do retrato congelado da renderização

O useState atualiza na hora?

Não

O que acontece, segundo a documentação, é agrupamento: o React junta as atualizações de estado e só atualiza a tela depois que todos os manipuladores de evento terminam de rodar e chamarem suas funções set

Até o React 17 isso valia só dentro dos manipuladores de evento do React

A partir do React 18, lançado em 29 de março de 2022, atualizações dentro de promises, setTimeout e eventos nativos também são agrupadas automaticamente

Como forçar o React a atualizar a tela antes?

Usando flushSync

É o caminho que a documentação aponta quando tu precisa que o React atualize a tela mais cedo, por exemplo pra acessar o DOM logo em seguida

Mas usa com parcimônia, é exceção e não rotina

Por que meu componente não re-renderizou depois de chamar a função set?

Provavelmente tu setou o mesmo valor que já estava lá

Se o novo valor for idêntico ao estado atual segundo uma comparação com Object.is, o React pula a re-renderização do componente e dos filhos

Cuidado especial com objetos e arrays: mutar o objeto antigo e setar ele de novo passa nessa comparação, então cria um objeto novo

Por que minha função atualizadora roda duas vezes em desenvolvimento?

É o Strict Mode

O React chama a função atualizadora duas vezes de propósito, pra te ajudar a encontrar impurezas acidentais

É comportamento só de desenvolvimento e não afeta a produção, então não sai tentando ‘consertar’ isso

Como evitar que o valor inicial do useState seja recalculado toda hora?

Passa uma função pro useState em vez do valor pronto

Se tu passar uma função, o React só chama ela quando precisa do valor inicial, ou seja, na primeira renderização do componente

É o chamado inicializador preguiçoso: useState(() => calculoPesado())

Preciso guardar em estado um valor que dá pra calcular?

Não

A documentação oficial orienta que, quando algo pode ser calculado a partir das props ou do estado existentes, tu não coloca em estado, calcula durante a renderização

Menos estado pra sincronizar, menos bug pra caçar

Como resetar o estado de um componente?

Passando uma key diferente pro componente

O React mantém o estado enquanto o mesmo componente é renderizado na mesma posição, então trocar a key faz ele recriar o componente do zero, com o estado limpo

Qual a versão atual do React?

O React 19 é a major atual, e a última versão estável é a 19.2.8, publicada em 21 de julho de 2026

O React 19 saiu estável em 5 de dezembro de 2024 e trouxe useActionState, useOptimistic, useFormStatus e a API use()

Depois veio o 19.2, em 1 de outubro de 2025, e o React Compiler 1.0 estável, em 7 de outubro de 2025, com memoização automática

Leia também

Subscribe
Notify of
guest

0 Comentários
Oldest
Newest Most Voted

Formações

Formação SAAS com IA

Formação SAAS com IA

Tire usas ideias do papel criando softwares com IA, integre pagamentos e lance seu projeto!

  • 291 aulas
  • 18 projetos
  • 24h 17min

Blog | Mais populares