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>
);
}
}

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);
}
}
....
}
Thanks for the quick response. My externalScrollView class is like below. Is it correct?
class ExtendedScrollView extends BaseScrollView {
scrollTo(...args) {
if (this._scrollViewRef) {
this._scrollViewRef.scrollTo(...args);
}
}
render() {
return (
<Animated.ScrollView {...this.props}
ref={scrollView => {this._scrollViewRef = scrollView;}}
scrollEventThrottle={1}
onScroll={Animated.event([this.props.animatedEvent], {listener: this.props.onScroll,useNativeDriver: true})}
/>
)}
}
Looks correct. Is it working fine now?
Please see the step below. The issue is in the 4th step.
onEndReached called and new data appended to the list +10 items. (Working fine)onEndReached called and api sent response but no data appended to the list. Here I was getting the this._scrollViewRef.scrollTo is not a function error. Now the error is not showing but new data is also not appending. And it is producing extra space about 250px at the top of the list. (issue is in this step)If I do not use externalScrollView then it is working fine. But I need to use externalScrollView to animate things.
I'll need a sample to look into it. I don't think this a RLV issue. Most likely there must be some bug in your code. You can try your externalScrollView in one of the samples to see if it works fine.
@naqvitalha can you provide a full example of how to use the scrollTo with externalScrollView? I'm trying to do this and it's not working. Should the below code work: https://snack.expo.io/r1IoPqEkm?
@rootedy-ffit did you found any solution for scrollTo please ?
try using .scrollToOffset(0,0,true)
Looks like you haven't fully implemented
BaseScrollViewinterface. That is necessary since you're usingexternalScrollView.
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.
I ran into this error while using a higher-order component to wrap my ExtendedScrollView, like so:
export default withNavigation(ExtendedScrollView);
This made the scrollTo() defined in ExtendedScrollView inaccessible since the component exported is the wrapped component, not the original component. A solution is to move the wrapping to a child component.
Seems like the solution offered by @tanmaybhatt should work for the combination with Animated.ScrollView, so I think this issue can be closed.
I ran into this. the snack https://snack.expo.io/r1IoPqEkm throws the error and I use the same setup. What is the issue? Some typo? @naqvitalha @evert-smit
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.
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)
}
This worked for me:
const listView = useRef();
const scrollToTop = () => {
listView.current?.scrollToOffset(0, 0, true);
};
<RecyclerListView ref={listView}...
Thank you, @msmfsd. It works fine!!!