This must be trivial but I can’t seem to figure out.
Context: I have a custom component to hide the keyboard everytime the user taps somewhere on the screen.
HideKeyboard.tsx
import { TouchableWithoutFeedback, Keyboard, } from 'react-native'
import React from 'react'
export interface HideKeyboardProps {
children: React.ReactNode;
}
export default function HideKeyboard(props: HideKeyboardProps) {
return (
<TouchableWithoutFeedback onPress={() => { Keyboard.dismiss(); }}>
{props.children}
</TouchableWithoutFeedback>
)
}
This works fine, but the problem arises when the user taps on a button on the screen. The expected behaviour would be – the keyboard dismisses and the click handler of the button gets executed.
But, because of the HideKeyboard
control, the initial tap gets captured and is used to dismiss the keyboard and so the user has to tap again.
Is there a way to tackle this? Can we somehow execute the event in the onPress handler?
2
Answers
One possible way to ensure the event gets bubbled when using TouchableWithoutFeedback is to use the
onPressOut
prop instead of theonPress
prop. For example, you can change your HideKeyboard component to something like this:This will dismiss the keyboard when the user releases the touch, but will also allow the event to bubble up to the button’s
onPress
handler.I’d change the behavior so that the tap event is not "consumed" by the
TouchableWithoutFeedback
. Wrap your components withView
instead ofTouchableWithoutFeedback
and use theonStartShouldSetResponder
property of theView
to detect touch events.How to modify the
HideKeyboard
component:By returning
false
from theonStartShouldSetResponder
handler, you’re telling React Native to continue propagating the touch event to other views. Button click handler should be executed as expected.I think this gives you the behavior you’re looking for – dismissing the keyboard when the user taps somewhere on the screen without interfering with button clicks.