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.
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.
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.
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.
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.
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.
Segala sesuatu pasti ada kekurangan dan kelebihannya masing-masing, tak terkecuali dengan Infinity Scroll, berikut ini adalah beberapa kekurangan menggunakan infinity scrolling :
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.
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 😃
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
setelah selesai setup project nya, kita akan mulai membuat layoutnya, replace isi dari App.js dengan code berikut :
App.js1import React from 'react';2import './styles.css';3import Avatar from './avatar.png';45const 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}3031export 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.css1html,2body {3 margin: 0;4 padding: 0;5}67.container {8 max-width: 600px;9 margin: 0 auto;10 padding: 20px;11}1213.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}2021.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}2829.avatar {30 width: 75px;31 height: 75px;32 border-radius: 50%;33}3435.text-container {36 padding-left: 15px;37}3839.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}4748.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
silakan replace App.js dengan code berikut :
App.js1import React from 'react';2import './styles.css';3import Avatar from './avatar.png';4import InfiniteScroll from 'react-infinite-scroller';5import { generateRandomData } from './helpers';67const 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 ]);1718 const fetchMoreData = () => {19 const newData = [...contacts, ...generateRandomData(5)];20 setTimeout(() => {21 setContacts(newData);22 }, 2000);23 }2425 return (26 <div className="container">27 <h1 className="title">My Contacts</h1>28 <InfiniteScroll29 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}4950export default App;
Penjelasan kode :
1const fetchMoreData = () => {2 const newData = [...contacts, ...generateRandomData(5)];3 setTimeout(() => {4 setContacts(newData);5 }, 2000);6};
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)
1<InfiniteScroll2 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.js1import Avatar from './avatar.png';23export 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};1314export 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.
silakan buat file baru bernama ContactSkeletonLoading.js yang isinya seperti ini :
ContactSkeletonLoading.js1import React from 'react';2import './styles.css';3import Skeleton from 'react-loading-skeleton';45const 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}1819export 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.js1import 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';89const 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 ]);1920 const fetchMoreData = () => {21 const newData = [...contacts, ...generateRandomData(5)];22 setTimeout(() => {23 setContacts(newData);24 }, 2000);25 }2627 return (28 <div className="container">29 <h1 className="title">My Contacts</h1>30 <InfiniteScroll31 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}5354export default App;
Kemudian buka http://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! 😁 🙏
Always open to new ideas. 🕊️
Articles that you might want to read.
Otomatisasi build, testing, screenshot, dan deployment aplikasi iOS ke Testflight & AppStore.
Dokumentasikan project-mu dengan DocC!
Tutorial Drag & Drop React JS menggunakan react-beautiful-dnd