Search code examples
reactjsreact-nativereact-native-flatlist

Minimize React Native Flatlist re-renders


I have a case with a Flatlist where users can scroll down to load more rows. I do not know if this is the correct way to check if components are re-rendering, but I added a log statement in the component to see how often it is triggered. Right now, when I load more rows, previous rows are re-rendered, therefore making the process slow as more rows are added.

This is what I am doing so far. I thought using a memo would solve this issue, but I don't think that is working for me. Ideally, I want the componentB to render just once although I am aware that useEffect in componentB may cause re-rendering. Even if I am changing totally unrelated state variable, all components are re-rendered

ComponentA = () => {
  const [x, setX] = useState([]);
  
  const [y, setY] = useState(0);
  

  const loadMore = () => {
     ...load more
     setX(newX);

     //tested to see if setting y will trigger re-render which it did
     setY(1);
  }

  return <FlatList
    data={x}
    keyExtractor={item => item.id}
    onEndReached={loadMore}
    renderItem={({ item }) => { return <ComponentB item={item}> })
  >
}
ComponentB = ({item}) => {
  useEffect(() => {
     fetch some info using item
  })
  return ...
}

export default memo(ComponentB);

Also, when I navigate to a screen and then come back, componentB is re-rendered although nothing has changed. Note that I tried using memo(ComponentB, customComparator) to check for equality.


Solution

  • using memo was a good solution but not enough, you need the remove any anonymous function because it will be recreated on each render which will cause performance issues sometimes.

    For example:

    const renderItem = useCallback(({item}) => (
       <View key={item.key}>
          <Text>{item.title}</Text>
       </View>
     ), []);
    
    const keyExtractor =useCallback(({item}) => item.id, []);
    
    return (
      // ...
    
      <FlatList data={items} keyExtractor={keyExtractor} renderItem={renderItem} />;
      // ...
    );
    

    Refer to this : https://reactnative.dev/docs/optimizing-flatlist-configuration#avoid-anonymous-function-on-renderitem