zadders
zadders

Reputation: 438

How to add infinite scrolling to a list of cards? [ReactJS]

I've been working on a pokedex project that allows me to display a list of pokecards.

the code for the PokemonList.js is as follows

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

export default class PokemonList extends Component {
  state = {
    url: "http://pokeapi.co/api/v2/pokemon/?limit=200",
    pokemon: null,
    itemsCountPerPage: 20,
    activePage: 1
  };

  async componentDidMount() {
    const res = await axios.get(this.state.url);
    this.setState({ pokemon: res.data["results"] });
  }

  render() {
    console.log(this.state.pokemon);
    return (
      <React.Fragment>
        {this.state.pokemon ? (
          <div className="row">
            {this.state.pokemon.map(pokemon => (
              <PokemonCard
                key={pokemon.name}
                name={pokemon.name}
                url={pokemon.url}
              />
            ))}
          </div>
        ) : (
          <h1>Loading Pokemon</h1>
        )}
      </React.Fragment>
    );
  }
}

I have been trying to use infinite scroller addons such as https://www.npmjs.com/package/react-infinite-scroller but I've never seemed to get it to work. How could I apply infinite scrolling that'd load 20 cards at a time?

-----------------EDIT-------------------------------- enter image description here

Upvotes: 0

Views: 3841

Answers (1)

JulienRioux
JulienRioux

Reputation: 3092

Here is how to implement an infinite scroll using this API:

import React, { Component } from "react";
import ReactDOM from "react-dom";
import axios from "axios";
import InfiniteScroll from "react-infinite-scroller";

export default class App extends Component {
  state = {
    url: "https://pokeapi.co/api/v2/pokemon/?limit=200",
    pokemon: [],
    itemsCountPerPage: 20,
    activePage: 1
  };

  loadPokemon = () => {
    axios
      .get(this.state.url)
      .then(res => {
        this.setState(prevState => {
          return {
            pokemon: [...prevState.pokemon, ...res.data.results],
            url: res.data.next
          };
        });
      })
      .catch(function(error) {
        // handle error
        console.log(error);
      });
  };

  render() {
    // console.log(this.state.pokemon);
    return (
      <React.Fragment>
        {this.state.pokemon ? (
          <div className="row">
            <InfiniteScroll
              pageStart={0}
              loadMore={this.loadPokemon}
              hasMore={this.state.url}
              loader={
                <div className="loader" key={0}>
                  Loading ...
                </div>
              }
            >
              {this.state.pokemon.map((pokemon, i) => (
                <div
                  style={{ borderBottom: "1px solid", padding: "10px" }}
                  key={pokemon.name + i}
                >
                  <div>{pokemon.name}</div>
                  <div>{pokemon.url}</div>
                </div>
              ))}
            </InfiniteScroll>
          </div>
        ) : (
          <h1>Loading Pokemon</h1>
        )}
      </React.Fragment>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

You can see it up and running in a codesandbox here:

Edit bitter-paper-9sleu

Upvotes: 1

Related Questions