Respond to an intimate scroll

I tried to get a minimal example of infinite scroll. So I have this:

var React = require('react-native'); var { StyleSheet, View, Image, ListView, } = React; var data = [ { "id": 1, "profile_picture": { "href": "//like1.r.worldssl.net/ui_big/1305634.jpg" } }, { "id": 2, "profile_picture": { "href": "//like1.r.worldssl.net/ui_big/1305634.jpg" } }, { "id": 3, "profile_picture": { "href": "//like1.r.worldssl.net/ui_big/1305634.jpg" } }, { "id": 4, "profile_picture": { "href": "//like1.r.worldssl.net/ui_big/1305634.jpg" } }, { "id": 5, "profile_picture": { "href": "//like1.r.worldssl.net/ui_big/1305634.jpg" } }, { "id": 6, "profile_picture": { "href": "//like1.r.worldssl.net/ui_big/1305634.jpg" } } ]; var InfiniteScreen = React.createClass({ getInitialState: function () { return { isLoadingTail: false, dataSource: new ListView.DataSource({ rowHasChanged: (row1, row2) => row1 !== row2, }) }; }, componentDidMount: function () { this.setState({ dataSource: this.getDataSource(data) }); }, renderRow: function (item) { return ( <View> <Image style={{width: 80, height: 80}} source={{uri: 'http:' + item.profile_picture.href}}/> </View> ); }, onEndReached: function () { console.log('onEndReached', this.state.isLoadingTail); if (this.state.isLoadingTail) { // We're already fetching return; } this.setState({ isLoadingTail: true }); this.setState({ isLoadingTail: false, dataSource: this.getDataSource(data) }); }, getDataSource: function (users):ListView.DataSource { return this.state.dataSource.cloneWithRows(users); }, render: function () { return ( <View> <ListView dataSource={this.state.dataSource} renderRow={this.renderRow} onEndReached={this.onEndReached} /> </View>); } }); 

If I scroll to the very bottom, onEndReached () is triggered, but new data is not displayed. Any ideas?

+7
javascript reactjs react-native
source share
3 answers

You always clone your data source with the same data, so nothing new appears. Here is a working example (add new data via concat ):

 var React = require('react-native'); var { StyleSheet, View, Image, ListView, } = React; var data = [ { "id": 1, "profile_picture": { "href": "//like1.r.worldssl.net/ui_big/1305634.jpg" } }, { "id": 2, "profile_picture": { "href": "//like1.r.worldssl.net/ui_big/1305634.jpg" } }, { "id": 3, "profile_picture": { "href": "//like1.r.worldssl.net/ui_big/1305634.jpg" } }, { "id": 4, "profile_picture": { "href": "//like1.r.worldssl.net/ui_big/1305634.jpg" } }, { "id": 5, "profile_picture": { "href": "//like1.r.worldssl.net/ui_big/1305634.jpg" } }, { "id": 6, "profile_picture": { "href": "//like1.r.worldssl.net/ui_big/1305634.jpg" } } ]; var InfiniteScreen = React.createClass({ getInitialState: function () { return { isLoadingTail: false, dataSource: new ListView.DataSource({ rowHasChanged: (row1, row2) => row1 !== row2, }) }; }, componentDidMount: function () { this._data = []; this.setState({ dataSource: this.getDataSource(data) }); }, renderRow: function (item) { return ( <View> <Image style={{width: 80, height: 80}} source={{uri: 'http:' + item.profile_picture.href}}/> </View> ); }, onEndReached: function () { console.log('onEndReached', this.state.isLoadingTail); if (this.state.isLoadingTail) { // We're already fetching return; } this.setState({ isLoadingTail: true }); this.setState({ isLoadingTail: false, dataSource: this.getDataSource(data) }); }, getDataSource: function (users):ListView.DataSource { this._data = this._data.concat(users); return this.state.dataSource.cloneWithRows(this._data); }, render: function () { return ( <View style={styles.container}> <ListView dataSource={this.state.dataSource} renderRow={this.renderRow} onEndReached={this.onEndReached} /> </View>); } }); var styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', backgroundColor: '#F5FCFF', }, }); 
+21
source share

https://facebook.imtqy.com/react/docs/component-api.html#setstate

setState () does not immediately mutate this.state, but creates a pending state transition. Accessing this.state after calling this method can potentially return an existing value. There is no guarantee that setState calls will work synchronously and calls may be collected to improve performance.

so the problems are here

  this.setState({ isLoadingTail: true }); this.setState({ isLoadingTail: false, dataSource: this.getDataSource(data) }); 
0
source share

I have been looking for this solution for a very long time. Finally, I came up with this small library: -

https://www.npmjs.com/package/rn-infinite-scroll

 import InfiniteListView from 'rn-infinite-scroll'; <InfiniteListView data ={this.state.items} renderRow={this.renderRow} canLoad={this.canLoad()} isLoading={this.state.isLoading} onLoad={this.onLoad} /> 
-one
source share

All Articles