antd-mobile ListView长列表的数据更新遇到的坑


Posted in Javascript onApril 08, 2020

遇到的问题

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长列表的数据更新遇到的坑的详细内容,更多关于antd-mobile ListView长列表的资料请关注三水点靠木其它相关文章!

Javascript 相关文章推荐
JavaScript 学习笔记(七)字符串的连接
Dec 31 Javascript
JQuery制作的放大效果的popup对话框(未添加任何jquery plugin)分享
Apr 28 Javascript
在javaScript中关于submit和button的区别介绍
Oct 20 Javascript
javascript正则表达式之search()用法实例
Jan 19 Javascript
javascript父子页面通讯实例详解
Jul 17 Javascript
整理关于Bootstrap列表组的慕课笔记
Mar 29 Javascript
基于vue+ bootstrap实现图片上传图片展示功能
May 17 Javascript
ReactNative之FlatList的具体使用方法
Nov 29 Javascript
vue接入腾讯防水墙代码
May 07 Javascript
24个解决实际问题的ES6代码片段(小结)
Feb 02 Javascript
关于JavaScript中异步/等待的用法与理解
Nov 18 Javascript
vue中watch的用法汇总
Dec 28 Vue.js
详解element上传组件before-remove钩子问题解决
Apr 08 #Javascript
javascript 设计模式之享元模式原理与应用详解
Apr 08 #Javascript
javascript 设计模式之组合模式原理与应用详解
Apr 08 #Javascript
JS async 函数的含义和用法实例总结
Apr 08 #Javascript
微信小程序以ssm做后台开发的实现示例
Apr 08 #Javascript
JS co 函数库的含义和用法实例总结
Apr 08 #Javascript
JS Thunk 函数的含义和用法实例总结
Apr 08 #Javascript
You might like
PHP与MongoDB简介|安全|M+PHP应用实例详解
2013/06/17 PHP
PHP获取客户端及服务器端IP的封装类
2016/07/21 PHP
PHP实现微信模拟登陆并给用户发送消息的方法【文字,图片,图文】
2017/06/29 PHP
详解php与ethereum客户端交互
2018/04/28 PHP
javascript实现的距离现在多长时间后的一个格式化的日期
2009/10/29 Javascript
JavaScript对象、属性、事件手册集合方便查询
2010/07/04 Javascript
jquery中push()的用法(数组添加元素)
2014/11/25 Javascript
Bootstrap模态框调用功能实现方法
2016/09/19 Javascript
js放大镜放大购物图片效果
2017/01/18 Javascript
jquery 仿锚点跳转到页面指定位置的实例
2017/02/14 Javascript
vue生成token保存在客户端localStorage中的方法
2017/10/25 Javascript
jQuery实现的两种简单弹窗效果示例
2018/04/18 jQuery
解决Layui数据表格中checkbox位置不居中的方法
2018/08/15 Javascript
vue移动端项目缓存问题实践记录
2018/10/29 Javascript
详解vuex 渐进式教程实例代码
2018/11/27 Javascript
JavaScript中的回调函数实例讲解
2019/01/27 Javascript
简单了解Javscript中兄弟ifream的方法调用
2019/06/17 Javascript
详细教你微信公众号正文页SVG交互开发技巧
2019/07/25 Javascript
解决在layer.open中使用时间控件laydate失败的问题
2019/09/11 Javascript
jQuery HTML获取内容和属性操作实例分析
2020/05/20 jQuery
详解js创建对象的几种方式和对象方法
2021/03/01 Javascript
压缩包密码破解示例分享(类似典破解)
2014/01/17 Python
Python 抓取动态网页内容方案详解
2014/12/25 Python
python3实现TCP协议的简单服务器和客户端案例(分享)
2017/06/14 Python
名片管理系统python版
2018/01/11 Python
解决项目pycharm能运行,在终端却无法运行的问题
2019/01/19 Python
对IPython交互模式下的退出方法详解
2019/02/16 Python
python爬虫scrapy框架之增量式爬虫的示例代码
2021/02/26 Python
视图的作用
2014/12/19 面试题
元旦晚会感言
2014/03/12 职场文书
《彭德怀和他的大黑骡子》教学反思
2014/04/12 职场文书
教师专业自荐信
2014/05/31 职场文书
2014年征兵标语
2014/06/20 职场文书
行政助理岗位职责
2015/02/10 职场文书
2015年财务部工作总结
2015/04/10 职场文书
css display table 自适应高度、宽度问题的解决
2021/05/07 HTML / CSS