Skip to content
This repository has been archived by the owner on Nov 27, 2022. It is now read-only.

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

Open
2 of 5 tasks
a-sane opened this issue Aug 7, 2021 · 10 comments
Open
2 of 5 tasks

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

a-sane opened this issue Aug 7, 2021 · 10 comments

Comments

@a-sane
Copy link

a-sane commented Aug 7, 2021

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: callstack/react-native-pager-view#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

video_2021-08-08_01-34-54.mp4

More real world example with react navigation V6:

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

video_2021-08-08_01-48-13.mp4

Expected behavior

No random onPress handle like in V2

video_2021-08-08_01-52-47.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

  • Android
  • 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
@github-actions
Copy link

github-actions bot commented Aug 7, 2021

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?

@matfin
Copy link

matfin commented Aug 9, 2021

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.

@kashmiry
Copy link

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

@darrychen92
Copy link

Got the same issue. Have you fixed it?

@alantoa
Copy link

alantoa commented Dec 17, 2021

same issue...

@itsramiel
Copy link

same issue

@salonisahu
Copy link

Any update?

@Gregoirevda
Copy link

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>
  );
}

@patrik-u
Copy link

patrik-u commented Feb 4, 2022

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.

@ProkhoDim
Copy link

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!!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

10 participants