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 相关文章推荐
jquery模拟按下回车实现代码
Sep 20 Javascript
教你用jquery实现iframe自适应高度
Jun 11 Javascript
JavaScript将数组转换成CSV格式的方法
Mar 19 Javascript
javascript实现俄罗斯方块游戏的思路和方法
Apr 27 Javascript
javascript实现完美拖拽效果
May 06 Javascript
javaScript中with函数用法实例分析
Jun 08 Javascript
jqGrid用法汇总(全经典)
Jun 28 Javascript
浅谈jquery上下滑动的注意事项
Oct 13 Javascript
jQuery实现在HTML文档加载完毕后自动执行某个事件的方法
May 08 jQuery
vuejs事件中心管理组件间的通信详解
Aug 09 Javascript
详解ES6语法之可迭代协议和迭代器协议
Jan 13 Javascript
js逆向解密之网络爬虫
May 30 Javascript
详解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扩展程序实现守护进程
2015/04/16 PHP
PHP SPL标准库之接口(Interface)详解
2015/05/11 PHP
微信公众平台开发之天气预报功能
2015/08/31 PHP
杨氏矩阵查找的JS代码
2013/03/21 Javascript
jquery数组之存放checkbox全选值示例代码
2013/12/20 Javascript
浅析javascript 定时器
2014/12/23 Javascript
js实现圆盘记速表
2015/08/03 Javascript
jQuery插件Validate实现自定义校验结果样式
2016/01/18 Javascript
jQuery选择器基础入门教程
2016/05/10 Javascript
javascript 小数乘法结果错误的处理方法
2016/07/28 Javascript
纯js实现html转pdf的简单实例(推荐)
2017/02/16 Javascript
nodeJS微信分享
2017/12/20 NodeJs
React数据传递之组件内部通信的方法
2017/12/31 Javascript
Vue Element 分组+多选+可搜索Select选择器实现示例
2018/07/23 Javascript
详解如何在nuxt中添加proxyTable代理
2018/08/10 Javascript
微信小程序自定义单项选择器样式
2019/07/25 Javascript
微信小程序之滑动页面隐藏和显示组件功能的实现代码
2020/06/19 Javascript
查找Vue中下标的操作(some和findindex)
2020/08/12 Javascript
[03:44]2015国际邀请赛选手档案—Cloud9.NoTail
2015/07/28 DOTA
深入理解Python对Json的解析
2017/02/14 Python
python 3.6 +pyMysql 操作mysql数据库(实例讲解)
2017/12/20 Python
Python面向对象之类的内置attr属性示例
2018/12/14 Python
Python实现将通信达.day文件读取为DataFrame
2018/12/22 Python
Python OpenCV对本地视频文件进行分帧保存的实例
2019/01/08 Python
关于Python Tkinter Button控件command传参问题的解决方式
2020/03/04 Python
基于pycharm实现批量修改变量名
2020/06/02 Python
HTML5+CSS3:3D展示商品信息示例
2017/01/03 HTML / CSS
美国知名玩具品牌:Melissa & Doug
2016/08/16 全球购物
同学聚会欢迎辞
2014/01/14 职场文书
大学生涯自我鉴定
2014/01/16 职场文书
银行办公室岗位职责
2014/03/10 职场文书
本科毕业生自荐信
2014/06/02 职场文书
党员干部廉洁自律承诺书
2015/04/28 职场文书
奖励申请报告范文
2015/05/15 职场文书
三好学生竞选稿
2015/11/21 职场文书
2020年基层司法所建设情况调研报告
2019/11/30 职场文书