React native flatlist, slow to render from api call

Viewed 29

I am using FlatList to display articles and fetch more articles from the api when the user scrolls down. The api call takes longer than expected, can I cache old articles or speed up the fetch somehow?

api call:

const getNewsList = async (limit, offset, categories) => {
    const queryParams = {
        limit,
        offset,
    };
    queryParams.category = categories;
    try {
        const response = await anonymousGet(API_NEWS_LIST, queryParams);
        console.log(response)
        return response.payload;
    } catch (e) {
        logger.error('Error getting news list', e);
        throw e;
    }
};

Flastlist:

export const LatestNewsScreen = (props) => {
    const { navigation } = props;
    const initialNoOfItems = 5;
    const [state, setState] = useState({
        newsData: [],
        fuelData: undefined,
        limit: initialNoOfItems,
        offset: 0,
        loading: true,
        error: null,
        startLoadMore: false,
    });

    const {
        loading, offset, limit, newsData, startLoadMore,
    } = state;
    // logger.error(`>>>>>>>>>>>>>>>>>>>>: ${JSON.stringify(newsData, null, 4)}`);
    const fetchNews = () => {
        trackButtonClickEventAction(buttonClick.LATEST_NEWS);
        const fetch = async () => {
            try {
                const category = await getSelectedCategory();
                const newsItems = await getNewsList(limit, offset, category);
                // logger.error(`>>>>>>>>>>>>>>>>>>>>: ${JSON.stringify(newsItems, null, 4)}`);
                setState((prevState) => ({
                    ...prevState,
                    newsData: offset === 0 ? newsItems : mergeArrays(prevState.newsData, newsItems, 'id'),
                    loading: false,
                    startLoadMore: false,
                }));
            } catch (e) {
                setState((prevState) => ({
                    ...prevState,
                    offset: 0,
                    newsData: [],
                    loading: false,
                    startLoadMore: false,
                }));
                logger.error('Error fetching news', e);
            }
        };
        fetch();
    };

    useMountEffect(() => {
        trackScreen(screens.NEWS);
    });

    useEffect(() => {
        if (startLoadMore === true && loading === false) {
            fetchNews();
        }
    }, [startLoadMore]);

    useEffect(() => {
        if (loading === true && startLoadMore === false) {
            fetchNews();
        }
    }, [loading]);

    useFocusEffect(
        useCallback(() => {
            setState((prevState) => ({
                ...prevState,
                newsData: [],
                offset: 0,
                loading: true,
            }));
          }, []),
    );

    useEffect(() => {
        const unsubscribeTabPress = navigation.addListener('tabPress', () => {
            trackButtonClickEventAction(buttonClick.NEWS_LATEST_NEWS);
        });
        return [unsubscribeTabPress].forEach((unsub) => unsub());
      }, [navigation]);

    const handleLoadMore = () => {
        if (!loading) {
            setState((prevState) => ({
                ...prevState,
                offset: prevState.offset + 5,
                startLoadMore: true,
            }));
        }
    };

    const onRefresh = () => {
        setState((prevState) => ({
            ...prevState,
            newsData: [],
            offset: 0,
            loading: true,
        }));
    };

    const renderFooter = () => {
        if (!loading && !startLoadMore) return null;

        return (
            <View
                style={styles.footer}
            >
                <ActivityIndicator animating size="large" color={colors.GREYONE} />
            </View>
        );
    };
const headerComponent = useCallback(
    () => {
    return (
        <Text>hello</Text>
    );
}, [],
);
    return (
        loading ? (
            <RACSpinner />
        ) : (
                <View style={styles.flatListParentView}>
                    <FlatList
                        refreshControl={(
                            <RefreshControl
                                refreshing={loading}
                                onRefresh={onRefresh}
                            />
                        )}
                        ListHeaderComponent={headerComponent}
                        ListHeaderComponentStyle={styles.listHeader}
                        refreshing={loading}
                        contentContainerStyle={styles.flatListContainerStyle}
                        numColumns={1}
                        data={newsData}
                        renderItem={
                            ({ item }) => (
                                <View
                                    style={styles.renderItemView}
                                >
                                    <NewsListItem item={item} />
                                </View>
                            )
                        }
                        keyExtractor={(item) => item.id.toString()}
                        ListFooterComponent={renderFooter}
                        onEndReached={handleLoadMore}
                        onEndReachedThreshold={(Platform.OS === 'android' ? 1 : 1)}
                        initialNumToRender={initialNoOfItems}
                    />
                </View>
            )
    );
};
0 Answers
Related