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的ES6版本中的解构赋值
Jul 28 Javascript
Jquery跨域获得Json的简单实例
May 18 Javascript
JavaScript兼容浏览器FF/IE技巧
Aug 14 Javascript
jquery请求servlet实现ajax异步请求的示例
Jun 03 jQuery
vue better-scroll插件使用详解
Jan 25 Javascript
ejsExcel模板在Vue.js项目中的实际运用
Jan 27 Javascript
Angular 封装并发布组件的方法示例
Apr 19 Javascript
微信小程序实现漂亮的弹窗效果
May 26 Javascript
JavaScript中this关键字用法实例分析
Aug 24 Javascript
vue input输入框关键字筛选检索列表数据展示
Oct 26 Javascript
jQuery zTree树插件的使用教程
Aug 16 jQuery
js+css实现全屏侧边栏
Jun 16 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中的日期及时间
2006/11/23 PHP
PHP Google的translate API代码
2008/12/10 PHP
关于PHP结束标签的使用细节探讨及联想
2013/03/04 PHP
php生成QRcode实例
2014/09/22 PHP
PHP使用递归算法无限遍历数组示例
2017/01/13 PHP
tp5(thinkPHP5框架)使用DB实现批量删除功能示例
2019/05/28 PHP
TopList标签和JavaScript结合两例
2007/08/12 Javascript
javascript add event remove event
2008/04/07 Javascript
通过上下左右键和回车键切换光标实现代码
2013/03/08 Javascript
JQuery onload、ready概念介绍及使用方法
2013/04/27 Javascript
javascript实现数字验证码的简单实例
2014/02/10 Javascript
使用node.js半年来总结的 10 条经验
2014/08/18 Javascript
JavaScript中的原型prototype属性使用详解
2015/06/05 Javascript
Javascript监视变量变化的方法
2015/06/09 Javascript
图解js图片轮播效果
2015/12/20 Javascript
整理AngularJS框架使用过程当中的一些性能优化要点
2016/03/05 Javascript
javascript 解决浏览器不支持的问题
2016/09/24 Javascript
js仿百度音乐全选操作
2017/01/13 Javascript
基于JavaScript实现屏幕滚动效果
2017/01/18 Javascript
Bootstrap页面缩小变形的快速解决办法
2017/02/03 Javascript
vue-cli之router基本使用方法详解
2017/10/17 Javascript
js制作提示框插件
2020/12/24 Javascript
jquery自定义组件实例详解
2020/12/31 jQuery
[01:12:53]完美世界DOTA2联赛PWL S2 Forest vs SZ 第一场 11.25
2020/11/26 DOTA
浅谈python函数之作用域(python3.5)
2017/10/27 Python
python通过Windows下远程控制Linux系统
2018/06/20 Python
Python使用gRPC传输协议教程
2018/10/16 Python
删除pycharm鼠标右键快捷键打开项目的操作
2021/01/16 Python
HTML5手机端弹出遮罩菜单特效代码
2016/01/27 HTML / CSS
New Balance波兰官方商城:始于1906年,百年慢跑品牌
2017/08/15 全球购物
法国一家芭蕾舞鞋公司:Repetto
2018/11/12 全球购物
Tommy Hilfiger美国官网:美国高端休闲领导品牌
2019/01/14 全球购物
Java如何支持I18N?
2016/10/31 面试题
2013年保送生自荐信格式
2013/11/20 职场文书
趣味运动会通讯稿
2015/07/18 职场文书
导游词之澳门妈祖庙
2019/12/19 职场文书