JavaScript/React/useState
JavaScript⏱ ~2 min de leitura

useState

Gerenciando estado local em componentes

Estado (state) é um dado que pertence a um componente e pode mudar ao longo do tempo. Quando o estado muda, o React re-renderiza o componente automaticamente — a UI sempre reflete o estado atual. O hook useState é a forma de adicionar estado a componentes funcionais.

useState retorna um array com dois itens: o valor atual do estado e uma função para atualizá-lo. Chamar a função de atualização com um novo valor dispara um re-render. O valor inicial pode ser qualquer tipo: string, number, boolean, array, object, null.

Estados nunca devem ser mutados diretamente. Para arrays e objetos, sempre crie um novo valor: setLista([...lista, novoItem]) ao invés de lista.push(novoItem). Múltiplos estados são gerenciados com múltiplos useState — cada um é independente. Para estados complexos e inter-relacionados, considere useReducer.

Exemplo.java
import { useState } from "react";

// ── Estado simples ────────────────────────────────
function Contador() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>Contagem: {count}</p>
      <button onClick={() => setCount(count + 1)}>+</button>
      <button onClick={() => setCount(prev => prev - 1)}>-</button>
      <button onClick={() => setCount(0)}>Reset</button>
    </div>
  );
}

// ── Atualização funcional (segura para estado derivado) ─
// setCount(prev => prev + 1)  ← sempre use a versão anterior

// ── Estado com objeto ─────────────────────────────
function Formulario() {
  const [form, setForm] = useState({ nome: "", email: "" });

  const handleChange = (campo) => (e) => {
    setForm(prev => ({ ...prev, [campo]: e.target.value }));
    // spread: copia tudo e sobrescreve só o campo alterado
  };

  return (
    <form>
      <input value={form.nome} onChange={handleChange("nome")} />
      <input value={form.email} onChange={handleChange("email")} />
      <p>{form.nome} — {form.email}</p>
    </form>
  );
}

// ── Estado com array ──────────────────────────────
function Lista() {
  const [itens, setItens] = useState([]);
  const [texto, setTexto] = useState("");

  const adicionar = () => {
    if (!texto.trim()) return;
    setItens(prev => [...prev, { id: Date.now(), texto }]); // ✅ imutável
    setTexto("");
  };

  const remover = (id) => {
    setItens(prev => prev.filter(item => item.id !== id));
  };

  return (
    <div>
      <input value={texto} onChange={e => setTexto(e.target.value)} />
      <button onClick={adicionar}>Adicionar</button>
      <ul>
        {itens.map(item => (
          <li key={item.id}>
            {item.texto}
            <button onClick={() => remover(item.id)}>×</button>
          </li>
        ))}
      </ul>
    </div>
  );
}
💡 Dica pro

Nunca mute estado diretamente: itens.push(x) não dispara re-render! Use sempre setItens([...itens, x]). Para objetos aninhados complexos, considere immer ou zustand para simplificar as atualizações imutáveis.

Recompensa+35 XP+exercícios