React Native ListView

编程入门 行业动态 更新时间:2024-10-14 00:26:19
本文介绍了React Native ListView - rowHasChanged 不会触发的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在尝试在 React Native 中实现无限滚动.以下是组件的来源:

I am trying to implement an infinite scroll in React Native. Below is the source of the component:

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

问题是,每当我追加(或添加)新数据时,DataSource 的 rowHasChanged 方法不会触发.它只是重新渲染每一行,即使没有任何变化(新数据除外).知道为什么绕过该方法吗?

The problem is that whenever I append (or prepend) new data, the rowHasChanged method of the DataSource doesn't fire. It just re-renders every row, even tho nothing has changed (except the new data). Any idea why the method is bypassed?

推荐答案

将函数传递给 setState 以避免竞争条件

Pass a function to setState to avoid race conditions

我刚刚想通了.如果您遇到同样的问题,请检查您使用新的 dataSource 更改状态的点.我的是这样的:

I just figured it out. If you are having the same issue, check the point at which you change your state with the new dataSource. Mine was like this:

this.setState({ dataSource: this.ds.cloneWithRows(posts) });

相反,您应该始终使用先前状态中的 dataSource,如下所示:

Instead you should always use the dataSource from the previous state, like this:

this.setState(state => ({ dataSource: state.dataSource.cloneWithRows(posts) }))

干杯!

更多推荐

React Native ListView

本文发布于:2023-10-11 14:21:25,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1481953.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:React   Native   ListView

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!