PagerView renders all the pages and not considering the value provided to offscreenPageLimit
Environment
node v18.19.1 react v18.2.0 react-native v0.73.4 react-native-pager-view v^6.3.0
Description
I use PagerView to achieve ViewPager equivalent in Android. Even after I provide value to the prop offscreenPageLimit all the pages are getting rendered on UI. This makes multiple API calls from all the screens, which makes the application to use more memory as I do manage files by downloading them and also make the application slow. In Android PagerView is dead slow, where it takes at least 5 to 10 seconds to respond. Due to confidentiality I won't be able to share the screenshots or screen recordings. But I would be able to share the similar code to reproduce this bug.
Reproducible Demo
Code used:
<PagerView
ref={pagerViewRef}
initialPage={currentPosition}
useNext={false}
style={styles.pagerContainer}
offscreenPageLimit={1}
keyboardDismissMode={'on-drag'}
onPageSelected={(e) => {
const position = e.nativeEvent.position;
setCurrentPosition(position);
}}
>
{filteredList.map((model, key) => (
<View key={key}>
{renderTabScreen(model)}
</View>
))}
</PagerView>
In code you may replace the following as per your wish, renderTabScreen(mode) returns a JSX element. The main idea is that number of pages that's initially loaded into memory to display should be equal to the value provided to the offscreenPageLimit prop, but on observing all the n-pages are getting rendered.
Please provide a repro repository
Same issue here i am using AnimatedPagerView and it seems its rendering all the pages despite using offscreenPageLimit={1}
package version :- "react-native-pager-view": "^6.7.0"
here is the bare minimum code which shows all screens are beeing rendered it simply uses useLayoutEffect and shows a Alert on each page.
import React, { useLayoutEffect, useMemo } from 'react';
import { Alert, Text, View } from 'react-native'
import { usePagerView } from 'react-native-pager-view';
const Fragment1 = () => {
return <View style={{ flex: 1, backgroundColor: 'red' }}></View>
}
const Fragment2 = () => {
useLayoutEffect(() => {
Alert.alert('This is not suppose to popup untill i reach fragment 2')
}, [])
return <View style={{ flex: 1, backgroundColor: 'green' }}></View>
}
const Fragment3 = () => {
useLayoutEffect(() => {
Alert.alert('This is not suppose to popup untill i reach fragment 3')
}, [])
return <View style={{ flex: 1, backgroundColor: 'blue' }}></View>
}
const Fragment4 = () => {
useLayoutEffect(() => {
Alert.alert('This is not suppose to popup untill i reach fragment 4')
}, [])
return <View style={{ flex: 1, backgroundColor: 'black' }}></View>
}
export default function Test2Screen() {
const { AnimatedPagerView, ref, ...rest } = usePagerView({ pagesAmount: 4 });
const pages = useMemo(
() =>
rest.pages.map((_, index) => {
switch (index) {
case 0:
return <Fragment1 key={'f_' + index} />
case 1:
return <Fragment2 key={'f_' + index} />
case 2:
return <Fragment3 key={'f_' + index} />
case 3:
return <Fragment4 key={'f_' + index} />
default:
return <View></View>;
}
}),
[rest.pages]
);
return <AnimatedPagerView
ref={ref}
style={{ flex: 1 }}
initialPage={0}
layoutDirection="ltr"
overdrag={rest.overdragEnabled}
scrollEnabled={rest.scrollEnabled}
offscreenPageLimit={1}
orientation="horizontal"
>
{pages}
</AnimatedPagerView>
}
Same issue.
import React, { useLayoutEffect, useMemo } from 'react';
import { Alert, Text, View } from 'react-native'
import { usePagerView } from 'react-native-pager-view';
const Fragment1 = () => {
return <View style={{ flex: 1, backgroundColor: 'red' }}></View>
}
const Fragment2 = () => {
useLayoutEffect(() => {
Alert.alert('This is not suppose to popup untill i reach fragment 2')
}, [])
return <View style={{ flex: 1, backgroundColor: 'green' }}></View>
}
const Fragment3 = () => {
useLayoutEffect(() => {
Alert.alert('This is not suppose to popup untill i reach fragment 3')
}, [])
return <View style={{ flex: 1, backgroundColor: 'blue' }}></View>
}
const Fragment4 = () => {
useLayoutEffect(() => {
Alert.alert('This is not suppose to popup untill i reach fragment 4')
}, [])
return <View style={{ flex: 1, backgroundColor: 'black' }}></View>
}
export default function Test2Screen() {
const { AnimatedPagerView, ref, ...rest } = usePagerView({ pagesAmount: 4 });
const pages = useMemo(
() =>
rest.pages.map((_, index) => {
switch (index) {
case 0:
return <Fragment1 key={'f_' + index} />
case 1:
return <Fragment2 key={'f_' + index} />
case 2:
return <Fragment3 key={'f_' + index} />
case 3:
return <Fragment4 key={'f_' + index} />
default:
return <View></View>;
}
}),
[rest.pages]
);
return <AnimatedPagerView
ref={ref}
style={{ flex: 1 }}
initialPage={0}
layoutDirection="ltr"
overdrag={rest.overdragEnabled}
scrollEnabled={rest.scrollEnabled}
offscreenPageLimit={1}
orientation="horizontal"
>
{pages}
</AnimatedPagerView>
}
@MrRefactor please take a look
Any update on this ?