React-native-reanimated: FlatList onEndReached not working if onScroll is set in renderScrollComponent

Created on 19 Feb 2020  路  11Comments  路  Source: software-mansion/react-native-reanimated

  <FlatList
    onEndReached={() => {
      console.log("reached");
    }}
    renderScrollComponent={props => {
      return (
        <Animated.ScrollView
          {...props}
          onScroll={Animated.event(
            [{ nativeEvent: { contentOffset: { y: value } } }],
            { useNativeDriver: true }
          )}
        />
      );
    }}
  />;

I did get the value update. However, onEndReached is never called.

Any idea how to get the value update and not breaking onEndReached?

鉂換uestion

Most helpful comment

Yes it does! thanks

All 11 comments

Hi @frankyjuang,

does onEndReached work when you don't use Reanimated at all, i.e. you just render < ScrollView {...props} />?

@jakub-gonet No

    <FlatList
      onEndReached={() => {
        console.log("reached");
      }}
      renderScrollComponent={props => (
        <ScrollView
          {...props}
          onScroll={() => {
            console.log("scrolling");
          }}
        />
      )}
    />

Found this https://github.com/facebook/react-native/issues/12461
What they suggested is to avoid setting onScroll in custom scroll component. But seems like the only way to use reanimated in FlatList is to use renderScrollComponent. Any idea how to workaround this? Thanks.

Describe what you want to animate, maybe createAnimatedComponent(FlatList) will suffice?

Yes it does! thanks

Describe what you want to animate, maybe createAnimatedComponent(FlatList) will suffice?

Issue with this is to once you update state of data it will re-render the whole list every single time and scroll you back to the top of it.
Any possible solutions for this?

@CallMeHeisenberg, it has to rerender because React works that way. I don't know why it doesn't keep scrolled position though, hard to say without code.

@CallMeHeisenberg, it has to rerender because React works that way. I don't know why it doesn't keep scrolled position though, hard to say without code.

Quickly coded an example proving my point:
The items that I'm rendering are images taken from CameraRoll however displayed as red boxed views. You can easily simulate this by either recreating this with CameraRoll lib or by inserting 20 new items to state every time it calls onEndReached

````
render() {
const AnimatedFlatList = Animated.createAnimatedComponent(FlatList)
return (
)} backgroundColor={"black"} imageContainerStyle={{borderRadius: 5}} data={this.state.photos}
onEndReached={() => {
if (this.loaded) {
this.props.onEndReached();
}
}} onEndReachedThreshold={0.8}/>

    );
};

````

And there's the unexpected behaviour:
Keep an eye on the right vertical scroll

https://drive.google.com/file/d/1tCL1ss7Hl5qmAzFM9SnuFbVhjPMWAgzu/view?usp=drivesdk

Hey @CallMeHeisenberg 馃憢
Your short snippet with repro is not enough for us to work on this issue.
Can you provide the whole thing?

I'll close until you provide whole repro, have a nice day 馃槂 !

Hey @CallMeHeisenberg 馃憢
Your short snippet with repro is not enough for us to work on this issue.
Can you provide the whole thing?

I'll close until you provide whole repro, have a nice day 馃槂 !

Actually I will provide you with a solution
After looking deeply in your code, I solved it using that:

const FlatListWithEventThrottle = React.forwardRef((props, ref) => (
    <FlatList scrollEventThrottle={0.0001} {...props} ref={ref} />
));

module.exports = (Animated.createAnimatedComponent(
    FlatListWithEventThrottle,
));

You can perhaps update the Animated.FlatList or I can just create a pull request with the fix

Btw same goes for ScrollView

Cheers, George

@CallMeHeisenberg So the issue is possibly around ForwardRef right? I definitely look forward you Pull Requests, as they are always welcome 馃槃. In other case, leave the repro and we'll try to catch up on this issue.

@CallMeHeisenberg @jkadamczyk I also managed to work around this by memoizing the animated flatlist

    const AnimatedFlatList = useMemo(
      () => Animated.createAnimatedComponent(FlatList),
      [],
    );

Not sure if this is the right approach, but it got me working since the other suggestions above didn't seem to work.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

bdrobinson picture bdrobinson  路  3Comments

dinhmai74 picture dinhmai74  路  3Comments

wasim-abuzaher picture wasim-abuzaher  路  3Comments

mldb picture mldb  路  3Comments

colinux picture colinux  路  3Comments