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.
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>
);
}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.