Yogesh Tripathi
Yogesh Tripathi

Reputation: 735

FlatList is re-rendering items everytime screen is scrolled

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

ISSUE :

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: "[email protected]"
  },
  {
    id: 2,
    first_name: "Ania",
    last_name: "Cotilard",
    email: "[email protected]"
  },
  {
    id: 3,
    first_name: "Hagen",
    last_name: "Lisciandri",
    email: "[email protected]"
  }
]

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;

Upvotes: 4

Views: 2935

Answers (2)

dan_boy
dan_boy

Reputation: 2019

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

Upvotes: 2

Bhavya Koshiya
Bhavya Koshiya

Reputation: 1806

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

Upvotes: 0

Related Questions