2

I'm using functional components, and using Flatlist to render list of datas, it's working ok, but each time state get additional data it always re-rendering existing and it will cause performance problem, I have read these articles from SO but still has no clues

here is my code that using main Flatlist

<FlatList
  horizontal={false}
  showsHorizontalScrollIndicator={false}
  data={users}
  keyExtractor={(item, index) => String(index)}
  renderItem={RenderUser}
  onEndReachedThreshold={0.7}
  onEndReached={callBackMoreData}
/>

and here is working RenderUser but the problem it re render existing item if state has additional data, what I would like to achieve is only render additional data

import React from 'react';
import { ListItem } from 'react-native-elements';

const RenderUser = ({ item, index }) => {

  return (
    <React.Fragment>
      { console.log('index: ', index)}
      <ListItem 
        title={item.attributes.name}
      />
    </React.Fragment>
  );
};

export default RenderUser;

and I did tried using this code below (but I get an error message saying TypeError: renderItem is not a function. (in 'renderItem(props)', 'renderItem' is an instance of object))

import React, { memo } from 'react';
import { ListItem } from 'react-native-elements';

const RenderUser = ({ item, index }) => {

  return (
    <React.Fragment>
      { console.log('index: ', index)}
      <ListItem 
        title={item.attributes.name}
      />
    </React.Fragment>
  );
};

export default memo(RenderUser);
widjajayd
  • 5,554
  • 3
  • 21
  • 33

1 Answers1

2

According to react official documentation:

By default it will only shallowly compare complex objects in the props object. If you want control over the comparison, you can also provide a custom comparison function as the second argument

function MyComponent(props) {
  /* render using props */
}
function areEqual(prevProps, nextProps) {
  /*
  return true if passing nextProps to render would return
  the same result as passing prevProps to render,
  otherwise return false
  */
}
export default React.memo(MyComponent, areEqual);

In your case you need to add condtion:

import React, { memo } from 'react';
import { ListItem } from 'react-native-elements';

const RenderUser = ({ item, index }) => {

  return (
    <React.Fragment>
      { console.log('index: ', index)}
      <ListItem 
        title={item.attributes.name}
      />
    </React.Fragment>
  );
};

function arePropsEqual(prevProps, nextProps) {
      /*
      return true if passing nextProps to render would return
      the same result as passing prevProps to render,
      otherwise return false
      */
      return nextProps.item.attribute.name===prevProps.item.attribute.name
    }

export default memo(RenderUser,arePropsEqual);

Note : Not sure how many props you are getting and what are unique. Basically you need to compare that last one is equal to this one return true in that way react does not re-render your component

Shubham Verma
  • 3,814
  • 1
  • 4
  • 18