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 相关文章推荐
如何让easyui gridview 宽度自适应窗口改变及fitColumns应用
Jan 25 Javascript
只需一行代码,轻松实现一个在线编辑器
Nov 12 Javascript
JQuery的Ajax请求实现局部刷新的简单实例
Feb 11 Javascript
js和C# 时间日期格式转换的简单实例
May 28 Javascript
angular ngClick阻止冒泡使用默认行为的方法
Nov 03 Javascript
Websocket协议详解及简单实例代码
Dec 12 Javascript
基于javascript的Form表单验证
Dec 29 Javascript
vue中使用sessionStorage记住密码功能
Jul 24 Javascript
angular 用Observable实现异步调用的方法
Dec 27 Javascript
详解Vue前端生产环境发布配置实战篇
May 07 Javascript
在Vue中使用icon 字体图标的方法
Jun 14 Javascript
Vue实现跑马灯样式文字横向滚动
Nov 23 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经典算法集锦【经典收藏】
2016/09/14 PHP
php获取ajax的headers方法与内容实例
2017/12/27 PHP
Smarty模板语法详解
2019/07/20 PHP
php传值和传引用的区别点总结
2019/11/19 PHP
脚本安需导入(装载)的三种模式的对比
2007/06/24 Javascript
用jquery实现学校的校历(asp.net+jquery ui 1.72)
2010/01/01 Javascript
缓动函数requestAnimationFrame 更好的实现浏览器经动画
2012/12/07 Javascript
jQuery动态改变图片显示大小(修改版)的实现思路及代码
2013/12/24 Javascript
jquery选择器之基本过滤选择器详解
2014/01/27 Javascript
浅析jquery的js图表组件highcharts
2014/03/06 Javascript
一个用jquery写的判断div滚动条到底部的方法【推荐】
2016/04/29 Javascript
jQuery中选择器的基础使用教程
2016/05/23 Javascript
必备的JS调试技巧汇总
2016/07/20 Javascript
jQuery事件绑定方法学习总结(推荐)
2016/11/21 Javascript
JavaScript中this的用法及this在不同应用场景的作用解析
2017/04/13 Javascript
详解webpack中的hash、chunkhash、contenthash区别
2018/01/05 Javascript
从零开始封装自己的自定义Vue组件
2018/10/09 Javascript
[02:07]2017国际邀请赛中国区预选赛直邀战队前瞻
2017/06/23 DOTA
Python切片工具pillow用法示例
2018/03/30 Python
python3 cvs将数据读取为字典的方法
2018/12/22 Python
python logging模块的使用总结
2019/07/09 Python
python连接PostgreSQL过程解析
2020/02/09 Python
Python下载的11种姿势(小结)
2020/11/18 Python
Ubuntu配置Pytorch on Graph (PoG)环境过程图解
2020/11/19 Python
Python爬虫中Selenium实现文件上传
2020/12/04 Python
软件测试工程师面试问题精选
2016/10/28 面试题
传统软件工程与面向对象的软件工程有什么区别
2012/05/31 面试题
大学本科毕业生的自我鉴定范文
2013/11/19 职场文书
菜篮子工程实施方案
2014/03/08 职场文书
人力资源管理专业应届生求职信
2014/04/24 职场文书
英文推荐信格式范文
2014/05/09 职场文书
学校学习雷锋活动总结
2014/07/03 职场文书
小学重阳节活动总结
2015/03/24 职场文书
抢劫罪辩护词
2015/05/21 职场文书
保护环境的宣传语
2015/07/13 职场文书
Java 常见的限流算法详细分析并实现
2022/04/07 Java/Android