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 append()方法与html()方法的区别及使用介绍
Aug 01 Javascript
兼容各大浏览器的JavaScript阻止事件冒泡代码
Jul 09 Javascript
浅析JavaScript中浏览器的兼容问题
Apr 19 Javascript
原生js实现弹出层效果
Jan 20 Javascript
微信小程序wx.uploadfile 本地文件转base64的实现代码
Jun 28 Javascript
jQuery插件实现的日历功能示例【附源码下载】
Sep 07 jQuery
vue项目中跳转到外部链接的实例讲解
Sep 20 Javascript
jQuery实现的自定义轮播图功能详解
Dec 28 jQuery
Vue.js如何使用Socket.IO的示例代码
Sep 05 Javascript
iview form清除校验状态的实现
Sep 19 Javascript
js实现GIF图片的分解和合成
Oct 24 Javascript
react的hooks的用法详解
Oct 12 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
Oracle 常见问题解答
2006/10/09 PHP
浅谈PHP语法(1)
2006/10/09 PHP
PHP 采集程序原理分析篇
2010/03/05 PHP
php Xdebug 调试扩展的安装与使用.
2010/03/13 PHP
PHP编程计算日期间隔天数的方法
2017/04/26 PHP
php 7新特性之类型申明详解
2017/06/06 PHP
WordPress 插件——CoolCode使用方法与下载
2007/07/02 Javascript
javascript强大的日期函数代码分享
2013/09/04 Javascript
使用JavaScript获取地址栏参数的方法
2014/12/19 Javascript
教你如何在Node.js中使用jQuery
2016/08/28 Javascript
js实现微博发布小功能
2017/01/12 Javascript
ECMAScript6 新特性范例大全
2017/03/24 Javascript
在node中如何使用 ES6
2017/04/22 Javascript
Easyui ueditor 整合解决不能编辑的问题(推荐)
2017/06/25 Javascript
Bootstrap与Angularjs的模态框实例代码
2017/08/03 Javascript
Angular 4.x+Ionic3踩坑之Ionic3.x pop反向传值详解
2018/03/13 Javascript
webpack4+react多页面架构的实现
2018/10/25 Javascript
有趣的JavaScript隐式类型转换操作实例分析
2020/05/02 Javascript
全面解析JavaScript Module模式
2020/07/24 Javascript
Python实现的百度站长自动URL提交小工具
2014/06/27 Python
Python中splitlines()方法的使用简介
2015/05/20 Python
python复制列表时[:]和[::]之间有什么区别
2018/10/16 Python
通过shell+python实现企业微信预警
2019/03/07 Python
Python后台开发Django的教程详解(启动)
2019/04/08 Python
Python2.7版os.path.isdir中文路径返回false的解决方法
2019/06/21 Python
使用python的pandas为你的股票绘制趋势图
2019/06/26 Python
财务工作个人求职的自我评价
2013/12/19 职场文书
商场拾金不昧表扬信
2014/01/13 职场文书
法律进社区实施方案
2014/03/21 职场文书
《回乡偶书》教学反思
2014/04/12 职场文书
干部选拔任用方案
2014/05/26 职场文书
2019如何书写演讲稿?
2019/07/01 职场文书
写作技巧:如何撰写一份优秀的营销策划书
2019/08/13 职场文书
撤回我也能看到!教你用Python制作微信防撤回脚本
2021/06/11 Python
MySql分区类型及创建分区的方法
2022/04/13 MySQL
Spring Data JPA框架持久化存储数据到数据库
2022/04/28 Java/Android