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.
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