FlatList
andScrollView
's limitations- React Native version
- Android performance
- Unreliable callbacks
- Unreliable first item
- Error with Jest
- RTL support (experimental)
- Carousel is not visible until you start swiping
Note that this plugin is built on top of React Native's FlatList
which, in turn, is based on VirtualizedList
and ScrollView
. Unfortunately, their implementations have flaws that affect the plugin, the most problematic ones being the following:
- there is no
scrollEnd
event scrollTo
method doesn't accept any callback- Android's
scrollTo
animation is quite brutal - it is not possible to specify a scroll duration
- there are rendering and performance issues with the
FlatList
component.
On top of that, FlatList
has its own set of bugs and buggy behaviors.
We're trying to work around these issues, but the result is not always as smooth as we'd want it to be. You can help by letting the React Native team know how badly we need those features! React Native has a dedicated canny for feature requests; here are the ones that need your vote the most:
- [ScrollView] Add completion callback to scrollTo
- snapToInterval for Android
- Add speed attribute to scrollTo
- Bring ios only methods to Android ScrollView
- ScrollView Animation Events (e.g. onScrollAnimationEnd)
Remember that every vote counts and take a look at #203 for more info!
>= 3.0.0
since it was the first version to introduce the FlatList
component. Since version 3.5.0
, the component will fall back to rendering a ScrollView
if you're using an older version of React Native (mirroring the effect of setting prop useScrollView
to true
). But keep in mind that the ScrollView
component is not suited to render a huge number of items. If you experience performance issues, consider updating your React Native version and using the default FlatList
version.
Bear in mind that we follow RN evolutions closely, which means newer versions of the plugin might break when used in conjunction with a version of RN that is not the latest stable one.
It can take user experience from "crappy and sluggish" to "pretty good" - it's Android though, so nothing like "perfect" or "incredibly smooth"...
Also, make sure to implement all the recommendations listed here.
When enableMomentum
is disabled (default behavior), providing a reliable callback is really tricky since no scrollEnd
event has been exposed yet for the ScrollView
component. We can only rely on the scrollEndDrag
event, which comes with a huge bunch of issues. See #34 for more information.
Version 2.3.0 tackled these issues with all sorts of flags and hacks. But you could still be facing the following one: when you build a debug version of your app without enabling JS remote debugging, timers may desynchronize and cause a complete callback mess. Try to either enable remote debugging or build a production version of your app, and everything should get back to normal.
Callback handling has been completely revamped in version 3.2.0, in a less hacky and more reliable way. There is one issue though: callbacks now rely on scroll events. Usually, this is not a problem since the plugin features a native-powered scroll. But there has been a regression in React Native 0.46.x, that has been fixed in version 0.48.2.
If you're using an in-between version, you're in for some trouble since events won't be fired frequently enough (particularly on Android). We've added a prop callbackOffsetMargin
to help with this situation.
By design, the FlatList
component only renders a small chunk if items initially.
This means you may need to rely on inherited props getItemLayout
& initialScrollIndex
to get the firstItem
prop to work properly (usable from version 3.8.3
on).
You might encounter the following error when using the plugin in conjonction with Jest: TypeError: Cannot read property 'style' of undefined at Object.<anonymous>
.
As you can see here, this is because React Native mocks ScrollView
for you when you write unit tests with Jest.
The easiest workaround is to add jest.unmock('ScrollView')
before importing the component in your test file (thanks @hoangnm for the tip!).
Since version 2.1.0, the plugin is compatible with RTL layouts. Our implementation relies on miscellaneous hacks that work around a React Native bug with horizontal ScrollView
. As such, this feature should be considered experimental since it might break with newer versions of React Native.
Note that you may want to reverse the order of your data array for your items to be displayed in the proper RTL order. We've tried implementing it internally, but this led to numerous and unnecessary issues. You'll just have to do something as simple as myCustomData.reverse()
.
There's a known issue where the Carousel will not be visible on the screen and will only show up after you start swiping. This issue has been reported a few times and is caused by a known React Native bug in the FlatList component.
It may be solved using one these three possible workarounds:
- Adding removeClippedSubviews={false} to the Carousel element: Note that this will disable all optimizations from the FlatList Component.
- Adding useScrollView to the Carousel element: Similar solution to the one provided above. Replaces FlatList component with ScrollView, only recommended for small sets of data.
- As of version 3.5.0, you may use the triggerRenderingHack() method: This hacky solution was specifically implemented for this bug, allowing you to keep the FlatList component). [Note: This is recommended if you need the performance optimizations that FlatList provides).