react-native-web
react-native-web copied to clipboard
infinite FlatList with inverted prop becomes crazy
The problem
When loading many items in a FlatList with the inverted prop, the list gets weird behaviours. The scroll moves on its own. It is also reverted whereas it shouldn't, and to top it all, some elements of the list gets inaccessible...
How to reproduce
Steps to reproduce:
- just go to the top of the list to load more messages.
- repeat the process a few time, and things should start to become weird.
Expected behavior
If you remove the inverted prop, you get the expected behaviour. inverted should just make the items of the list to be displayed from bottom to top and onEndReached to be called when reaching the top.
Environment (include versions). Did this work in previous versions?
- React Native for Web (version): 0.10.0
- React (version): 16.5.1
- Browser: Chrome 72.0.3626.109
verticallyInverted: {
transform: [{scaleY: -1}],
},
horizontallyInverted: {
transform: [{scaleX: -1}],
},
Ouch! I don't think that this is a great way to handle the inverted property!
Replacing flex-direction: column by flex-direction: column-reverse would probably do a much better job, no?
FlatList is a copy of what's in React Native
Then how come it behave so differently in the browser? Using this mirror trick is responsible for the scroll to go in the opposite way, which is very unnatural. Moreover, the onEndReach events firing become completely broken...
Ok, I think I can fix it. I'll make a PR.
This is the pending PR. I will try to fix this problem directly with RN team with this discussion.
Linking the related issue @Sharcoux created for Yoga https://github.com/facebook/yoga/issues/866
I had this issue - some very confusing behaviour with an inverted FlatList on web only. For anyone looking for a workaround disableVirtualization={true} seems to stop the weird behaviour for me, although it's obviously not an ideal solution.
@sdcooke disableVirtualization={true} works for me too. But it is deprecated and will not be on Expo either in the near future. What can we do next?
I solved this problem as follows https://github.com/necolas/react-native-web/issues/1579#issuecomment-683318144
Experienced something similar to this. The weird scrolling issue seemed to go away after using the getItemLayout prop or having fixed heights on all items. Unfortunately, we are trying to get variable height items to work with FlatList (they work well enough on native, but on web behave erratically after a certain length). One workaround is to cache the length + offset of each renderItem just once via onLayout and then reference this value again later.
I actually found a pretty neat workaround making "inverted lists" work nicely with RNW - even in a shared code environment along with RN.
The solution is to achieve the inverted style in a different way with the very same effect. I hope this helps some of you:
const isWeb = Platform.OS === 'web';
const listStyle: ViewStyle | undefined = isWeb
? { flexDirection: 'column-reverse' }
: undefined;
const contentContainerStyle: ViewStyle | undefined = isWeb
? { flexDirection: 'column-reverse' }
: undefined;
<SectionList
{...otherListProps}
inverted={!isWeb} // <-- do not invert to prevent transform: [{scaleY: -1}]
contentContainerStyle={contentContainerStyle} // <-- 'column-reverse' to make it scroll to the bottom
style={listStyle} // <-- 'column-reverse' to reverse you list array
/>
@mrsimply onEndReached is not called with this approach.
I ended doing this for now:
<SectionList
...
disableVirtualization={Platform.OS == "web"}
/>
Hey guys! I found the problems that cause this issue and also made PRs to fix them. Check them out and let me know what you think.
I encountered this issue in an Expo app. When I inspected the element(s) I saw that the list had 2 nested div elements with the same classes applied (i.e. <div classes> <div classes> {children} </div> </div>), so the individual list elements were being transformed (inverted) once but the list itself was being transformed twice and so still displayed top-to-bottom. I fixed by wrapping the list in a RN View with transform: [{ scaleY: -1 }]. Very hacky but it's working nicely.
Closing this old issue because VirtualizedList/FlatList will be developed exclusively out of the RN monorepo in the future. An open PR will be the last list-related change to be made to RNW, and should fix this. There may still be an issue in other code that's part of RNW, so feel free to create a new issue with latest info if needed.