首页 > 解决方案 > 如何在 React.js 中实现分页?

问题描述

我正在学习 React js,这听起来像是一个新手问题。我正在尝试通过 API 数据在 react js 中实现分页功能。我不确定如何实现逻辑。我已经传递了诸如页面大小、当前页面和需要呈现的数据之类的道具。这是我的代码:

应用程序.js

import React, { Component } from 'react'
import Result from './Result';
import Form from 'react-bootstrap/Form';
import Button from 'react-bootstrap/Button';
import Navbar from 'react-bootstrap/Navbar'
import Card from './Card';
import Loading from './Loading'
import Paginate from './Paginate';


export default class App extends Component {
  constructor(){
    super();
    this.state = {
      data: [],
      totalData:[],
      searchText:'',
      searchResult:[],
      isSearch:false,
      isLoading:true,
      pageSize:15,
      currentPage:1
    }
    this.onSearchChange=this.onSearchChange.bind(this);
    this.handlePageChange=this.handlePageChange.bind(this);
  }

  onSearchChange= (e) =>{
    console.log("search change "+this.state.searchText)
    this.setState({
      searchText:e.target.value,
      isSearch:true
    })
    console.log("api data"+this.state.data[0])
  }

  /* fetchSearchResult= () =>{
    console.log(this.state.searchText)
    console.log("inside fetch")
   let store= this.state.data.map(item=>{
      let {country}=item
      return(country)
    })
    console.log(store)
    var areEqual = store.includes(this.state.searchText);
     console.log(this.state.areEqual)
     return (areEqual)? 
      store:'not matched'
  //  return store;

  } */

  componentDidMount() {
    const url =
    'https://corona.lmao.ninja/countries?sort=country'
    fetch(url)
      .then(result => result.json())
      .then(result => {
        this.setState({
          data: result.reverse(),
          isLoading:false
        })
      })
      const totalUrl =
      'https://corona.lmao.ninja/all'
      fetch(totalUrl)
        .then(result => result.json())
        .then(result => {
          //let store=result;
          //console.log("store data"+store)
          this.setState({
            totalData: result
          })
          console.log("2nd fetched data"+this.state.totalData)
        })   
  }

  handlePageChange= (page) =>{
    this.setState({
      currentPage:page
    })

  }
  render() {
    return (

       this.state.isLoading?<Loading/>:
       <div id="main">
       <Navbar bg="dark" variant="dark">
    <Navbar.Brand href="#home">
    <Button id="live_text"
    >Live</Button>
      <img
        alt=""
        src="/logo.svg"
        width="100"
        height="30"
        className="d-inline-block align-top"
      />{' '}
     Covid-19 dashboard
     {this.state.curTime}
    </Navbar.Brand>
  </Navbar>

      <Form.Group>
       <Form.Label>Search</Form.Label>
        <Form.Control value={this.state.searchText}onChange={this.onSearchChange} type="text" placeholder="Enter country" />
      </Form.Group>
        <Card totalData={this.state.totalData}/>
      <Paginate 
        dataCount={this.state.data.length} 
        pageSize={this.state.pageSize}
        onPageChange={this.handlePageChange}
        currentPage={this.state.currentPage}/>

        <Result data={this.state.data} 
        toSearch={this.state.searchText} 
        searchCheck={this.state.isSearch}
        searchValue={this.state.searchText}/>

    </div>

    )
  }
}

分页.js

import React from 'react'
import _ from 'lodash'

export default function Paginate(props) {
    const {pageSize, dataCount, onPageChange, currentPage}=props;
    console.log("current page"+currentPage)
    const pagesCount=Math.ceil(dataCount/pageSize);
    const pages=_.range(1,pagesCount+1);
    return (
        <div>
            <nav aria-label="...">
  <ul class="pagination">
      {pages.map((page)=>{
          return(
        <li key={page}class={(page===currentPage)?"page-item active":"page-item"}>
        <a class="page-link" href="#" onClick={()=>onPageChange(page)}>{page}</a>
        </li>
          )
      })}


  </ul>
</nav>
        </div>
    )
}

结果.js

import React  from 'react'
import Table from 'react-bootstrap/Table';

const Result = (props) => {
    console.log('props value is:'+props.data)
    let {searchCheck, searchValue}=props;


   let update=props.data.map((item)=>{

    const { countryInfo, country, cases, deaths, recovered, active, casesPerOneMillion} = item;
    return(
    (searchCheck)?country.toUpperCase().includes(searchValue.toUpperCase())?
        <tbody>
        <tr key={countryInfo._id}>
          <td><img style={{height:'25px',width:'50px'}}src={countryInfo.flag}/></td>
         <td>{country}</td>
          <td>{cases}</td>
          <td>{active}</td>
          <td>{recovered}</td>
          <th>{casesPerOneMillion}</th>
          <td>{deaths}</td>
        </tr>
      </tbody>:
      '':
      <tbody>
        <tr key={countryInfo._id}>
          <td><img style={{height:'25px',width:'50px'}}src={countryInfo.flag}/></td>
         <td>{country}</td>
          <td>{cases}</td>
          <td>{active}</td>
          <td>{recovered}</td>
          <th>{casesPerOneMillion}</th>
          <td>{deaths}</td>
        </tr>
      </tbody>
    )  
    })
    return (
      <div>
          <Table striped bordered hover variant="dark">
          <thead>
        <tr>

          <th>Flag</th>
          <th>Country</th>
          <th>Cases</th>
          <th>Active</th>
          <th>Recovered</th>
          <th>Cases per one Million</th>
          <th>Deaths</th>


        </tr>
      </thead>
          {update}
          </Table>
      </div>
    )
  }
