FS
Você realmente entende como o useState funciona?
Entenda por que o useState não atualiza o valor imediatamente e evite os erros mais comuns em componentes React.
Quando falamos em React, um dos primeiros conceitos que aprendemos é o useState. Ele é simples, fácil de usar e muito poderoso. Mas justamente por parecer simples, muita gente acaba usando de forma incorreta — e aí surgem aqueles bugs que são difíceis de entender e ainda mais difíceis de encontrar.
Neste artigo, vou te mostrar o que realmente acontece quando você chama setState, e como isso pode afetar o comportamento do seu componente se você não estiver atento.
O que acontece quando você usa setState?
Diferente de outras tecnologias reativas, o React não atualiza o valor na hora.
Quando você chama setState, o React agenda uma atualização. Ou seja, o novo valor só vai ser aplicado depois que o componente terminar de renderizar.
Exemplo clássico:
setCount(count + 1)
console.log(count) // Ainda mostra o valor antigo!Esse comportamento pode gerar diversos problemas se você tentar usar o valor atualizado logo após o setState.
Exemplo 1 – Incrementos consecutivos
setCount(count + 1)
setCount(count + 1)Aqui, você pode esperar que o valor aumente em 2, mas o que acontece na prática é que ambas as chamadas usam o mesmo valor anterior de count, então o estado só vai para +1.
Como resolver:
setCount(prev => prev + 1)
setCount(prev => prev + 1)Usar a função no setState garante que você está sempre trabalhando com o valor mais recente.
PS: prev vem de previous, ou seja, o valor anterior.
Exemplo 2 – Sobrescrevendo objetos
Outro erro comum ocorre ao atualizar estados que são objetos, como em um formulário:
setForm({ ...form, name: 'Ana' })
setForm({ ...form, email: 'ana@email.com' })O problema aqui é que a segunda chamada pode sobrescrever a primeira, porque ambas estão usando o mesmo valor antigo de form.
Solução:
setForm(prev => ({ ...prev, name: 'Ana' }))
setForm(prev => ({ ...prev, email: 'ana@email.com' }))Exemplo 3 – Estado em chamadas de API
Você atualiza o estado e logo em seguida quer usar o novo valor:
setUserId(42)
fetch(`/api/user/${userId}`) // ❌ userId ainda é o antigo! O valor de userId ainda não mudou. Por isso, o ideal aqui é usar a própria variável que você acabou de definir:
const newId = 42 setUserId(newId)
fetch(`/api/user/${newId}`)Exemplo 4 – Condições enganadoras
if (!isOpen) {
setIsOpen(true)
}Se o valor de isOpen ainda não foi atualizado, esse tipo de lógica pode quebrar. O mais seguro é trabalhar com a função que acessa o valor anterior:
setIsOpen(prev => !prev ? true : prev)Exemplo 5 – useEffect com dependência errada
useEffect(() => {
if (count === 5) alert('Chegou em 5!')
}, []) // ❌ Não será executado quando count mudar Aqui, você precisa garantir que o useEffect escute as mudanças do estado:
useEffect(() => {
if (count === 5) alert('Chegou em 5!')
}, [count])Conclusão
O useState parece simples, mas se você não entende como ele realmente funciona, é fácil cair em armadilhas. Lembre-se:
setStatenão muda o valor imediatamenteSempre que possível, use
setState(prev => ...)Evite depender do novo valor logo após atualizá-lo
Reaja a mudanças de estado com
useEffect
Essa compreensão muda completamente a forma como você escreve componentes e te ajuda a evitar bugs difíceis de rastrear.
Post criado/atualizado em: 24/04/2025
Autor: Felipe Santiago
Trabalho com desenvolvimento web Frontend desde 2023 com foco em React e Typescript. TailwindCSS foi uma reviravolta em meus projetos, não consigo mais ficar sem ele. Evoluindo para aplicações FullStack, foquei muito para criação de APIs com Node e Fastify/Express e manutenção de banco de dados como PostgreSQL.