راهنمای 2024 برای اسکرول بی نهایت در React/Next.js

آیا تا به حال دیده اید که اگر به پایین پیمایش کنید چگونه پست ها در بخش فید X (تویتر) یا اینستاگرام نمایش داده می شوند؟
آن “چیز” طومار بی نهایت نامیده می شود.
اسکرول بی نهایت چیست؟
پیمایش بی نهایت تکنیک یا رویکردی در توسعه وب است که در آن منابع بیشتری واکشی شده و با اسکرول کاربر به پایین در صفحه نمایش داده می شود.
به عنوان مثال، در پلتفرم های رسانه های اجتماعی مانند X (توئیتر)، اگر در فید به پایین اسکرول کنید، پست های بیشتری برای شما نمایش داده می شود.
این رویکرد زمانی مفید است که منابع زیادی برای نمایش در صفحه دارید و نمی خواهید همه آنها را یکجا واکشی کنید و سرعت برنامه را کاهش دهید.
چگونه از آن در React/Next.js استفاده کنیم؟
البته، شما می توانید جزء اسکرول بی نهایت خود را از ابتدا بسازید، اما در بسیاری از موارد، بهتر است از کتابخانه استفاده کنید.
در Libertas، من از یک کتابخانه محبوب به نام react-infinite-scroll-component استفاده کرده ام.
این کتابخانه دارای یک جزء داخلی است که رفتار اسکرول بی نهایت را برای ما انجام می دهد. ما فقط باید کد خود را برای واکشی چندین مورد در داخل این کد خالی کنیم.
بازخورد در مورد این رویکرد قدردانی می شود.
درک سناریو
من یک صفحه فید در Libertas دارم که در آن تمام پست هایی که کاربران ایجاد کرده اند را نشان می دهم. درست مانند نحوه نمایش موارد مختلف در صفحه فید در Reddit، X، Medium، Nike و دیگر پلتفرمهای مشابه.
هدف ما این است که وقتی صفحه به طور کامل بارگیری می شود، برخی از پست ها / موارد را واکشی کنیم. هنگامی که کاربر به پایین صفحه یا آخرین موردی که هنگام بارگیری صفحه واکشی شده است پیمایش می کند، ما یک درخواست GET را برای دریافت پست های بیشتر راه اندازی می کنیم.
این فرآیند تا زمانی که همه موارد واکشی شوند تکرار می شود، که اگر تعداد موارد زیاد باشد (بیش از 500 مورد) ممکن است امکان پذیر نباشد. از این رو، نام “طومار بی نهایت”! کاربران خسته خواهند شد، اینطور نیست؟
مراحل پیاده سازی react-infinite-scroll-component
در زیر مراحلی وجود دارد که در آن به نحوه اضافه کردن این مؤلفه به Libertas اشاره می کنم.
بسته را نصب کنید
برای npm:
npm i react-infinite-scroll-component
برای نخ:
yarn add react-infinite-scroll-component
کد زیر را برای اسکرول بی نهایت در لیبرتاس کپی و جایگذاری کنید
Loading...}
endMessage={
Yay! You have seen it all
}
>
{items}
درک لوازم جانبی
مطابق با react-infinite-scroll-component
صفحه GitHub:
طول داده: طول داده ها را تنظیم کنید این قفل تماسهای بعدی را باز میکند.
بعد: تابعی که پس از رسیدن به پایین باید فراخوانی شود. باید نوعی اقدام را راه اندازی کند که داده های بعدی را واکشی کند. داده ها در کودکی به آن منتقل می شودInfiniteScroll
جزء و داده ها باید حاوی موارد قبلی نیز باشند. به عنوان مثال اولیهdata = [1, 2, 3]
و سپس بار بعدی داده ها باید باشد[1, 2, 3, 4, 5, 6]
.
بیشتر داشتن: به آن می گویدInfiniteScroll
مؤلفه در مورد فراخوانی تابع بعدی با رسیدن به پایین و نشان می دهدendMessage
به کاربر
لودر: میتوانید یک مؤلفه لودر را ارسال کنید تا زمانی که مؤلفه منتظر بارگذاری بعدی داده است، نشان داده شود. به عنوان مثالLoading…
یا هر عنصر لودر فانتزی
endMessage: این پیام زمانی به کاربر نشان داده می شود که او تمام رکوردها را دیده باشد، به این معنی که او در پایین است و hasMore نادرست است.
موارد: لیست مواردی که باید واکشی شوند و در صفحه نمایش داده شوند. در مورد لیبرتاس،{items}
لیستی از پست های ایجاد شده توسط کاربران است.
مراحل بعدی:
- وقتی صفحه بارگیری می شود، برخی از پست ها را واکشی کنید
- نمایش لیست پست ها در صفحه
- یک تغییر جزئی در درخواست API GET (Backend) ایجاد کنید تا لیست بعدی پست ها را دریافت کنید
- لیست بعدی پست ها را در قسمت جلویی واکشی کنید
کد نهایی:
const [posts, setPosts] = useState([]);
const [count, setCount] = useState(4);
const [currentCount, setCurrentCount] = useState(null);
const [total, setTotal] = useState(null);
const fetchPosts = async () => {
const data = await fetchAllPosts(count);
console.log(data?.data?.data);
setPosts(data?.data?.data);
setCurrentCount(data?.data?.currentLength);
setTotal(data?.data?.total);
setCount(count + 2);
};
useEffect(() => {
fetchPosts();
}, []);
return (
Loading...}
endMessage={
Yay! You have seen it all
}
>
{posts.map((post) => (
handleVote(upvoteAPost, post._id)}
handleDownvote={() => handleVote(downvoteAPost, post._id)}
individualView={false}
/>
))}
);
تجزیه کد
من یک درخواست GET به نام ایجاد کردم fetchAllPosts
که هنگام بارگذاری صفحه 4 پست دریافت می کند. من از تابع نقشه برای لیست کردن تمام پست های داخل استفاده کردم InfiniteScroll
جزء.
برای واکشی مجموعه پستهای بعدی، مجبور شدم یک تغییر جزئی در API درخواست (نوشته شده در Node.js) در جایی که پستها را واکشی میکنم ایجاد کنم. آن تغییر اضافه کردن یک تعداد یا یک عدد بود که به من می گوید چند پست واکشی کنم. هنگامی که کاربر صفحه وب را به پایین اسکرول می کند، آن تعداد پست از پایگاه داده دریافت شده و نمایش داده می شود.
// @desc Get all the posts
// @route GET /api/user/posts
// @access Public
const getAllPosts = asyncHandler(async (req, res, next) => {
const { count } = req.query;
const posts = await PostModel.find();
const postsToDisplay = posts.reverse().slice(0, count);
res.status(200).json({
success: true,
total: posts.length,
currentLength: postsToDisplay.length,
data: postsToDisplay,
});
});
من یک متغیر شمارش اضافه کردم که از پرس و جو در URL درست مانند این است: api/v1/posts?count=4
. این فقط 4 پست واکشی می کند.
- حالا همه چیز راحت تر بود. زمان اضافه کردن کد ظاهری برای واکشی مجموعه پست های بعدی است.
const [posts, setPosts] = useState([]);
const [count, setCount] = useState(4);
const [currentCount, setCurrentCount] = useState(null);
const [total, setTotal] = useState(null);
const fetchPosts = async () => {
const data = await fetchAllPosts(count);
setPosts(data?.data?.data);
setCurrentCount(data?.data?.currentLength);
setTotal(data?.data?.total);
setCount(count + 2);
};
کد بالا ابتدا 4 پست (از مقدار اولیه متغیر حالت شمارش) واکشی می کند.
همچنین تعداد فعلی یا طول فعلی پست ها را تنظیم می کند که در اولین واکشی 4 خواهد بود.
ارزش کل شماره از پست ها نیز به عنوان در حال بازگشت در پاسخ API تنظیم شده است.
در نهایت، مقدار به روز رسانی تعداد به 6، که برای فراخوانی تابع واکشی بعدی استفاده می شود.
مقادیر بالا در InfiniteScroll
جزء زیر:
Loading...}
endMessage={
Yay! You have seen it all
}
>
{posts.map((post) => (
handleVote(upvoteAPost, post._id)}
handleDownvote={() => handleVote(downvoteAPost, post._id)}
individualView={false}
/>
))}
کار از InfiniteScroll
جزء
در کد بالا لیست پست ها نمایش داده می شود. بعد از این:
- ارزش
dataLength
به تعداد پست هایی که برای اولین بار واکشی می شوند اختصاص می یابد. - وقتی کاربر به پایین اسکرول می کند،
hasMore
پروپوزال وارد عمل می شود.
hasMore
به ما می گوید که اگر درست باشد، تابع موجود در پروپ بعدی را شروع کنید. در کد ما، زمانی که تعداد فعلی یا طول فعلی پستها با شماره کل برابر نباشد. از پست ها، تماس بگیریدfetchPosts
تابع. - سپس
fetchPosts
با مقدار به روز شده تعداد 6 فراخوانی می شود، سپس 6 پست واکشی می شود و مقدار آرایه پست ها به روز می شود. ارزشdataLength
نیز به روز می شود. - اگر همه پستها واکشی نشدند، محتوای داخل پایه لودر بعد از آخرین پست نمایش داده میشود. در حالت ایده آل، این می تواند یک جزء اسکلت یا یک متن/انیمیشن بارگیری باشد.
- اگر
hasMore
نادرست است یا به عبارت دیگر، تمام پست ها از پایگاه داده، عنصری که در داخل است، واکشی می شوندendMessage
prop بعد از آخرین پست نمایش داده می شود.
نتیجه
اسکرول بی نهایت یک روش خوب برای عملکرد بهتر یک وب سایت است، اما مانند همه چیز در فناوری، این رویکرد برای هر وب سایتی نیست. بیشتر به نوع پلتفرم و نوع کاربران (مخاطب هدف) بستگی دارد.
من این را به Libertas، پلتفرم گفتگوی آنلاین ساخته شده با Next.js اضافه کردم، زیرا کاربران چندین پست ایجاد می کنند و رندر کردن همه چیز به طور همزمان در یک صفحه وب یک سردرد/کابوس خواهد بود. اینطور نیست؟
آیا نمی دانید لیبرتاس چیست؟
لیبرتاس یک وب سایت گفتگوی آنلاین است برای کاربران که در آن فقط می توانند بحث کنند. آزادانه بحث کنید. بدون قانون، بدون ناظر.
شما فقط می توانید به پست هایی که کاربران ایجاد کرده اند نگاه کنید یا اگر احساس می کنید درگیر هستید، می توانید ثبت نام کنید و شروع به ایجاد کنید! میتوانید به پستها رأی موافق/مخالف بدهید و روی آنها نظر دهید. اگر رمز عبور خود را فراموش کردید، گزینه ای برای بازنشانی آن نیز وجود دارد!
Libertas را اینجا امتحان کنید.
می توانید در لینکدین یا به من اطلاع دهید توییتر اگر ویژگی خاصی می خواهید یا می خواهید پیشنهادی داشته باشید.
هر گونه بازخورد عمیقا قدردانی می شود!