• React Ant Design Mobile 中 ListView 简单使用,搞懂每一行代码


    初用Ant Design Mobile 中 ListView ,看到官方示例,新手朋友估计第一反应都是一脸蒙逼,现在我们写一个最简单的示例,除了让代码运作起来,也让大家知道每一行代码的作用
    "dependencies": {
        "antd": "^3.26.11",
        "antd-mobile": "^2.3.1",
        "axios": "^0.19.2",
        "qs": "^6.9.1",
        "react": "^16.6.3",
        "react-dom": "^16.6.3",
        "react-redux": "^6.0.0",
        "react-router-dom": "^4.3.1",
        "redux": "^4.0.5"
    }

    直接上代码示例,基本只要把请求方法换一下,就能直接用,对于关键代码都有注释,个人觉得比官网示例更简单易上手

    import React, { Component } from 'react'
    import { NavBar, Icon, ListView, PullToRefresh, Toast } from 'antd-mobile'
    import Api from '@/api/index.js'
    
    
    class myCourse extends Component {
      constructor(props) {
        super(props)
        // 创建ListViewDataSource对象
        const dataSource = new ListView.DataSource({
          rowHasChanged: (row1, row2) => row1 !== row2 // rowHasChanged(prevRowData, nextRowData); 用其进行数据变更的比较
        })
        this.state = {
          dataSource,
          datas: [],
          pageNo: 1,
          pageSize: 2,
          hasMore: true,
          refreshing: true,
          isLoading: true,
          dataArr: [],
        }
      }
    
      componentDidMount() {
        this.getData(true)
      }
    
      getData(ref = false) {
        //获取数据
        var para = {}
        para.pageSize = this.state.pageSize
        para.pageNo = this.state.pageNo
        Api.get('http://www.xxx.com/api/myCourse', para, res => {
          const dataList = res.data.list
          const len = dataList.length 
          if (len <= 0) { // 判断是否已经没有数据了
            this.setState({
              refreshing: false,
              isLoading: false,
              hasMore: false
            })
    
            Toast.info('没有数据了~', 1)
            return false
          }
          if (ref) {
            //这里表示刷新使用
            // 下拉刷新的情况,重新添加数据即可(这里等于只直接用了第一页的数据)
            this.setState({
              pageNo: this.state.pageNo,
              dataSource: this.state.dataSource.cloneWithRows(dataList), // 数据源中的数据本身是不可修改的,要更新datasource中的数据,请(每次都重新)调用cloneWithRows方法
              hasMore: true, // 下拉刷新后,重新允许开下拉加载
              refreshing: false, // 是否在刷新数据
              isLoading: false, // 是否在加载中
              dataArr: dataList // 保存数据进state,在下拉加载时需要使用已有数据
            })
          } else {
            // 这里表示上拉加载更多
            // 合并state中已有的数据和新增的数据
            var dataArr = this.state.dataArr.concat(dataList) //关键代码
            this.setState({
              pageNo: this.state.pageNo,
              dataSource: this.state.dataSource.cloneWithRows(dataArr), // 数据源中的数据本身是不可修改的,要更新datasource中的数据,请(每次都重新)调用cloneWithRows方法
              refreshing: false,
              isLoading: false,
              dataArr: dataArr // 保存新数据进state
            })
          }
        })
      }
    
      // 下拉刷新
      onRefresh = () => {
        this.setState({
          refreshing: true,
          isLoading: true,
          pageNo: 1 // 刷新嘛,一般加载第一页,或者按你自己的逻辑(比如每次刷新,换一个随机页码)
        }, ()=>{
          this.getData(true)
        })
      }
    
      // 滑动到底部时加载更多
      onEndReached = (event) => {
        // 加载中或没有数据了都不再加载
        if (this.state.isLoading || !this.state.hasMore) {
          return
        }
        this.setState({
          isLoading: true,
          pageNo: this.state.pageNo + 1, // 加载下一页
        }, ()=> {
          this.getData(false)
        })
    
      }
    
      render() {
        const row = (rowData, sectionID, rowID) => {
          // 这里rowData,就是上面方法cloneWithRows的数组遍历的单条数据了,直接用就行
          return (
            <div key={rowID} className="article">
              <div className="article-title">
                {rowData.courseTitle}
              </div>
              <div className="article-body">
                <div className="hidden">id: {rowData.id}</div>
                <div ><label className="label-3em">姓名</label>:{ rowData.userName }</div>
              </div>
            </div>
          )
        }
        return (
          <div className="content-bg">
            <div className="content-box">
              <ListView
                ref={el => this.lv = el}
                dataSource={this.state.dataSource}
                renderHeader={() => (<NavBar
                  mode="light"
                  icon={<Icon type="left" />}
                  onLeftClick={() => this.props.history.push('/usercenter') }
                >我的课程</NavBar>)}
                renderFooter={() => (<div className="footer">{this.state.isLoading ? '加载中...' : '暂无更多数据'}</div>)}
                renderRow={row}
                useBodyScroll
                pullToRefresh={<PullToRefresh
                  refreshing={this.state.refreshing}
                  onRefresh={this.onRefresh}
                />}
                onEndReachedThreshold={10}
                onEndReached={this.onEndReached}
                pageSize={5}
              />
            </div>
          </div>
        );
      }
    }
    
    export default myCourse

    如果不使用下拉刷新,那代码就更少了,关键代码就是要合并新增数据和之前加载的数据,concat方法即可

    var dataArr = this.state.dataArr.concat(dataList) 

    然后就是更新到dataSource中,需要用cloneWithRows方法,这点可以参考官方文档的解释,这里的官方文档不是antd文档, 是React Native https://reactnative.cn/docs/0.45/listviewdatasource.html 关于 ListView.DataSource的介绍,读懂的这个,再用Antd ListView就好理解多了

    import React, { Component } from 'react'
    import { NavBar, Icon, ListView, PullToRefresh, Toast } from 'antd-mobile'
    import Api from '@/api/index.js'
    
    
    class myCourse extends Component {
      constructor(props) {
        super(props)
        // 创建ListViewDataSource对象
        const dataSource = new ListView.DataSource({
          rowHasChanged: (row1, row2) => row1 !== row2 // rowHasChanged(prevRowData, nextRowData); 用其进行数据变更的比较
        })
        this.state = {
          dataSource,
          datas: [],
          pageNo: 1,
          pageSize: 2,
          hasMore: true,
          refreshing: true,
          isLoading: true,
          dataArr: [],
        }
      }
    
      componentDidMount() {
        this.getData(true)
      }
    
      getData(ref = false) {
        //获取数据
        var para = {}
        para.pageSize = this.state.pageSize
        para.pageNo = this.state.pageNo
        Api.get('http://www.xxx.com/api/myCourse', para, res => {
          const dataList = res.data.list
          const len = dataList.length 
          if (len <= 0) { // 判断是否已经没有数据了
            this.setState({
              refreshing: false,
              isLoading: false,
              hasMore: false
            })
    
            Toast.info('没有数据了~', 1)
            return false
          }
         
          // 这里表示上拉加载更多
          // 合并state中已有的数据和新增的数据
          var dataArr = this.state.dataArr.concat(dataList) //关键代码
          this.setState({
            pageNo: this.state.pageNo,
            dataSource: this.state.dataSource.cloneWithRows(dataArr), // 数据源中的数据本身是不可修改的,要更新datasource中的数据,请(每次都重新)调用cloneWithRows方法
            refreshing: false,
            isLoading: false,
            dataArr: dataArr // 保存新数据进state
          })
        })
      }
    
     
    
      // 滑动到底部时加载更多
      onEndReached = (event) => {
        // 加载中或没有数据了都不再加载
        if (this.state.isLoading || !this.state.hasMore) {
          return
        }
        this.setState({
          isLoading: true,
          pageNo: this.state.pageNo + 1, // 加载下一页
        }, ()=> {
          this.getData(false)
        })
    
      }
    
      render() {
        const row = (rowData, sectionID, rowID) => {
          // 这里rowData,就是上面方法cloneWithRows的数组遍历的单条数据了,直接用就行
          return (
            <div key={rowID} className="article">
              <div className="article-title">
                {rowData.courseTitle}
              </div>
              <div className="article-body">
                <div className="hidden">id: {rowData.id}</div>
                <div ><label className="label-3em">姓名</label>:{ rowData.userName }</div>
              </div>
            </div>
          )
        }
        return (
          <div className="content-bg">
            <div className="content-box">
              <ListView
                ref={el => this.lv = el}
                dataSource={this.state.dataSource}
                renderHeader={() => (<NavBar
                  mode="light"
                  icon={<Icon type="left" />}
                  onLeftClick={() => this.props.history.push('/usercenter') }
                >我的课程</NavBar>)}
                renderFooter={() => (<div className="footer">{this.state.isLoading ? '加载中...' : '暂无更多数据'}</div>)}
                renderRow={row}
                useBodyScroll
                onEndReachedThreshold={10}
                onEndReached={this.onEndReached}
                pageSize={5}
              />
            </div>
          </div>
        );
      }
    }
    
    export default myCourse
    漫思
  • 相关阅读:
    MySql使用游标Cursor循环(While)更新数据
    初试TinyIoCContainer笔记
    用Razor做静态页面生成器
    在CentOS6.5上安装MariaDB
    mono的远程调试
    mono3.2.3+Jexus5.5+openSuSE13.1的asp.net
    mono3.2和monodevelop4.0在ubuntu12.04上两天的苦战
    第一节知识点:.net与c#的概念
    支付宝支付功能(使用支付宝sdk)
    vs2017/vs2019 去掉 单击aspx文件预览页面
  • 原文地址:https://www.cnblogs.com/sexintercourse/p/13799773.html
Copyright © 2020-2023  润新知