تكرار السؤال: …
الإجابة المختصرة
ننشئ Hook يراقب عنصراً مستهدفاً (Sentinel Ref) في أسفل القائمة، وعند تقاطعه مع الـ viewport يطلق دالة جلب المزيد من البيانات تلقائياً.
الشرح
باستخدام IntersectionObserver داخل useEffect مع تنظيف المراقب عند فك المكون، نقوم بفحص ظهور العنصر الأخير. يفيد تمرير حالات مثل hasMore و isLoading لمنع تكرار إطلاق الطلبات الشبكية أثناء انتظار الاستجابة أو عند استنفاد كافة البيانات.
مثال بالكود
function useInfiniteScroll(onLoadMore: () => void, hasMore: boolean, loading: boolean) {
const sentinelRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (!hasMore || loading) return;
const observer = new IntersectionObserver(([entry]) => {
if (entry.isIntersecting) {
onLoadMore();
}
});
if (sentinelRef.current) observer.observe(sentinelRef.current);
return () => observer.disconnect();
}, [onLoadMore, hasMore, loading]);
return sentinelRef;
}أخطاء شائعة
- الاستماع لحدث scroll المباشر على window دون تقييد (throttling)، مما يسبب استهلاكاً مكثفاً للمعالج.
أسئلة متابعة
- كيف تبني Custom Hook لإدارة استهلاك الـ LocalStorage مع دعم التزامن بين النوافذ؟
- كيف تصمم Custom Hook للـ Debouncing للقيم أو الدوال مع إلغاء العمليات السابقة؟