Search code examples
react-nativereact-native-sectionlist

scrollToLocation from sectionlist in ios is not working. On Android the list scrolls back to index 0 but the same doesn't happen on ios


I'm using a SectionList to render a list of sections and below is the code snippet. I have tested on Android and the list is scrolling back to index 0 when the section is changed but it doesn't happen on ios.

export const ListSymbol = ({
    region = '',
    currency = '',
    rate = '',
    channel = {},
    sections = [],
    loading = false,
    fetchData=null,
    renderItem: renderItemOptional = null,
    renderSectionHeader: renderSectionHeaderOptional = null
}) => {
    const [sectionsExpanded, setSectionsExpanded] = useState([])
    const [itemsGraphShow, setItemsGraphShow] = useState([])
    const sectionListRef = useRef()

    useEffect(() => {
        setSectionsExpanded([]);
        setItemsGraphShow([]);
        if (!isEmpty(sections)) {
             scrollToSection();
        }
    }, [sections])

    const keyExtractor = (item, index) => `list symbol - ${channel?.channelName} ${item?.symbol} ${item?.groupTitle} ${item?.unitCode} ${item?.unitName} ${index}`
    const renderSectionHeader = () => null

    const scrollToSection = () => {
        console.log("@@@@ scrollToSection", sectionListRef);
        sectionListRef.current?.scrollToLocation({
            animated: true,
            sectionIndex: 0,
            itemIndex: 0,
            // viewPosition: 0,
            // viewOffset: 0
        });
    };
    
    const scrollToIndexFailed = info => {
        const wait = new Promise(resolve => setTimeout(resolve, 500));
        wait.then(() => {
            sectionListRef.current?.scrollToIndex({ index: info?.index, animated: true });
        });
    }

    const renderItem = ({ item = {}, index = 0, section = [] }) => {
        return (
            <SymbolItem
                {...{
                    region,
                    currency,
                    rate,
                    item,
                    index,
                    section,
                    sectionsExpanded,
                    setSectionsExpanded,
                    itemsGraphShow,
                    setItemsGraphShow
                }}
            />
        )
    }

    return (
        <SectionList
            ref={sectionListRef}
            onScrollToIndexFailed={scrollToIndexFailed}
            refreshing={loading}
            onRefresh={fetchData}
            nestedScrollEnabled
            sections={sections}
            keyExtractor={keyExtractor}
            renderItem={renderItemOptional || renderItem}
            renderSectionHeader={renderSectionHeaderOptional || renderSectionHeader}
            showsVerticalScrollIndicator={false}
        />
    )
}

I've tried multiple solutions like using initialNumToRenderwhich has that initial position in it and getItemLayout but it wasn't helpful.


Solution

  • Got a work around for this issue. Had to add a delay before calling the scrollToLocation.

    const wait = new Promise(resolve => setTimeout(resolve, 500));
    wait.then(() => {
            sectionListRef.current?.scrollToLocation({
                y: 0,
                animated: true,
                sectionIndex: 0,
                itemIndex: 0,
                viewPosition: 0
            })
        });