کامپوننت اسکرول بی نهایت با استفاده از useSWRInfinite

Summarize this content to 400 words in Persian Lang در این پست، من شما را با ایجاد یک مولفه اسکرول بی نهایت راهنمایی می کنم. این که آیا شما با این مفهوم تازه کار هستید یا فقط نیاز به تجدید نظر دارید، ما آن را مرحله به مرحله تجزیه و تحلیل خواهیم کرد.
این رویکرد در توسعه محصول من، TubeMemo، بسیار مفید بود، جایی که کاربران میتوانند به طور موثر در یادداشتهای ویدیویی YouTube پیمایش کنند و بدون اینکه در یک لحظه تحت تأثیر اطلاعات بیش از حد غرق شوند.
یادداشت لوله – یادداشت برداری بی دردسر YouTube
با یکپارچه سازی رونوشت یکپارچه، لحظات کلیدی ویدیو را ضبط، حاشیه نویسی و سازماندهی کنید. ایده آل برای دانش آموزان، محققان و تولیدکنندگان محتوا
tubememo.com
بررسی اجمالی: آنچه ما در حال ساختن هستیم
ما یک مؤلفه ایجاد می کنیم که لیستی از پست های وبلاگ را از یک سرور بارگیری می کند.
ما استفاده خواهیم کرد useSWRInfinite قلاب برای واکشی داده ها و useInView برای تشخیص زمانی که کاربر به انتهای لیست می رسد.
راهاندازی ساختار مؤلفه مؤلفه ما این موارد را انجام میدهد:
مدیریت ایالت: ما بررسی می کنیم که آیا در حالت انتخاب هستیم، کدام موارد انتخاب شده اند و آیا پیمایش بی نهایت به پایان رسیده است.
واکشی داده ها: استفاده خواهیم کرد useSWRInfinite برای رسیدگی به بارگیری داده های صفحه بندی شده از سرور.
موارد ارائه شده: پست ها در یک شبکه نمایش داده می شوند و پست های جدید با اسکرول کاربر بارگیری می شوند.
تشخیص اسکرول: useInView به ما کمک می کند تشخیص دهیم که کاربر چه زمانی به انتهای لیست رفته است.
بخش های کلیدی کد توضیح داده شده است
بیایید بخش های کلیدی کد را تجزیه کنیم تا بتوانید بفهمید که چگونه همه با هم کار می کنند.
حالت اولیه و هوک:
const { ref, inView } = useInView();
const { userId } = useAuth();
const [finished, setFinished] = useState(false);
استفاده می کنیم useInView برای دانستن اینکه چه زمانی یک عنصر خاص (یک محل قرارگیری div در پایین لیست) روی صفحه قابل مشاهده است. را finished نشان می دهد که آیا ما همه داده های موجود را بارگیری کرده ایم یا خیر.
واکشی داده با useSWRInfinite:
const getKey = (pageIndex: number, previousPageData: any) => {
if (previousPageData && !previousPageData.length) {
setFinished(true);
return null;
}
const offset = pageIndex === 0 ? null : previousPageData?.[previousPageData.length – 1]?.id;
return `/api/posts?offset=${offset}&limit=10`;
};
را getKey تابع برای هر درخواست API پارامترها را تولید می کند. اگر داده دیگری وجود نداشته باشد (به عنوان مثال، previousPageData خالی است)، درخواست های بیشتر را با بازگشت متوقف می کند null.
را fetcher تابع مسئول برقراری تماس API است:
interface Post {
id: string;
content: string;
}
const fetcher = async (url: string): Promise<Post[]> => {
const response = await fetch(url);
return response.json();
};
مدیریت رویدادهای اسکرول:
useEffect(() => {
if (inView && !isLoading && !isValidating && !finished) {
setSize((prevSize) => prevSize + 1);
}
}, [inView, isLoading, isValidating, setSize]);
این useEffect قلاب بررسی می کند که آیا پایین لیست مشاهده می شود (inView). اگر اینطور است، و در حال حاضر داده ها را بارگیری یا تأیید نمی کنیم، و بارگیری همه پست ها را تمام نکرده ایم، اندازه صفحه را افزایش می دهیم تا داده های بیشتری بارگیری شود.
ارائه محتوا
پستها در یک شبکه ارائه میشوند و با دریافت دادههای جدید، به لیست اضافه میشوند. ما همچنین یک نشانگر وضعیت بارگیری داریم که در حین واکشی داده های جدید، یک مکان نگهدار را نشان می دهد:
return (
<div className=”relative pt-4 w-full h-full space-y-2″>
<h2 className=”text-xl font-semibold”>Your posts</h2>
<div className=”grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-2 md:gap-4″>
{items?.map((item: any) => (
<BlogPost key={item?.id} data={item} />
))}
{isLoading && isValidating ? (
<div ref={ref}> Loading… </div>
) : null}
</div>
</div>
);
همه را کنار هم گذاشتن
import React, { useState, useEffect } from ‘react’;
import useSWRInfinite from ‘swr/infinite’;
import { useInView } from ‘@react-intersection-observer’;
const fetcher = async (url: string) => {
const response = await fetch(url);
if (!response.ok) {
throw new Error(‘Network error’);
}
return response.json();
};
const InfinityScrollList: React.FC = () => {
const { ref, inView } = useInView();
const [finished, setFinished] = useState(false);
const getKey = (pageIndex: number, previousPageData: any) => {
if (previousPageData && !previousPageData.length) {
setFinished(true);
return null;
}
const offset = pageIndex === 0 ? null : previousPageData?.[previousPageData.length – 1]?.id;
return `/api/posts?offset=${offset}&limit=8`;
};
const { data, error, size, setSize, isValidating } = useSWRInfinite(getKey, fetcher);
useEffect(() => {
if (inView && !isValidating && !finished) {
setSize((prevSize) => prevSize + 1);
}
}, [inView, isValidating, finished, setSize]);
const posts = data?.flat();
return (
<div className=”relative pt-4 w-full h-full space-y-2″>
<h2 className=”text-xl font-semibold”>Your posts</h2>
<div className=”grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-2 md:gap-4″>
{posts?.map?.((post: any) => (
<div key={post.id} className=”bg-gray-200 p-4 rounded-lg”>
<h3 className=”text-lg font-bold”>{post.title}</h3>
<p>{post.content}</p>
</div>
))}
{(isValidating && size > 1) && (
<div ref={ref}> Loading… </div>
)}
</div>
</div>
);
};
export default InfinityScrollList;
نتیجه گیری
پیمایش بینهایت میتواند تعامل کاربران را بهویژه در برنامههای پر محتوا به میزان زیادی افزایش دهد. با استفاده از این راهنما، باید برای اجرای آن در پروژه های خود به خوبی مجهز باشید.
در این پست، من شما را با ایجاد یک مولفه اسکرول بی نهایت راهنمایی می کنم. این که آیا شما با این مفهوم تازه کار هستید یا فقط نیاز به تجدید نظر دارید، ما آن را مرحله به مرحله تجزیه و تحلیل خواهیم کرد.
این رویکرد در توسعه محصول من، TubeMemo، بسیار مفید بود، جایی که کاربران میتوانند به طور موثر در یادداشتهای ویدیویی YouTube پیمایش کنند و بدون اینکه در یک لحظه تحت تأثیر اطلاعات بیش از حد غرق شوند.
بررسی اجمالی: آنچه ما در حال ساختن هستیم
ما یک مؤلفه ایجاد می کنیم که لیستی از پست های وبلاگ را از یک سرور بارگیری می کند.
ما استفاده خواهیم کرد useSWRInfinite
قلاب برای واکشی داده ها و useInView
برای تشخیص زمانی که کاربر به انتهای لیست می رسد.
راهاندازی ساختار مؤلفه مؤلفه ما این موارد را انجام میدهد:
-
مدیریت ایالت: ما بررسی می کنیم که آیا در حالت انتخاب هستیم، کدام موارد انتخاب شده اند و آیا پیمایش بی نهایت به پایان رسیده است.
-
واکشی داده ها: استفاده خواهیم کرد
useSWRInfinite
برای رسیدگی به بارگیری داده های صفحه بندی شده از سرور. -
موارد ارائه شده: پست ها در یک شبکه نمایش داده می شوند و پست های جدید با اسکرول کاربر بارگیری می شوند.
-
تشخیص اسکرول:
useInView
به ما کمک می کند تشخیص دهیم که کاربر چه زمانی به انتهای لیست رفته است.
بخش های کلیدی کد توضیح داده شده است
بیایید بخش های کلیدی کد را تجزیه کنیم تا بتوانید بفهمید که چگونه همه با هم کار می کنند.
- حالت اولیه و هوک:
const { ref, inView } = useInView();
const { userId } = useAuth();
const [finished, setFinished] = useState(false);
استفاده می کنیم useInView
برای دانستن اینکه چه زمانی یک عنصر خاص (یک محل قرارگیری div در پایین لیست) روی صفحه قابل مشاهده است. را finished
نشان می دهد که آیا ما همه داده های موجود را بارگیری کرده ایم یا خیر.
-
واکشی داده با
useSWRInfinite
:
const getKey = (pageIndex: number, previousPageData: any) => {
if (previousPageData && !previousPageData.length) {
setFinished(true);
return null;
}
const offset = pageIndex === 0 ? null : previousPageData?.[previousPageData.length - 1]?.id;
return `/api/posts?offset=${offset}&limit=10`;
};
را getKey
تابع برای هر درخواست API پارامترها را تولید می کند. اگر داده دیگری وجود نداشته باشد (به عنوان مثال، previousPageData
خالی است)، درخواست های بیشتر را با بازگشت متوقف می کند null
.
را fetcher
تابع مسئول برقراری تماس API است:
interface Post {
id: string;
content: string;
}
const fetcher = async (url: string): Promise<Post[]> => {
const response = await fetch(url);
return response.json();
};
- مدیریت رویدادهای اسکرول:
useEffect(() => {
if (inView && !isLoading && !isValidating && !finished) {
setSize((prevSize) => prevSize + 1);
}
}, [inView, isLoading, isValidating, setSize]);
این useEffect
قلاب بررسی می کند که آیا پایین لیست مشاهده می شود (inView
). اگر اینطور است، و در حال حاضر داده ها را بارگیری یا تأیید نمی کنیم، و بارگیری همه پست ها را تمام نکرده ایم، اندازه صفحه را افزایش می دهیم تا داده های بیشتری بارگیری شود.
ارائه محتوا
پستها در یک شبکه ارائه میشوند و با دریافت دادههای جدید، به لیست اضافه میشوند. ما همچنین یک نشانگر وضعیت بارگیری داریم که در حین واکشی داده های جدید، یک مکان نگهدار را نشان می دهد:
return (
<div className="relative pt-4 w-full h-full space-y-2">
<h2 className="text-xl font-semibold">Your posts</h2>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-2 md:gap-4">
{items?.map((item: any) => (
<BlogPost key={item?.id} data={item} />
))}
{isLoading && isValidating ? (
<div ref={ref}> Loading... </div>
) : null}
</div>
</div>
);
همه را کنار هم گذاشتن
import React, { useState, useEffect } from 'react';
import useSWRInfinite from 'swr/infinite';
import { useInView } from '@react-intersection-observer';
const fetcher = async (url: string) => {
const response = await fetch(url);
if (!response.ok) {
throw new Error('Network error');
}
return response.json();
};
const InfinityScrollList: React.FC = () => {
const { ref, inView } = useInView();
const [finished, setFinished] = useState(false);
const getKey = (pageIndex: number, previousPageData: any) => {
if (previousPageData && !previousPageData.length) {
setFinished(true);
return null;
}
const offset = pageIndex === 0 ? null : previousPageData?.[previousPageData.length - 1]?.id;
return `/api/posts?offset=${offset}&limit=8`;
};
const { data, error, size, setSize, isValidating } = useSWRInfinite(getKey, fetcher);
useEffect(() => {
if (inView && !isValidating && !finished) {
setSize((prevSize) => prevSize + 1);
}
}, [inView, isValidating, finished, setSize]);
const posts = data?.flat();
return (
<div className="relative pt-4 w-full h-full space-y-2">
<h2 className="text-xl font-semibold">Your posts</h2>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-2 md:gap-4">
{posts?.map?.((post: any) => (
<div key={post.id} className="bg-gray-200 p-4 rounded-lg">
<h3 className="text-lg font-bold">{post.title}</h3>
<p>{post.content}</p>
</div>
))}
{(isValidating && size > 1) && (
<div ref={ref}> Loading... </div>
)}
</div>
</div>
);
};
export default InfinityScrollList;
نتیجه گیری
پیمایش بینهایت میتواند تعامل کاربران را بهویژه در برنامههای پر محتوا به میزان زیادی افزایش دهد. با استفاده از این راهنما، باید برای اجرای آن در پروژه های خود به خوبی مجهز باشید.