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倒数计时按钮setTimeout的实例代码
Jul 04 Javascript
DOM基础教程之模型中的模型节点
Jan 19 Javascript
超赞的动手创建JavaScript框架的详细教程
Jun 30 Javascript
JS实现微信弹出搜索框 多条件查询功能
Dec 13 Javascript
在DWR中实现直接获取一个JAVA类的返回值的两种方法
Dec 25 Javascript
微信小程序图表插件(wx-charts)实例代码
Jan 17 Javascript
touch.js 拖动、缩放、旋转 (鼠标手势)功能代码
Feb 04 Javascript
vue.js模仿京东省市区三级联动的选择组件实例代码
Nov 22 Javascript
使用react实现手机号的数据同步显示功能的示例代码
Apr 03 Javascript
利用jquery和BootStrap实现动态滚动条效果
Dec 03 jQuery
webpack4实现不同的导出类型
Apr 09 Javascript
vue全屏事件开发详解
Jun 17 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
openPNE常用方法分享
2011/11/29 PHP
php中$美元符号与Zen Coding冲突问题解决方法分享
2014/05/28 PHP
PHP实现操作redis的封装类完整实例
2015/11/14 PHP
PHP删除二维数组中相同元素及数组重复值的方法示例
2017/05/05 PHP
php弹出提示框的是实例写法
2019/09/26 PHP
JavaScript高级程序设计 读书笔记之九 本地对象Array
2012/02/27 Javascript
仅IE支持clearAttributes/mergeAttributes方法使用介绍
2012/05/04 Javascript
javascript数组去重3种方法的性能测试与比较
2013/03/26 Javascript
jQuery替换字符串(实例代码)
2013/11/13 Javascript
浅谈JavaScript函数参数的可修改性问题
2013/12/05 Javascript
我的Node.js学习之路(四)--单元测试
2014/07/06 Javascript
JQuery判断radio是否选中并获取选中值的示例代码
2014/10/17 Javascript
javascript引用赋值(地址传值)用法实例
2015/01/13 Javascript
jQuery插件uploadify实现ajax效果的图片上传
2016/06/18 Javascript
jQuery绑定自定义事件的魔法升级版
2016/06/30 Javascript
利用js给datalist或select动态添加option选项的方法
2018/01/25 Javascript
Vue-Router模式和钩子的用法
2018/02/28 Javascript
layer ui 导入文件之前传入数据的实例
2019/09/23 Javascript
vue实现选中效果
2020/10/07 Javascript
python实现查找两个字符串中相同字符并输出的方法
2015/07/11 Python
Python基于回溯法子集树模板解决取物搭配问题实例
2017/09/02 Python
python 删除指定时间间隔之前的文件实例
2018/04/24 Python
python求加权平均值的实例(附纯python写法)
2019/08/22 Python
wxpython绘制音频效果
2019/11/18 Python
python如何使用代码运行助手
2020/07/03 Python
Python之字典对象的几种创建方法
2020/09/30 Python
检测浏览器对HTML5和CSS3支持度的方法
2015/06/25 HTML / CSS
上海微创软件面试题
2012/06/14 面试题
酒店个人培训自我鉴定
2013/12/11 职场文书
学前教育学生自荐信范文
2013/12/31 职场文书
好人好事事迹材料
2014/02/12 职场文书
中学清明节活动总结
2014/07/04 职场文书
初中毕业感言300字
2015/07/31 职场文书
患者身份识别制度
2015/08/06 职场文书
银行培训心得体会范文
2016/01/09 职场文书
医学会议开幕词
2016/03/03 职场文书