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