logo
hero image

Infinity Scroll pada React JS

Tutorial membuat infinity scroll dan skeleton loading pada React JS
15 May 2020 · 10 Minutes

Infinity Scroll adalah teknik menyajikan konten yang sangat banyak dengan membaginya ke beberapa bagian agar lebih cepat dalam penyajiannya, berbeda dengan pagination, untuk melihat konten lebih banyak, infinity scroll tidak perlu klik button apapun, tapi cukup dengan menscroll pagenya saja. contoh implementasi infinity scroll adalah pada penyajian postingan di aplikasi Facebook, penyajian data product pada aplikasi E-Commerce seperti shopee, dan masih banyak lagi.

Kenapa menggunakan Infinity Scroll?

  1. Automatic Loading : dengan me-load konten secara otomatis ketika page discroll, tentu saja akan memudahkan user dalam mencari konten yang diinginkan dan dengan mudah bisa membandingkan konten satu dengan yang lain tanpa harus berpindah-pindah halaman.

  2. Easy Browsing : tujuan utama infinity scroll adalah untuk memudahkan user dalam menggunakan sebuah aplikasi, ketika dihadapkan dengan dengan banyak sekali pages pada pagination, menurut saya itu akan menyulitkan user saat mencari konten yang diinginkan. jadi lebih baik dibuat infinity scroll saja agar lebih mudah dalam melakukan pencarian.

  3. User Engagement : ketika konten disajikan secara continously (berkelanjutan) pada halaman yang sama, dengan mudahnya user akan melihat konten-konten baru saat page kita discroll, sehingga kemungkinan mereka akan terus stay di website kita sampai menemukan konten yang dicari.

  4. Fast Browsing : Kecepatan menyajikan konten menjadi masalah utama dalam UX (User Experience), Berdasarkan survey yang dilakukan Google, 53% pengguna internet akan meninggalkan website yang loading websitenya lebih dari 3 detik, dengan Infinity scroll masalah kecepatan tersebut bisa terselesaikan karena user tidak perlu menunggu loading untuk menuju halaman berikutnya.

  5. Cocok untuk mobile device : pengguna perangkat mobile seperti andoid dan IOS, mereka lebih prefer untuk berinteraksi dengan gesture dibandingkan dengan button-button, karena ukuran layarnya yang relatif lebih kecil sehingga akan terasa sesak jika terlalu banyak komponen yang ditampilkan.

Kekurangan menggunakan Infinity Scroll

Segala sesuatu pasti ada kekurangan dan kelebihannya masing-masing, tak terkecuali dengan Infinity Scroll, berikut ini adalah beberapa kekurangan menggunakan infinity scrolling :

  1. Ketika user scroll terlalu jauh kebawah, user akan kesulitan untuk kembali keatas, maka dari itu sebaiknya buatlah FAB (Floating Action Button) yang berfungsi untuk scroll menuju ke atas.

  2. Device resources, pada beberapa website yang menampilkan kontennya menggunakan infinity scroll, terutama jika kontennya berisi foto atau video kualitas tinggi, ketika discroll pada device yang mempunyai sedikit resource mungkin akan sedikit lagging karena assets yang di-load cukup besar dalam satu page.

Kita sudah mengetahui apa itu Infinity Scroll, kelebihan dan kekurangan jika menggunakannya, sekarang kita akan mencoba mengimplementasikannya menggunakan React JS, konsep dari Infinity Scroll itu gini, setiap kali page discroll maka akan mengecek jarak scroll terhadap bagian paling bawah page, jika jaraknya lebih dari sekian maka trigger fetch data baru.

tapi untuk memudahkan, kita tidak perlu membuatnya dari awal, kita akan memakai library react-infinite-scroller, ohya nanti ketika fetch data baru kita akan menampilkan skeleton loading, skeleton loading adalah loading indicator yang tampilannya seolah olah menyerupai layout pada component yang akan ditampilkan ketika loading selesai, untuk membuatnya kita akan menggunakan library react-loading-skeleton.

Contoh Project yang akan kita buat simple aja, Bayangkan kita punya Data Contact yang sangat banyak, nah kita akan menampilkan List Contact tersebut menggunakan Infinity Scroll 😃

1. Setup Project

jalankan command berikut :

1create-react-app my-contacts && cd my-contacts

kemudian install library yang kita perlukan

