【已开源】分享一个IT资讯软件,使用React Native写的
发布于 8 年前 作者 tomoya92 4670 次浏览 来自 分享

开源地址:https://github.com/tomoya92/ITNews-React-Native

介绍

平时看资讯用的app,里面很多功能都用不上,所以就想到了把它们集成到一块了,虽然网上也有很多这样的软件,但正好学一下rn,就自己实现了一个,实现思路是,有接口的,就调用接口,没有接口的,就直接抓取见面了用cheerio解析出数据

功能非常简单,列表(listview)+详情(webview)+分享功能

用到的组件:

  • StackNavigator
  • react-native-webview2
  • react-native-vector-icons
  • cheerio-without-node-native

截图:

image.png image.png Simulator Screen Shot 2017年8月7日 16.22.21.png

问题

现在发现了一个问题,ListView的加载更多问题,用的是onEndReached方法,在滚动到最后一行的时候,会触发的方法,在这里调用下一页,但在第一次加载更多的时候,会再一次加载第一页的内容,这样就导致了数据重复了,代码写法如下

export default class ItemList extends Component {
 static navigationOptions = ({navigation}) => ({
 title: `${navigation.state.params.name}`,
 });
 constructor(props) {
 super(props);
 this.state = ({
 refreshing: true,
 loadMore: false,
 name: this.props.name,
 pageNo: 1,
 dataSource: [],
 })
 }
 componentDidMount() {
 this._fetchData();
 }
 _fetchData() {
 fetch(url + 'api/v1/topics?page=' + this.state.pageNo)
 .then(response => response.json())
 .then(json => {
 this.setState({
 refreshing: false,
 loadMore: false,
 dataSource: this.state.pageNo === 1 ? json.data : this.state.dataSource.concat(json.data)
 })
 })
 .catch(error => console.info(error));
 }
 _onRefresh() {
 this.setState({
 pageNo: 1,
 });
 this._fetchData();
 }
 _onEndReached() {
 this.setState({
 loadMore: true,
 pageNo: this.state.pageNo + 1
 });
 this._fetchData();
 }
 _onPress(rowData) {
 const {navigate} = this.props.navigation;
 navigate('NewsDetail', {
 title: rowData.title,
 href: url + 'topic/' + rowData.id
 })
 }
 _renderRow(rowData) {
 return <TouchableHighlight
 underlayColor='#008b8b'
 onPress={() => this._onPress(rowData)}>
 <View style={styles.rowStyle}>
 <Image
 style={{width: 40, height: 40, borderRadius: 20}}
 source={{uri: rowData.author.avatar_url}}
 />
 <View style={{paddingLeft: 10, flexDirection: 'column', flex: 1}}>
 <Text style={{fontSize: 18,}}>{rowData.title}</Text>
 <View style={{flexDirection: 'row', justifyContent: 'space-between', alignItems: 'flex-end'}}>
 <Text style={styles.other}>{Moment(rowData.create_at).fromNow()}</Text>
 <Text style={[styles.other]}>{rowData.reply_count} 个回复</Text>
 </View>
 </View>
 </View>
 </TouchableHighlight>
 }
 render() {
 const FooterView = this.state.loadMore ?
 <View style={styles.footer}>
 <Text style={{fontSize: 18, color: '#777'}}>加载更多...</Text>
 </View> : null;
 return <ListView
 refreshControl={
 <RefreshControl
 refreshing={this.state.refreshing}
 onRefresh={this._onRefresh.bind(this)}
 />
 }
 style={[styles.listView]}
 dataSource={ds.cloneWithRows(this.state.dataSource)}
 enableEmptySections={true}
 renderRow={this._renderRow.bind(this)}
 onEndReachedThreshold={10}
 onEndReached={this._onEndReached.bind(this)}
 renderFooter={() => FooterView}
 />
 }
}

在这求大神帮忙看看,怎么能解决这个问题呢?

4 回复

这个问题有点难度

这有什么难的,如果正在加载更多就不再请求 来自 牛读 - 定制的技术类资讯聚合阅读器

因为this.setState({})方法是异步的,所以要用

this.setState({
	pageNo: 1
}, ()=>this._fetchData())

来进行调用,这样才能保证分页正确

回到顶部

AltStyle によって変換されたページ (->オリジナル) /