FlatList is re-rendering items everytime screen is scrolled

Viewed 133

I have a list of 300 items. I'm using FlatList to render the items.

ISSUE :

  • List items re-rendering when I scroll the screen. Even when I have wrapped the component in React.memo.

I tried to optimise the list by tweaking the windowSize, maxToRenderPerBatch but the issue still persist.

You can check the code in below sandbox link.

Thankyou in advance !

https://codesandbox.io/s/gracious-dhawan-i4d51h?file=/src/App.js

Below is the code snippet

const data = [
{
    id: 1,
    first_name: "Shaina",
    last_name: "Osorio",
    email: "sosorio0@a8.net"
  },
  {
    id: 2,
    first_name: "Ania",
    last_name: "Cotilard",
    email: "acotilard1@about.me"
  },
  {
    id: 3,
    first_name: "Hagen",
    last_name: "Lisciandri",
    email: "hlisciandri2@nature.com"
  }
]

const isEqual = (prev, next) => {
  return true;
};

const RenderItem = React.memo((props) => {
  const { id, first_name, email } = props;
  console.log("id >>> ", id);

  return (
    <View
      style={{
        padding: 5,
        backgroundColor: "lightblue",
        marginVertical: 3
      }}
    >
      <Text>First Name : {first_name}</Text>
      <Text>Email : {email}</Text>
    </View>
  );
}, isEqual);

function App() {

  return (
    <View style={{ flex: 1 }}>
      <FlatList
        data={data}
        renderItem={({ item }) => (
          <RenderItem
            id={item.id}
            first_name={item.first_name}
            email={item.email}
          />
        )}
        initialNumToRender={15}
        maxToRenderPerBatch={15}
        keyExtractor={(item) => item.id}
      />
    </View>
  );
}

export default App;

2 Answers

In your example, you are logging inside your renderItem, so when a new element comes into the rendered area, it is logged. This happens when you scroll. But this doesn't mean that the whole list will be re-rendered. Just place a conosle.log directly in the component that hosts the list, and you'll see that it's only rendered once, unlike the renderItem, which is rendered every time a new item is created by a scroll.

const App = ()=> {
  console.log("Entire List Rerendered");
  return (
    <View style={{ flex: 1 }}>
      <FlatList
        data={data}
        renderItem={rendering}
        initialNumToRender={5}
        maxToRenderPerBatch={5}
        keyExtractor={(item) => item.id}
      />
    </View>
  );
}

Flashlist might help, because it recycles renderItems and doesn't destroy them like Flatlist does. But you should test that better.

Also check out this attempt to visually explain your console logs.

enter image description here

Check out FlashList by Shopify they are saying that it is much more optimized than Flatlist. maybe it can meet your needs. no harm in trying: Click Here

    import React from "react";
    import { View, Text, StatusBar } from "react-native";
    import { FlashList } from "@shopify/flash-list";
    
    const DATA = [
      {
        title: "First Item",
      },
      {
        title: "Second Item",
      },
    ];
    
    const MyList = () => {
      return (
        <FlashList
          data={DATA}
          renderItem={({ item }) => <Text>{item.title}</Text>}
          estimatedItemSize={200}
        />
      );
    };
Related