React-native: "keyboardShouldPersistTaps" prop not works on FlatList

Created on 9 May 2020  路  10Comments  路  Source: facebook/react-native

Please provide all the information requested. Issues that do not follow this format are likely to stall.

Description

"keyboardShouldPersistTaps" prop not works on FlatList

React Native version: 0.62.2

I just did copy one of my components which working on RN : 0.61.5 but it doesn't dismiss the f..ing Android keyboard.

This was my code:

            <FlatList
              keyboardShouldPersistTaps="handled"
              ...
Keyboard FlatList Needs

Most helpful comment

Ok, solved it in my case! 馃槃

What happened is that my modal is wrapped on a ScrollView in a parent component like two levels above. That parent ScrollView was capturing tap events and preventing them to reach its children (ie. the modal's children). So, my recommendation to @cybercoder and @Slapbox and any other reading this: Make sure there's no ScrollView, FlatList or any other component that inherits from ScrollView wrapping the component you are building. It was enough to add keyboardShouldPersistTaps="handled" and nestedScrollEnabled={true} to the parent ScrollView to make everything work again.

EDIT: About the change of behavior, in my case the change was introduced by another developer in a parent component, and I wasn't aware of those changes (totally my fault), which made me spend at least 2 days "tracking this bug"... This is likely to happen in big projects where many devs are involved. Maybe that could be a cause of change in behavior for you guys too 馃槃. Just make sure to double check :). Best of luck!

All 10 comments

Same issue, but I'm on 0.61.x via Expo. Not working on any FlatList on any OS.

Unchanged code last known working in 0.59.8.

Same issue occurring on 0.61.4, ejected. Not working on any platform.

info Fetching system and libraries information...
System:
    OS: macOS 10.15.4
    CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
    Memory: 239.84 MB / 16.00 GB
    Shell: 5.7.1 - /bin/zsh
  Binaries:
    Node: 12.16.3 - ~/.nvm/versions/node/v12.16.3/bin/node
    Yarn: 1.22.4 - /usr/local/bin/yarn
    npm: 6.14.4 - ~/.nvm/versions/node/v12.16.3/bin/npm
    Watchman: 4.9.0 - /usr/local/bin/watchman
  SDKs:
    iOS SDK:
      Platforms: iOS 13.4, DriverKit 19.0, macOS 10.15, tvOS 13.4, watchOS 6.2
    Android SDK:
      API Levels: 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29
      Build Tools: 28.0.3, 29.0.2, 29.0.3
      System Images: android-29 | Google APIs Intel x86 Atom, android-29 | Google Play Intel x86 Atom
  IDEs:
    Xcode: 11.4.1/11E503a - /usr/bin/xcodebuild
  npmPackages:
    react: 16.9.0 => 16.9.0
    react-native: 0.61.4 => 0.61.4

Actually, it seems it doesn't work for ScrollView either. Anyone has seen into this? Any workarounds? In my case this view (FlatView or ScrollView, i tried both) is inside a Modal. Does that affect?

It mostly depends on how we interpret the documentation on keyboardShouldPersistTaps and what expect from the ScrollView component

As you can see from the following snack keyboardShouldPersistTaps works when clicking on component like TouchableOpacity, but it does not with a child View.

I guess ScrollView intercepts the click event from the children View.

'handled', the keyboard will not dismiss automatically when the tap was handled by children of the scroll view (or captured by an ancestor).

If the ScrollView intercepts the click from the children View, the hte issue is not keyboardShouldPersistTaps, but pointerEvents={"box-none"} https://github.com/facebook/react-native/issues/20897 (to be used to fix the behaviour).

I believe the issue is related to pointerEvents not working correctly with the ScrollView.

If we replace the ScrollView with the View, the functionality works correctly.
The issue may be connected to the GestureDetection functionalities that allow us to scroll a view, but on the other side intercepts the clicks on child componets

@cybercoder please close this issue

further information in the gesture response documentation

I also create a snack so that you can test the functionality with a ScrollView. The children Views need to catch the touches as following:

     <ScrollView>
         <View
           onStartShouldSetResponder={() => {return true}} />
    </ScrollView>

Otherwise the View will not catch the touch and the ScrollView does in his place and closes the keyboard, but if you implement the functionality as in the code above, it works (as demonstrated in the snack).

As you can verify from the snack, buttons and touchable opacity inside a ScrollView will catch the touch and not close the keyboard, but children View will not... more info in my post above (hidden as Outdated). This is the behaviour from keyboardShouldPersistTaps as I quote the documentation:

'handled', the keyboard will not dismiss automatically when the tap was handled by children of the scroll view (or captured by an ancestor).

Considering that we have 744 open issues and you have a solution for this one, would you consider closing this issue? Thanks

snack

In a FlatList renderItem prop:

  const renderItem = ({item}) => (
    <View
      onStartShouldSetResponder={() => {
        return true;
      }}>
      <TouchableOpacity
        onPress={() => {
          props.onSelectItem(item);
        }}>
....

unfortunately App closed, ...

In my case it still doesn't work neither wrapping the item in a view with onStartShouldSetResponder={() => {return true}} nor applying pointerEvents="box-none" to the parent view. What ends up happening is the keyboard being dismissed (even though there's no Keyboard.dismiss() anywhere). In my particular case, the FlatList is inside a Modal, and is sibling to a view that contains a text input that starts focused when the modal is set visible. So, my question is... Does it have anything to do with it being inside a modal?

@cybercoder does your code happens to be inside of a modal?

@fabriziobertoglio1987 could you validate reproducing the error inside of a modal?

Also, the scenario is, the focus is on the text input, and according to the user input, some options will appear in the FlatList passed through the data property. These options are implemented with a TouchableOpacity, so, Ideally, i would like the tap to produce the text input to loose focus, the correspondent TouchableOpacity to receive the press event, and the keyboard to be dismissed, all at the same time. I'm not focusing on the keyboard dismissing part because i can call that in one of the handlers. My problem is, the TouchableOpacity does not seem te be receiving the touch event, no matter whether I add keyboardShouldPersistTaps="handled" and/or pointerEvents="box-none" to the container FlatList or ScrollView (I tried using both).

I'll keep digging and share if I find any workaround. Please! Any help would be much appreciated! Thanks!

@fabriziobertoglio1987 - it's absolutely absurd to tell multiple people that report something that's started functioning differently with no mention in changelogs or documentation to close the issue.

If this wasn't a _change in behavior_ then I'd agree - but it is.

Ok, solved it in my case! 馃槃

What happened is that my modal is wrapped on a ScrollView in a parent component like two levels above. That parent ScrollView was capturing tap events and preventing them to reach its children (ie. the modal's children). So, my recommendation to @cybercoder and @Slapbox and any other reading this: Make sure there's no ScrollView, FlatList or any other component that inherits from ScrollView wrapping the component you are building. It was enough to add keyboardShouldPersistTaps="handled" and nestedScrollEnabled={true} to the parent ScrollView to make everything work again.

EDIT: About the change of behavior, in my case the change was introduced by another developer in a parent component, and I wasn't aware of those changes (totally my fault), which made me spend at least 2 days "tracking this bug"... This is likely to happen in big projects where many devs are involved. Maybe that could be a cause of change in behavior for you guys too 馃槃. Just make sure to double check :). Best of luck!

@throoze Awesome, Thanks

Was this page helpful?
0 / 5 - 0 ratings

Related issues

josev55 picture josev55  路  3Comments

DreySkee picture DreySkee  路  3Comments

lazywei picture lazywei  路  3Comments

janmonschke picture janmonschke  路  3Comments

axelg12 picture axelg12  路  3Comments