rgommezz / react-native-scroll-bottom-sheet

Cross platform scrollable bottom sheet with virtualisation support, native animations at 60 FPS and fully implemented in JS land :fire:
MIT License
1.54k stars 66 forks source link

renderRow re-renders? #22

Closed kickbk closed 4 years ago

kickbk commented 4 years ago

Hi @rgommezz, thanks a lot for this great component.

I'm seeing a behavior with renderItems for the BottomList that I cannot quite understand. I expect it to behave similarly to a FlatList, which it extends. So let me get to the point and show you code with debug:

For testing purposes:

const renderRow = React.useCallback(
  ({ item, index }) =>
    console.log(`Running render with index ${index}`, item),
  []
);

Your code (I only changed the data Array to 20 instead of 100):

<ScrollBottomSheet<string>
  ...
  data={Array.from({ length: 20 }).map((_, i) => String(i))}
  renderItem={renderRow}
/>

Console output:

Running render with index 0 0
Running render with index 1 1
Running render with index 2 2
Running render with index 3 3
Running render with index 4 4
Running render with index 0 0
Running render with index 1 1
Running render with index 2 2
Running render with index 3 3
Running render with index 4 4
Running render with index 5 5
Running render with index 6 6
Running render with index 7 7
Running render with index 8 8
Running render with index 9 9
Running render with index 10 10
Running render with index 11 11
Running render with index 12 12
Running render with index 13 13
Running render with index 14 14
Running render with index 0 0
Running render with index 1 1
Running render with index 2 2
Running render with index 3 3
Running render with index 4 4
Running render with index 5 5
Running render with index 6 6
Running render with index 7 7
Running render with index 8 8
Running render with index 9 9
Running render with index 10 10
Running render with index 11 11
Running render with index 12 12
Running render with index 13 13
Running render with index 14 14
Running render with index 15 15
Running render with index 16 16
Running render with index 17 17
Running render with index 18 18
Running render with index 19 19

Simple FlatList code:

<FlatList
  data={Array.from({ length: 20 }).map((_, i) => String(i))}
  renderItem={renderRow}
/>

Console output:

Running render with index 0 0
Running render with index 1 1
Running render with index 2 2
Running render with index 3 3
Running render with index 4 4
Running render with index 5 5
Running render with index 6 6
Running render with index 7 7
Running render with index 8 8
Running render with index 9 9
Running render with index 10 10
Running render with index 11 11
Running render with index 12 12
Running render with index 13 13
Running render with index 14 14
Running render with index 15 15
Running render with index 16 16
Running render with index 17 17
Running render with index 18 18
Running render with index 19 19

For the record, I'm getting this when using your own example code, not just when using in my own project. As you can see, FlatList returns what I would expect, but I'm not sure this is a bug or a problem. This may be a newbie question, if so I apologize. Perhaps it's meant to behave this way, but then I don't quite get why. Isn't it re-rendering the same data over and over?

rgommezz commented 4 years ago

Hi @kickbk,

Glad you found it useful! 🚀

I believe that sequence is different because the FlatList example of this repo has as individual items horizontal FlatLists, which in turn manage a list of images and may not be fully optimised. That wasn't obviously the purpose of the example, but rather to illustrate a potential use-case :)

If you replace renderRow in the example for the one below, you should see a normal sequence as you you would expect with a normal FlatList:

const renderRow = React.useCallback(({ index }) => {
    console.log('rendering with index', index);
    return (
      <View style={{ height: 56, width: '100%' }}>
        <Text>{`Element ${index}`}</Text>
      </View>
    );
  }, []);

Just so you know, this component doesn't handle any specific behaviour of the underlying lists and acts as a proxy for all their props.

Hope that clarifies your question!