小编典典

渲染数据数组作为分页组件

reactjs

我是React的新手,所以如果我误解了术语,请原谅我。

我想创建一种对组件数组进行分页的方法。为此,我按所需的每页项目数量对数组进行了切片,并将每页存储到一个ne数组中,例如:

const limit = 4
const numPages = 20
let pagewrapper = []

for (let i = 0; i < numPages; i++) {

  let start = i * limit
  let end = start + limit

  let pageItems = children.slice(start, end)

  // Skip first array push as 'page 1' is already showing.
  if (end != limit) {
    pagewrapper.push(<Grid gridContainerStyles={'grid-page__' + i} items={pageItems} />)
  }
}

然后,我创建了一个简单的按钮来一次显示每个页面。

    <Button
      onClick={this.pagerHandleClick}
    >
      {'Show more'}
    </Button>

处理程序如下所示:

  pagerHandleClick() {
    this.setState(state => ({
      page: state.page + 1,
    }))
  }

但是从这里我有点卡住了。我不知道如何告诉每个<Grid />人展示自己。我用Google提出的所有解决方案似乎都将组件包装在if语句中,但是将每个数组项包装在自己的if语句中似乎很奇怪。

过去,我会使用简单的Vanilla JS或JQuery完成此操作,getElementByClass.但我不知道这是否可以通过React这样实现。

有人能在这里指出正确的方向吗?

非常感谢


阅读 263

收藏
2020-07-22

共1个答案

小编典典

假设您一次获得了所有数据(例如,从API提取),并且只需要呈现其中的一部分,则可以简单地动态地对源数据数组进行切片,从而在组件状态下跟踪当前页面(例如,页面长度为5项)
):

const [data, setData] = useState([]),
      [page, setPage] = useState(0),
      maxPage = Math.ceil(data.length/5),
      onNextPage = () => setPage((page+1)%maxPage),
      onPrevPage = () => setPage((page+5-1)%maxPage)



<Grid container>
        {
          data
            .slice(page*5,5*(page+1))
            .map((content,key) => (
              <Grid item {...{key}}>
                <Paper className="paper">{content}</Paper>
              </Grid>
            ))
        }
</Grid>

您可能想查看以下演示以获得完整的示例(我猜您一直在使用material-ui来设置组件样式):

//dependencies

const { render } = ReactDOM,

      { useState, useEffect } = React,

      { Button, Paper, Grid, LinearProgress } = MaterialUI,

      { get } = axios



//paginated output, by default 5 items per page

const PaginatedBoard = () => {



  //initiate state and event handlers

  const [data, setData] = useState([]),

        [page, setPage] = useState(0),

        maxPage = Math.ceil(data.length/5),

        onNextPage = () => setPage((page+1)%maxPage),

        onPrevPage = () => setPage((page+5-1)%maxPage)



  //fetch src data on component render

  useEffect(() => get('https://api.nytimes.com/svc/topstories/v2/science.json?api-key=k9DaUAw5wUAei4J5WXRsy3EL988RADE3').then(({data:{results}}) => setData(results.map(({abstract}) => abstract))),[])



  //return components body

  return data.length ?

      (<div>

        <Grid container spacing="2" >

          {

            data

              .slice(page*5,5*(page+1))

              .map((content,key) => (

                <Grid item {...{key}}>

                  <Paper className="paper">{content}</Paper>

                </Grid>

              ))

          }

        </Grid>

              <div>

                <Button onClick={onPrevPage} disabled={!page}>&lt;Prev</Button>

                <Button onClick={onNextPage} disabled={page==Math.ceil(data.length/5)-1}>Next&gt;</Button>

              </div>



      </div>) :

      <LinearProgress style={{margin:'70px',width:'50%'}} />

}



//render

render (

  <PaginatedBoard />,

  document.getElementById('root')

)


.grid {

  width:70%;

  margin:auto;

}



.paper {

  width:100px;

  height:145px;

  overflow:hidden;

}


<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.11.0/umd/react-dom.production.min.js"></script><script src="https://unpkg.com/@material-ui/core@latest/umd/material-ui.development.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.1/axios.min.js"></script><div id="root"></div>
2020-07-22