Fitur Load More dengan React

Setelah kemarin membuat dokumentasi singkat tentang pembuatan text overlay pada gambar, kali ini saya akan lanjut buat dokumentasi tentang pembuatan fitur load more sederhana dengan menggunakan React. Mungkin bagi teman-teman yang sudah familiar atau sering menggunakan React dalam mengembangkan aplikasi web punya cara lain yang lebih advance lagi dalam membuat fitur ini.

Disini saya akan menjelaskan cara yang saya temukan sendiri ketika membuat fitur ini. Jika teman-teman punya saran atau ingin menjelaskan cara kalian sendiri dalam membuatnya, feel free to reach me lewat sini.

So basically, fitur ini digunakan untuk menampilkan data dalam range atau jarak tertentu dari keseluruhan data yang ada. Misalnya, pada awalnya kita hanya menampilkan data sebanyak 5 buah pada aplikasi kita. Lalu ketika kita menggunakan fitur load more ini, kita dapat menampilkan kembali 5 data selanjutnya atau bahkan bisa lebih dari itu sampai urutan terakhir dari data yang dimiliki.

Fitur ini saya butuhkan untuk menampilkan data pada tampilan awal dari proyek sampingan saya yang kemudian ditampilkan menggunakan text overlay seperti pada tulisan saya sebelumnya.

Jadi, langsung saja kita mulai!

Setup Proyek

Langkah pertama yang dilakukan adalah... sudah jelas setup proyeknya terlebih dahulu.

Disini saya membuat proyek baru menggunakan Create React App dengan menjalankan perintah npx create-react-app load-more-with-react. Kemudian menunggu beberapa saat hingga proyek berhasil digenerate. Setelah itu silahkan buka proyek tersebut menggunakan kode editor kesayangan kalian.

Kali ini saya akan membuat dua metode untuk fitur load more, yaitu dengan data statis dan data yang didapatkan dari API. Untuk data dari API yang digunakan sebagai contoh disini adalah data daftar users dari JSON Placeholder. Saya juga akan banyak bermain di dalam folder components. Di dalam folder components, saya membuat 2 komponen baru yang saya beri nama LoadMoreStaticData dan LoadMoreApiData.

Dengan data statis

Setelah setup proyek, saatnya beraksi membuat dua metode load more yang ada di atas. Untuk metode pertama yang akan saya buat adalah dengan data statis. Datanya saya buat sendiri dan sangat sederhana, yaitu daftar buah-buahan.

Tapi sebelum membuat datanya, saya membuat sebuah file terlebih dahulu di dalam folder components dengan nama LoadMoreStaticData.js. Ini akan menjadi komponen yang menampung fitur load more dengan data statis.

Selanjutnya, saya membuat data daftar buah-buahan yang akan dipakai. Berikut ini adalah datanya.

const fruits = [
  "Banana",
  "Apple",
  "Lemon",
  "Grape",
  "Watermelon",
  "Durian",
  "Jackfruit",
  "Orange",
  "Lime",
  "Melon",
  "Guava",
  "Cherry",
  "Raspberry",
  "Strawberry",
  "Mango",
];

Data di atas adalah daftar buah-buahan dengan total sebanyak 15 data.

Setelah itu saya membuat counter yang berguna untuk menentukan berapa banyak data yang akan ditampilkan pada komponen. Counter ini saya jadikan state dengan bantuan salah satu dari React Hooks yaitu useState.

Selain membuat counter-nya, saya juga membuat fungsi untuk menambah nilai dari counternya ketika menekan tombol Load More yang akan saya buat nanti. Berikut ini adalah baris kodenya.

const [counter, setCounter] = useState(5);
const incrementCounterValue = () => {
  if (counter < fruits.length) {
    setCounter(counter + 5);
  } else {
    setCounter(5);
  }
};

Setelah itu, saya lanjut membuat metode untuk me-render datanya dan membuat tampilan dari komponen ini. Struktur yang saya buat untuk kedua komponen adalah title, list dari data yang akan di render, dan tombol load more. Berikut ini adalah baris kode yang saya buat untuk membuat tampilannya.

return (
  <div>
    <h3>Daftar Buah-Buahan</h3>
    <ul>
      {fruits.slice(0, counter).map((fruit, index) => (
        <li key={index}>{fruit}</li>
      ))}
    </ul>
    <button onClick={incrementCounterValue}>
      {counter === fruits.length ? "Show Less" : "Load More"}
    </button>
  </div>
);

Untuk mekanisme dari fitur load more ini adalah data akan melalui proses slice dimulai dari data pertama sampai nilai dari counter, lalu dilakukan proses map untuk me-render data yang sudah di-slice sebelumnya.

Pada tombol load more dipasangkan sebuah fungsi yang akan menambahkan nilai dari counter dengan nilai yang sudah ditetapkan, misalnya saya disini menambahkan nilai 5 ke counter setiap tombol load more ditekan selama nilai counter kurang dari total data. Ketika nilai counter berubah, maka proses slice dan map akan dilakukan kembali terhadap data target.

Proses ini berlaku untuk kedua tipe yang saya buat, yang membedakan hanyalah sumber dari datanya saja.

Berikut ini adalah tampilan penuh dari baris kode yang saya tulis di dalam komponen LoadMoreStaticData.

import { useState } from "react";