1npm i react-infinite-scroller react-loading-skeleton

setelah itu hapus semua file yang ada di folder src kecuali App.js index.js dan serviceWorker.js

2. Membuat Layout

setelah selesai setup project nya, kita akan mulai membuat layoutnya, replace isi dari App.js dengan code berikut :

App.js
icon
1import React from 'react';
2import './styles.css';
3import Avatar from './avatar.png';
4
5const App = () => {
6 const [contacts, setContacts] = React.useState([
7 { "id": 1, "photo": Avatar, "name": "Tamma Everill", "phone": "+351 888 411 5474" },
8 { "id": 2, "photo": Avatar, "name": "Alejandrina Alexis", "phone": "+62 188 649 7200" },
9 { "id": 3, "photo": Avatar, "name": "Hakim Bruntjen", "phone": "+86 241 773 8545" },
10 { "id": 4, "photo": Avatar, "name": "Prudi Dagwell", "phone": "+62 606 216 1097" },
11 { "id": 5, "photo": Avatar, "name": "Prent Frizell", "phone": "+86 808 891 5427" },
12 { "id": 6, "photo": Avatar, "name": "Curtis Enterlein", "phone": "+64 836 110 1773" },
13 { "id": 7, "photo": Avatar, "name": "Margret Brissard", "phone": "+372 242 306 0100" },
14 ]);
15 return (
16 <div className="container">
17 <h1 className="title">My Contacts</h1>
18 {contacts.map(({ id, photo, name, phone }) => (
19 <div className="contact-container" key={id}>
20 <img src={photo} alt={name} className="avatar" />
21 <div className="text-container">
22 <h5 className="name">{name}</h5>
23 <p className="phone">{phone}</p>
24 </div>
25 </div>
26 ))}
27 </div>
28 )
29}
30
31export default App;

selain membuat layout, kita juga menyiapkan sebuah initialData yang bernama contacts, data contacts ini berisi id, foto, nama, dan nomor hp.

pada file diatas kita mengimport sebuah gambar avatar, nah gambar tersebut bisa kalian ganti dengan gambar yang kalian mau

setelah itu tambahkan sedikit styling agar lebih menarik, buatlah file styles.js yang isinya seperti ini :

styles.css
icon
1html,
2body {
3 margin: 0;
4 padding: 0;
5}
6
7.container {
8 max-width: 600px;
9 margin: 0 auto;
10 padding: 20px;
11}
12
13.title {
14 font-family: poppins, sans-serif;
15 font-size: 30px;
16 font-weight: bold;
17 color: rgb(255, 196, 0);
18 margin-bottom: 15px;
19}
20
21.contact-container {
22 padding: 15px;
23 border: none;
24 border-bottom: 2px solid rgb(233, 233, 233);
25 display: flex;
26 align-items: center;
27}
28
29.avatar {
30 width: 75px;
31 height: 75px;
32 border-radius: 50%;
33}
34
35.text-container {
36 padding-left: 15px;
37}
38
39.name {
40 font-family: poppins, sans-serif;
41 font-size: 18px;
42 font-weight: bold;
43 color: rgb(73, 73, 73);
44 margin-top: 5px;
45 margin-bottom: 5px;
46}
47
48.phone {
49 font-family: poppins, sans-serif;
50 font-size: 12px;
51 font-weight: lighter;
52 color: rgb(151, 151, 151);
53}

sampai sini layoutnya sudah selesai, untuk melihat hasilnya, jalankan command berikut :

1npm run start

3. Membuat Infinity Scroll

silakan replace App.js dengan code berikut :

