2015-05-15 32 views
6

Tôi đã cố gắng để có được một ví dụ tối thiểu về cuộn vô hạn. Vì vậy, tôi có điều này:React Native Infinite Scroll

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

Nếu tôi cuộn xuống cuối rất, onEndReached() là bắn, nhưng các dữ liệu mới không xuất hiện. Bất kỳ ý tưởng?

Trả lời

20

Bạn luôn sao chép nguồn dữ liệu của bạn với cùng một dữ liệu, vì vậy không có gì xuất hiện mới. Dưới đây là ví dụ hoạt động (thêm dữ liệu mới qua 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', 
    }, 
}); 
0

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

setstate() không ngay lập tức đột biến this.state nhưng tạo ra một chuyển trạng thái chờ giải quyết. Truy cập this.state sau khi gọi phương thức này có khả năng trả về giá trị hiện tại. Không có bảo đảm hoạt động đồng bộ của cuộc gọi đến setState và các cuộc gọi có thể được thực hiện theo đợt để đạt được hiệu suất.

nên vấn đề là ở đây

this.setState({ 
     isLoadingTail: true 
    }); 

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

trả lời bởi @vkurchatkin là tốt hơn và nó chắc chắn giải quyết vấn đề. Nhưng, dù sao, mã mà tôi chỉ vào là bị hỏng. Thành phần sẽ không hiển thị lại sau mỗi setState –

+1

cách điều này có thể trả lời câu hỏi? –

+0

Nó không, tôi đoán tại thời điểm đó tôi không có đủ nghiệp để đăng bình luận, vì vậy tôi đã đăng một câu trả lời. –

0

Tôi đã tìm giải pháp này trong một thời gian rất dài. Cuối cùng tôi đến với thư viện trọng lượng nhẹ này: -

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} 
/> 
Các vấn đề liên quan