Boas Práticas Fundamentais do React Native
Um resumo condensado das 25 melhores práticas mais importantes, extraídas de cada página desta seção.
Busque em todas as páginas da documentação
Um resumo condensado das 25 melhores práticas mais importantes, extraídas de cada página desta seção.
Envolva strings em Text: React Native não possui nós de texto DOM - colocar uma string pura dentro de View gera um redbox. Cada caractere visível ao usuário deve estar dentro de <Text>.
Conheça o padrão flex: O flex do React Native tem como padrão column, o oposto do CSS da web. Defina flexDirection: "row" explicitamente sempre que desejar um layout horizontal.
Cacheie estilos com StyleSheet.create: Definir objetos de estilo inline cria novas referências a cada renderização. StyleSheet.create registra os estilos uma vez e permite que o lado nativo os cacheie para melhor desempenho.
Aplique safe area uma vez na raiz da tela: Aninhar componentes SafeAreaView ou combiná-los com paddingTop: insets.top manual dobra o inset. Escolha um proprietário por eixo - geralmente o wrapper de tela mais externo.
Use contentContainerStyle para padding do ScrollView: O padding no próprio ScrollView recorta os indicadores de rolagem de forma estranha no iOS. Coloque o espaçamento interno em contentContainerStyle, não no contêiner de rolagem.
Combine sombras iOS com elevation Android: shadowColor e shadowOffset são ignorados no Android. Use Platform.select para aplicar props de sombra do iOS juntamente com elevation.
Aninhe Text dentro de Text para spans inline: Envolver palavras individuais em View quebra o fluxo de texto inline e prejudica a acessibilidade. Use nós <Text> aninhados para spans inline em negrito, coloridos ou com links.
Trate props como somente leitura: Mutar uma prop ou objeto de estado in-place (todo.done = true; setTodos(todos)) pode pular re-renderizações porque a referência não muda. Sempre retorne novos objetos e arrays dos atualizadores.
Derive valores computáveis durante a renderização: Armazenar listas filtradas ou ordenadas em useState separado duplica atualizações e arrisca dessincronização. Use useMemo para derivar da única fonte de verdade.
Estabilize callbacks em listas virtualizadas: onPress={() => toggle(id)} inline dentro de renderItem quebra memo a cada renderização. Passe manipuladores useCallback estáveis ou deixe componentes de linha memoizados possuírem o manipulador.
Memoize objetos de valor de contexto: value={{ user, theme }} recriado a cada renderização re-renderiza todos os consumidores. Memoize o objeto de valor ou divida contextos por frequência de atualização.
Profile antes de otimizar demais: useMemo e useCallback têm seu próprio custo. Otimize linhas de lista e computações puras genuinamente caras - não todo objeto inline.
Prefira Pressable a TouchableOpacity: Pressable expõe os estados pressed, hovered e focused, envia android_ripple e hitSlop como recursos de primeira classe, e evita o desvanecimento da opacidade em toda uma subárvore.
Atinga alvos de toque mínimos de 44pt: Um ícone de 20×20 sem padding falha nos mínimos do HIG e Material. Adicione hitSlop ou envolva com padding para que a área interativa atinja aproximadamente 44×44 pontos.
Mostre o estado desabilitado visual e semanticamente: disabled silencia onPress, mas o controle ainda pode parecer ativo. Combine estilos desabilitados, accessibilityState={{ disabled: true }} e pointerEvents onde overlays competem.
Use Platform.select para pequenas diferenças: Dividir arquivos .ios e .android para uma diferença de cor de uma linha adiciona sobrecarga de manutenção. Reserve arquivos específicos da plataforma para UI materialmente diferentes ou imports nativos.
Importe o nome do arquivo base, não .ios: import X from "./Foo.ios" quebra os bundles Android. Importe ./Foo e deixe o Metro resolver o arquivo de plataforma correto.
Sempre inclua um padrão em Platform.select: Web e outros alvos Expo recebem undefined sem uma chave default. Cada chamada Platform.select em um aplicativo multiplataforma precisa de um fallback.
Defina dimensões explícitas em imagens remotas: Imagens { uri } sem width, height ou aspectRatio renderizam em 0×0 e aparecem invisíveis. Sempre restrinja o layout para fontes de rede.
Mantenha os caminhos require() estáticos: Metro analisa os imports de assets no momento da compilação - require('./assets/' + name + '.png') falha. Use um mapa de lookup constante de requires estáticos em vez disso.
Pré-carregue assets antes de ocultar o splash: Ocultar o splash imediatamente enquanto as imagens decodificam mostra um flash em branco. await Asset.loadAsync(...) e então chame SplashScreen.hideAsync().
Assine mudanças de dimensão com um hook: Dimensions.get('window') é um snapshot - a UI permanece em layout retrato após a rotação. Use useWindowDimensions() ou Dimensions.addEventListener.
Use breakpoints de largura para tablets multiplataforma: Platform.isPad cobre apenas o iOS. Um breakpoint de largura lógico (por exemplo, >= 768) funciona em tablets Android e foldables também.
Assuma Nova Arquitetura por padrão no RN 0.86: Expo SDK 57 envia com Fabric e TurboModules habilitados. Verifique a compatibilidade da biblioteca com a Nova Arquitetura antes de atualizar - o sucesso da compilação não garante estabilidade em tempo de execução.
Depure Hermes com React Native DevTools: A depuração remota no Chrome não se conecta fielmente ao bytecode Hermes. Pressione j no Metro ou use o menu de desenvolvimento para abrir o React Native DevTools para breakpoints e profiling no dispositivo.
react-native ou módulos Expo que são enviados com o template padrão.expo-asset assumem um fluxo de trabalho Expo ou prebuild, mas as regras subjacentes também se aplicam ao RN puro.<Text>, mesmo palavras únicas dentro de uma View.memo e forçam cada linha visível a re-renderizar a cada tick do pai.useCallback e mantenha os componentes de linha memoizados.Platform.select dentro de um arquivo compartilhado é mais limpo.newArchEnabled em app.json / app.config.js (habilitado por padrão em templates recentes).npx expo-doctor e inspecione os logs de compilação nativa para inicialização do Fabric/TurboModule.Dimensions.get('window') na renderização do componente por useWindowDimensions().@3x com milhares de pixels de largura e exibi-lo em um avatar de 48×48.expo-image com modos de redimensionamento apropriados.Versões da Stack: Esta página foi escrita para React 19.2.3, React Native 0.86.0 e Expo SDK 57 (
expo~57.0.4).
Revisado por Chris St. John·Última atualização: 9 de jul. de 2026