How to implement pagination for react by semantic-ui-react
Asked Answered
G

2

7

I'm implementing pagination functionality by semantic-ui-react.
I can implement pagination component itself, but can't implement onPageChange to set activePage and control number of pages displayed.

I use react for client side functionality.
Also I use semantic-ui-react for css framework.

All contents of array is listed on single page now.
But I want to implement pagination and limit to display 5 contents on single page.
I somehow understand I need to use onPageChange, but don't know how to implement to achieve that goal.

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;

I expect the pagination functionality to limit number of displayed content to 5 on single page.
But actually I don't know how to implement this functionality.

Game answered 13/8, 2019 at 5:58 Comment(0)
G
4

I resolved this issue.
Here is the code:

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;

Game answered 14/8, 2019 at 7:31 Comment(0)
F
2

From the semantic-ui docs, onPageChange is a function with two arguments:

  • event - React's original SyntheticEvent
  • data - An object containing all props

Looking inside the data object, there is a key named activePage which represents the new page number when the pagination is changed.

Here's a very basic example that demonstrates this, by logging the newly selected page number to the console.

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

However, I think you're expectation of how Pagination in Semantic UI works may not be correct. The Pagination component purely renders a clickable list of page numbers, it does not handle the display of results or limits the number of results displayed.

This is something that is generally handled in the API. A common approach is to have a ?page=x query string parameter (or sometimes ?offset=) in the URL. You could then use the activePage value from the Semantic Pagination component to indicate to the server which page of results to return.

Fiendish answered 13/8, 2019 at 15:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.