Skip to content
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

Make animated components use different tags for events #5960

Merged
merged 2 commits into from May 8, 2024

Conversation

szydlovsky
Copy link
Contributor

@szydlovsky szydlovsky commented Apr 30, 2024

Summary

Turns out the usual component tag (used for Layout Animations, Shared Element Transitions and Animated Styles) won't always work for events if the component with nested event emitters is made animated. Thus I am splitting these two into different tag variables.

Test plan

You can check out the following code (logs in console):

Code
import React from 'react';
import Animated, { useAnimatedScrollHandler } from 'react-native-reanimated';
import { StyleSheet, View, Text } from 'react-native';
import { FlashList } from '@shopify/flash-list';

const AnimatedFlashList = Animated.createAnimatedComponent(FlashList);

const data = new Array(45);

export default function EmptyApp() {
  const scrollHandler = useAnimatedScrollHandler(
    {
      onBeginDrag: () => {
        'worklet';
        console.log('ON BEGIN DRAG');
      },
      onScroll: () => {
        'worklet';
        console.log('ON SCROLL');
      },
      onMomentumEnd: () => {
        'worklet';
        console.log('ON END');
      },
    },
    []
  );

  const renderFlashListItem = () => {
    return <View style={styles.itemFlash} />;
  };

  const renderFlatListItem = () => {
    return <View style={styles.itemFlat} />;
  };

  return (
    <View style={styles.container}>
      <View style={styles.listContainer}>
        <Text>Animated FlashList</Text>
        <AnimatedFlashList
          onScroll={scrollHandler}
          renderItem={renderFlashListItem}
          data={data}
          estimatedItemSize={40}
        />
      </View>
      <View style={styles.listContainer}>
        <Text>Animated FlatList</Text>
        <Animated.FlatList
          onScroll={scrollHandler}
          renderItem={renderFlatListItem}
          data={data}
        />
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'row',
  },
  listContainer: {
    flex: 1,
    flexDirection: 'column',
  },
  itemFlash: {
    width: 20,
    height: 20,
    backgroundColor: 'red',
    margin: 10,
  },
  itemFlat: {
    width: 20,
    height: 20,
    backgroundColor: 'green',
    margin: 10,
  },
});

Current tests work on:

  • Paper
  • Fabric
  • Web

@szydlovsky szydlovsky changed the title Make animated components use different tag for events Make animated components use different tags for events Apr 30, 2024
@efstathiosntonas efstathiosntonas mentioned this pull request May 1, 2024
@gronxb
Copy link

gronxb commented May 3, 2024

I haven't checked detail, but gorhom/react-native-bottom-sheet was behaving strangely after applying that patch.

@szydlovsky
Copy link
Contributor Author

@gronxb if you were able to provide a small example where the react-native-bottom-sheet behaves strangely I’d be able to check it out and make sure it works as well

@gronxb
Copy link

gronxb commented May 3, 2024

I've been busy and haven't prepared a repro, I'll do it as soon as I can.

When calling Pressable onPress from within the bottom sheet, the bottom sheet is forced down.

@szydlovsky
Copy link
Contributor Author

@gronxb I'm sorry to bother you but we are about to go through with reviewing this PR - do you maybe have time to provide the example of gorhom/react-native-bottom-sheet working strangely with this patch?

Copy link
Contributor

@tjzel tjzel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While it's fine for me that we might have two tags, first for events and the second for other operations, I think that we should focus on the "why" here.

  1. How comes that we actually need two different tags? Do all operations that require _componentViewTag work properly when _eventViewTag is correct? Or is it a "switch-like" situation?

  2. Why didn't we need it before? Which change exactly forces us to make the split here? Or maybe it was always like this and only now we have detected it?

  3. What about useScrollViewOffset here? Is it always able to get the tag it actually requires?

We definitely need to try to answer those questions.

@gronxb
Copy link

gronxb commented May 6, 2024

@szydlovsky

Sorry for the delay, here's the reproduction, I think it's the backdrop, if you press anywhere on the bottom sheet, it forces it to go down.