const fruits = [
  "Banana",
  "Apple",
  "Lemon",
  "Grape",
  "Watermelon",
  "Durian",
  "Jackfruit",
  "Orange",
  "Lime",
  "Melon",
  "Guava",
  "Cherry",
  "Raspberry",
  "Strawberry",
  "Mango",
];

export default function LoadMoreStaticData() {
  const [counter, setCounter] = useState(5);
  const incrementCounterValue = () => {
    if (counter < fruits.length) {
      setCounter(counter + 5);
    } else {
      setCounter(5);
    }
  };
  return (
    <div>
      <h3>Daftar Buah-Buahan</h3>
      <ul>
        {fruits.slice(0, counter).map((fruit, index) => (
          <li key={index}>{fruit}</li>
        ))}
      </ul>
      <button onClick={incrementCounterValue}>
        {counter === fruits.length ? "Show Less" : "Load More"}
      </button>
    </div>
  );
}

Dengan data dari API

Setelah selesai membuat tipe pertama yang menggunakan data statis, saatnya melanjutkan membuat tipe yang kedua yaitu dengan data dari API.

Sumber data yang saya gunakan adalah data daftar dummy users yang ada di JSON Placeholder.

Okey, mari kita lanjutkan cetak-cetiknya!

Pertama-tama jelas saya akan membuat file di dalam folder components dengan nama LoadMoreApiData.js. Selanjutnya, saya membuat fungsi untuk fetch data dari API. Berikut ini adalah baris kode dari fungsi yang saya buat.

const fetchUsersData = async () => {
  const data = await fetch("https://jsonplaceholder.typicode.com/users");
  const body = data.json();

  if (!data.ok) {
    throw new Error(data.statusText);
  }

  return body;
};

Selanjutnya saya membuat state counter dan fungsi untuk menambahkan nilainya sama seperti tipe sebelumnya. Lalu menambahkan fungsi untuk mengambil data users dan memasukkannya ke dalam state yang sudah dibuat sebelumnya di dalam React Hooks yang lain yaitu useEffect.

Berikut ini adalah baris kodenya.

const [usersData, setUsersData] = useState([]);
const [counter, setCounter] = useState(5);
const incrementCounterValue = () => {
  if (counter < usersData.length) {
    setCounter(counter + 5);
  } else {
    setCounter(5);
  }
};

useEffect(() => {
  const getUsersData = async () => {
    const res = await fetchUsersData();
    setUsersData(res);
  };

  getUsersData();
}, []);

Langkah yang terakhir dalam membuat tipe kedua ini adalah membuat metode untuk me-render datanya dan membuat tampilan dari komponen ini. Struktur yang dibuat sama seperti tipe pertama yaitu title, list dari data yang akan di render, dan tombol load more. Berikut ini adalah baris kodenya.

return (
  <div>
    <h3>Daftar Data Pengguna</h3>
    <ul>
      {usersData.length !== 0 ? (
        usersData
          .slice(0, counter)
          .map((user) => <li key={user.id}>{user.name}</li>)
      ) : (
        <p>Tidak ada data pengguna tersedia.</p>
      )}
    </ul>
    <button disabled={usersData.length === 0} onClick={incrementCounterValue}>
      {counter === usersData.length ? "Show Less" : "Load More"}
    </button>
  </div>
);

Berikut ini adalah tampilan penuh dari baris kode yang saya tulis di dalam komponen LoadMoreApiData.

import { useEffect, useState } from "react";

const fetchUsersData = async () => {
  const data = await fetch("https://jsonplaceholder.typicode.com/users");
  const body = data.json();

  if (!data.ok) {
    throw new Error(data.statusText);
  }

  return body;
};

export default function LoadMoreApiData() {
  const [usersData, setUsersData] = useState([]);
  const [counter, setCounter] = useState(5);
  const incrementCounterValue = () => {
    if (counter < usersData.length) {
      setCounter(counter + 5);
    } else {
      setCounter(5);
    }
  };

  useEffect(() => {
    const getUsersData = async () => {
      const res = await fetchUsersData();
      setUsersData(res);
    };

    getUsersData();
  }, []);

  return (
    <div>
      <h3>Daftar Data Pengguna</h3>
      <ul>
        {usersData.length !== 0 ? (
          usersData
            .slice(0, counter)
            .map((user) => <li key={user.id}>{user.name}</li>)
        ) : (
          <p>Tidak ada data pengguna tersedia.</p>
        )}
      </ul>
      <button disabled={usersData.length === 0} onClick={incrementCounterValue}>
        {counter === usersData.length ? "Show Less" : "Load More"}
      </button>
    </div>
  );
}

Dan selesai!

Jika ingin melihat hasilnya, bisa langsung import dan declare kedua komponen di App.js. Atau jika ingin melihat hasil dari contoh yang saya buat, langsung aja bisa dilihat disini.

Penutup

Lagi-lagi itu tadi sedikit dokumentasi dari saya tentang proses pembuatan fitur load more dengan data statis dan data dari api.

Tentu saja, semoga suatu saat nanti dapat berguna untuk saya dan kalian yang sedang membaca tulisan ini.

Masih seperti tulisan saya yang sebelumnya, ini ditulis menggunakan Neovim.

Makasih ya udah mampir, semoga sehat selalu!

© 2022 Built with Next.js and ChakraUI. Inspired by Takuya Matsuyama's site.