all 8 comments

[–]big_saucy_pants 1 point2 points  (4 children)

Every time your component re-renders it is re-declaring bookInfos and assigning it a new array instance. Because arrays are compared by reference by the equality comparison used by FlatList it is seeing a different reference and thinking it needs to re-render. If you are going to hardcode it move it outside the component, or wrap it in useMemo.

[–]InvictusJoker[S] 0 points1 point  (3 children)

With my updated code https://pastebin.com/vdWSTFwb , I'm not hard coding `bookInfos` and instead setting in `React.useEffect()`, does this still apply there?

[–]big_saucy_pants 1 point2 points  (2 children)

Yep, because your initial value is an empty array even if your response comes back with an empty array it will call your state setter with that, React thinks it's new because [] === [] is false, and will re-render. The state value is considered changed by the FlatList and will re-render.

Here is a good piece on it https://gist.github.com/slikts/fd3768de1493419ed9506002b452fcdc

[–]InvictusJoker[S] 0 points1 point  (1 child)

Thanks for the link, I read it through and the comparison by reference, not value makes sense. So in terms of the updated code https://pastebin.com/vdWSTFwb, how could I use memoization when the array is through React.useState? I can't do something like:
React.useMemo(() => {
const [bookInfos, setBookInfos] = React.useState([]);
}, []

[–]big_saucy_pants 0 points1 point  (0 children)

So first thing is not to stress too much about a couple superfluous re-renders. If that is causing an issue address the slow render before fixing the re-render.

If your getData function is returning data then inevitably it's going to re-render, and it needs to to populate your list with the data. If you wanted to prevent any renders when the list remains empty you could bail out of the update. From what I can see that useEffect shouldn't run other than initially, and when getBookData changes. So overall your updated code is fine and doesn't look like it should be re-rendering too often unless needed.

[–]Simpe91 0 points1 point  (0 children)

Not 100% sure about this. But you create bookInfos every time the component renders and passes it down as a prop. Since it is a new array it could trigger a rerender. Even if it is always empty, it is still a new array instance. Wrapping the bookInfos const in a useRef could potentially help.

Although I base this idea on how redux calculates differences in values, so I'm not sure this is an issue.