App.js
icon
1import React from 'react';
2import './styles.css';
3import Avatar from './avatar.png';
4import InfiniteScroll from 'react-infinite-scroller';
5import { generateRandomData } from './helpers';
6
7const App = () => {
8 const [contacts, setContacts] = React.useState([
9 { "id": 1, "photo": Avatar, "name": "Tamma Everill", "phone": "+351 888 411 5474" },
10 { "id": 2, "photo": Avatar, "name": "Alejandrina Alexis", "phone": "+62 188 649 7200" },
11 { "id": 3, "photo": Avatar, "name": "Hakim Bruntjen", "phone": "+86 241 773 8545" },
12 { "id": 4, "photo": Avatar, "name": "Prudi Dagwell", "phone": "+62 606 216 1097" },
13 { "id": 5, "photo": Avatar, "name": "Prent Frizell", "phone": "+86 808 891 5427" },
14 { "id": 6, "photo": Avatar, "name": "Curtis Enterlein", "phone": "+64 836 110 1773" },
15 { "id": 7, "photo": Avatar, "name": "Margret Brissard", "phone": "+372 242 306 0100" },
16 ]);
17
18 const fetchMoreData = () => {
19 const newData = [...contacts, ...generateRandomData(5)];
20 setTimeout(() => {
21 setContacts(newData);
22 }, 2000);
23 }
24
25 return (
26 <div className="container">
27 <h1 className="title">My Contacts</h1>
28 <InfiniteScroll
29 initialLoad={false}
30 loadMore={fetchMoreData}
31 hasMore={true}
32 loader={(
33 <h1>Loading...</h1>
34 )}
35 >
36 {contacts.map(({ id, photo, name, phone }) => (
37 <div className="contact-container" key={id}>
38 <img src={photo} alt={name} className="avatar" />
39 <div className="text-container">
40 <h5 className="name">{name}</h5>
41 <p className="phone">{phone}</p>
42 </div>
43 </div>
44 ))}
45 </InfiniteScroll>
46 </div>
47 )
48}
49
50export default App;

Penjelasan kode :

icon
1const fetchMoreData = () => {
2 const newData = [...contacts, ...generateRandomData(5)];
3 setTimeout(() => {
4 setContacts(newData);
5 }, 2000);
6};
  1. karena API untuk mengambil datanya ngga ada, jadi kita buat fake api call alias pemanggilan api palsu, fungsi generateRandomData dari file helpers.js akan mereturn sebuah array yang berisi 5 data contact random. (file helpers.js akan kita buat setelah ini)

icon
1<InfiniteScroll
2 initialLoad={false}
3 loadMore={fetchMoreData}
4 hasMore={true}
5 loader={(
6 <h1>Loading...</h1>
7 )}
8>

2. untuk menggunakan library react-infinite-scroller kita hanya perlu membungkus items yang akan dijadikan infinity scroll kedalam component InfinityScroll, berikut adalah penjelasan props yang kita pakai

a. initialLoad={false} : ini untuk memberitahu bahwa ketika page pertama kali di-load jangan jalankan function fetchMoreData (default nya adalah true)

b. loadMore={fetchMoreData} : kita taruh function yang berfungsi untuk mengambil data baru di props ini.

c. hasMore={true} : kalo diset false nanti infinity scroll nya seperti ter-disabled alias engga jalan. saya biasanya kasih kondisi begini : jika total data yg di frontend === total data yang di server maka set jadi false agar ketika datanya udah ditampilkan semua, infinity scrollnya tidak melakukan fetch ke API lagi.

d. loader : kita bisa taruh component loading kita di props ini.

Setelah mengedit file App.js menjadi seperti diatas, silakan buat file baru bernama helpers.js yang didalamnya berisi function untuk meng-generate data random, isi file nya seperti berikut :

helpers.js
icon
1import Avatar from './avatar.png';
2
3export const generateRandomString = (length) => {
4 let result = "";
5 const characters =
6 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
7 const charactersLength = characters.length;
8 for (let i = 0; i < length; i++) {
9 result += characters.charAt(Math.floor(Math.random() * charactersLength));
10 }
11 return result;
12};
13
14export const generateRandomData = (length) => {
15 let result = [];
16 for (let i = 0; i < length; i++) {
17 result.push({
18 id: Math.floor(Math.random() * 1000),
19 photo: Avatar,
20 name: generateRandomString(15),
21 phone: '+62 188 649 7200',
22 });
23 }
24 return result;
25};

sekarang kita sudah berhasil membuat infinity scroll nya, silakan buka http://localhost:3000 untuk melihat hasilnya.

http://localhost:3000http://localhost:3000

4. Membuat Skeleton loading

silakan buat file baru bernama ContactSkeletonLoading.js yang isinya seperti ini :

