इस लेख में, हम यह पता लगाएंगे कि रिएक्ट क्वेरी का उपयोग करके फ़ीड पेज कैसे बनाया जाए!
यहां बताया गया है कि हम क्या बनाएंगे:
यह आलेख ऐप के निर्माण में शामिल प्रत्येक चरण और विवरण को कवर नहीं करेगा।
इसके बजाय, हम मुख्य विशेषताओं पर ध्यान केंद्रित करेंगे, विशेष रूप से "अनंत स्क्रॉल" और "स्क्रॉल-टू-टॉप" कार्यक्षमताओं पर।
यदि आप संपूर्ण कार्यान्वयन से परामर्श लेने में रुचि रखते हैं, तो आप इस GitHub रिपॉजिटरी में पूरा कोडबेस पा सकते हैं।
सबसे पहले, हम निम्नलिखित कमांड के साथ Vite का उपयोग करके अपना रिएक्ट एप्लिकेशन बनाएंगे:
npm create vite@latest feed-page-rq -- --template react-ts
और, हम आवश्यक निर्भरताएँ स्थापित करेंगे, axios और react-query:
npm install axios @tanstack/react-query@4
हमें एक RESTful सर्वर का अनुकरण करने की भी आवश्यकता है, इसलिए हम json-server का उपयोग करेंगे, जो हमें हमारे रिएक्ट ऐप के लिए नकली एपीआई एंडपॉइंट प्रदान करके बैकएंड अनुकरण करने की अनुमति देता है।
हम एक पोस्ट इकाई के साथ काम करेंगे जिसमें निम्नलिखित विशेषताएं शामिल हैं:
{ "id": "1", "title": "Sample Post Title", "body": "This is a sample post body", "userId": "2", "createdAt": 1728334799169 // date timestamp }
एक बार सर्वर सेट हो जाने पर, हम इसे इसका उपयोग करके चलाएंगे:
npx json-server --watch db.json
"अनंत स्क्रॉल" सुविधा का तंत्र सीधा है:
जब उपयोगकर्ता पोस्ट की सूची में स्क्रॉल करता है और कंटेनर के नीचे पहुंचता है, तो रिएक्ट क्वेरी पोस्ट के अगले बैच की तलाश करेगी। यह प्रक्रिया तब तक दोहराई जाती है जब तक कि लोड करने के लिए कोई और पोस्ट न बचे।
हम वर्तमान स्क्रॉल स्थिति (स्क्रॉलटॉप) को दृश्यमान स्क्रीन ऊंचाई (क्लाइंटहाइट) में जोड़कर सत्यापित करते हैं कि उपयोगकर्ता नीचे के करीब है या नहीं और इस योग की तुलना से करते हैं। कंटेनर की कुल ऊंचाई (स्क्रॉलहाइट)।
यदि योग कुल कंटेनर ऊंचाई से अधिक या उसके बराबर है, तो हम रिएक्ट क्वेरी से अगला पृष्ठ लाने के लिए कहते हैं।
const { scrollTop, scrollHeight, clientHeight } = elemRef.current; if(scrollTop clientHeight >= scrollHeight) { fetchNextPage(); }
सबसे पहले, हम रिएक्ट क्वेरी के यूज़इनफिनिटक्वेरी को लपेटने के लिए एक कस्टम हुक बनाएंगे।
कस्टम हुक के भीतर, हम पेज दर पेज पोस्ट लाने के लिए क्वेरी को कॉन्फ़िगर करते हैं, प्रारंभिक पेज नंबर और अगले पेज को पुनः प्राप्त करने वाले फ़ंक्शन को निर्दिष्ट करते हैं:
import { QueryFunctionContext, useInfiniteQuery } from "@tanstack/react-query"; import axios from "axios"; const URL = "http://localhost:3000"; const POSTS = "posts"; export const fetchInfinitePosts = async ({ pageParam, }: QueryFunctionContext) => { const result = await axios.get( `${URL}/${POSTS}?_sort=-createdAt&_page=${pageParam}&_per_page=10`, ); return result.data; }; export const useInfinitePosts = () => { return useInfiniteQuery({ queryKey: [POSTS], queryFn: fetchInfinitePosts, initialPageParam: 1, getNextPageParam: (lastPage) => lastPage.next, }); };
अब, हम पोस्ट की सूची प्रदर्शित करने के लिए अपने घटक में कस्टम हुक का उपयोग करेंगे।
ऐसा करने के लिए, हम पहले पृष्ठों के माध्यम से लूप करते हैं और फिर उन्हें प्रस्तुत करने के लिए प्रत्येक पृष्ठ के भीतर पोस्ट पर पुनरावृति करते हैं।
import { useInfinitePosts } from './hooks/useInfinitePosts'; const PostList = () => { const { data: postLists } = useInfinitePosts(); return ({postLists?.pages.map((page) => page.data.map(post => (); }; export default PostList;)) )}{post.title}
{post.body}
अनंत स्क्रॉल व्यवहार को लागू करने के लिए, हमें उस कंटेनर में एक स्क्रॉल इवेंट श्रोता जोड़ना होगा जहां पोस्ट प्रदर्शित होते हैं। यह ईवेंट श्रोता ऑनस्क्रॉल फ़ंक्शन को ट्रिगर करता है, जो जांचता है कि उपयोगकर्ता कंटेनर के निचले भाग के पास है या नहीं, और यदि हां, तो अधिक सामग्री लोड करने के लिए FetchNextPage को कॉल करता है।
import React, { useRef, useEffect } from 'react'; import { useInfinitePosts } from './hooks/useInfinitePosts'; const PostList = () => { const { data: postLists, fetchNextPage } = useInfinitePosts(); const elemRef = useRef(null); const onScroll = useCallback(() => { if (elemRef.current) { const { scrollTop, scrollHeight, clientHeight } = elemRef.current; const isNearBottom = scrollTop clientHeight >= scrollHeight; if(isNearBottom) { fetchNextPage(); } } }, [fetchNextPage]); useEffect(() => { const innerElement = elemRef.current; if (innerElement) { innerElement.addEventListener("scroll", onScroll); return () => { innerElement.removeEventListener("scroll", onScroll); }; } }, [onScroll]); return ({postLists?.pages.map((page, i) => page.data.map(post => (); }; export default PostList;)) )}{post.title}
{post.body}
इसके बाद, हम एक "स्क्रॉल टू टॉप" बटन बनाएंगे जो एक नई पोस्ट जोड़ने पर दिखाई देता है। यह बटन उपयोगकर्ता को नवीनतम अपडेट देखने के लिए तुरंत शीर्ष पर लौटने देता है।
चूंकि पोस्ट निर्माण तिथि के अनुसार क्रमबद्ध की जाती हैं, इसलिए कोई भी नई जोड़ी गई पोस्ट सूची के शीर्ष पर दिखाई देगी।
हमारे फीचर का तर्क इस आधार पर बनाया जाएगा।
हम नवीनतम बनाई गई पोस्ट को लाने और कैश करने के लिए एक नई क्वेरी बनाकर शुरुआत करते हैं। हम इस पोस्ट को prevNewestPost कहेंगे।
हम चाहते हैं कि prevNewestPost कुछ कदम पीछे रहे, या ज़्यादा से ज़्यादा, सूची की पहली पोस्ट से मेल खाए। इसलिए, हम इसके रीफ़ेच को मैन्युअल रूप से नियंत्रित करेंगे।
हम इसे क्वेरी विकल्पों में सक्षम: गलत सेट करके हासिल करेंगे।
export const fetchNewestPost = async () => { const result = await axios.get(`${URL}/${POSTS}?_sort=-createdAt`); return result.data[0]; }; export const useNewestPost = () => { return useQuery({ queryKey: [POSTS, "newest"], queryFn: () => fetchNewestPost(), enabled: false, }); };
रिएक्ट क्वेरी के साथ, पोस्ट सूची विशिष्ट घटनाओं पर स्वचालित रूप से अपडेट हो जाती है। (इन घटनाओं की पूरी सूची के लिए दस्तावेज़ीकरण लिंक यहां दिया गया है।)
हम इस अद्यतन सूची का उपयोग यह निर्धारित करने के लिए करेंगे कि पहली पोस्ट के साथ prevNewestPost की तुलना करके 'स्क्रॉल टू टॉप' बटन कब प्रदर्शित किया जाए।
यदि वे भिन्न हैं, तो यह इंगित करता है कि एक नया पोस्ट जोड़ा गया है, इसलिए 'स्क्रॉल टू टॉप' बटन दिखाया जाएगा।
setIsShowButton(postLists?.pages[0].data[0].id !== prevNewestPost?.id);
जब उपयोगकर्ता पोस्ट सूची कंटेनर के शीर्ष पर हो तो हमें "स्क्रॉल टू टॉप" बटन नहीं दिखाना चाहिए।
इसलिए, जब उपयोगकर्ता शीर्ष पर पहुंचता है, तो हमें क्वेरी रीफ़ेच को ट्रिगर करके prevNewestPost को वर्तमान नवीनतम पोस्ट के साथ पुन: सिंक करने की आवश्यकता होती है।
const { data: prevNewestPost, refetch } = useNewestPost(); const [isShowButton, setIsShowButton] = useState(false); useEffect(() => { if (!isNearTop) { setIsShowButton(postLists?.pages[0].data[0].id !== prevNewestPost?.id); } else { setIsShowButton(false); refetch(); } }, [postLists, prevNewestPost, isNearTop]);
ToTopBtn बटन पर क्लिक करने से सूची के शीर्ष पर स्क्रॉल किया जाएगा, बटन को छिपाने के लिए मौजूदा तर्क को ट्रिगर किया जाएगा और सूची की पहली पोस्ट के साथ prevNewestPost को सिंक करने के लिए डेटा को दोबारा प्राप्त किया जाएगा।
import { RefObject } from "react"; type ToTopBtnProps = { elemRef: RefObject; }; export default function ToTopBtn({ elemRef }: ToTopBtnProps) { return ( ); }
हमारी "स्क्रॉल टू टॉप" बटन कार्यक्षमता का परीक्षण करने के लिए, हमें फ़ीड में नई पोस्ट जोड़ने की आवश्यकता है।
इसके लिए, हम सर्वर पर एक नई पोस्ट जोड़ने के लिए रिएक्ट क्वेरी से useMutation का उपयोग करेंगे और प्रत्येक म्यूटेशन के बाद हमारी कैश्ड पोस्टलिस्ट को फिर से सत्यापित करेंगे।
हम एक उत्परिवर्तन स्थापित करेंगे जो हमें उपयोगकर्ता द्वारा किसी बटन पर क्लिक करने पर यादृच्छिक डेटा के साथ एक नई पोस्ट बनाने की अनुमति देगा।
export const savePost = async (post: NewPostData) => axios.post(`${URL}/${POSTS}`, post); export const useAddPost = () => { const queryClient = useQueryClient(); return useMutation({ mutationFn: savePost, onSuccess: () => { queryClient.invalidateQueries({ queryKey: [POSTS] }); }, }); };
export default function AddNewPostBtn() { const mutation = useAddPost(); return ();
इस ट्यूटोरियल में, हमने वास्तविक उपयोग के मामले के माध्यम से रिएक्ट क्वेरी की शक्ति का पता लगाया, जिससे डेवलपर्स को उपयोगकर्ता अनुभव को बढ़ाने वाले गतिशील इंटरफेस बनाने में मदद करने की इसकी क्षमता पर प्रकाश डाला गया।
अस्वीकरण: उपलब्ध कराए गए सभी संसाधन आंशिक रूप से इंटरनेट से हैं। यदि आपके कॉपीराइट या अन्य अधिकारों और हितों का कोई उल्लंघन होता है, तो कृपया विस्तृत कारण बताएं और कॉपीराइट या अधिकारों और हितों का प्रमाण प्रदान करें और फिर इसे ईमेल पर भेजें: [email protected] हम इसे आपके लिए यथाशीघ्र संभालेंगे।
Copyright© 2022 湘ICP备2022001581号-3