【问题标题】:How to paginate tables without libraries in React Next.js?如何在 React Next.js 中对没有库的表进行分页?
【发布时间】:2021-04-14 02:30:22
【问题描述】:

我正在学习为没有库的 ReactJS / NextJS 应用程序创建数据表。

我很难对表格进行分页,请您提供一个代码示例来处理这个问题。

这是我使用的表格代码:

const Table = () => {

  const data = [
    {name: 'Rara', profile: 'profile1', comment: 'comra'},
    {name: 'Dada', profile: 'profile2', comment: 'comda'},
    {name: 'Gaga', profile: 'profile1', comment: 'comga'},
    {name: 'Mama', profile: 'profile3', comment: 'comma'},
    {name: 'Papa', profile: 'profile4', comment: 'compa'},
    // ...
  ]

  const columns = [
    { id: 1, title: "Name", accessor: "name" },
    { id: 2, title: "Profile", accessor: "profile" },
    { id: 3, title: "Comment", accessor: "comment" },
  ];

  return (
    <table className={styles.container}>
      <thead>
        <tr>
          {columns.map((col) => (
            <th key={col.id}>{col.title}</th>
          ))}
        </tr>
      </thead>
      <tbody>
        {data.map((user, i) => (
          <tr key={i}>
            {columns.map((col) => (
              <td key={col.id}>{user[col.accessor]}</td>
            ))}
          </tr>
        ))}
      </tbody>
    </table>
  );
};

我非常感谢任何答案。

【问题讨论】:

  • 请考虑到前端分页可能会导致一些性能问题,因此我建议在后端分页而不是建议here
  • 这能回答你的问题吗? how to implement Pagination in reactJs
  • @luckongas 是的,对于大量数据,这张表只处理数百个数据,感谢您的建议。

标签: javascript reactjs next.js


【解决方案1】:

Array#slice 与递增的page 状态一起使用。这样的事情应该让你开始:


