Boolean inside useRef is not giving correct value, and it is always false in React/React native. Even if the keyboard is present isKeyboardShown inside keyboardDissmissPanResponder = useRef is always false
const isKeyboardShown = keyboardState?.isKeyboardShown ?? false;
const keyboardDissmissPanResponder = useRef(
PanResponder.create({
onMoveShouldSetPanResponderCapture: (_e, gestureState) => {
const isHorizonSwipe = Math.abs(gestureState.dx) > Math.abs(gestureState.dy);
return isHorizonSwipe && isKeyboardShown;
},
onPanResponderGrant: Keyboard.dismiss,
}),
).current;
How can I fix it? If someone knows what went wrong then please let me know. Thank you
2
Answers
I’d recommend using state, that code will only run once.
isKeyboardShown
will never change value.If you make it a state then the value will always be updated, something like this:
I’m supposing that the
keyboardState
is an actual state.isKeyboardShown
is always false or never updates because it’s a stale Javascript closure over it in theonMoveShouldSetPanResponderCapture
callback handler. TheuseRef
is initially set to the value passed to it, thePanResponder
object, and that ref’s initialcurrent
value is saved tokeyboardDissmissPanResponder
.From what I can understand it seems you really just want to provide a stable
PanResponder
object. Use theuseMemo
hook to create the stable reference with a dependency on thekeyboardState
reference. Each time thekeyboardState
reference updates, a newPanResponder
object is created and returned for use in the UI.Example:
In some cases where consumers internalize the handlers and don’t react to new instances you may need to take a slightly different approach. Use a React ref to cache the current
keyboardState
value so the ref can be referenced in thePanResponder
handlers. This removeskeyboardState
as an external dependency for thePanResponder
memoization.Example: