From cfa784c5cec060506d3d76e7819b50934f2c69be Mon Sep 17 00:00:00 2001 From: Karol Latusek Date: Tue, 21 May 2024 09:51:35 -0700 Subject: [PATCH] Avoid redundant state updates in Pressable if children and style are not functions (#44615) Summary: Goal of this PR is to optimise `Pressable` component, similarly to https://github.com/react-native-tvos/react-native-tvos/pull/724 . `Pressable` `style` and `children` properties can, but doesn't have to be functions. Usually we passing objects or arrays. `pressed` state is used only when `style` or `children` are `functions`, so let's update that state only in such case, otherwise let's skip state updates to improve the performance. That way we won't have to rerender the component when it is being pressed (assuming that `style` and `children` are not going to be functions) ## Changelog: [GENERAL] [CHANGED] - Improve performance of `Pressable` component. Pull Request resolved: https://github.com/facebook/react-native/pull/44615 Test Plan: Verify that `Pressable` updates its `pressed` state when `style` or `children` are functions. Reviewed By: javache Differential Revision: D57614309 Pulled By: fabriziocucci fbshipit-source-id: 473e0ab3c4bf7b3ef04ba19f76105ac65371a3fb --- .../Libraries/Components/Pressable/Pressable.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/react-native/Libraries/Components/Pressable/Pressable.js b/packages/react-native/Libraries/Components/Pressable/Pressable.js index de350029419510..bd0d6a43a3a666 100644 --- a/packages/react-native/Libraries/Components/Pressable/Pressable.js +++ b/packages/react-native/Libraries/Components/Pressable/Pressable.js @@ -245,6 +245,9 @@ function Pressable( const [pressed, setPressed] = usePressState(testOnly_pressed === true); + const shouldUpdatePressed = + typeof children === 'function' || typeof style === 'function'; + let _accessibilityState = { busy: ariaBusy ?? accessibilityState?.busy, checked: ariaChecked ?? accessibilityState?.checked, @@ -300,7 +303,7 @@ function Pressable( if (android_rippleConfig != null) { android_rippleConfig.onPressIn(event); } - setPressed(true); + shouldUpdatePressed && setPressed(true); if (onPressIn != null) { onPressIn(event); } @@ -310,7 +313,7 @@ function Pressable( if (android_rippleConfig != null) { android_rippleConfig.onPressOut(event); } - setPressed(false); + shouldUpdatePressed && setPressed(false); if (onPressOut != null) { onPressOut(event); } @@ -333,6 +336,7 @@ function Pressable( onPressOut, pressRetentionOffset, setPressed, + shouldUpdatePressed, unstable_pressDelay, ], );