React: Noções básicas sobre estado: useState

Última atualização: 2026-10-26

O State é a memória de um componente. Se os Props são parâmetros fornecidos por terceiros (somente leitura), então o State é o seu próprio caderninho (editável). O useState é o “chip de memória” que o React instala em um componente.


1. O que você vai aprender



2. Reflexões suscitadas por um contador

(1) Problema: as variáveis regulares não acionam atualizações na interface do usuário

Bob quer criar um contador simples: quando você clica no botão, o número aumenta em 1.

▶ Experimente

Bob descobriu um problema: As variáveis comuns não avisam o React para atualizar a interface do usuário. Toda vez que o componente é renderizado novamente, count é redefinido para 0.

(2) Uma solução utilizando useState

▶ Experimente

Valor de retorno: useState retorna um array [current value, setter function]. Após chamar setCount, o React re-renderiza automaticamente o componente para exibir os valores mais recentes.



3. Conceitos fundamentais do useState

(1) Análise da tarefa

JSX
import { useState } from 'react'

// useState(initialValue) Back [value, setValue]
const [count, setCount] = useState(0)
//      ^      ^          ^
//      |      |          └─ Initial value(Applies only to the first render)
//      |      └─ Update Function(Triggers a re-render after being called)
//      └─ Current status value(Get the latest value on every render)
▶ Experimente
Seção Descrição
count Valor atual do estado; o valor mais recente é recuperado a cada renderização
setCount Função de atualização: ao chamá-la → o React refaz a renderização do componente
useState(0) Valor inicial (usado durante a primeira renderização; ignorado nas renderizações subsequentes)

(2) Mecanismo de atualização

▶ Experimente

Conceito-chave: setCount(count + 1) significa “solicitar ao React que atualize count na próxima renderização”, e não “alterar count imediatamente”. Isso é chamado de atualização assíncrona.

(3) Atualizações funcionais

Se o novo estado depender do antigo, você deve usar atualizações funcionais:

▶ Experimente
Método Sintaxe Características
Atualizar diretamente setCount(count + 1) Simples, mas os dados são perdidos em chamadas consecutivas
Atualização funcional setCount(prev => prev + 1) Preciso; funciona corretamente mesmo com chamadas consecutivas


4. Atualização de matrizes e objetos (imutabilidade)

O React exige que o estado não seja modificado diretamente. Nunca use state.push() ou state.name = 'xxx'; em vez disso, crie um novo array ou objeto para substituir o valor antigo.

(1) Objetos a serem atualizados

▶ Experimente

(2) Atualizar o array

▶ Experimente

Saída:

TEXT
Estado: arr

▶ Exemplo: Tabela de referência rápida para operações com matrizes

JSX
// ============================================
// Example:React Array Operations in C 6 Common Scenarios
// ============================================

const [arr, setArr] = useState([1, 2, 3])

// 1. Append to the end
setArr([...arr, 4])           // [1, 2, 3, 4]

// 2. Add to the beginning
setArr([0, ...arr])           // [0, 1, 2, 3]

// 3. Insert in the middle
const insertAt = 1
setArr([...arr.slice(0, insertAt), 99, ...arr.slice(insertAt)])
                              // [1, 99, 2, 3]

// 4. Delete Element(filter)
setArr(arr.filter(n => n !== 2))  // [1, 3]

// 5. Update Element(map)
setArr(arr.map(n => n === 2 ? 22 : n))  // [1, 22, 3]

// 6. Sort(Copy first, then sort)
setArr([...arr].sort((a, b) => b - a))  // [3, 2, 1]
▶ Experimente

Saída:

TEXT
Operações de estado de array: push → adiciona item, filter → remove item, map → atualiza item. Cada operação retorna uma nova referência de array para que o React renderize novamente


5. Várias variáveis de estado

Um componente pode ter várias variáveis de estado. Recomenda-se dividi-las por lógica, em vez de agrupá-las em um único objeto grande:

JSX
function RegistrationForm() {
  // ✅ Recommendations:Logical Breakdown
  const [name, setName] = useState('')
  const [email, setEmail] = useState('')
  const [password, setPassword] = useState('')
  const [isSubmitting, setIsSubmitting] = useState(false)
  const [errors, setErrors] = useState({})

  // ❌ Not recommended:All states are stored in a single object
  const [form, setForm] = useState({
    name: '', email: '', password: '',
    isSubmitting: false, errors: {}
  })
  // Expand the entire object when updating,Fields that are easy to overlook
}
▶ Experimente
Estratégia Vantagens Desvantagens
Dividir em vários useStates Atualizações precisas, seguras em termos de tipos e fáceis de ler Muitas variáveis quando há muito estado
Combinado em um único useState Prático para atualizar vários campos de uma só vez A sintaxe de atualização é complicada e é fácil esquecer de expandi-la

Recomendação: Use várias instâncias de useState para estados independentes (como campos de entrada, indicadores de carregamento e mensagens de erro); campos logicamente relacionados (como todos os campos de um perfil de usuário) podem ser combinados em um único objeto.



6. Elevando o Estado

Quando vários componentes precisam compartilhar o mesmo estado, transfira o estado para o componente pai comum mais próximo.

100%
graph TB
    subgraph "Before the status upgrade(Data is not shared)"
        A[Parent Component App] --- B[Child component A<br/>Have their own count]
        A --- C[Child component B<br/>Have their own count]
    end
    
    subgraph "After the status upgrade(Data Sharing)"
        D[Parent Component App<br/>**count Here**] --- E[Child component A<br/>Read count, Call setCount]
        D --- F[Child component B<br/>Read count, Call setCount]
    end

