如何通过semantic-ui-react实现react的分页

How to implement pagination for react by semantic-ui-react

我正在通过 semantic-ui-react 实现 pagination 功能。
我可以实现分页组件本身,但无法实现 onPageChange 来设置 activePage 和控制显示的页数。

我将 React 用于客户端功能。
我还使用 semantic-ui-react 用于 css 框架。

现在数组的所有内容都列在一个页面上。
但是我想实现分页并限制在一个页面上显示5个内容。
我以某种方式理解我需要使用 onPageChange,但不知道如何实现该目标。

import React from 'react';
import {Link} from 'react-router-dom';
import {Grid, Segment, Container, Header, Pagination} from 'semantic-ui-react';
import axios from 'axios';
import {Article} from '../articleData';

interface ArticleState {
  articles: Article[];
}

class List extends React.Component<{}, ArticleState> {
  constructor(props: {}) {
    super(props);
    this.state = {
      articles: [],
    };
    this.serverRequest = this.serverRequest.bind(this);
    this.btnClick = this.btnClick.bind(this);
  }

  serverRequest() {
    axios
      .get('/api/articles')
      .then(response => {
        this.setState({articles: response.data});
      })
      .catch(response => console.log('ERROR!! occurred in Backend.'));
  }

  btnClick(event: React.MouseEvent<HTMLAnchorElement>, data: object) {
  }

  componentDidMount() {
    this.setState({articles: []});
    this.serverRequest();
  }

  render() {
    return (
      <Container style={{marginTop: '7em'}} text>
        <Grid columns={1} divided="vertically">
          <Grid.Row>
            {(this.state.articles || []).map(function(articleData, i) {
              return (
                <Grid.Column>
                  <Segment>
                    <Header as="h1">{articleData.title}</Header>
                    <p>{articleData.content}</p>
                    <Link to={`/detail/${articleData.id}`}>
                      continue reading
                    </Link>
                  </Segment>
                </Grid.Column>
              );
            })}
          </Grid.Row>
        </Grid>
        <Pagination
          defaultActivePage={5}
          totalPages={Math.floor(this.state.articles.length / 2) + 1}
        //onPageChange={this.btnClick}
        />
      </Container>
    );
  }
}

export default List;

我希望分页功能能够将单页显示内容的数量限制为 5 个。
但实际上我不知道如何实现这个功能

来自语义-ui 文档,onPageChange 是一个有两个参数的函数:

  • 事件 - React 的原始 SyntheticEvent
  • data - 包含所有道具的对象

查看数据对象内部,有一个名为activePage的键,代表分页改变时的新页码。

这是一个非常基本的示例,通过将新选择的页码记录到控制台来演示这一点。

<Pagination 
  defaultActivePage={5}
  totalPages={10}
  onPageChange={(event, data) => console.log(data.activePage)}
/>

但是,我认为您对语义分页 UI 工作方式的期望可能不正确。 Pagination 组件纯粹渲染一个可点击的页码列表,它不处理结果的显示或限制显示的结果数量。

这是一般在API中处理的事情。一种常见的方法是在 URL 中有一个 ?page=x 查询字符串参数(或有时 ?offset=)。然后,您可以使用语义分页组件中的 activePage 值向服务器指示结果页面 return.

我解决了这个问题。
这是代码:

import React from 'react';
import {Link} from 'react-router-dom';
import {
  Grid,
  Segment,
  Container,
  Header,
  Pagination,
  PaginationProps,
  Icon,
} from 'semantic-ui-react';
import axios from 'axios';
import {Article} from '../articleData';

interface ArticleState {
  articles: Article[];
  articleDatas: Article[];
  begin: number;
  end: number;
  activePage: number;
}

class List extends React.Component<{}, ArticleState> {
  constructor(props: {}) {
    super(props);
    this.state = {
      articles: [],
      articleDatas: [],
      begin: 0,
      end: 5,
      activePage: 1,
    };
    this.serverRequest = this.serverRequest.bind(this);
    this.btnClick = this.btnClick.bind(this);
  }

  async serverRequest() {
    const res = await axios.get('/api/articles');
    this.setState({articles: res.data});
  }

  async btnClick(
    event: React.MouseEvent<HTMLAnchorElement>,
    data: PaginationProps
  ) {
    await this.setState({activePage: data.activePage as number});
    await this.setState({begin: this.state.activePage * 5 - 5});
    await this.setState({end: this.state.activePage * 5});
    this.setState({
      articleDatas: this.state.articles.slice(this.state.begin, this.state.end),
    });
  }

  async componentDidMount() {
    this.setState({articles: []});
    await this.serverRequest();
    this.setState({
      articleDatas: this.state.articles.slice(this.state.begin, this.state.end),
    });
  }

  render() {
    return (
      <Container style={{marginTop: '3em'}} text>
        <Grid columns={1} divided="vertically">
          <Grid.Row>
            {(this.state.articleDatas || []).map(function(articleData, i) {
              return (
                <Grid.Column>
                  <Segment>
                    <Header as="h1">{articleData.title}</Header>
                    <p>{articleData.content}</p>
                    <Link to={`/detail/${articleData.id}`}>
                      continue reading
                    </Link>
                  </Segment>
                </Grid.Column>
              );
            })}
          </Grid.Row>
        </Grid>
        <Pagination
          defaultActivePage={1}
          totalPages={Math.ceil(this.state.articles.length / 5)}
          onPageChange={this.btnClick}
        />
      </Container>
    );
  }
}

export default List;