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 相关文章推荐
juqery 学习之三 选择器 可见性 元素属性
Nov 25 Javascript
JavaScript模板入门介绍
Sep 26 Javascript
js转化毫秒为时间格式代码
Apr 10 Javascript
js实现select组件的选择输入过滤代码
Oct 14 Javascript
javascript数组详解
Oct 22 Javascript
JS设置网页图片vspace和hspace属性的方法
Apr 01 Javascript
使用bootstraptable插件实现表格记录的查询、分页、排序操作
Aug 06 Javascript
jQueryUI Sortable 应用Demo(分享)
Sep 07 jQuery
Vue infinite update loop的问题解决
Apr 23 Javascript
JS正则表达式封装与使用操作示例
May 15 Javascript
JavaScript实现公告栏上下滚动效果
Mar 13 Javascript
vue+canvas实现拼图小游戏
Sep 18 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 默默经典版本
2009/08/04 PHP
一步一步学习PHP(1) php开发环境配置
2010/02/15 PHP
PHP常用技巧总结(附函数代码)
2012/02/04 PHP
百度地图API应用之获取用户的具体位置
2014/06/10 PHP
JS 树形递归实例代码
2010/05/18 Javascript
jquery实现图片等比例缩放以及max-width在ie中不兼容解决
2013/03/21 Javascript
Knockout数组(observable)使用详解示例
2013/11/15 Javascript
jquery跟随屏幕滚动效果的实现代码
2016/04/13 Javascript
Bootstrap面板(Panels)的简单实现代码
2017/03/17 Javascript
微信小程序HTTP接口请求封装的实现
2019/02/21 Javascript
Vue项目中配置pug解析支持
2019/05/10 Javascript
关于element-ui的隐藏组件el-scrollbar的使用
2019/05/29 Javascript
vue项目出现页面空白的解决方案
2019/10/31 Javascript
JavaScript中break、continue和return的用法区别实例分析
2020/03/02 Javascript
vue.js页面加载执行created,mounted的先后顺序说明
2020/11/07 Javascript
Python 装饰器使用详解
2017/07/29 Python
详解python3中tkinter知识点
2018/06/21 Python
python对日志进行处理的实例代码
2018/10/06 Python
Python 多线程不加锁分块读取文件的方法
2018/12/11 Python
Python爬虫实现使用beautifulSoup4爬取名言网功能案例
2019/09/15 Python
python 消除 futureWarning问题的解决
2019/12/25 Python
基于python实现删除指定文件类型
2020/07/21 Python
Python3.9最新版下载与安装图文教程详解(Windows系统为例)
2020/11/28 Python
CSS3解决移动页面上点击链接触发色块的问题
2016/06/03 HTML / CSS
css3实现椭圆轨迹旋转的示例代码
2018/10/29 HTML / CSS
Shopee新加坡:东南亚与台湾电商平台
2019/01/25 全球购物
四年的大学生生活自我评价
2013/12/09 职场文书
创业计划书如何吸引他人眼球
2014/01/10 职场文书
爱情检讨书大全
2014/01/21 职场文书
幼儿园招生广告
2014/03/19 职场文书
教导主任竞聘演讲稿
2014/05/16 职场文书
创建文明城市标语
2014/06/16 职场文书
鸟的天堂导游词
2015/01/31 职场文书
酒店采购员岗位职责
2015/04/03 职场文书
幼儿园开学温馨提示
2015/07/15 职场文书
2016年企业安全生产月活动总结
2016/04/06 职场文书