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 相关文章推荐
$.ajax json数据传递方法
Nov 19 Javascript
一个JQuery写的点击上下滚动的小例子
Aug 27 Javascript
ASP.NET jQuery 实例16 通过控件CustomValidator验证RadioButtonList
Feb 03 Javascript
关于JQuery($.load)事件的用法和分析
Apr 09 Javascript
在子窗口中关闭父窗口的一句代码
Oct 21 Javascript
Js调用Java方法并互相传参的简单实例
Aug 11 Javascript
Angular.js实现多个checkbox只能选择一个的方法示例
Feb 24 Javascript
Bootstrap表单控件学习使用
Mar 07 Javascript
vue2过滤器模糊查询方法
Sep 16 Javascript
JavaScript根据json生成html表格的示例代码
Oct 24 Javascript
OpenLayers加载缩放控件使用方法详解
Sep 25 Javascript
小程序实现上下切换位置
Nov 16 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
基于Snoopy的PHP近似完美获取网站编码的代码
2011/10/23 PHP
Yii扩展组件编写方法实例分析
2015/06/29 PHP
php实现Session存储到Redis
2015/11/11 PHP
PHP实现的Redis多库选择功能单例类
2017/07/27 PHP
PHP PDO和消息队列的个人理解与应用实例分析
2019/11/25 PHP
Javascript中浮点数相乘的一个解决方法
2014/06/03 Javascript
基于Flowplayer打造一款免费的WEB视频播放器附源码
2015/09/06 Javascript
jquery判断复选框是否选中进行答题提示特效
2015/12/10 Javascript
javascript中eval解析JSON字符串
2016/02/27 Javascript
js调用webservice构造SOAP进行身份验证
2016/04/27 Javascript
jQuery实现元素的插入
2017/02/27 Javascript
vue mint-ui tabbar变组件使用
2018/05/04 Javascript
JS原生瀑布流效果实现
2019/04/26 Javascript
ES6小技巧之代替lodash
2019/06/07 Javascript
Jquery动态列功能完整实例
2019/08/30 jQuery
Vue项目中如何使用Axios封装http请求详解
2019/10/23 Javascript
微信小程序获取当前位置和城市名
2019/11/13 Javascript
JavaScript基于用户照片姓名生成海报
2020/05/29 Javascript
使用Mixin设计模式进行Python编程的方法讲解
2016/06/21 Python
Python中函数及默认参数的定义与调用操作实例分析
2017/07/25 Python
处理python中多线程与多进程中的数据共享问题
2019/07/28 Python
Python整数与Numpy数据溢出问题解决
2019/09/11 Python
django中嵌套的try-except实例
2020/05/21 Python
Python猫眼电影最近上映的电影票房信息
2020/09/18 Python
pycharm进入时每次都是insert模式的解决方式
2021/02/05 Python
介绍CSS3使用技巧5个
2009/04/02 HTML / CSS
国际书籍零售商:Wordery
2017/11/01 全球购物
解释下列WebService名词:WSDL、SOAP、UDDI
2012/06/22 面试题
幼儿师范毕业生自荐信
2013/11/09 职场文书
会计岗位说明书
2014/07/29 职场文书
搞笑的爱情检讨书
2014/10/01 职场文书
市场部经理岗位职责
2015/02/02 职场文书
2016个人廉洁自律承诺书
2016/03/25 职场文书
餐厅营销的秘密:为什么老顾客会流水?
2019/08/08 职场文书
解决golang结构体tag编译错误的问题
2021/05/02 Golang
vue递归实现树形组件
2022/07/15 Vue.js