-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Add displayName
to forwardRef
from AnimatedComponent
#6978
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
tomekzaw
approved these changes
Feb 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, haven't tested it though
tjzel
approved these changes
Feb 10, 2025
piaskowyk
approved these changes
Feb 11, 2025
m-bert
added a commit
to software-mansion/react-native-gesture-handler
that referenced
this pull request
Feb 12, 2025
## Description Currently, when user wraps `SVG` component with `createAnimatedComponent`, we have no way to detect that `child` node passed into [Wrap](https://github.com/software-mansion/react-native-gesture-handler/blob/6e8d88e5a3b15bb399c188d4c23603b4e0f4a8bc/src/handlers/gestures/GestureDetector/Wrap.web.tsx#L9) comes from `SVG`. This results in additional `div` with `display" contents;` being added, which effectively breaks `SVG`. >[!CAUTION] >In order to fix this, I've opened [PR against Reanimated](software-mansion/react-native-reanimated#6978) that adds inner component name into `displayName` of the `forwardRef` that `createAnimatedComponent` returns. Fixes #3356 ## Test plan <details> <summary>Tested on the code from issue</summary> ```jsx import { useMemo, useRef } from 'react'; import { Text, View, Animated, PanResponder } from "react-native"; import { Svg, Rect } from 'react-native-svg'; import { GestureDetector, Gesture, GestureHandlerRootView } from 'react-native-gesture-handler'; import RNRAnimated, { useSharedValue, useAnimatedProps} from 'react-native-reanimated' const RNRAnimatedRect = RNRAnimated.createAnimatedComponent(Rect) const AnimatedRect = Animated.createAnimatedComponent(Rect) export default function Index() { const pan = useRef(new Animated.Value(0)).current; const panResponder = useRef( PanResponder.create({ onMoveShouldSetPanResponder: () => true, onPanResponderMove: Animated.event([null, {dx: pan}]), onPanResponderRelease: () => { pan.extractOffset(); }, }), ).current; const RNTest = <View style={{borderWidth: 1}}> <Text>With RN... though this isn't ideal because it lets you drag the yellow region</Text> <Animated.View {...panResponder.panHandlers}> <Svg width={200} height={100} > <Rect width={200} height={100} fill='yellow'/> <AnimatedRect width={100} height={100} x={pan} y={0} fill='red'/> </Svg> </Animated.View> </View> const x = useSharedValue(0) const animatedX = useAnimatedProps(() => ({x: x.value}), [x]); const xStart = useSharedValue(0); const svgPanGesture = useMemo(() => { return Gesture.Pan() .onBegin(() => {xStart.value = x.value}) .onChange((e) => { x.value = xStart.value + e.translationX }) }, []) const RNGHTest = <View style={{borderWidth: 1}}> <Text>With RNGH and RNR</Text> <Svg width={200} height={100}> <Rect width={200} height={100} fill='yellow'/> <GestureDetector gesture={svgPanGesture}> <RNRAnimatedRect width={100} height={100} animatedProps={animatedX} y={0} fill='red' /> </GestureDetector> </Svg> </View> return ( <GestureHandlerRootView style={{ flex: 1 }}> <View style={{ flex: 1, justifyContent: "center", }} > {RNTest} {RNGHTest} </View> </GestureHandlerRootView> ); } ``` </details>
m-bert
added a commit
that referenced
this pull request
Feb 18, 2025
After switching to new `findNodeHandle` implementation based on `display: contents;`, we can no longer detect components from `SVG` that are wrapped using `createAnimatedComponent` (see [issue](software-mansion/react-native-gesture-handler#3356) on Gesture Handler side). This is because our [Wrap](https://github.com/software-mansion/react-native-gesture-handler/blob/7f90209add0b761d3738882339f4949b31f6f88f/src/handlers/gestures/GestureDetector/Wrap.web.tsx#L9) receives `forwardRef` as child - that makes it impossible to detect what component is used inside. Theoretically we could do something like ```js child.type.render().displayName ``` and use regex to get component name, but it would be very expensive. Instead, we can add `displayName` directly to `forwardRef` on Reanimated side. This should help us detect if component passed inside `createAnimatedComponent` was from `SVG`. Code used inside our [Wrap.web.tsx](https://github.com/software-mansion/react-native-gesture-handler/blob/7f90209add0b761d3738882339f4949b31f6f88f/src/handlers/gestures/GestureDetector/Wrap.web.tsx#L9) ```jsx const child = React.Children.only(children); console.log(child) console.log(child.type.displayName) ``` gives the following result: <img width="605" alt="image" src="https://github.com/user-attachments/assets/e12059bb-ebbc-4812-8a1a-ae8eb6507cf2" />
tjzel
pushed a commit
that referenced
this pull request
Feb 18, 2025
After switching to new `findNodeHandle` implementation based on `display: contents;`, we can no longer detect components from `SVG` that are wrapped using `createAnimatedComponent` (see [issue](software-mansion/react-native-gesture-handler#3356) on Gesture Handler side). This is because our [Wrap](https://github.com/software-mansion/react-native-gesture-handler/blob/7f90209add0b761d3738882339f4949b31f6f88f/src/handlers/gestures/GestureDetector/Wrap.web.tsx#L9) receives `forwardRef` as child - that makes it impossible to detect what component is used inside. Theoretically we could do something like ```js child.type.render().displayName ``` and use regex to get component name, but it would be very expensive. Instead, we can add `displayName` directly to `forwardRef` on Reanimated side. This should help us detect if component passed inside `createAnimatedComponent` was from `SVG`. Code used inside our [Wrap.web.tsx](https://github.com/software-mansion/react-native-gesture-handler/blob/7f90209add0b761d3738882339f4949b31f6f88f/src/handlers/gestures/GestureDetector/Wrap.web.tsx#L9) ```jsx const child = React.Children.only(children); console.log(child) console.log(child.type.displayName) ``` gives the following result: <img width="605" alt="image" src="https://github.com/user-attachments/assets/e12059bb-ebbc-4812-8a1a-ae8eb6507cf2" />
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
After switching to new
findNodeHandle
implementation based ondisplay: contents;
, we can no longer detect components fromSVG
that are wrapped usingcreateAnimatedComponent
(see issue on Gesture Handler side). This is because our Wrap receivesforwardRef
as child - that makes it impossible to detect what component is used inside. Theoretically we could do something likeand use regex to get component name, but it would be very expensive.
Instead, we can add
displayName
directly toforwardRef
on Reanimated side. This should help us detect if component passed insidecreateAnimatedComponent
was fromSVG
.Test plan
Code used inside our Wrap.web.tsx
gives the following result: