react-native-pager-view icon indicating copy to clipboard operation
react-native-pager-view copied to clipboard

PagerView renders all the pages and not considering the value provided to offscreenPageLimit

Open kavinraju opened this issue 1 year ago • 5 comments

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.

kavinraju avatar Sep 19 '24 10:09 kavinraju

Please provide a repro repository

MrRefactor avatar Nov 27 '24 17:11 MrRefactor

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>
}



Kaizodo avatar Feb 19 '25 11:02 Kaizodo

Same issue.

joaqo avatar Feb 25 '25 23:02 joaqo

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

Kaizodo avatar Mar 05 '25 09:03 Kaizodo

Any update on this ?

Kaizodo avatar Mar 17 '25 13:03 Kaizodo