React é fácil de começar e igualmente fácil de bagunçar. A diferença entre um código que dá gosto de manter e um que assusta raramente está em truques avançados — está em alguns hábitos simples. Estas boas práticas de React são pra quem já escreve componentes mas quer parar de repetir os mesmos tropeços.

Componentes pequenos, uma responsabilidade
O melhor componente é aquele que faz uma coisa e faz bem. Quando um componente começa a misturar busca de dados, lógica de negócio e um monte de JSX, ele vira um nó difícil de entender e de testar.
Alguns sinais de que passou da hora de quebrar: você rola muito pra ler o componente inteiro, ele tem vários pedaços de estado que não conversam entre si, ou você hesita na hora de dar um nome porque ele faz coisas demais. Quebrar cedo é mais barato do que desamarrar depois.
Estado o mais perto possível de quem usa
Uma tentação comum é jogar todo o estado lá no topo "pra facilitar". Quase sempre é o contrário: quanto mais longe o estado está de quem realmente usa, mais componentes re-renderizam à toa e mais difícil fica seguir o fluxo.
Deixe cada pedaço de estado no componente que precisa dele. Só suba o estado (o famoso "lifting") quando dois componentes de fato precisam compartilhar a mesma informação — e mesmo assim, suba só até o ancestral comum mais próximo, nem um nível a mais.
useEffect não é "faça quando renderizar"
Esse é o mal-entendido que mais gera bug em quem está aprendendo. O useEffect existe pra sincronizar seu componente com algo de fora do React: uma requisição de rede, um evento do DOM, um timer, uma inscrição. Não é um gancho genérico de "rode este código a cada render".
Se você está usando um efeito só pra calcular um valor a partir de props ou estado, provavelmente não precisa de efeito nenhum — veja a próxima seção.
Derive, não duplique
Guardar no estado uma informação que dá pra calcular a partir de outra é pedir por bugs de sincronia: uma hora as duas cópias discordam. Se você tem uma lista de itens e quer o total, não guarde o total num estado separado — calcule na hora de renderizar. Menos estado significa menos coisas pra manter em sincronia, e menos formas de errar.
Keys em listas não são decoração

Quando você renderiza uma lista, o React usa a key pra saber qual item é qual entre um render e outro. Use um id estável do dado como key.
O atalho de usar o índice do array parece inofensivo e funciona — até a lista reordenar, receber um item no meio ou perder um. Aí o React se confunde sobre o que mudou, e você vê estado indo parar no item errado. Id estável resolve isso de graça.
Props e nomes que se explicam
Código bom se lê quase como texto. Nomeie componentes e props pela intenção, não pela aparência: isLoading diz mais que flag, onConfirm diz mais que handleClick2.
E desconfie quando um componente acumula muitas props booleanas (isBig, isPrimary, isDisabled, isRound...). Costuma ser sinal de que ele está tentando ser vários componentes ao mesmo tempo — e aí voltamos à primeira regra: quebre em pedaços menores.
Nenhuma dessas práticas é sofisticada, e é justamente esse o ponto. Componentes pequenos, estado no lugar certo, efeitos só pra sincronizar, dados derivados em vez de duplicados: some tudo e você tem uma base de código que cresce sem virar um campo minado. O React agradece — e o você do futuro também.