If I don't apply that patch, it only goes down normally when I press backdrop.

It seems like something conflicts and thinks backdrop is pressed even if you press anywhere.

https://github.com/gronxb/reanimated-repro/blob/main/App.tsx

  • Apply Patch
2024-05-07.12.02.04.mov
  • No Patch
2024-05-07.12.09.12.mov

@szydlovsky
Copy link
Contributor Author

@tjzel I think all of the questions have answers:

  1. How comes that we actually need two different tags? Do all operations that require _componentViewTag work properly when _eventViewTag is correct? Or is it a "switch-like" situation?

The _componentViewTag is the tag of the top-level component, used in all SET's, animated styles and animated props. The _eventViewTag is a tag of the event-emitting component, sometimes is the top-level one, sometimes might be nested or might even not exist (and it won't affect the other tag). We need it for all event handlers. So there are separate scenarios for each.

  1. Why didn't we need it before? Which change exactly forces us to make the split here? Or maybe it was always like this and only now we have detected it?

We had it before, but the implementation wasn't well readable and clear. It worked and then was removed in WorkletEventHandler revamp under the assumption that is was redundant. What I'm doing here is reverting it and making it readable so that anyone that stumbles upon it in the future will know why it is this way.

  1. What about useScrollViewOffset here? Is it always able to get the tag it actually requires?

Yeah, native implementation needs some changes in this regard. Thanks for pointing that out, I will add it to this PR.

@szydlovsky
Copy link
Contributor Author

@gronxb alright I found the issue, could you please try out this patch -
react-native-reanimated+3.11.0.patch

@gronxb
Copy link

gronxb commented May 7, 2024

@szydlovsky it works fine 👍

@szydlovsky
Copy link
Contributor Author

@tjzel @gorhom/bottom-sheets now works fine with the fix AND turns out useScrollViewOffset gets its tags very well for all scenarios (Web/Paper/Fabric) - it didn't need any changes. Therefore it is now reviewable again

@tjzel
Copy link
Contributor

tjzel commented May 8, 2024

@szydlovsky I assume you tested it natively on iOS only? Android can have a different view hierarchy, please check it too.

Is this PR something that could be verified by runtime tests?

@szydlovsky
Copy link
Contributor Author

@tjzel I tested it on all: iOS and Android (both Paper and Fabric) and Web. Works fine everywhere. If it comes to runtime tests, we would have to use flash-list and botom-sheets as dependencies so I am not so sure - taking under consideration that this fix is quite highly demanded.

@tjzel
Copy link
Contributor

tjzel commented May 8, 2024

Oh, that's great then! We can list those as dev dependencies, that's not a problem, but let's not incorporate 3rd party libraries into our runtime tests yet. I will add it as a potential task for the future.

Copy link
Contributor

@tjzel tjzel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, but I'd like @piaskowyk or @tomekzaw to take a look at it as well.

@szydlovsky szydlovsky added this pull request to the merge queue May 8, 2024
Merged via the queue into main with commit deb7825 May 8, 2024
8 checks passed
@szydlovsky szydlovsky deleted the @szydlovsky/rework-animatedComponent-tags branch May 8, 2024 14:53
@ChadyAyoub4
Copy link

@szydlovsky Works perfectly.

@sraut1
Copy link

sraut1 commented May 21, 2024

@szydlovsky I am facing this issue #4730.
should this patch fix this one too? is this patch part of 3.11.0 release?

@szydlovsky
Copy link
Contributor Author

@sraut1 This patch will be in the next release after 3.11. And no, this one most likely doesn't fix the issue since it has nothing to do with animated styles. Nevertheless, feel free to use the patch, maybe it sorts something out.

@sraut1
Copy link

sraut1 commented May 21, 2024

@szydlovsky the patch fixes issue #4730. thanks

@szydlovsky
Copy link
Contributor Author

@sraut1 woah, I'll let the ppl know then 🤯

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[3.9.0] useAnimatedScrollHandler does not fire events from FlashList onScroll
6 participants