software-mansion / react-native-reanimated

React Native's Animated library reimplemented
https://docs.swmansion.com/react-native-reanimated/
MIT License
8.61k stars 1.27k forks source link

Make animated component's event tag properly update #6030

Closed szydlovsky closed 3 weeks ago

szydlovsky commented 1 month ago

Summary

Turns out (thanks to @j-piasecki for noticing) that animated component's event-emitting viewTag can change through re-rendering. The following fix takes care of that.

Test plan

You can go through all ComposedEventHandler examples form Example app, as well as code snippets in https://github.com/software-mansion/react-native-reanimated/pull/5845#issue-2211354383.

Also, this should work perfectly regardless of re-renders:

Code ``` TYPESCRIPT import React, { useState } from 'react'; import { Button, StyleSheet, View } from 'react-native'; import { GestureDetector, Gesture } from 'react-native-gesture-handler'; import Animated, { useSharedValue, useAnimatedStyle, withSpring, } from 'react-native-reanimated'; function Ball(props) { const isPressed = useSharedValue(false); const offset = useSharedValue({ x: 0, y: 0 }); const animatedStyles = useAnimatedStyle(() => { return { transform: [ { translateX: offset.value.x }, { translateY: offset.value.y }, { scale: withSpring(isPressed.value ? 1.2 : 1) }, ], backgroundColor: isPressed.value ? 'yellow' : 'blue', }; }); const gesture = Gesture.Pan() .onBegin(() => { 'worklet'; isPressed.value = true; }) .onChange((e) => { 'worklet'; offset.value = { x: e.changeX + offset.value.x, y: e.changeY + offset.value.y, }; }) .onFinalize(() => { 'worklet'; isPressed.value = false; }); return ( ); } export default function Example() { const [counter, setCounter] = useState(0); return (