☂️ Pager View Improvements
Intro
It is been a while since I am maintaining the react-native-pager-view. Previously it was part of the RN core, but then it has been extracted into a separate package. It has used 2 versions of ViewPager (v1, v2) and UIPageView. I tried to fix all issues, but some of them required some workarounds that were not stable enough. Those workarounds created other issues, hence other workarounds were used to fix that. To be honest, I was a little bit exhausted from it, hence together with @krozniata and @okwasniewski decided to build those components from the scratch
Next branch
@alpha0010 did a great job by implementing the LazyViewPager component. We released his changes into the next branch and we had the plan to merge it into the main branch. But we did some internal tests on real applications and in some cases, it did not work well. Internally we used another workaround to achieve the lazy effect. Moreover, we did not want to add additional complexity, when it did not bring more benefits and would add additional bugs to fix. With new architecture implementing a lazy approach should be much easier. Unfortunately, we won’t merge the next branch into the main. We will implement a lazy approach using a new architecture. If you would like to maintain LazyViewPager, feel free to make a fork
New architecture support
Meta has released a new architecture called fabric. In this library, we would like to focus first on the new architecture. After that, we will evaluate, if it would be worth migrating a new solution to the old arch (Right now it is hard to estimate it based on a priori knowledge)
Motivation
We would like to have more control over native components to easily fix issues or add new features. Right now, those components are black boxes, which are hard to maintain. Moreover, UIPageViewController is not maintained anymore and is not used in the iOS world. Unfortunately, we cannot use UICollectionView, because it does not work well in the RN world.
The same thing refers RecyclerView component for Android. The currently used ViewPager2 component on Android brought more issues than benefits since it uses the earlier-mentioned RecyclerView.
Here you can see a draft implementation on an iOS platform: https://github.com/callstack/react-native-pager-view/pull/672
What's the recommended way to implement lazy loading screens with the latest releases? I can't find any documentation, yet you mention that it's easier now? LazyPagerView was working great for us.
@troZee Hello, thanks! What's the complexity with UICollectionView? Is it the fact that reactSubviews expose subviews of view, but there's no such equivalent of cells for a UICollectionView?
Also, side question - is React Native's FlatList implemented with plain UIScrollView, not UICollectionView?
Thanks.
What's the recommended way to implement lazy loading screens with the latest releases? I can't find any documentation, yet you mention that it's easier now? LazyPagerView was working great for us.
Same, do you have an update on this?
What's the recommended way to implement lazy loading screens with the latest releases? I can't find any documentation, yet you mention that it's easier now? LazyPagerView was working great for us.
Same, do you have an update on this?
We switched to just using the default import PagerView from "react-native-pager-view"; and implementing a simple lazy load logic in the sub view:
// Using pager
<PagerView
onPageSelected={onPageSelected}
>
{things.map((thing, index) => (
<LazyLoadView
key={thing.id}
item={thing}
index={index}
currentIndex={currentNavigation.currentIndex}
/>
))}
</PagerView>
// LazyLoadView
const LazyLoadView = ({ item, currentIndex, index }) => {
const isActive = indexIsActive(currentIndex, index);
if (!isActive) {
return <View key={item.id}></View>
}
// Expensive render full
return // ...
}
export function indexIsActive(currentIndex, myIndex) {
return currentIndex == myIndex ||
currentIndex-1 == myIndex ||
currentIndex+1 == myIndex;
}
So far the performance is equal.
@erkie what is
currentIndex={currentNavigation.currentIndex}
@mweel1 it's just a memoised object that I can pass around with details about the navigation state:
const currentNavigation = useMemo(() => {
return {
currentIndex,
totalLength: posts.length
}
}, [currentIndex, posts.length]);
You can of course just use a currentIndex variable instead.
Is this going to be a part of the improvements? https://github.com/callstack/react-native-pager-view/issues/321
How does it relate to #173? We received an email from Google Play yesterday stating that the number of crashes on one of the devices is too high, which may result in limited visibility of our app in the store.
{things.map((thing, index) => ( <LazyLoadView key={thing.id} item={thing} index={index} currentIndex={currentNavigation.currentIndex} /> ))}
Could you please share the OnpageSelected Function and how did you calculated the curetindex and in my useCase i dont want to render all the screens since it has api calls involved and could you share the detailed code example with example screns integrated so it would be helpfull
I noticed that react-native-tab-view has a lazy prop. https://reactnavigation.org/docs/tab-view/#use-lazy-and-renderlazyplaceholder-props-to-render-routes-as-needed
but I think it would be nice if PagerView can do this automatically.
Moreover, UIPageViewController is not maintained anymore and is not used in the iOS world.
As an iOS developer in the iOS world, I don't understand this. What do you mean it is not maintained? Looking at Apple's documentation it is not marked as deprecated. Moving away from UIPageViewController will lose the built-in lazy loading and built in page indicators.