Acessibilidade em Componentes React
1 min de leitura
React não deixa uma interface acessível sozinho. Ele renderiza HTML. Se o HTML, os atributos e o foco não comunicarem a mudança certa, a tela pode parecer funcionar visualmente e ainda ficar confusa para teclado e leitor de tela.
import { useState } from 'react';
function FavoriteButton({ pressed, onToggle }) {
return (
<button type="button" aria-pressed={pressed} onClick={onToggle}>
{pressed ? 'Remover dos favoritos' : 'Adicionar aos favoritos'}
</button>
);
}
export default function ProductFavorite() {
const [favorite, setFavorite] = useState(false);
return (
<section>
<h2>Café Catuaí</h2>
<FavoriteButton
pressed={favorite}
onToggle={() => setFavorite((current) => !current)}
/>
<p role="status">
{favorite ? 'Produto salvo nos favoritos.' : 'Produto fora dos favoritos.'}
</p>
</section>
);
}
O botão é nativo, então já funciona com mouse, teclado e leitor de tela. O
atributo aria-pressed comunica o estado "ligado/desligado", e role="status"
anuncia a mudança sem interromper a pessoa.
Prefira HTML nativo
Use <button>, <a>, <label>, <input>, <form> e headings reais antes de
criar controles com div. Quando você usa o elemento certo, o navegador entrega
comportamento, foco e semântica como ponto de partida.
// Evite
<div onClick={save}>Salvar</div>
// Prefira
<button type="button" onClick={save}>Salvar</button>
Estado visual precisa ter estado semântico
Se a tela mostra "selecionado", "aberto", "atual" ou "pressionado", esse estado também deve aparecer no HTML quando for relevante.
<button aria-expanded={isOpen} onClick={() => setIsOpen(!isOpen)}>
Filtros
</button>
{isOpen && <aside id="filters">Opções de filtro</aside>}
Teste como a pessoa usa
Não teste só clicando. Navegue com Tab, ative com Enter e Espaço, leia os
nomes dos controles e veja se mensagens importantes aparecem no momento certo.
- Elemento nativo: dá comportamento acessível como base.
- Atributo semântico: comunica estados que não aparecem só no texto.
- Região de status: anuncia mudanças importantes sem depender de olhar para a tela.
- Teste por teclado: revela problemas que o clique não mostra.
Dica: ARIA complementa HTML; não use ARIA para fingir que uma
divé botão quando um<button>resolveria com menos trabalho.
No próximo nó, vamos compartilhar um mesmo estado entre dois componentes sem criar cópias divergentes.
// Quiz
Qual combinação deixa um botão de favoritar mais acessível?