Pressable — o que é, manipulação de pressionamentos no React Native

Autor: IT Sectr Publicado: 2026-07-06 Tempo de leitura: 10 min

Pressable é um componente moderno do React Native para manipular toques, substituindo os obsoletos TouchableHighlight, TouchableOpacity e TouchableWithoutFeedback. O Pressable fornece uma API unificada com detecção dos estados pressed, hovered e focused. O componente foi introduzido no React Native 0.63 e é recomendado pela Meta para todos os novos projetos. Saiba mais em documentação da Meta.

Principais pontos

  • Pressable — um componente universal para manipular toques com suporte aos estados pressed, hovered e focused
  • API inclui callbacks onPress, onLongPress, onPressIn, onPressOut e uma função de estilo baseada no estado
  • hitSlop estende a área de toque além dos limites visíveis do componente para melhorar a UX
  • Substituição do Touchable — Pressable unifica a API de todos os componentes Touchable em uma interface flexível
  • Acessibilidade — o componente suporta papéis ARIA e lida automaticamente com VoiceOver e TalkBack

O que é Pressable?

Pressable é um componente React Native que fornece uma interface unificada para manipular todos os tipos de toques. Ao contrário de três componentes Touchable diferentes (TouchableHighlight, TouchableOpacity, TouchableWithoutFeedback), o Pressable substitui todos eles com um sistema flexível de estados e estilos.

O componente foi introduzido no React Native 0.63 (setembro de 2020). De acordo com a Meta (2026), 70% dos novos projetos em React Native usam Pressable em vez dos componentes Touchable. O Pressable resolve o problema principal do Touchable — uma API fragmentada e a necessidade de alternar entre componentes para efeitos diferentes.

Filosofia do Pressable

Ao contrário do TouchableOpacity, onde o efeito de pressão é fixo (mudança de opacidade), o Pressable fornece uma função que recebe o estado atual. O desenvolvedor decide como responder visualmente a um pressionamento: alterar cor, escala, sombra ou uma combinação de efeitos. Isso dá controle total sobre a UX.

Estados do Pressable: pressed, hovered, focused

Pressable define três estados de interação: pressed (dedo na tela), hovered (cursor sobre o elemento na Web/TV), focused (elemento em foco do teclado). Cada estado ativa o callback correspondente e é passado para a função de estilo e para a função de renderização filha.

EstadoCondiçãoReação típica
pressedDedo na tela ou clique pressionadoAlteração de opacidade, escala ou cor de fundo
hoveredCursor sobre o elemento (Web, TV)Destaque, sombra, sublinhado
focusedElemento em foco do tecladoContorno, borda, mudança de cor

Importante: hovered e focused funcionam apenas em plataformas com suporte a ponteiro (Web, Android TV, Apple TV). Em dispositivos móveis, apenas pressed está disponível. Para aplicativos multiplataforma, projete reações visuais considerando essa limitação.

js
<Pressable
  style={({ pressed }) => [
    styles.button,
    pressed && styles.buttonPressed,
  ]}
  onPress={handlePress}>
  {({ pressed }) => (
    <Text style={pressed ? styles.textPressed : styles.text}>
      {pressed ? 'Release' : 'Press'}
    </Text>
  )}
</Pressable>

API e callbacks do Pressable

A API do Pressable inclui quatro callbacks principais: onPress (pressionamento completo com liberação), onLongPress (pressionamento longo), onPressIn (início do toque) e onPressOut (fim do toque). A combinação de onPressIn e onPressOut permite criar animações personalizadas.

Props adicionais: delayLongPress (atraso do pressionamento longo, padrão 500 ms), pressRetentionOffset (área além da qual o pressionamento é cancelado), android_ripple (efeito ripple no Android). Nota: Ripple funciona apenas no Android 5+.

js
<Pressable
  onPress={() => console.log('Pressionado')}
  onLongPress={() => console.log('Pressão longa')}
  onPressIn={() => console.log('Dedo para baixo')}
  onPressOut={() => console.log('Dedo para cima')}
  delayLongPress={300}
  android_ripple={{ color: 'rgba(0,0,0,0.1)', borderless: false }}
  style={styles.button}>
  <Text>Press me</Text>
</Pressable>

onPress só é chamado se o dedo for levantado dentro da área do componente (considerando pressRetentionOffset). Se o usuário mover o dedo para fora dos limites, onPress não é acionado, evitando pressionamentos falsos. onPressOut é chamado em qualquer caso ao liberar.

hitSlop: expandindo a área de toque

hitSlop é uma prop do Pressable que estende a área de toque além dos limites visíveis do componente. Isso é crítico para elementos pequenos: ícones, caixas de seleção, botões de opção. A Apple HIG recomenda um tamanho mínimo de alvo de toque de 44×44 pontos. O hitSlop permite atender a esse requisito sem alterar o tamanho visual.

hitSlop aceita um objeto { top, bottom, left, right } ou um único número para todos os lados. Os valores são especificados em pixels lógicos (dp/pt). Para ícones de 24×24, recomenda-se um hitSlop de pelo menos 10–12 de cada lado para atingir o alvo de toque de 44×44.

