How do I show an activity indicator every time my flatlist data changes?
Asked Answered
R

2

7

I'm setting the data that my flatlist component displays using a state called selectedStream. selectedStream changes every time the user presses a different group option. I've noticed that the flatlist takes 1-3 seconds to refresh all the posts that it's currently displaying already. I want there to be a loading indicator so that by the time the indicator goes away, the list is already properly displayed with the newly updated data.

        <FlatList   
                    maxToRenderPerBatch={5}
                    bounces={false}
                    windowSize={5}
                    ref={feedRef}   
                    data={selectedStream}/> 
Reconsider answered 28/11, 2021 at 6:9 Comment(0)
P
8

Whenever we are working with anything related to the UI, sometimes we may face delays in UI re-rendering. However, we need to first figure out what is actually causing the delay.

The right question to ask about your code would be:

Is the rendering of items taking longer than expected ? Or, is the data being passed with a delay because it is dependant on an API call or any other async task ?

Once you answer that question, you may end up with two scenarios:

1. FlatList taking longer to render views

This doesn't usually happen as the RN FlatList will only render views that are visible to the user at any given time and will keep rendering new views as the user scrolls through the list. However, there may be some flickering issues for which you can refer to the below article:

8 Ways to optimise your RN FlatList

2. Passing the data causes the delay

This is the most common scenario, where we may call an API endpoint and get some data and then do setState to update any view/list accordingly. A general approach is to show some sort of a progress-bar that would indicate that the application is busy and thus maintaining a proper user-experience. The easiest way to do that is by conditional rendering.

A general example would be:

const [myList, setMyList] = useState();

function callAPIforMyList(){
// logic goes here
}

return {
  {myList ? <ActivityIndicator .../> : <Flatlist .... />
}

The above code will check if myList is undefined or has a value. If undefined, it will render the ActivityIndicator or else the FlatList.

Another scenario could be when myList may have existing data but you need to update/replace it with new data. This way the above check may fail, so we can put another check:

const [myList, setMyList] = useState();
const [isAPIbusy, setAPIBusy] = useState(false)

function callAPIformyList() {
  setAPIBusy(true)
  /// other logics or async calls or redux-dispatch
  
  setAPIBusy(false)
}

return {
  {!isAPIBusy && myList ? (<Flatlist .... />) : (<ActivityIndicator .../>)

 }

You can add multiple conditions using more ternaries such as isAPIBusy ? <View1> : otherBoolean ? <View2> : <Default_View_When_No_Conditions_Match)/>

Hope this helps clarify your needs.

Protomorphic answered 28/11, 2021 at 7:21 Comment(0)
W
11

Try to use ListEmptyComponent. So I assume you have an initial state of {data: {}, loading: false, error: false, success: false}

 <FlatList
 ListEmptyComponent={
   loading ? 
   <ActivityIndicator animating={true} color={colors.blue} />
   :
   <View style={styles.empty}>
      <Text>0 results</Text>
   </View>
 }
 />

Every time you make a request to change the data, make sure to set loading: true

Wetterhorn answered 22/10, 2023 at 10:42 Comment(0)
P
8

Whenever we are working with anything related to the UI, sometimes we may face delays in UI re-rendering. However, we need to first figure out what is actually causing the delay.

The right question to ask about your code would be:

Is the rendering of items taking longer than expected ? Or, is the data being passed with a delay because it is dependant on an API call or any other async task ?

Once you answer that question, you may end up with two scenarios:

1. FlatList taking longer to render views

This doesn't usually happen as the RN FlatList will only render views that are visible to the user at any given time and will keep rendering new views as the user scrolls through the list. However, there may be some flickering issues for which you can refer to the below article:

8 Ways to optimise your RN FlatList

2. Passing the data causes the delay

This is the most common scenario, where we may call an API endpoint and get some data and then do setState to update any view/list accordingly. A general approach is to show some sort of a progress-bar that would indicate that the application is busy and thus maintaining a proper user-experience. The easiest way to do that is by conditional rendering.

A general example would be:

const [myList, setMyList] = useState();

function callAPIforMyList(){
// logic goes here
}

return {
  {myList ? <ActivityIndicator .../> : <Flatlist .... />
}

The above code will check if myList is undefined or has a value. If undefined, it will render the ActivityIndicator or else the FlatList.

Another scenario could be when myList may have existing data but you need to update/replace it with new data. This way the above check may fail, so we can put another check:

const [myList, setMyList] = useState();
const [isAPIbusy, setAPIBusy] = useState(false)

function callAPIformyList() {
  setAPIBusy(true)
  /// other logics or async calls or redux-dispatch
  
  setAPIBusy(false)
}

return {
  {!isAPIBusy && myList ? (<Flatlist .... />) : (<ActivityIndicator .../>)

 }

You can add multiple conditions using more ternaries such as isAPIBusy ? <View1> : otherBoolean ? <View2> : <Default_View_When_No_Conditions_Match)/>

Hope this helps clarify your needs.

Protomorphic answered 28/11, 2021 at 7:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.