Tôi đang cố gắng triển khai một cuộn vô hạn trong React Native. Dưới đây là nguồn gốc của các thành phần:React Native ListView - rowHasChanged không kích hoạt
var React = require('react-native');
var server = require('../server');
var Post = require('./Post');
var SwipeRefreshLayoutAndroid = require('./SwipeRefreshLayout');
var backEvent = null;
var lastPostId = "";
var isLoadingMore = false;
var isLoadingTop = false;
var onEndReachedActive = false;
var {
StyleSheet,
ListView,
View,
Text,
Image,
ProgressBarAndroid,
BackAndroid
} = React;
class Stream extends React.Component {
constructor(props) {
super(props);
this.ds = new ListView.DataSource({
rowHasChanged: (row1, row2) => {
console.log("rowHasChenged FIRED!!");
return false;
}
});
this.state = {
dataSource: this.ds.cloneWithRows(['loader']),
hasStream: false,
posts: []
};
}
componentDidMount() {
BackAndroid.addEventListener('hardwareBackPress',() => {
this.props.navigator.jumpBack();
return true;
}.bind(this));
server.getStream('', '', 15).then((res) => {
lastPostId = res[res.length-1].m._id;
this.setState({
posts: res,
hasStream: true,
dataSource: this.ds.cloneWithRows(res)
},() => onEndReachedActive = true);
})
}
onRefresh() {
var posts = this.state.posts;
var firstPost = posts[0].m._id;
console.log(this.state.dataSource._rowHasChanged);
isLoadingTop = true;
server.getStream('', firstPost, 4000)
.then(res => {
console.log(posts.length);
posts = res.concat(posts);
console.log(posts.length);
this.setState({
dataSource: this.ds.cloneWithRows(posts),
posts
},() => {
this.swipeRefreshLayout && this.swipeRefreshLayout.finishRefresh();
isLoadingTop = false;
});
}).catch((err) => {
isLoadingTop = false;
})
}
onEndReached(event) {
if(!onEndReachedActive) return;
if(this.state.loadingMore || this.state.isLoadingTop)return;
isLoadingMore = true;
var posts = this.state.posts;
server.getStream(posts[posts.length-1].m._id, '', 15)
.then(res => {
console.log('received posts');
posts = posts.concat(res);
lastPostId = posts[posts.length-1].m._id;
this.setState({
dataSource: this.ds.cloneWithRows(posts),
posts
},()=>isLoadingMore = false);
})
}
renderHeader() {
return (
<View style={styles.header}>
<Text style={styles.headerText}>Header</Text>
</View>
)
}
renderRow(post) {
if(post === 'loader') {
return (
<ProgressBarAndroid
styleAttr="Large"
style={styles.spinnerBottom}/>
)
}
let hasLoader = post.m._id === lastPostId;
let loader = hasLoader ?
<ProgressBarAndroid
styleAttr="Large"
style={styles.spinnerBottom}/> : null;
return (
<View>
<Post
post={post}/>
{loader}
</View>
)
}
render() {
return (
<ListView
style={styles.mainContainer}
dataSource={this.state.dataSource}
renderRow={this.renderRow.bind(this)}
onEndReached={this.onEndReached.bind(this)}
onEndReachedThreshold={1}
pageSize={15} />
);
}
}
Vấn đề là bất cứ khi nào tôi thêm (hoặc thêm vào trước) dữ liệu mới, phương pháp rowHasChanged
của DataSource
không cháy. Nó chỉ làm lại mọi hàng, thậm chí tho không có gì thay đổi (ngoại trừ dữ liệu mới). Bất kỳ ý tưởng nào tại sao phương thức bị bỏ qua?
Có ai biết nếu điều này là docu mented bất cứ nơi nào trong các tài liệu React Native? Tôi không thể tìm thấy nó đề cập cụ thể và điều này có vẻ quan trọng ... –
Nếu bạn đang sử dụng trạng thái hiện tại để cập nhật trạng thái, bạn có nghĩa vụ phải sử dụng biểu mẫu 'this.setState ((state) => ({dataSource: state.dataSource.cloneWithRows (posts)})); '. Thông qua setState một hàm làm giảm nguy cơ của một điều kiện chủng tộc. – jtolds
@jtolds Đã chỉnh sửa, cảm ơn! –