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

Layout Transitions does not work with custom list (FlashList) #6278

Closed
Bayramito opened this issue Jul 16, 2024 · 4 comments
Closed

Layout Transitions does not work with custom list (FlashList) #6278

Bayramito opened this issue Jul 16, 2024 · 4 comments
Labels
Platform: Android This issue is specific to Android Platform: iOS This issue is specific to iOS Repro provided A reproduction with a snippet of code, snack or repo is provided

Comments

@Bayramito
Copy link
Contributor

Bayramito commented Jul 16, 2024

Description

Layout transitions does not work at all with custom list component that you created via Animated.createAnimatedComponent like FlashList.

It works with Animated.FlatList but has some limitations like if you use numOfColumns, does not work again.

AnimatedFlashList example (NOT WORKING)
https://github.com/user-attachments/assets/6637373e-caf0-4f46-b465-02d269be951a

Animated.FlatList with numOfColumns (NOT WORKING)
https://github.com/user-attachments/assets/3fde8556-6a60-4143-8b9a-9e2f4525553c

Animated.FlatList regular (WORKING)
https://github.com/user-attachments/assets/48d41cde-78a8-4d29-9998-47ead828ff26

Steps to reproduce

  1. Boxes are clickable, once you click one of them, its being removed from the list
  2. Try with AnimatedFlashList component in reproducable
  3. Try with Animated.FlatList by passing numOfColumns

Snack or a link to a repository

https://github.com/Bayramito/reproducables

Reanimated version

4.14.0

React Native version

0.74.3

Platforms

Android, iOS

JavaScript runtime

Hermes

Workflow

React Native

Architecture

Fabric (New Architecture)

Build type

Debug app & dev bundle

Device

iOS simulator

Device model

No response

Acknowledgements

Yes

@github-actions github-actions bot added Repro provided A reproduction with a snippet of code, snack or repo is provided Platform: Android This issue is specific to Android Platform: iOS This issue is specific to iOS labels Jul 16, 2024
@MatiPl01
Copy link
Member

Hey! Thank you for the detailed issue description. I was able to reproduce the issue and I was looking for the solution to the problem, but it might be impossible to implement.

FlashList uses custom CellRenderer native component, which is used as a wrapper for item components rendered in the list. It doesn't support layout animations, thus, list items cannot be animated using layout animations.

When it comes to the Animated.FlatList, there is a difference in how react native renders list items when numColumns is greater than 1. For a single-column list, every list item is rendered within a CellRendererComponent, which can be customized by passing the CellRendererComponent component implementation as a property of the FlatList. This is what Animated.Flatlist does under the hood, it just passes creates a custom CellRendererComponent with the specified layout animation.
For a mutli-column FlatList, react-native adds another wrapper for the whole row of items and wraps this row within CellRendererComponent instead of wrapping all list items. In such a case, layout animations don't work because list items are rendered within different parent (row) components when list items are added/removed. Because the parent changes, layout animation does not work.

tl;dr

FlatList layout animations work only with single-column lists.

We would have to add this remark to the docstring of the itemLayoutAnimation property.

@Bayramito
Copy link
Contributor Author

Hey! Thank you for the detailed issue description. I was able to reproduce the issue and I was looking for the solution to the problem, but it might be impossible to implement.

FlashList uses custom CellRenderer native component, which is used as a wrapper for item components rendered in the list. It doesn't support layout animations, thus, list items cannot be animated using layout animations.

When it comes to the Animated.FlatList, there is a difference in how react native renders list items when numColumns is greater than 1. For a single-column list, every list item is rendered within a CellRendererComponent, which can be customized by passing the CellRendererComponent component implementation as a property of the FlatList. This is what Animated.Flatlist does under the hood, it just passes creates a custom CellRendererComponent with the specified layout animation. For a mutli-column FlatList, react-native adds another wrapper for the whole row of items and wraps this row within CellRendererComponent instead of wrapping all list items. In such a case, layout animations don't work because list items are rendered within different parent (row) components when list items are added/removed. Because the parent changes, layout animation does not work.

tl;dr

FlatList layout animations work only with single-column lists.

We would have to add this remark to the docstring of the itemLayoutAnimation property.

Thank you for the detailed information. It is npw clear why cannot be possible.
numOfColumns issue is not that important for my case tho, since i can replicate the columns by using flexWrap

github-merge-queue bot pushed a commit that referenced this issue Jul 23, 2024
## Summary

This PR adds example usage of `itemLayoutAnimation` prop to the example
app and docs page with example recording and details.

## Example image of the added docs page

![Screenshot 2024-07-22 at 15 46
23](https://github.com/user-attachments/assets/bcb5667c-afb5-45b9-9c25-114f7b06e0c0)

## Related context

Related issue: #6278

Support for `multi-column` lists seems to be impossible to implement.
react-native adds additional wrapper component for each row and
re-renders list items in different rows when new items are added or
items are removed from the list. Because the parent of list items
changes and the layout animation cannot be applied to the wrapper that
is added to list rows, layout animations won't work for lists with
multiple columns.

At least, I didn't come up with any valid solution.

PR that adds support for `FlatList` items animations: #2674
What react-native does for mutli-column lists:
https://github.com/facebook/react-native/blob/2098806c2207f376027184329a7285913ef8d090/packages/react-native/Libraries/Lists/FlatList.js#L643

---------

Co-authored-by: Tomasz Żelawski <40713406+tjzel@users.noreply.github.com>
@JustJoostNL
Copy link

Is there a workaround for using FlashList with react-native-reanimated , and then specifically layout transitions?

@MatiPl01
Copy link
Member

Is there a workaround for using FlashList with react-native-reanimated , and then specifically layout transitions?

Rather not. I looked for quite a while on the source code of the @shopify/flash-list and recyclerlistview, which is internally used by the @shopify/flash-list library. I tried replacing all wrapper View components that they add for list items with Animated.View components with the layout transition but it didn't help.

I might be wrong but I think that the main problem is that flash list re-renders components within different parent container when the order of items changes, so the layout of list items is not re-calculated.

You can try yourself to look at the source code of the @shopify/flash-list library and see if you can come up with a solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Platform: Android This issue is specific to Android Platform: iOS This issue is specific to iOS Repro provided A reproduction with a snippet of code, snack or repo is provided
Projects
None yet
Development

No branches or pull requests

3 participants