Saída:

TEXT
Estado: arr (setter: setArr)

▶ Exemplo: Aplicação prática da promoção de estado

▶ Experimente

Saída:

TEXT
Ao digitar 100 em Celsius → o Fahrenheit exibe 212.0 automaticamente. Exibe "100°C = 212.0°F". Os dois campos permanecem sincronizados.


7. Exemplo completo: Contador do carrinho de compras

▶ Expandir exemplo executável (96 linhas)
▶ Experimente

Saída:

TEXT
Subtítulo: "Temperature Converter". Exibe: "Celsius(°C):". Estado: temperature (setter: setTemperature)

Fluxo de interação:

  • Toque em +/− para ajustar a quantidade; o subtotal e o total são atualizados em tempo real
  • Clique em ✕ para excluir um item; exiba uma mensagem amigável quando o carrinho de compras estiver vazio
  • Digite o código promocional REACT2026 para economizar 20 yuan

▶ Exemplo 3: Atualizando o estado de um objeto — Editando informações do usuário

JSX
function UserEditor() {
  const [user, setUser] = useState({ name: 'Alice', email: 'alice@test.com', age: 28 })

  function updateField(field, value) {
    setUser(prev => ({ ...prev, [field]: value }))
  }

  return (
    <div style={{ maxWidth: 400, margin: '0 auto' }}>
      <h3>Edit Profile</h3>
      <input value={user.name} onChange={e => updateField('name', e.target.value)}
        placeholder="Name" style={{ width: '100%', padding: 8, marginBottom: 8, borderRadius: 4 }} />
      <input value={user.email} onChange={e => updateField('email', e.target.value)}
        placeholder="Email" style={{ width: '100%', padding: 8, marginBottom: 8, borderRadius: 4 }} />
      <input type="number" value={user.age} onChange={e => updateField('age', Number(e.target.value))}
        placeholder="Age" style={{ width: '100%', padding: 8, marginBottom: 8, borderRadius: 4 }} />
      <pre style={{ background: '#f5f5f5', padding: 12, borderRadius: 4, fontSize: 13 }}>
        {JSON.stringify(user, null, 2)}
      </pre>
    </div>
  )
}
▶ Experimente

Saída:

TEXT
Estado: address. Campos de entrada: Street, City, ZIP

Saída:

TEXT
Exibe: "Edit Profile". Estado: user (setter: setUser). Entrada: Name, Email, Age

▶ Exemplo 4: Estados de objetos aninhados — Gerenciamento de endereços

▶ Experimente

Saída:

TEXT
Formulário de endereço de entrega: Street, City, ZIP, menu suspenso de país (US/CN/JP), caixa de seleção "Primary address". Todos os campos atualizam o estado de forma reativa.

Saída:

TEXT
Exibe: "Shipping Address". Estado: address (setter: setAddress). Entrada: Street, City, ZIP. Menu suspenso: United States, China, Japan

▶ Exemplo 5: As atualizações funcionais resolvem o problema das atualizações em lote

▶ Experimente

Saída:

TEXT
Score: 0, Multiplier: x1. +10/+50/+100 somam pontos × multiplicador. "2x Multiplier" dobra o multiplicador (máx. x8). Reset → Score: 0, x1

❓ Perguntas Frequentes

P Qual é a diferença de desempenho entre useState e as variáveis comuns?
R useState acarreta uma sobrecarga adicional (rastreamento de alterações, agendamento de renderização), portanto, só deve ser usada em cenários em que “as atualizações da interface do usuário são acionadas quando ocorrem alterações”. Se uma variável for alterada, mas não exigir uma atualização da interface do usuário (como um ID de temporizador ou a posição de rolagem), é mais adequado usar useRef (Lição 10).
P Quantos useStates podem existir em um único componente? Há algum problema de desempenho?
R Não há limite para o número. A documentação oficial do React recomenda dividir os elementos em vários useStates com base na lógica, em vez de usar um único objeto grande. Cada chamada de useState é uma “unidade de estado”, e o React consegue lidar com eficiência com um grande número de useStates. Componentes comuns geralmente têm de 3 a 8 useStates.
P A atualização do setState é síncrona ou assíncrona?
R Antes do React 18, o setState era “agrupado automaticamente” dentro de manipuladores de eventos, mas era síncrono nas chamadas do setTimeout e do Promise. O React 18 introduziu o Agrupamento Automático, de modo que setState agora é agrupado de forma assíncrona, independentemente de ser chamado dentro de um manipulador de eventos, setTimeout, Promise ou callback de fetch. Se você precisar absolutamente acessar o DOM atualizado de forma síncrona, pode usar flushSync(() => setState(...)).

📖 Resumo


📝 Exercícios

  1. Exercício básico (Dificuldade ⭐): Crie um componente LikeButton que alterne entre os estados ❤️ e 🤍 quando clicado e exiba o número de curtidas.
  2. Exercício avançado (Dificuldade ⭐⭐): Crie um componente ExpenseTracker que utilize useState para gerenciar uma lista de despesas (descrição, valor, data) e permita adicionar e remover itens.
  3. Desafio (Dificuldade: ⭐⭐⭐): Crie um componente ColorPicker que utilize três instâncias de useState para gerenciar os valores dos controles deslizantes R, G e B (0–255) e exiba uma pré-visualização da cor em tempo real e o código hexadecimal da cor.
Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%