Skip to content

Pressable has unchangeable delay for opacity effect (onPressIn) #29376

@mrousavy

Description

@mrousavy

Description

The <Pressable /> component has an unchangeable delay between pressing and visual feedback.

See:

Pressable TouchableOpacity

As you can see, the TouchableOpacity has instant visual feedback when I press it, where as the Pressable takes about 120ms (wild guess).
I though 49b2a6e should fix this delay?

React Native version:

info Fetching system and libraries information...
(node:46144) Warning: Accessing non-existent property 'padLevels' of module exports inside circular dependency
(Use `node --trace-warnings ...` to show where the warning was created)
System:
    OS: macOS 10.15.5
    CPU: (16) x64 Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz
    Memory: 6.86 GB / 32.00 GB
    Shell: 5.7.1 - /bin/zsh
  Binaries:
    Node: 14.4.0 - /usr/local/bin/node
    Yarn: 1.22.4 - /usr/local/bin/yarn
    npm: 6.14.6 - /usr/local/bin/npm
    Watchman: 4.9.0 - /usr/local/bin/watchman
  Managers:
    CocoaPods: 1.9.3 - /usr/local/bin/pod
  SDKs:
    iOS SDK:
      Platforms: iOS 13.5, DriverKit 19.0, macOS 10.15, tvOS 13.4, watchOS 6.2
    Android SDK:
      API Levels: 25, 28, 29
      Build Tools: 28.0.3, 29.0.2, 29.0.3, 30.0.0, 30.0.0, 30.0.0
      System Images: android-29 | Google APIs Intel x86 Atom, android-29 | Google Play Intel x86 Atom
      Android NDK: 21.2.6472646
  IDEs:
    Android Studio: 4.0 AI-193.6911.18.40.6514223
    Xcode: 11.5/11E608c - /usr/bin/xcodebuild
  Languages:
    Java: 1.8.0_252 - /usr/bin/javac
    Python: 2.7.16 - /usr/bin/python
  npmPackages:
    @react-native-community/cli: Not Found
    react: 16.13.1 => 16.13.1 
    react-native: 0.63.1 => 0.63.1 
  npmGlobalPackages:
    *react-native*: Not Found

Steps To Reproduce

Provide a detailed list of steps that reproduce the issue.

  1. Create <Pressable /> component
  2. Give it an opacity effect with the new style function that supplies the pressed argument
  3. See delay between press and effect

Expected Results

The opacity effect/visual feedback should appear instantly, like on the TouchableOpacity.

Snack, code example, screenshot, or link to a repository:

PressableOpacity.ts:

import React, { useCallback } from 'react';
import { Pressable, PressableProps, PressableStateCallbackType, StyleProp, ViewStyle } from 'react-native';

export interface PressableOpacityProps extends PressableProps {
	disabledOpacity?: number;
}

export type StyleType = (state: PressableStateCallbackType) => StyleProp<ViewStyle>;

export default function PressableOpacity(props: PressableOpacityProps): JSX.Element {
	const { style, disabled, disabledOpacity, ...passThroughProps } = props;

	const getOpacity = useCallback(
		(pressed: boolean) => {
			if (disabled) return disabledOpacity ?? 1;
			else return pressed ? 0.6 : 1;
		},
		[disabled, disabledOpacity],
	);
	const _style = useCallback<StyleType>(({ pressed }) => [style, { opacity: getOpacity(pressed) }], [getOpacity, style]);

	return <Pressable style={_style} disabled={disabled} {...passThroughProps} />;
}

Now just use it:

App.js

export default function App() {
  return (<PressableOpacity style={{ width: 200, height: 30 }} onPress={() => console.log('hello!')} />);
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions