recyclerlistview: this._scrollViewRef.scrollTo is not a function

The recyclerlistview performance is very good. But i am having a issue with the onEndReached props. After calling the onEndReached i am adding the new data to the DataProvider. But after the data is added i m getting error this._scrollViewRef.scrollTo is not a function

class NewsList extends React.Component {

constructor(props) {
    super(props);
this.dataProvider = new DataProvider((r1, r2) => {
                return r1 !== r2;
            }).cloneWithRows(this.props.list);
}

componentWillReceiveProps  ()  {   
   this.setState(prevState => ({
    dataProvider: prevState.dataProvider.cloneWithRows(this.props.list)
  }))   
  }

render() {     
 return (
  <View style={{flex:1}}>
<RecyclerListView
         ref={ref => {this.listRef = ref;}}
          contentContainerStyle={{paddingBottom:80}}
         externalScrollView={ExtendedScrollView}
         layoutProvider={this._layoutProvider}
         dataProvider={this.state.dataProvider}
         rowRenderer={this._rowRenderer} 
         onEndReached={() => this.props.handleLoadMore()}
         onEndReachedThreshold={0.3}
         renderFooter={this.renderFooter}
         animatedEvent={{nativeEvent: {contentOffset: {y: this.scroll}}}}
         renderAheadOffset={250}        
         refreshControl={
              <RefreshControl
              refreshing={this.state.refreshing}
              onRefresh={this._onRefresh.bind(this)} />
                  }
         /> 
    </View>    
    );
  }
}

screenshot_20180507-123302

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 15 (3 by maintainers)

Most upvoted comments

This worked for me:

const listView = useRef();

const scrollToTop = () => {
  listView.current?.scrollToOffset(0, 0, true);
};

<RecyclerListView ref={listView}...

Thanks for your reply! @evert-smit, what I had imagined would be that the ref would be somehow magically passed on to the component but of course it would not be.

Reading your comment I did this 5min solution as I really need the ref to control it from some other UI components.

render() {
    return <RecyclerListView 
    setScrollViewRef={(ref) => this.scrollViewRef = ref}
    externalScrollView={ExternalScrollView}
    layoutProvider={this._layoutProvider}
    dataProvider={this.state.dataProvider}
    rowRenderer={this._rowRenderer} />;
 };

and setScrollViewRef will be passed on to the ExternalScrollView and you can do something like

componentDidMount(){
    this.props.setScrollViewRef(this._scrollViewRef)
  }

You’re setting a ref called listView on your RecyclerListView:

render() {
    return <RecyclerListView 
    ref={ref => {this.listView = ref}}
    externalScrollView={ExternalScrollView}
    layoutProvider={this._layoutProvider}
    dataProvider={this.state.dataProvider}
    rowRenderer={this._rowRenderer} />;
 }

and then you’re doing this:

componentDidMount() {
   setTimeout(()=>{
       this.listView.scrollTo({y: 300, animated: true});
   }, 5000);
}

This is not going to work because your RecycleTestComponent doesn’t have a scrollTo method: that’s the method that you’re trying to access here.

It also won’t work because you’re not doing the scrolling on the component that should actually be scrolled: your ExternalScrollView.

So, you can move that scrollTo call to your ExternalScrollView component. You can get rid of setting the listView ref.

Looks like you haven’t fully implemented BaseScrollView interface. That is necessary since you’re using externalScrollView. e.g,

class ExtendedScrollView extends BaseScrollView {
scrollTo(...args) {
      //Get this from your impl
      if(this._scrollViewRef) {
         this._scrollViewRef.scrollTo(...args);
      }
   }
 ....
}

Since it is an Animated ScrollView you will have to use getNode() function on _scrollViewRef.

if(this._scrollViewRef) {
     this._scrollViewRef.getNode().scrollTo(...args);
}

This worked for me.

@rootedy-ffit did you found any solution for scrollTo please ?