本篇内容主要讲解“antd-mobile ListView长列表的数据更新时常见问题”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“antd-mobile ListView长列表的数据更新时常见问题”吧!
遇到的问题
listView这个组件我真的是看文档看得脑壳疼。好不容易看文档写完长列表数据展示了。然后遇到一个需求,即用户有一个点赞操作,问题出现了,点赞完数据更新之后listView不刷新列表。
解决列表不刷新问题
官方的demo里有这么一个函数 rowHasChanged ,这个函数返回true或者false,如果是true,则认为这行数据改变了,然后刷新这行数据,也就更新了列表。
// 官方
constructor(props) {
super(props);
...
const dataSource = new ListView.DataSource({
...
rowHasChanged: (row1, row2) => row1 !== row2 // 这个方法
});
}
然后就各种百度,最后在github上看到这个 issue。最后大家得出的结论就是如果要继续用这个组件,又想刷新列表的话就只能写成下面这样。
but,这样写会让所有的数据都更新,对性能的消耗挺大的。
// !!!这样写
rowHasChanged: ( row1, row2) => true
emmm,但是我不想去看其他的插件了,所以就采用了上面的写法。
下面就讲一下我怎么配置这个listView的,因为我觉得这个组件官方demo还真的写得蛮看不懂的。
ListView在实际项目中使用
下面的代码主要展示怎么配置listview,不要扣小地方,因为我把很多业务代码去掉了。
class Message extends React.Component {
constructor(props) {
super(props);
const dataSource = new ListView.DataSource({
// 这样写,每次都执行rowHasChanged,每次都更新row
rowHasChanged: ( row1, row2) => true
});
this.state = {
dataSource,
};
}
componentDidMount() {
// 请求初始化数据
}
// 在这里维护长列表数据,把从接口获取来的数据赋值给state里的dataSource。
componentWillReceiveProps(nextProps) {
if(nextProps.message.commentList !== this.props.message.commentList){
this.setState({
// 注意!这里的cloneWithRows(),antd里规定用它来更新dataSource,这个不是拼接数据,用这个函数,dataSource会更新成nextProps.message.commentList。
//所以在接受后端分页数据时,就把拼接好的数据赋值给nextProps.message.commentList(这个在model.js里写了)
dataSource: this.state.dataSource.cloneWithRows(nextProps.message.commentList),
});
}
}
// onEndReached,列表被滚动到距离最底部不足`onEndReachedThreshold`个像素的距离时调用
// 在这里写分页请求
onEndReached = (event) => {
const { dispatch } = this.props;
const { email } = this.props.user;
const { pageNum, pageSize, contentId, totalCount, commentList } = this.props.message;
let hasMore = totalCount > commentList.length ? true : false;
// load new data
// hasMore: from backend data, indicates whether it is the last page, here is false
if (!hasMore) {
return;
}
dispatch({
type: "message/updateStates",
payload: {
pageNum: pageNum+1,
isLoading: true,
isLongList: true
}
})
setTimeout(() => {
dispatch({
type: "message/getCommentsByContentId",
payload: {
contentId,
identity: email,
pageNum: pageNum+1,
pageSize
}
})
}, 1000);
}
render() {
// 列表的item
const row = (rowData, sectionID, rowID) => {
const item = rowData;
return (
<div className={styles.item} key={rowID}>
<div onClick={toggleLike}>点赞</div>
<div className={styles.content}>{item.content}</div>
</div>
</div>
);
};
return (
<Fragment>
<ListView
ref={el => this.lv = el}
dataSource={this.state.dataSource}
renderHeader={() => (
<div className={styles.sub}>
<span>列表头,什么写点什么</span>
</div>
)}
renderFooter={() => (<div style={{ padding: 10, textAlign: 'center' }}>
{ isLoading ? '加载中' : '加载完毕'}
</div>)}
renderRow={row}
className="am-list"
pageSize={pageSize}
useBodyScroll
scrollRenderAheadDistance={500}
onEndReached={this.onEndReached}
onEndReachedThreshold={10}
/>
</Fragment>
);
}
}
model.js
*getCommentsByContentId({ payload }, { call, put, select }) {
const { data } = yield call(getCommentsByContentId, payload);
const { message } = yield select(state=>state);
const { commentList } = message;
if (data.code === 200) {
// 长列表,上一次页的数据+这次的数据,赋值给新的commentList
let list = [...commentList, ...data.data.list]
yield put({
type: 'updateStates',
payload: {
totalCount: data.data.totalCount,
commentList: list
}
});
} else {
Toast.fail(data.msg, 1)
}
},
到此,相信大家对“antd-mobile ListView长列表的数据更新时常见问题”有了更深的了解,不妨来实际操作一番吧!这里是天达云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!