js
<Pressable
  hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
  onPress={handleIconPress}
  style={styles.iconButton}>
  <Icon name="star" size={24} />
</Pressable>

pressRetentionOffset — o inverso do hitSlop: define a área na qual o usuário pode sair dos limites do componente sem cancelar o pressionamento. Por padrão, é igual ao hitSlop. Se precisar que o pressionamento persista ao sair dos limites, aumente pressRetentionOffset.

Pressable vs Touchable: quando migrar

Pressable vs Touchable — uma questão chave ao escolher um componente para manipular toques. TouchableOpacity, TouchableHighlight e TouchableWithoutFeedback são componentes obsoletos que não serão removidos, mas não receberão novos recursos. A Meta recomenda Pressable para novos projetos.

Principais vantagens do Pressable: API unificada para todos os tipos de efeitos, acesso ao estado pressed para estilização personalizada, suporte aos estados hovered/focused, hitSlop e pressRetentionOffset, callback onLongPress sem configuração adicional. TouchableOpacity é adequado apenas para alterações simples de opacidade.

CenárioTouchablePressable
Pressionamento simplesTouchableOpacityPressable + opacity no style
Destaque de fundoTouchableHighlightPressable + backgroundColor
Sem efeito visualTouchableWithoutFeedbackPressable com style vazio
Pressionamento longoonLongPress em qualquer TouchableonLongPress no Pressable
Animação personalizadaAnimated + onPressIn/OutPressable + useAnimatedStyle
Ripple no AndroidTouchableNativeFeedbackPressable + android_ripple

Exemplos de uso do Pressable

Pressable permite criar elementos interativos complexos com código mínimo. Abaixo está um exemplo de um botão animado com mudança de escala ao pressionar e efeito ripple no Android. Esse botão substitui a combinação TouchableOpacity + Animated.

js
const AnimatedButton = ({ title, onPress }) => {
  const scale = React.useRef(new Animated.Value(1)).current;

  const handlePressIn = () => {
    Animated.spring(scale, {
      toValue: 0.96,
      useNativeDriver: true,
    }).start();
  };

  const handlePressOut = () => {
    Animated.spring(scale, {
      toValue: 1,
      friction: 3,
      useNativeDriver: true,
    }).start();
  };

  return (
    <Pressable
      onPress={onPress}
      onPressIn={handlePressIn}
      onPressOut={handlePressOut}
      android_ripple={{ color: 'rgba(255,255,255,0.3)' }}
      style={styles.button}>
      <AnimatedView style={[styles.inner, { transform: [{ scale }] }]}>
        <Text style={styles.text}>{title}</Text>
      </AnimatedView>
    </Pressable>
  );
};

Importante: use useNativeDriver: true para animações no Pressable. Isso transfere a animação para a thread nativa, evitando quedas de quadros durante pressionamentos rápidos. O driver nativo é suportado para transform e opacity em todas as plataformas.

Perguntas frequentes

Posso usar Pressable em vez de TouchableOpacity sem alterar o código?

Não, Pressable tem uma API diferente. TouchableOpacity aplica opacidade automaticamente ao pressionar. Pressable requer especificação explícita do estilo através de uma função de estado. A substituição é trivial: passe style={({ pressed }) => [{ opacity: pressed ? 0.5 : 1 }]}.

Como criar um efeito ripple como no Material Design?

Use a prop android_ripple com um objeto { color, borderless }. A cor do ripple é especificada em formato rgba. Para botões redondos, use borderless: true. Ripple funciona apenas no Android 5+. No iOS, use animação personalizada.

Por que onPress não dispara durante rolagem rápida?

Pressable tem proteção integrada contra pressionamentos acidentais durante a rolagem. Se o usuário rolar uma lista, onPress não é chamado. Esse comportamento pode ser configurado via pressRetentionOffset e delayPressIn.

Como detectar pressionamento longo com Pressable?

Use a prop onLongPress — suporte integrado para pressionamento longo. O atraso é configurável via delayLongPress (padrão 500 ms). Para menus de contexto e arrastar e soltar, combine onLongPress com onPressIn.

Pressable suporta navegação por teclado?

Sim, Pressable suporta o estado focused para navegação por teclado no Android TV, Apple TV e Web. Use estilização via { focused } para exibir o foco. Em dispositivos móveis, o estado focused não é aplicável.

Resumo

  • Pressable — um componente universal React Native para manipular toques, substituindo TouchableOpacity, TouchableHighlight e TouchableWithoutFeedback
  • Estados pressed, hovered, focused são passados para a função de estilo, permitindo personalizar a reação para cada cenário
  • hitSlop estende o alvo de toque para 44×44 pontos sem alterar o tamanho visual, melhorando a UX em elementos pequenos
  • API inclui onPress, onLongPress, onPressIn, onPressOut com atraso configurável via delayLongPress
  • android_ripple adiciona um efeito ripple do Material Design no Android 5+ com cor e forma personalizáveis
  • Migração do Touchable requer substituir efeitos automáticos por estilização explícita através de uma função de estado
  • Animated + Pressable criam animações de pressionamento suaves com useNativeDriver para desempenho

Vamos desenvolver um aplicativo móvel chave na mão

A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.

Discutir o projeto

Leia também