ContactSkeletonLoading.js
icon
1import React from 'react';
2import './styles.css';
3import Skeleton from 'react-loading-skeleton';
4
5const ContactSkeletonLoading = () => {
6 return (
7 <div className="contact-container" key={0}>
8 <Skeleton circle width={75} height={75} duration={0.5} />
9 <div className="text-container">
10 <div style={{ marginBottom: 10 }}>
11 <Skeleton width={200} height={21} duration={0.5} />
12 </div>
13 <Skeleton width={120} height={14} duration={0.5} />
14 </div>
15 </div>
16 )
17}
18
19export default ContactSkeletonLoading;

terakhir import ContactSkeletonLoading tersebut ke dalam file App.js dan ganti value dari props loader dengan component <ContactSkeletonLoading />, sehingga nanti file App.js kita menjadi seperti ini :

App.js
icon
1import React from 'react';
2import './styles.css';
3import Avatar from './avatar.png';
4import InfiniteScroll from 'react-infinite-scroller';
5import { generateRandomData } from './helpers';
7import ContactSkeletonLoading from './ContactSkeletonLoading';
8
9const App = () => {
10 const [contacts, setContacts] = React.useState([
11 { "id": 1, "photo": Avatar, "name": "Tamma Everill", "phone": "+351 888 411 5474" },
12 { "id": 2, "photo": Avatar, "name": "Alejandrina Alexis", "phone": "+62 188 649 7200" },
13 { "id": 3, "photo": Avatar, "name": "Hakim Bruntjen", "phone": "+86 241 773 8545" },
14 { "id": 4, "photo": Avatar, "name": "Prudi Dagwell", "phone": "+62 606 216 1097" },
15 { "id": 5, "photo": Avatar, "name": "Prent Frizell", "phone": "+86 808 891 5427" },
16 { "id": 6, "photo": Avatar, "name": "Curtis Enterlein", "phone": "+64 836 110 1773" },
17 { "id": 7, "photo": Avatar, "name": "Margret Brissard", "phone": "+372 242 306 0100" },
18 ]);
19
20 const fetchMoreData = () => {
21 const newData = [...contacts, ...generateRandomData(5)];
22 setTimeout(() => {
23 setContacts(newData);
24 }, 2000);
25 }
26
27 return (
28 <div className="container">
29 <h1 className="title">My Contacts</h1>
30 <InfiniteScroll
31 initialLoad={false}
32 loadMore={fetchMoreData}
33 hasMore={true}
35 loader={(
36 <ContactSkeletonLoading />
37 )}
39 >
40 {contacts.map(({ id, photo, name, phone }) => (
41 <div className="contact-container" key={id}>
42 <img src={photo} alt={name} className="avatar" />
43 <div className="text-container">
44 <h5 className="name">{name}</h5>
45 <p className="phone">{phone}</p>
46 </div>
47 </div>
48 ))}
49 </InfiniteScroll>
50 </div>
51 )
52}
53
54export default App;

Kemudian buka http://localhost:3000

http://localhost:3000http://localhost:3000

Finally selesai juga… 🥳🎉 kalau kita recap, kita telah belajar mengenai apa itu Infinity Scroll, kelebihan dan kekurangannya, apa itu Skeleton Loading, dan terakhir kita telah mengimplementasikannya pada React JS.

Source code : https://github.com/alfinsyahruddin/my-contacts

Live Demo : https://infinity-scroll.now.sh


Oke mungkin itu saja yang bisa saya bagikan kali ini, kalau kamu merasa artikel ini bermanfaat silakan Like & Share artikel ini ke teman-teman kamu atau jika kamu punya pertanyaan, tulis aja di kolom komentar, Thank you! 😁 🙏

React
Web Development

Written by :
Alfin Syahruddin
Developer · Stock Trader · Libertarian · Freethinker

Always open to new ideas. 🕊️

Loading...

Related articles

Articles that you might want to read.

hero image
CI/CD aplikasi iOS dengan Fastlane dan Github Actions

Otomatisasi build, testing, screenshot, dan deployment aplikasi iOS ke Testflight & AppStore.

24 September 2023 · 9 Minutes
iOS Development
CI/CD
Fastlane
Github Actions
hero image
DocC Tutorial

Dokumentasikan project-mu dengan DocC!

19 March 2023 · 8 Minutes
iOS Development
Swift
DocC
CI/CD
hero image
Drag & Drop Component pada React JS

Tutorial Drag & Drop React JS menggunakan react-beautiful-dnd

4 May 2020 · 10 Minutes
React
Web Development
All rights reserved © Alfin Syahruddin · 2019
RSS Feed