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 相关文章推荐
js 覆盖和重载 函数
Sep 25 Javascript
js escape,unescape解决中文乱码问题的方法
May 26 Javascript
js 判断checkbox是否选中的操作方法
Nov 09 Javascript
jQuery表单获取和失去焦点输入框提示效果的实例代码
Aug 01 Javascript
checkbox设置复选框的只读效果不让用户勾选
Aug 12 Javascript
js判断手机端(Android手机还是iPhone手机)
Jul 22 Javascript
原生JavaScript实现滚动条效果
Mar 24 Javascript
JS实现随页面滚动显示/隐藏窗口固定位置元素
Feb 26 Javascript
react-native 封装选择弹出框示例(试用ios&amp;android)
Jul 11 Javascript
Jquery中.bind()、.live()、.delegate()和.on()之间的区别详解
Aug 01 jQuery
jstree中的checkbox默认选中和隐藏示例代码
Dec 29 Javascript
electron踩坑之dialog中的callback解决
Oct 06 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面向对象全攻略 (十四) php5接口技术
2009/09/30 PHP
详解WordPress中的头像缓存和代理中的缓存更新方法
2016/03/01 PHP
PHP数组函数知识汇总
2016/05/12 PHP
thinkPHP3.2简单实现文件上传的方法
2016/05/16 PHP
php+websocket 实现的聊天室功能详解
2020/05/27 PHP
可在线编辑网页文字效果代码(单击)
2013/03/02 Javascript
使用jQuery实现返回顶部
2015/01/26 Javascript
JS网页在线获取鼠标坐标值的方法
2015/02/28 Javascript
Node.js与Sails ~项目结构与Mvc实现及日志机制
2015/10/14 Javascript
基于JavaScript将表单序列化类型的数据转化成对象的处理(允许对象中包含对象)
2015/12/28 Javascript
js仿3366小游戏选字游戏
2016/04/14 Javascript
文本框只能输入数字的js代码(含小数点)
2016/07/10 Javascript
js实现常用排序算法
2016/08/09 Javascript
ionic实现可滑动的tab选项卡切换效果
2020/04/15 Javascript
js实现复选框的全选和取消全选效果
2017/01/03 Javascript
如何编写jquery插件
2017/03/29 jQuery
JS匹配日期和时间的正则表达式示例
2017/05/12 Javascript
bootstrap选项卡扩展功能详解
2017/06/14 Javascript
JavaScript中的一些隐式转换和总结(推荐)
2017/12/22 Javascript
Vue使用json-server进行后端数据模拟功能
2018/04/17 Javascript
原生JS实现简单的倒计时功能示例
2018/08/30 Javascript
JS实现音乐钢琴特效
2020/01/06 Javascript
js实现文字头像的生成代码
2020/03/07 Javascript
vue 判断页面是首次进入还是再次刷新的实例
2020/11/05 Javascript
JavaScript canvas实现雨滴特效
2021/01/10 Javascript
[01:06:42]VP vs NewBee Supermajor 胜者组 BO3 第二场 6.5
2018/06/06 DOTA
Python3安装Scrapy的方法步骤
2017/11/23 Python
浅述python中深浅拷贝原理
2018/09/18 Python
python 定义类时,实现内部方法的互相调用
2019/12/25 Python
Python实现异步IO的示例
2020/11/05 Python
利用三角函数在canvas上画虚线的方法
2018/01/11 HTML / CSS
怀旧收藏品和经典纪念品:Betty’s Attic
2018/08/29 全球购物
沙滩主题婚礼活动策划方案
2014/09/15 职场文书
政协会议宣传标语
2014/10/09 职场文书
2014年材料员工作总结
2014/11/19 职场文书
2015年度校学生会工作总结报告
2015/05/23 职场文书