【已开源】分享一个IT资讯软件,使用React Native写的
开源地址:https://github.com/tomoya92/ITNews-React-Native
介绍
平时看资讯用的app,里面很多功能都用不上,所以就想到了把它们集成到一块了,虽然网上也有很多这样的软件,但正好学一下rn,就自己实现了一个,实现思路是,有接口的,就调用接口,没有接口的,就直接抓取见面了用cheerio解析出数据
功能非常简单,列表(listview)+详情(webview)+分享功能
用到的组件:
- StackNavigator
- react-native-webview2
- react-native-vector-icons
- cheerio-without-node-native
截图:
问题
现在发现了一个问题,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 回复
这个问题有点难度
@zweigao 挺难的
这有什么难的,如果正在加载更多就不再请求 来自 牛读 - 定制的技术类资讯聚合阅读器
因为this.setState({})方法是异步的,所以要用
this.setState({
pageNo: 1
}, ()=>this._fetchData())
来进行调用,这样才能保证分页正确