react-native-tab-view icon indicating copy to clipboard operation
react-native-tab-view copied to clipboard

[V3] Random onPress handle in FlatList items while swiping tabs

Open a-sane opened this issue 3 years ago • 10 comments

Current behavior

Random onPress handle in FlatList items while swiping tabs after V3 update Especially noticeable on low-end android devices and in apps with many heavy components

Related issue: https://github.com/callstack/react-native-pager-view/issues/424

Example:

There is a function in demo that imitate CPU intensive operation in order for the issue to be stably reproduced in simple demo on high-end devices

https://snack.expo.dev/@sane.ecg/tab-nav-onpress-issue

https://user-images.githubusercontent.com/764967/128614536-3259f49a-0d80-480c-b12a-24b9e4d708c1.mp4

More real world example with react navigation V6:

https://snack.expo.dev/@sane.ecg/v6-tab-nav-issue

https://user-images.githubusercontent.com/764967/128614696-d46d2737-f801-4749-897a-5cc5e80798db.mp4

Expected behavior

No random onPress handle like in V2

https://user-images.githubusercontent.com/764967/128614762-807a60f5-06c7-4d59-9929-8eb36ff5c438.mp4

https://snack.expo.dev/@sane.ecg/tab-nav-v2-no-onpress-issue

Reproduction

https://snack.expo.dev/@sane.ecg/tab-nav-onpress-issue

Platform

  • [X] Android
  • [X] iOS
  • [ ] Web
  • [ ] Windows
  • [ ] MacOS

Environment

package version
react-native 0.64.2
react-native-tab-view 3.1.1
react-native-pager-view 5.4.0
expo 42.0.3

a-sane avatar Aug 07 '21 22:08 a-sane

Couldn't find version numbers for the following packages in the issue:

  • react-native

Can you update the issue to include version numbers for those packages? The version numbers must match the format 1.2.3.

The versions mentioned in the issue for the following packages differ from the latest versions on npm:

  • expo (found: 42.0.0, latest: 42.0.3)

Can you verify that the issue still exists after upgrading to the latest versions of these packages?

github-actions[bot] avatar Aug 07 '21 22:08 github-actions[bot]

I am getting the same behaviour. When I have a <TouchableOpacity /> inside a view that is contained in react-native-tab-view, an onPress is triggered as I swipe through the three views in the tab view container.

I am using React Native 0.64.2 and I have the Hermes Javascript engine enabled.

matfin avatar Aug 09 '21 08:08 matfin

Facing the same issue on iOS and Android after upgrading to V3. Button inside flat list get pressed while swiping.

kashmiry avatar Aug 10 '21 11:08 kashmiry

Got the same issue. Have you fixed it?

darrychen92 avatar Sep 01 '21 09:09 darrychen92

same issue...

alantoa avatar Dec 17 '21 10:12 alantoa

same issue

itsramiel avatar Jan 07 '22 09:01 itsramiel

Any update?

salonisahu avatar Jan 17 '22 09:01 salonisahu

Found a solution! Replace <TouchableHighlight with <FixedTouchableHighlight in your FlatList

// FixedTouchableHighlight.js
import React, { useRef } from 'react';
import { TouchableHighlight } from 'react-native';

export default function FixedTouchableHighlight({
  onPress,
  onPressIn,
  ...props
}) {
  const _touchActivatePositionRef = useRef(null);

  function _onPressIn(e) {
    const { pageX, pageY } = e.nativeEvent;

    _touchActivatePositionRef.current = {
      pageX,
      pageY,
    };

    onPressIn?.(e);
  }

  function _onPress(e) {
    const { pageX, pageY } = e.nativeEvent;

    const absX = Math.abs(_touchActivatePositionRef.current.pageX - pageX);
    const absY = Math.abs(_touchActivatePositionRef.current.pageY - pageY);

    const dragged = absX > 2 || absY > 2;
    if (!dragged) {
      onPress?.(e);
    }
  }

  return (
    <TouchableHighlight onPressIn={_onPressIn} onPress={_onPress} {...props}>
      {props.children}
    </TouchableHighlight>
  );
}

Gregoirevda avatar Jan 26 '22 17:01 Gregoirevda

Found a solution! Replace <TouchableHighlight with <FixedTouchableHighlight in your FlatList

Thanks, worked perfectly. In my case I wrapped TouchableOpacity and TouchableWithoutFeedback in the same way.

patrik-u avatar Feb 04 '22 23:02 patrik-u

Found a solution! Replace <TouchableHighlight with <FixedTouchableHighlight in your FlatList

// FixedTouchableHighlight.js
import React, { useRef } from 'react';
import { TouchableHighlight } from 'react-native';

export default function FixedTouchableHighlight({
  onPress,
  onPressIn,
  ...props
}) {
  const _touchActivatePositionRef = useRef(null);

  function _onPressIn(e) {
    const { pageX, pageY } = e.nativeEvent;

    _touchActivatePositionRef.current = {
      pageX,
      pageY,
    };

    onPressIn?.(e);
  }

  function _onPress(e) {
    const { pageX, pageY } = e.nativeEvent;

    const absX = Math.abs(_touchActivatePositionRef.current.pageX - pageX);
    const absY = Math.abs(_touchActivatePositionRef.current.pageY - pageY);

    const dragged = absX > 2 || absY > 2;
    if (!dragged) {
      onPress?.(e);
    }
  }

  return (
    <TouchableHighlight onPressIn={_onPressIn} onPress={_onPress} {...props}>
      {props.children}
    </TouchableHighlight>
  );
}

Thanks!!

ProkhoDim avatar May 05 '22 13:05 ProkhoDim