تنفيذ التمرير اللانهائي والتحميل البطيء للصور في رد الفعل
نشرت: 2022-03-10HTML
Intersection Observer
API لتنفيذ التمرير اللانهائي والتحميل البطيء للصور في مكون وظيفي في React. في هذه العملية ، سوف نتعلم كيفية استخدام بعض خطاطيف React وكيفية إنشاء خطافات مخصصة.إذا كنت تبحث عن بديل لترقيم الصفحات ، فإن التمرير اللانهائي يعد اعتبارًا جيدًا. في هذه المقالة ، سنستكشف بعض حالات الاستخدام لواجهة برمجة تطبيقات Intersection Observer في سياق مكون وظيفي لـ React. يجب أن يمتلك القارئ معرفة عملية بمكونات React الوظيفية. سيكون بعض الإلمام بخطافات React مفيدًا ولكن ليس مطلوبًا ، حيث سنلقي نظرة على بعضها.
هدفنا هو أنه في نهاية هذه المقالة ، سنقوم بتنفيذ التمرير اللانهائي والتحميل البطيء للصور باستخدام واجهة برمجة تطبيقات HTML أصلية. كنا قد تعلمنا أيضًا بعض الأشياء الأخرى حول خطافات React. باستخدام ذلك ، يمكنك تنفيذ التمرير اللانهائي والتحميل البطيء للصور في تطبيق React الخاص بك عند الضرورة.
هيا بنا نبدأ.
إنشاء خرائط باستخدام React و Leaflet
إن استيعاب المعلومات من ملف CSV أو JSON ليس أمرًا معقدًا فحسب ، بل إنه أمر ممل أيضًا. تمثيل نفس البيانات في شكل مساعدة بصرية أبسط. تشرح Shajia Abidi مدى قوة الأداة Leaflet وكيف يمكن إنشاء أنواع مختلفة من الخرائط. اقرأ مقالًا ذا صلة ←
واجهة برمجة تطبيقات Intersection Observer
وفقًا لمستندات MDN ، "توفر واجهة برمجة تطبيقات Intersection Observer طريقة لمراقبة التغييرات بشكل غير متزامن في تقاطع عنصر مستهدف مع عنصر سلف أو مع إطار عرض لمستند عالي المستوى".
تسمح لنا واجهة برمجة التطبيقات هذه بتنفيذ ميزات رائعة مثل التمرير اللانهائي والتحميل البطيء للصور. يتم إنشاء مراقب التقاطع من خلال استدعاء مُنشئه وتمريره إلى كائن خيارات ونداء. يتم استدعاء رد الاتصال عندما يتقاطع عنصر واحد ، يسمى target
، مع منفذ عرض الجهاز أو عنصرًا محددًا يسمى root
. يمكننا تحديد جذر مخصص في وسيطة الخيارات أو استخدام القيمة الافتراضية.
let observer = new IntersectionObserver(callback, options);
واجهة برمجة التطبيقات سهلة الاستخدام. مثال نموذجي يبدو كالتالي:
var intObserver = new IntersectionObserver(entries => { entries.forEach(entry => { console.log(entry) console.log(entry.isIntersecting) // returns true if the target intersects the root element }) }, { // default options } ); let target = document.querySelector('#targetId'); intObserver.observe(target); // start observation
entries
هي قائمة كائنات IntersectionObserverEntry
. يصف كائن IntersectionObserverEntry
تغيير التقاطع لعنصر هدف واحد تمت ملاحظته. لاحظ أن رد الاتصال يجب ألا يتعامل مع أي مهمة تستغرق وقتًا طويلاً حيث يتم تشغيلها على مؤشر الترابط الرئيسي.
تتمتع واجهة برمجة تطبيقات Intersection Observer حاليًا بدعم واسع من المستعرض ، كما هو موضح في caniuse.
يمكنك قراءة المزيد عن API في الروابط المتوفرة في قسم الموارد.
دعونا الآن نلقي نظرة على كيفية الاستفادة من واجهة برمجة التطبيقات هذه في تطبيق React حقيقي. سيكون الإصدار الأخير من تطبيقنا عبارة عن صفحة من الصور يتم تمريرها بلا حدود وسيتم تحميل كل صورة بشكل كسول.
إجراء مكالمات API باستخدام خطاف useEffect
للبدء ، قم باستنساخ مشروع البداية من عنوان URL هذا. لديها حد أدنى من الإعداد وبعض الأنماط المحددة. لقد أضفت أيضًا رابطًا إلى ملف CSS الخاص بـ Bootstrap
في الملف public/index.html
حيث سأستخدم فئاته للتصميم.
لا تتردد في إنشاء مشروع جديد إذا أردت. تأكد من تثبيت مدير حزمة yarn
إذا كنت تريد المتابعة مع الريبو. يمكنك العثور على إرشادات التثبيت لنظام التشغيل المحدد الخاص بك هنا.
في هذا البرنامج التعليمي ، سنلتقط الصور من واجهة برمجة تطبيقات عامة ونعرضها على الصفحة. سنستخدم واجهات برمجة تطبيقات Lorem Picsum.
في هذا البرنامج التعليمي ، سنستخدم نقطة النهاية ، https://picsum.photos/v2/list?page=0&limit=10
، والتي تعرض مصفوفة من كائنات الصورة. للحصول على الصور العشر التالية ، نقوم بتغيير قيمة الصفحة إلى 1 ، ثم 2 ، وهكذا.
سنقوم الآن ببناء مكون التطبيق قطعة قطعة.
افتح src/App.js
وأدخل الكود التالي.
import React, { useEffect, useReducer } from 'react'; import './index.css'; function App() { const imgReducer = (state, action) => { switch (action.type) { case 'STACK_IMAGES': return { ...state, images: state.images.concat(action.images) } case 'FETCHING_IMAGES': return { ...state, fetching: action.fetching } default: return state; } } const [imgData, imgDispatch] = useReducer(imgReducer,{ images:[], fetching: true}) // next code block goes here }
أولاً ، نحدد وظيفة المخفض ، imgReducer
. هذا المخفض يتعامل مع عمليتين.
- يربط الإجراء
STACK_IMAGES
مصفوفةimages
. - يقوم الإجراء
FETCHING_IMAGES
قيمة متغيرfetching
بينtrue
false
.
الخطوة التالية هي توصيل هذا المخفض إلى خطاف useReducer
. بمجرد أن يتم ذلك ، نعود إلى شيئين:
-
imgData
، التي تحتوي على متغيرين:images
هي مجموعة كائنات الصورة.fetching
هو منطقي يخبرنا ما إذا كان استدعاء API قيد التقدم أم لا. -
imgDispatch
، وهي وظيفة لتحديث كائن المخفض.
يمكنك معرفة المزيد عن الخطاف useReducer
في توثيق React.
الجزء التالي من الكود هو المكان الذي نجعل منه استدعاء API. قم بلصق التعليمة البرمجية التالية أسفل كتلة التعليمات البرمجية السابقة في App.js
// make API calls useEffect(() => { imgDispatch({ type: 'FETCHING_IMAGES', fetching: true }) fetch('https://picsum.photos/v2/list?page=0&limit=10') .then(data => data.json()) .then(images => { imgDispatch({ type: 'STACK_IMAGES', images }) imgDispatch({ type: 'FETCHING_IMAGES', fetching: false }) }) .catch(e => { // handle error imgDispatch({ type: 'FETCHING_IMAGES', fetching: false }) return e }) }, [ imgDispatch ]) // next code block goes here
داخل الخطاف useEffect
، نقوم باستدعاء نقطة نهاية API باستخدام fetch
API. نقوم بعد ذلك بتحديث مصفوفة الصور بنتيجة استدعاء API عن طريق إرسال الإجراء STACK_IMAGES
. نرسل أيضًا الإجراء FETCHING_IMAGES
بمجرد اكتمال استدعاء واجهة برمجة التطبيقات.
تحدد الكتلة التالية من التعليمات البرمجية القيمة المرجعة للدالة. أدخل الكود التالي بعد الخطاف useEffect
.
return ( <div className=""> <nav className="navbar bg-light"> <div className="container"> <a className="navbar-brand" href="/#"> <h2>Infinite scroll + image lazy loading</h2> </a> </div> </navv <div id='images' className="container"> <div className="row"> {imgData.images.map((image, index) => { const { author, download_url } = image return ( <div key={index} className="card"> <div className="card-body "> <img alt={author} className="card-img-top" src={download_url} /> </div> <div className="card-footer"> <p className="card-text text-center text-capitalize text-primary">Shot by: {author}</p> </div> </div> ) })} </div> </div> </div> );
لعرض الصور ، نقوم بتعيين مجموعة الصور في كائن imgData
.
الآن ابدأ التطبيق واعرض الصفحة في المتصفح. يجب أن تشاهد الصور معروضة بشكل جيد في شبكة متجاوبة.
آخر بت هو تصدير مكون التطبيق.
export default App;
الفرع المقابل في هذه المرحلة هو 01-make-api-calls.
دعنا الآن نوسع هذا من خلال عرض المزيد من الصور أثناء تمرير الصفحة.
تنفيذ Infinite Scroll
نهدف إلى تقديم المزيد من الصور أثناء تمرير الصفحة. من عنوان URL لنقطة نهاية واجهة برمجة التطبيقات ، https://picsum.photos/v2/list?page=0&limit=10
، نعلم أنه للحصول على مجموعة جديدة من الصور ، نحتاج فقط إلى زيادة قيمة page
. نحتاج أيضًا إلى القيام بذلك عند نفاد الصور لعرضها. لغرضنا هنا ، سنعلم أننا نفدت الصور عندما نصل إلى أسفل الصفحة. حان الوقت لنرى كيف تساعدنا واجهة برمجة تطبيقات Intersection Observer على تحقيق ذلك.
افتح src/App.js
جديدًا ، pageReducer
، أسفل imgReducer
.
// App.js const imgReducer = (state, action) => { ... } const pageReducer = (state, action) => { switch (action.type) { case 'ADVANCE_PAGE': return { ...state, page: state.page + 1 } default: return state; } } const [ pager, pagerDispatch ] = useReducer(pageReducer, { page: 0 })
نحدد نوع عمل واحد فقط. في كل مرة يتم فيها تشغيل إجراء ADVANCE_PAGE
، تتم زيادة قيمة page
بمقدار 1.
قم بتحديث عنوان URL في وظيفة fetch
لقبول أرقام الصفحات ديناميكيًا كما هو موضح أدناه.
fetch(`https://picsum.photos/v2/list?page=${pager.page}&limit=10`)
أضف pager.page
إلى مصفوفة التبعية إلى جانب imgData
. يضمن القيام بذلك تشغيل استدعاء API كلما pager.page
.
useEffect(() => { ... }, [ imgDispatch, pager.page ])
بعد ربط الخطاف useEffect
لاستدعاء API ، أدخل الكود أدناه. قم بتحديث خط الاستيراد الخاص بك أيضًا.
// App.js import React, { useEffect, useReducer, useCallback, useRef } from 'react'; useEffect(() => { ... }, [ imgDispatch, pager.page ]) // implement infinite scrolling with intersection observer let bottomBoundaryRef = useRef(null); const scrollObserver = useCallback( node => { new IntersectionObserver(entries => { entries.forEach(en => { if (en.intersectionRatio > 0) { pagerDispatch({ type: 'ADVANCE_PAGE' }); } }); }).observe(node); }, [pagerDispatch] ); useEffect(() => { if (bottomBoundaryRef.current) { scrollObserver(bottomBoundaryRef.current); } }, [scrollObserver, bottomBoundaryRef]);
نحدد متغير bottomBoundaryRef
بتعيين قيمته على useRef(null)
. يسمح useRef
للمتغيرات بالحفاظ على قيمها عبر تصيير المكون ، أي أن القيمة الحالية للمتغير تستمر عند إعادة تصيير المكون المحتوي. الطريقة الوحيدة لتغيير قيمته هي إعادة .current
الخاصية الحالية لهذا المتغير.
في حالتنا ، يبدأ bottomBoundaryRef.current
بقيمة null
. مع استمرار دورة عرض الصفحة ، قمنا بتعيين خاصيتها الحالية لتكون العقدة <div id='page-bottom-boundary'>
.
نستخدم تعليمة ref={bottomBoundaryRef}
لإخبار React بتعيين bottomBoundaryRef.current
ليكون div حيث يتم الإعلان عن هذا التعيين.
هكذا،
bottomBoundaryRef.current = null
في نهاية دورة العرض ، يصبح:
bottomBoundaryRef.current = <div></div>
سنرى أين يتم تنفيذ هذه المهمة في دقيقة واحدة.
بعد ذلك ، نحدد وظيفة scrollObserver
، والتي من خلالها نضبط المراقب. تقبل هذه الوظيفة عقدة DOM
لمراقبتها. النقطة الأساسية التي يجب ملاحظتها هنا هي أنه كلما وصلنا إلى التقاطع تحت المراقبة ، نرسل إجراء ADVANCE_PAGE
. يتمثل التأثير في زيادة قيمة pager.page
بمقدار 1. بمجرد حدوث ذلك ، تتم إعادة تشغيل الخطاف useEffect
الذي يحتوي عليه باعتباره تبعية. هذا إعادة التشغيل ، بدوره ، يستدعي استدعاء الجلب برقم الصفحة الجديد.
موكب الحدث يشبه هذا.
اضغط على التقاطع تحت الملاحظة ← استدعاء إجراءADVANCE_PAGE
← زيادة قيمةpager.page
بمقدار 1 ← خطافuseEffect
لتشغيل استدعاءfetch
← تشغيل استدعاء الجلب ← يتم ربط الصور المرتجعة بمصفوفةimages
.
scrollObserver
في خطاف useEffect
بحيث تعمل الوظيفة فقط عندما تتغير أي من تبعيات الخطاف. إذا لم نستدعي الوظيفة داخل خطاف useEffect
، فستعمل الوظيفة على كل صفحة تصيير.
تذكر أن bottomBoundaryRef.current
يشير إلى <div id="page-bottom-boundary" style="border: 1px solid red;"></div>
. نتحقق من أن قيمتها ليست فارغة قبل تمريرها إلى scrollObserver
. وإلا ، فإن مُنشئ IntersectionObserver
سيعيد خطأ.
لأننا استخدمنا scrollObserver
في خطاف useEffect
، علينا أن نلفه في خطاف useCallback
لمنع إعادة تصيير المكون الذي لا ينتهي. يمكنك معرفة المزيد عن useCallback في مستندات React.
أدخل الرمز أدناه بعد <div id='images'>
div.
// App.js <div id='image'> ... </div> {imgData.fetching && ( <div className="text-center bg-secondary m-auto p-3"> <p className="m-0 text-white">Getting images</p> </div> )} <div id='page-bottom-boundary' style={{ border: '1px solid red' }} ref={bottomBoundaryRef}></div>
عندما يبدأ استدعاء API ، قمنا بضبط fetching
على true
، ويصبح النص Getting images مرئيًا. بمجرد الانتهاء ، قمنا بتعيين fetching
على " false
" ، ويتم إخفاء النص. يمكننا أيضًا تشغيل استدعاء API قبل الوصول إلى الحد تمامًا عن طريق تعيين threshold
مختلفة في كائن خيارات المُنشئ. يتيح لنا الخط الأحمر في النهاية أن نرى بالضبط متى وصلنا إلى حد الصفحة.
الفرع المقابل في هذه المرحلة هو 02 - التمرير اللانهائي.
سنقوم الآن بتنفيذ التحميل البطيء للصورة.
تنفيذ تحميل الصور الكسولة
إذا قمت بفحص علامة تبويب الشبكة أثناء التمرير لأسفل ، فسترى أنه بمجرد أن تصل إلى الخط الأحمر (الحد السفلي) ، تحدث مكالمة واجهة برمجة التطبيقات ، وتبدأ جميع الصور في التحميل حتى عندما لا تتمكن من العرض هم. هناك مجموعة متنوعة من الأسباب التي قد تجعل هذا السلوك غير مرغوب فيه. قد نرغب في حفظ مكالمات الشبكة حتى يرغب المستخدم في رؤية صورة. في مثل هذه الحالة ، يمكننا اختيار تحميل الصور ببطء ، أي لن نقوم بتحميل صورة حتى يتم تمريرها إلى العرض.
افتح src/App.js
أسفل وظائف التمرير اللانهائية ، أدخل الكود التالي.
// App.js // lazy loads images with intersection observer // only swap out the image source if the new url exists const imagesRef = useRef(null); const imgObserver = useCallback(node => { const intObs = new IntersectionObserver(entries => { entries.forEach(en => { if (en.intersectionRatio > 0) { const currentImg = en.target; const newImgSrc = currentImg.dataset.src; // only swap out the image source if the new url exists if (!newImgSrc) { console.error('Image source is invalid'); } else { currentImg.src = newImgSrc; } intObs.unobserve(node); // detach the observer when done } }); }) intObs.observe(node); }, []); useEffect(() => { imagesRef.current = document.querySelectorAll('.card-img-top'); if (imagesRef.current) { imagesRef.current.forEach(img => imgObserver(img)); } }, [imgObserver, imagesRef, imgData.images]);
كما هو الحال مع scrollObserver
، نحدد وظيفة ، imgObserver
، والتي تقبل عقدة لمراقبة. عندما تصل الصفحة إلى تقاطع ، كما هو محدد بواسطة en.intersectionRatio > 0
، نقوم بتبديل مصدر الصورة على العنصر. لاحظ أننا نتحقق أولاً من وجود مصدر الصورة الجديد قبل إجراء التبديل. كما هو الحال مع وظيفة scrollObserver
، نقوم بلف imgObserver في خطاف useCallback
لمنع إعادة تصيير المكون الذي لا ينتهي.
لاحظ أيضًا أننا نتوقف عن ملاحظة عنصر img
بمجرد أن ننتهي من الاستبدال. نحن نفعل هذا بطريقة unobserve
.
في خطاف useEffect
التالي ، نلتقط جميع الصور بفئة .card-img-top
على الصفحة مع document.querySelectorAll
. ثم نكرر كل صورة ونضع مراقبًا عليها.
لاحظ أننا أضفنا imgData.images
كعنصر تبعية useEffect
. عندما يتغير هذا ، فإنه يقوم بتشغيل الخطاف useEffect
وبالتالي يتم استدعاء imgObserver
مع كل عنصر من عناصر <img className='card-img-top'>
.
قم بتحديث عنصر <img className='card-img-top'/>
كما هو موضح أدناه.
<img alt={author} data-src={download_url} className="card-img-top" src={'https://picsum.photos/id/870/300/300?grayscale&blur=2'} />
قمنا بتعيين مصدر افتراضي لكل عنصر <img className='card-img-top'/>
وقمنا بتخزين الصورة التي نريد عرضها في خاصية data-src
. عادةً ما يكون للصورة الافتراضية حجم صغير بحيث يتم تنزيلها بأقل قدر ممكن. عندما يظهر العنصر <img/>
في العرض ، تحل القيمة الموجودة في الخاصية data-src
محل الصورة الافتراضية.
في الصورة أدناه ، نرى صورة المنارة الافتراضية لا تزال تظهر في بعض المساحات.
الفرع المقابل في هذه المرحلة هو 03-lazy-load.
لنرى الآن كيف يمكننا تجريد كل هذه الوظائف حتى يمكن إعادة استخدامها.
جلب التجريد والتمرير اللانهائي والتحميل البطيء في خطافات مخصصة
لقد نجحنا في تنفيذ عمليات الجلب والتمرير اللانهائي والتحميل البطيء للصورة. قد يكون لدينا مكون آخر في تطبيقنا يحتاج إلى وظائف مماثلة. في هذه الحالة ، يمكننا تجريد هذه الوظائف وإعادة استخدامها. كل ما علينا فعله هو نقلهم داخل ملف منفصل واستيرادهم حيث نحتاجهم. نريد تحويلها إلى خطافات مخصصة.
تُعرِّف وثائق React الخطاف المخصص كوظيفة JavaScript يبدأ اسمها بـ "use"
والتي قد تستدعي الخطافات الأخرى. في حالتنا ، نريد إنشاء ثلاثة خطافات ، useFetch
، useInfiniteScroll
، useLazyLoading
.
قم بإنشاء ملف داخل المجلد src/
. customHooks.js
والصق الكود أدناه بالداخل.
// customHooks.js import { useEffect, useCallback, useRef } from 'react'; // make API calls and pass the returned data via dispatch export const useFetch = (data, dispatch) => { useEffect(() => { dispatch({ type: 'FETCHING_IMAGES', fetching: true }); fetch(`https://picsum.photos/v2/list?page=${data.page}&limit=10`) .then(data => data.json()) .then(images => { dispatch({ type: 'STACK_IMAGES', images }); dispatch({ type: 'FETCHING_IMAGES', fetching: false }); }) .catch(e => { dispatch({ type: 'FETCHING_IMAGES', fetching: false }); return e; }) }, [dispatch, data.page]) } // next code block here
يقبل الخطاف useFetch
وظيفة إرسال وكائن بيانات. تمرر وظيفة الإرسال البيانات من استدعاء API إلى مكون App
، بينما يتيح لنا كائن البيانات تحديث عنوان URL لنقطة نهاية API.
// infinite scrolling with intersection observer export const useInfiniteScroll = (scrollRef, dispatch) => { const scrollObserver = useCallback( node => { new IntersectionObserver(entries => { entries.forEach(en => { if (en.intersectionRatio > 0) { dispatch({ type: 'ADVANCE_PAGE' }); } }); }).observe(node); }, [dispatch] ); useEffect(() => { if (scrollRef.current) { scrollObserver(scrollRef.current); } }, [scrollObserver, scrollRef]); } // next code block here
يقبل الخطاف useInfiniteScroll
scrollRef
dispatch
. يساعدنا scrollRef
في إعداد المراقب ، كما تمت مناقشته سابقًا في القسم الذي طبقناه فيه. توفر وظيفة الإرسال طريقة لبدء إجراء يقوم بتحديث رقم الصفحة في عنوان URL لنقطة نهاية واجهة برمجة التطبيقات.
// lazy load images with intersection observer export const useLazyLoading = (imgSelector, items) => { const imgObserver = useCallback(node => { const intObs = new IntersectionObserver(entries => { entries.forEach(en => { if (en.intersectionRatio > 0) { const currentImg = en.target; const newImgSrc = currentImg.dataset.src; // only swap out the image source if the new url exists if (!newImgSrc) { console.error('Image source is invalid'); } else { currentImg.src = newImgSrc; } intObs.unobserve(node); // detach the observer when done } }); }) intObs.observe(node); }, []); const imagesRef = useRef(null); useEffect(() => { imagesRef.current = document.querySelectorAll(imgSelector); if (imagesRef.current) { imagesRef.current.forEach(img => imgObserver(img)); } }, [imgObserver, imagesRef, imgSelector, items]) }
يتلقى الخطاف useLazyLoading
. المحدد يستخدم للعثور على الصور. يؤدي أي تغيير في المصفوفة إلى تشغيل خطاف useEffect
الذي يقوم بإعداد المراقب على كل صورة.
يمكننا أن نرى أنها نفس الوظائف الموجودة في src/App.js
التي قمنا باستخراجها إلى ملف جديد. الشيء الجيد الآن هو أنه يمكننا تمرير الحجج بشكل ديناميكي. دعنا الآن نستخدم هذه الخطافات المخصصة في مكون التطبيق.
افتح src/App.js
قم باستيراد الخطافات المخصصة وحذف الوظائف التي حددناها لجلب البيانات والتمرير اللانهائي والتحميل البطيء للصور. اترك المخفضات والمقاطع حيث نستخدم useReducer
. الصق الكود أدناه.
// App.js // import custom hooks import { useFetch, useInfiniteScroll, useLazyLoading } from './customHooks' const imgReducer = (state, action) => { ... } // retain this const pageReducer = (state, action) => { ... } // retain this const [pager, pagerDispatch] = useReducer(pageReducer, { page: 0 }) // retain this const [imgData, imgDispatch] = useReducer(imgReducer,{ images:[], fetching: true }) // retain this let bottomBoundaryRef = useRef(null); useFetch(pager, imgDispatch); useLazyLoading('.card-img-top', imgData.images) useInfiniteScroll(bottomBoundaryRef, pagerDispatch); // retain the return block return ( ... )
لقد تحدثنا بالفعل عن bottomBoundaryRef
في القسم الخاص بالتمرير اللانهائي. نقوم بتمرير كائن pager
ووظيفة imgDispatch
إلى useFetch
. يقبل useLazyLoading
اسم الفئة .card-img-top
. لاحظ ال .
المدرجة في اسم الفصل. من خلال القيام بذلك ، لا نحتاج إلى تحديد document.querySelectorAll
. يقبل useInfiniteScroll
كلا من المرجع ودالة الإرسال لزيادة قيمة page
.
الفرع المقابل في هذه المرحلة هو 04 خطافات مخصصة.
خاتمة
يتحسن HTML في توفير واجهات برمجة تطبيقات لطيفة لتنفيذ ميزات رائعة. في هذا المنشور ، رأينا مدى سهولة استخدام مراقب التقاطع في مكون وظيفي لـ React. في هذه العملية ، تعلمنا كيفية استخدام بعض خطاطيف React وكيفية كتابة الخطافات الخاصة بنا.
موارد
- "Infinite Scroll + Image Lazy Loading" ، Orji Chidi Matthew ، GitHub
- "تمرير لانهائي ، ترقيم الصفحات أو" تحميل المزيد "من الأزرار؟ نتائج قابلية الاستخدام في التجارة الإلكترونية ، "كريستيان هولست ، مجلة سماشينج
- "لوريم بيكسوم ،" ديفيد ماربي ونيجيكو يونسكاي
- "دخول IntersectionObserver إلى العرض" ، Surma ، أساسيات الويب
- هل يمكنني استخدام…
IntersectionObserver
- "واجهة برمجة تطبيقات Intersection Observer ،" مستندات الويب MDN
- "المكونات والدعائم" رد فعل
- رد فعل "
useCallback
" - "
useReducer
،" رد فعل