const Table = () => {

    // .....

    const itemsPerPage = 10;
    const [page, setPage] = useState(1);
    const displayData = useMemo(() => {
        const start = (page - 1) * itemsPerPage;
        return data.slice(start, start + itemsPerPage);
    }, [data]);

    // .....

    return (
        <>
            <button onClick={() => setPage(page + 1)}> Next Page </button>
            <button onClick={() => setPage(page - 1)}> Prev Page </button>

            { /* ..... */ }

              <tbody>
                {displayData.map((user, i) => (
                
             { /* ..... */ }


        </>
    );
};

【讨论】:

  • 谢谢@mccallofthewild,我得到了提示。
【解决方案2】:

我不久前用 JS 做了一些事情。注意:我不太擅长 React,所以可能需要更正一些代码。

这是一个起点

class table extends React.Component {



  const data = [{
      name: 'Rara',
      profile: 'profile1',
      comment: 'comra'
    },
    {
      name: 'Dada',
      profile: 'profile2',
      comment: 'comda'
    },
    {
      name: 'Gaga',
      profile: 'profile1',
      comment: 'comga'
    },
    {
      name: 'Mama',
      profile: 'profile3',
      comment: 'comma'
    },
    {
      name: 'Papa',
      profile: 'profile4',
      comment: 'compa'
    },
    // ...
  ]

  this.state = {
    selectedPage: 1,
    totalPages: 0,
    pageSize: 20
  }
  // totalPages should be comming from the database eg when you get the data from ajax, if you have all the data here then this should be good to go
  this.state.totalPages =Math.ceil((data.length - 1) / this.state.pageSize);
  const columns = [{
      id: 1,
      title: "Name",
      accessor: "name"
    },
    {
      id: 2,
      title: "Profile",
      accessor: "profile"
    },
    {
      id: 3,
      title: "Comment",
      accessor: "comment"
    },
  ];

 // get the data depending on which page you are on
  getData() {
    return data.slice(this.state.selectedPage * this.state.pageSize, this.state.pageSize);
  }


  // this should calculate the total viewed pagination eg prev 1 2 3 4 5 next
  paging() {

    if (!this.state.selectedPage || this.state.selectedPage > this.state.totalPages)
      this.state.selectedPage = 1;

    var start = this.state.selectedPage;
    var end = this.state.selectedPage;
    var counter = 3;
    //If the page cannot be devised by 5 enter the loop
    if ((start % counter != 0) && (end % counter != 0)) {
      //Get the next nearest page that is divisible by 5
      while ((end % counter) != 0) {
        end++;
      }
      //Get the previous nearest page that is divisible by 5
      while ((start % counter) != 0) {
        start--;
      }

    }
    //The page is divisible by 5 so get the next 5 pages in the pagination
    else {
      end += counter;
    }
    //We are on the first page
    if (start == 0) {
      start++;
      end++;
    }



    //We are on the last page
    if (end == this.state.totalPages || end > this.state.totalPages) {
      end = this.state.totalPages;
    }

    if (start == this.state.selectedPage && start > 1)
      start--;

    while (end - start < counter && end - start > 0)
      start--;


    if (start <= 0)
      start = 1;

    while (end - start > counter)
      end--;


    return {
      start: start,
      end: end
    };


  }


  jumToPage(e) {
    var s = this.state;
    s.selectedPage = parseInt(e.innerText);
    this.setState(s);
  }

  next() {
    var s = this.state;
    s.selectedPage += 1;
    this.setState(s);
  }

  prev() {
    var s = this.state;
    s.selectedPage -= 1;
    this.setState(s);
  }

  render() {
    var footerData = this.paging();

    return ( <
      table className = {
        styles.container
      } >
      <
      thead >
      <
      tr > {
        columns.map((col) => ( <
          th key = {
            col.id
          } > {
            col.title
          } < /th>
        ))
      } <
      /tr> < /
      thead > <
      tbody > {
        this.getData().map((user, i) => ( <
          tr key = {
            i
          } > {
            columns.map((col) => ( <
              td key = {
                col.id
              } > {
                user[col.accessor]
              } < /td>
            ))
          } <
          /tr>
        ))
      } <
      /tbody>  <
      tfoot > ( <
        tr >
        ( <
          td >
          <
          p onClick = {
            this.prev.bind(this)
          }
          className = {
            this.state.selectedPage <= 1 ? "disabled" : ""
          } > prev < /p> <
          /td>
        ) <
        /td>
        <td cols={columns.length - 2 }>
        for (var i = footerData.start; i < footerData.end; i++) { 
            <
            p onClick = {
              this.jumToPage.bind(this)
            } > {
              i
            } < /p>
        }
       </td>
      ) <
      td >
      ( <
        td >
        <
        p onClick = {
          this.next.bind(this)
        }
        className = {
          this.state.selectedPage >= this.state.totalPages ? "disabled" : ""
        } > next < /p> <
        /td>
      ) <
      /tr> <
      /tfoot> <
      /table>
    );
  }
};

【讨论】:

  • 谢谢@Alen,我从你的代码中得到了很多提示。
  • 好吧,这不能回答你的问题吗?如果它剂量你会触发这个作为答案吗?
【解决方案3】:

所以我曾经负责为 API 端点进行分页,我所做的是我编写了一个控制器来处理它,并且采用的参数是 page 和 pageCount。

我的端点:http://localhost:8000/api/icecream/:page/:pageCount

页面指的是您想要数据所在的页面(取决于 pageCount) pageCount 是指你想要的单页数据的数量。

所以我只写了一个函数,它首先从数据库中检索所需的数据作为数组,然后根据作为 URL 参数提供的条件创建子数组。

代码如下所示:

module.exports.getIceCreamMenu = async function(req, res){
    try{
        const pageCount = parseInt(req.params.pageCount); // 10 flavours to be presented per page
        const page = parseInt(req.params.page); 
        const flavours = getFromDB(req.user.email); // fetching data from db as an array MONGODB

        var start = (page-1)*pageCount; // getting start point of the list
        var end = (pageCount*page); // getting end point of the list

        const requiredFlavourList = flavours.slice(start,end);
        res.json({success: true, flavours: requiredflavoursList});

    }catch(err){
        if(err) res.json({success: false, message: err.message});
    }
}

【讨论】:

    猜你喜欢
    • 2018-06-13
    • 2021-10-08
    • 2019-08-03
    • 1970-01-01
    • 1970-01-01
    • 2011-10-04
    • 1970-01-01
    • 2015-10-14
    • 2018-05-25
    相关资源
    最近更新 更多