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资料toString 方法
Mar 13 Javascript
用Javascript实现Sleep暂停功能代码
Sep 03 Javascript
JQuery CheckBox(复选框)操作方法汇总
Apr 15 Javascript
BootStrap中的table实现数据填充与分页应用小结
May 26 Javascript
常用的js验证和数据处理总结
Aug 02 Javascript
BootStrap轻松实现微信页面开发代码分享
Oct 21 Javascript
JavaScript中定义对象原型的两种使用方法
Dec 15 Javascript
jQuery基于ajax方式实现用户名存在性检查功能示例
Feb 10 Javascript
在ABP框架中使用BootstrapTable组件的方法
Jul 31 Javascript
JavaScript基础心法 深浅拷贝(浅拷贝和深拷贝)
Mar 05 Javascript
如何在wxml中直接写js代码(wxs)
Nov 14 Javascript
react中的DOM操作实现
Jun 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运行模式的深入理解
2013/06/03 PHP
常见的四种POST 提交数据方式(小总结)
2015/10/08 PHP
PHP中的session安全吗?
2016/01/22 PHP
php app支付宝回调(异步通知)详解
2018/07/25 PHP
PHP实现给定一列字符,生成指定长度的所有可能组合示例
2019/06/22 PHP
javascript 禁止复制网页
2009/06/11 Javascript
对比分析json及XML
2014/11/28 Javascript
js面向对象之静态方法和静态属性实例分析
2015/01/10 Javascript
JavaScript中反正弦函数Math.asin()的使用简介
2015/06/14 Javascript
js点击文本框后才加载验证码实例代码
2015/10/20 Javascript
js性能优化技巧
2015/11/29 Javascript
javascript实现table单元格点击展开隐藏效果(实例代码)
2017/04/10 Javascript
javascript编写简易计算器
2017/05/06 Javascript
AngularJS中使用ngModal模态框实例
2017/05/27 Javascript
Mac系统下Webstorm快捷键整理大全
2017/05/28 Javascript
vue keep-alive请求数据的方法示例
2018/05/16 Javascript
Vue实现美团app的影院推荐选座功能【推荐】
2018/08/29 Javascript
使用uni-app开发微信小程序的实现
2019/12/13 Javascript
[03:06]3分钟带你回顾DOTA2完美盛典&完美大师赛
2017/12/06 DOTA
python3.0 字典key排序
2008/12/24 Python
python处理大数字的方法
2015/05/27 Python
Python实现PS图像明亮度调整效果示例
2018/01/23 Python
pycharm内无法import已安装的模块问题解决
2020/02/12 Python
django 取消csrf限制的实例
2020/03/13 Python
中国跨境海淘网站:考拉海购
2016/08/01 全球购物
法律专业个人实习自我鉴定
2013/09/23 职场文书
新闻系毕业生推荐信
2013/11/16 职场文书
工程造价与管理专业应届生求职信
2013/11/23 职场文书
心理学专业大学生职业生涯规划范文
2014/02/19 职场文书
法人授权委托书格式
2014/04/08 职场文书
旅游安全协议书
2014/04/21 职场文书
2014年节能降耗工作总结
2014/12/11 职场文书
使用 MybatisPlus 连接 SqlServer 数据库解决 OFFSET 分页问题
2022/04/22 SQL Server
Meta增速拉垮,元宇宙难当重任
2022/04/29 数码科技
python可视化分析绘制带趋势线的散点图和边缘直方图
2022/06/25 Python
redis lua限流算法实现示例
2022/07/15 Redis