export default Result;

Codesandbox 直播

标签: javascriptreactjsecmascript-6

解决方案


在我的解决方案中,我根据页码从数据中获取所需的记录,并将它们存储在一个新数组中(作为一个状态)并将它们传递给 Result.js

提示:在 Result.js 中子级的顶层使用 Result.js 中的键,您使用的是标签处的键,而不是您需要的键

应用程序.js

import React, { Component } from "react";
import Result from "./Result";

import Paginate from "./Paginate";

export default class App extends Component {
  constructor() {
    super();
    this.state = {
      data: [],
      totalData: [],
      searchText: "",
      searchResult: [],
      isSearch: false,
      isLoading: true,
      pageSize: 15,
      currentPage: 1,
      dataToShow: []
    };
    this.onSearchChange = this.onSearchChange.bind(this);
    this.handlePageChange = this.handlePageChange.bind(this);
  }

  onSearchChange = e => {
    this.setState({
      searchText: e.target.value,
      isSearch: e.target.value === "" ? false : true
    });
  };

  /* fetchSearchResult= () =>{
    console.log(this.state.searchText)
    console.log("inside fetch")
   let store= this.state.data.map(item=>{
      let {country}=item
      return(country)
    })
    console.log(store)
    var areEqual = store.includes(this.state.searchText);
     console.log(this.state.areEqual)
     return (areEqual)? 
      store:'not matched'
  //  return store;

  } */

  componentDidMount() {
    const url = "https://corona.lmao.ninja/countries?sort=country";
    fetch(url)
      .then(result => result.json())
      .then(result => {
        this.setState({
          data: result.reverse(),
          dataToShow: result.slice(0, 15),
          isLoading: false
        });
      });
    const totalUrl = "https://corona.lmao.ninja/all";
    fetch(totalUrl)
      .then(result => result.json())
      .then(result => {
        // let store=result;
        // console.log("store data"+store)
        this.setState({
          totalData: result
        });
      });
  }

  handlePageChange = page => {
    const { data, pageSize } = this.state;
    this.setState({
      currentPage: page,
      dataToShow: data.slice(pageSize * (page - 1), pageSize * (page - 1) + 15)
    });
  };

  render() {
    const {
      searchText,
      data,
      pageSize,
      currentPage,
      isSearch,
      dataToShow
    } = this.state;
    return (
      <div id="main">
        <input
          value={searchText}
          onChange={this.onSearchChange}
          type="text"
          placeholder="Enter country"
        />

        <Paginate
          dataCount={data.length}
          pageSize={pageSize}
          onPageChange={this.handlePageChange}
          currentPage={currentPage}
        />

        <Result
          data={isSearch ? data : dataToShow}
          toSearch={searchText}
          searchCheck={isSearch}
          searchValue={searchText}
        />
      </div>
    );
  }
}

分页.js

import React from "react";

export default function Paginate(props) {
  const { pageSize, dataCount, onPageChange } = props;
  const pagesCount = Math.ceil(dataCount / pageSize);
  const Pages = new Array(pagesCount).fill(0);
  // const Pages = [1,2,3,5]
  return (
    <div>
      <nav aria-label="...">
        {Pages.map((element, index) => (
          <button
            key={index}
            type="button"
            onClick={() => onPageChange(index + 1)}
          >
            {index + 1}
          </button>
        ))}
      </nav>
    </div>
  );
}

结果.js

import React from "react";

const Result = props => {
  const { searchCheck, searchValue } = props;

  const update = props.data.map(item => {
    const {
      countryInfo,
      country,
      cases,
      deaths,
      recovered,
      active,
      casesPerOneMillion
    } = item;
    return searchCheck ? (
      country.toUpperCase().includes(searchValue.toUpperCase()) ? (
        <tbody key={countryInfo._id}>
          <tr>
            <td>
              <img
                style={{ height: "25px", width: "50px" }}
                src={countryInfo.flag}
              />
            </td>
            <td>{country}</td>
            <td>{cases}</td>
            <td>{active}</td>
            <td>{recovered}</td>
            <th>{casesPerOneMillion}</th>
            <td>{deaths}</td>
          </tr>
        </tbody>
      ) : (
        ""
      )
    ) : (
      <tbody key={countryInfo._id}>
        <tr>
          <td>
            <img
              style={{ height: "25px", width: "50px" }}
              src={countryInfo.flag}
            />
          </td>
          <td>{country}</td>
          <td>{cases}</td>
          <td>{active}</td>
          <td>{recovered}</td>
          <th>{casesPerOneMillion}</th>
          <td>{deaths}</td>
        </tr>
      </tbody>
    );
  });
  return (
    <div>
      <table>
        <thead>
          <tr>
            <th>Flag</th>
            <th>Country</th>
            <th>Cases</th>
            <th>Active</th>
            <th>Recovered</th>
            <th>Cases per one Million</th>
            <th>Deaths</th>
          </tr>
        </thead>
        {update}
      </table>
    </div>
  );
};
export default Result;

推荐阅读