1

I am having issues on even trying to get started with doing pagination without the use of any packages. I am pulling data from a JSON file that contains about 30-32 quotes. I need 15 quotes per page to be displayed and have no idea how to even do that using React. So far what I have is all the quotes being displayed by default. I have three buttons, each filters through the JSON to provide quotes by the theme of the quote which is displayed by the button. This is how far I got:

class App extends Component {
    constructor(props) {
        super(props);
        this.state ={
            results: quotes,
            search: ""
        }
    }

    gameFilterClick = event => {
        event.preventDefault();
        const games = [];


        for(let i = 0; i < quotes.length; i++){
            if (quotes[i].theme === "games"){
                games.push(quotes[i])
            }
        }
        this.setState({results: games})
    }

    movieFilterClick = event => {
        event.preventDefault();
                console.log('blah!!')

        const movies = [];

        for(let i =0; i < quotes.length; i++){
            if(quotes[i].theme === 'movies'){
                movies.push(quotes[i])
            }
        }
        this.setState({results: movies})
    }

    allButtonClick = event => {
        this.setState({results: quotes})
    }

    quoteSearch = query => {
        let search = quotes.map
    }


      render() {
        return (
          <div className="App">
            <h1>Quotes</h1>
            <Search />

            <div id='buttons'>
            Filters: 
                <button onClick={this.allButtonClick}>All Quotes</button>
                <button onClick={this.gameFilterClick}>Games</button> 
                <button onClick={this.movieFilterClick}>Movies</button>

            </div>


            <div id='resultsDiv'>
                <Results 
                    results={this.state.results}
                />
            </div>

          </div>
        );
      }
}

export default App;
Dženis H.
  • 7,284
  • 3
  • 25
  • 44
rnkwill
  • 11
  • 1
  • 5
  • Possible duplicate of [how to implement Pagination in reactJs](https://stackoverflow.com/questions/40232847/how-to-implement-pagination-in-reactjs) – Claies Jul 11 '18 at 23:15
  • Is it an absolute must that you don't use 3rd party packages? If not, I would recommend you a pretty decent one and show you how to properly implement it :) – Dženis H. Jul 11 '18 at 23:18
  • sadly it is an absolute must that I can't use 3rd party packages :( – rnkwill Jul 12 '18 at 15:11

2 Answers2

0

I would recommend using react-bootstrap for this. You'll need to install two packages (they use to come in one, but now pagination package is separated):

  • react-bootstrap-table-next
  • react-bootstrap-table2-paginator

So, let's install them:

npm i --save react-bootstrap-table-next npm i react-bootstrap-table2-paginator

And here goes a simple example of implementation:

import BootstrapTable from 'react-bootstrap-table-next';
import paginationFactory from 'react-bootstrap-table2-paginator';

// Let's imagine this is your JSON data
    const yourJsonData = [{id: 1, author: "David Goggins", quote: "Life goes on"}, 
                         { id: 2, author: "Robert Green", quote: "yes it does"}]:


// Here we define your columns

    const columns = [{
        dataField: 'author',
        text: 'AUTHOR'
        }, {
        dataField: 'quote',
        text: 'QUOTE'
        }];

        // Give it an option to show all quotes
        let allQuotes = Number(yourJsonData.length);

        // Set all of the major pagination options. You can reduce them if you want less

        const options = {
            paginationSize: 15,
            pageStartIndex: 0,
            firstPageText: 'First',
            prePageText: 'Back',
            nextPageText: 'Next',
            lastPageText: 'Last',
            nextPageTitle: 'First page',
            prePageTitle: 'Pre page',
            firstPageTitle: 'Next page',
            lastPageTitle: 'Last page',
            sizePerPageList: [{
              text: 'show 15', value: 15
            }, {
              text: 'show 30', value: 30
            }, {
              text: 'Show all', value: allQuotes
            }]
          };

... and then somewhere later in your code where you want to display the table with pagination you just insert this:

<BootstrapTable 
               keyField='rowNumber' 
               data={ yourJsonData } 
               columns={ columns } 
               pagination={ paginationFactory(options) } />

I hope this solves your problem.

Dženis H.
  • 7,284
  • 3
  • 25
  • 44
0

I've simplified your filtering logic and added client side pagination. Check out this simple working example (i've set item per page to 3, you can add more data and change it to 15 const QUOTES_PER_PAGE = <number of quotes per page>;)

const QUOTES_PER_PAGE = 3;

const Quote = ({text}) => <li>{text}</li>;

const Pagination = ({pages, goTo}) => (
  <div>
    {pages.map((p, i) => (
        <button key={i} onClick={goTo} value={i}>{i+1}</button>
    ))}
  </div>
)

class App extends React.Component {
   constructor(props) {
        super(props);
        this.state = {
          page: 0,
          pagedQuoutes: this.divideQuoutesIntoPages(props.quotes)
        };
    }
    
    divideQuoutesIntoPages = (quotes => {
      const pagedQuotes = [];
      [...Array(Math.ceil(quotes.length/QUOTES_PER_PAGE))].forEach((q, i) => {
        pagedQuotes.push(quotes.slice(0 + QUOTES_PER_PAGE*i, QUOTES_PER_PAGE + QUOTES_PER_PAGE*i))
      })
      return pagedQuotes;
    })
    
    filterQuoutes = (evt) => {
      const filterValue = evt.target.value;
      const filteredQuoutes = this.props.quotes.filter(q => !filterValue || q.theme === filterValue);
      this.setState({
        pagedQuoutes: this.divideQuoutesIntoPages(filteredQuoutes)
      })
    }
    
    goToPage = (evt) => {
      this.setState({
        page: evt.target.value
      })
    }
    
    render() {
      return (
        <div>
          <h1>Quotes</h1>
          <div>
          Filters: 
              <button onClick={this.filterQuoutes}>All Quotes</button>
              <button onClick={this.filterQuoutes} value="games">Games</button> 
              <button onClick={this.filterQuoutes} value="movies">Movies</button>
          </div>
          {this.state.pagedQuoutes[this.state.page]
            .map(q => (
            <ul>
              <Quote {...q} />
            </ul>
          ))}
          <Pagination pages={this.state.pagedQuoutes} goTo={this.goToPage} />
        </div>
      );
    }
}

const exampleQuotes = [{
  theme: 'games',
  text: 'games q1'
}, {
  theme: 'games',
  text: 'games q2'
}, {
  theme: 'games',
  text: 'games q3'
}, {
  theme: 'games',
  text: 'games q4'
}, {
  theme: 'games',
  text: 'games q5'
}, {
  theme: 'movies',
  text: 'movies q1'
}, {
  theme: 'movies',
  text: 'movies q2'
}, {
  theme: 'movies',
  text: 'movies q3'
}]
ReactDOM.render(<App quotes={exampleQuotes} />, document.getElementById("el"))
<div id="el"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
Moonjsit
  • 630
  • 3
  • 11