Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Crash when doing scrollToLocation on SectionList

We have an edge case in our app. After the UI is rendered and the user tries to scroll to a section it throws scrolltoindex should be used in conjunction with getitemlayout or on scrolltoindex failed. Now this happens only when he does this immediately after UI render.

_scrollToSection = index => {
    setTimeout(() => {
        this.list.scrollToLocation({
            animated: true,
            itemIndex: -1,
            sectionIndex: index,
            viewPosition: 0
        });
    }, 150);
};

Section list render:

        <SectionList
            sections={this.props.sections}
            extraData={this.props.subscriber}
            ref={ref => {
                if (ref) {
                    this.list = ref;
                }
            }}
            automaticallyAdjustContentInsets={true}
            contentInsetAdjustmentBehavior={'automatic'}
            windowSize={100}
            ListHeaderComponent={this.props.header || null}
            ItemSeparatorComponent={() => (
                <Separator
                    style={[mediumStyle.separatorEnd, { backgroundColor: IOS_GREY_02_03 }]}
                />
            )}
            renderSectionFooter={() => <View style={{ height: 17 }} />}
            keyExtractor={(item, index) => index}
            removeClippedSubviews={false}
            stickySectionHeadersEnabled={true}
            renderSectionHeader={({ section }) => (
                <SectionTitle title={section.title} theme={this.props.theme} />
            )}
            renderItem={this._renderItem}
            onEndReachedThreshold={0}
            onEndReached={() => HapticFeedback.trigger()}
            scrollEventThrottle={16}
        />

I tried to google the cause but was unsuccessful finding only outdated and closed issues without a solution. Did this happen to anybody else? How did you fixed it?

UPDATE: We have come up on a solution of constant item sizes which also takes in count the accessibility scale factor. So we had an item and header size we could use in getItemLayout. All worked as should, but the SectionList is glitchy. When we scrolled to lower sections, the list was jumpy by itself without any interaction. So far the best solution we had was to build the section list ourselves in native code and use that instead of the RN list.

like image 688
parohy Avatar asked Jan 10 '19 13:01

parohy


1 Answers

You're getting this error because scrollToIndex has failed and you have not implemented getItemLayout or onScrollToIndexFailed


getItemLayout in a section list is not exactly fun to setup however this medium post goes over how to do it https://medium.com/@jsoendermann/sectionlist-and-getitemlayout-2293b0b916fb

They suggest react-native-section-list-get-item-layout to calculate the sizes of the layout https://github.com/jsoendermann/rn-section-list-get-item-layout


onScrollToIndexFailed is easier to setup you can add the prop onScrollToIndexFailed={(info) => { /* handle error here /*/ }} You can catch the error and then decide on how you will handle it here.


I would also add a check to make sure that your reference to this.list exists before calling the scrollToLocation function. Something like this.

_scrollToSection = index => {
    setTimeout(() => {
      if (this.list) {
        this.list.scrollToLocation({
            animated: true,
            itemIndex: -1,
            sectionIndex: index,
            viewPosition: 0
        });
      }
    }, 150);
};
like image 97
Andrew Avatar answered Nov 08 '22 07:11

Andrew