2015-05-15 21 views
6

मैंने अनंत स्क्रॉल का एक न्यूनतम उदाहरण प्राप्त करने का प्रयास किया है।प्रतिक्रिया मूल अनंत स्क्रॉल

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

अगर मैं बहुत नीचे तक स्क्रॉल करें, onEndReached() निकाल दिया जाता है, लेकिन नए डेटा प्रकट नहीं होता है: तो मैं इस किया है। कोई विचार?

उत्तर

20

आप हमेशा एक ही डेटा के साथ अपने डेटा स्रोत क्लोन है, इसलिए कुछ भी नहीं नए दिखाई देता है।

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', 
    }, 
}); 
0

https://facebook.github.io/react/docs/component-api.html#setstate

setState() तुरंत this.state उत्परिवर्तित नहीं करता, लेकिन एक लंबित स्थिति संक्रमण पैदा करता है। इस विधि को कॉल करने के बाद this.state तक पहुंचने से संभावित रूप से मौजूदा मान वापस आ सकता है। सेटस्टेट पर कॉल के सिंक्रोनस ऑपरेशन की कोई गारंटी नहीं है और कॉल प्रदर्शन लाभ के लिए बैच किए जा सकते हैं।

तो समस्याओं यहाँ

this.setState({ 
     isLoadingTail: true 
    }); 

    this.setState({ 
     isLoadingTail: false, 
     dataSource: this.getDataSource(data) 
    }); 
+2

उत्तर बेहतर है और यह निश्चित रूप से समस्या का हल। लेकिन, वैसे भी, जिस कोड पर मैंने इशारा किया था वह टूटा हुआ है। प्रत्येक सेटस्टेट –

+1

के बाद घटक फिर से प्रस्तुत नहीं करेगा, यह प्रश्न का उत्तर कैसे दे सकता है? –

+0

ऐसा नहीं है, मुझे लगता है कि उस समय मेरे पास टिप्पणियां पोस्ट करने के लिए पर्याप्त कर्म नहीं था, इसलिए मैंने एक उत्तर पोस्ट किया। –

0

मैं बहुत लंबे समय के लिए इस समाधान तलाश रहे हैं: यहाँ एक काम उदाहरण (concat के माध्यम से नए डेटा जोड़ने) है। अंत में मैं इस हल्के वजन पुस्तकालय के साथ आया था: - @vkurchatkin द्वारा

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} 
/> 
संबंधित मुद्दे