जब आपको उपयोगकर्ता की कार्रवाइयों पर तुरंत प्रतिक्रिया देने और बैकएंड से नवीनतम डेटा प्राप्त करने की आवश्यकता होती है, तो आपको एक रिएक्ट हुक की आवश्यकता हो सकती है जो अनुक्रमिक अनुरोधों का समर्थन करता है। यह हुक पिछले अनुरोधों को रद्द कर सकता है यदि वे अभी भी जारी हैं और केवल सबसे हालिया डेटा लौटाता है। इससे न केवल प्रदर्शन में सुधार होता है बल्कि उपयोगकर्ता अनुभव भी बेहतर होता है।
आइए एक सरल अनुक्रमिक अनुरोध रिएक्ट हुक बनाकर शुरुआत करें:
import { useCallback, useRef } from 'react'; const buildCancelableFetch =( requestFn: (signal: AbortSignal) => Promise , ) => { const abortController = new AbortController(); return { run: () => new Promise ((resolve, reject) => { if (abortController.signal.aborted) { reject(new Error('CanceledError')); return; } requestFn(abortController.signal).then(resolve, reject); }), cancel: () => { abortController.abort(); }, }; }; function useLatest (value: T) { const ref = useRef(value); ref.current = value; return ref; } export function useSequentialRequest ( requestFn: (signal: AbortSignal) => Promise , ) { const requestFnRef = useLatest(requestFn); const currentRequest = useRef void } | null>(null); return useCallback(async () => { if (currentRequest.current) { currentRequest.current.cancel(); } const { run, cancel } = buildCancelableFetch(requestFnRef.current); currentRequest.current = { cancel }; return run().finally(() => { if (currentRequest.current?.cancel === cancel) { currentRequest.current = null; } }); }, [requestFnRef]); }
यहाँ मुख्य विचार "जावास्क्रिप्ट में वादों को कैसे रद्द करें" लेख से आता है। आप इसे इस तरह उपयोग कर सकते हैं:
import { useSequentialRequest } from './useSequentialRequest'; export function App() { const run = useSequentialRequest((signal: AbortSignal) => fetch('http://localhost:5000', { signal }).then((res) => res.text()), ); return ; }
इस तरह, जब आप बटन को कई बार तेजी से क्लिक करते हैं, तो आपको केवल नवीनतम अनुरोध से डेटा मिलेगा, और पिछले अनुरोध खारिज कर दिए जाएंगे।
यदि हमें अधिक व्यापक अनुक्रमिक अनुरोध रिएक्ट हुक की आवश्यकता है, तो उपरोक्त कोड में सुधार की गुंजाइश है। उदाहरण के लिए:
हम एक एबॉर्टकंट्रोलर का निर्माण तब तक के लिए टाल सकते हैं जब तक इसकी वास्तव में आवश्यकता न हो, जिससे अनावश्यक निर्माण लागत कम हो जाएगी।
हम किसी भी प्रकार के अनुरोध तर्क का समर्थन करने के लिए जेनेरिक का उपयोग कर सकते हैं।
यहाँ अद्यतन संस्करण है:
import { useCallback, useRef } from 'react'; function useLatest(value: T) { const ref = useRef(value); ref.current = value; return ref; } export function useSequentialRequest ( requestFn: (signal: AbortSignal, ...args: Args) => Promise, ) { const requestFnRef = useLatest(requestFn); const running = useRef(false); const abortController = useRef (null); return useCallback( async (...args: Args) => { if (running.current) { abortController.current?.abort(); abortController.current = null; } running.current = true; const controller = abortController.current ?? new AbortController(); abortController.current = controller; return requestFnRef.current(controller.signal, ...args).finally(() => { if (controller === abortController.current) { running.current = false; } }); }, [requestFnRef], ); }
ध्यान दें कि अंततः ब्लॉक में, हम जांचते हैं कि दौड़ की स्थिति को रोकने के लिए वर्तमान नियंत्रक abortController.current के बराबर है या नहीं। यह सुनिश्चित करता है कि केवल सक्रिय अनुरोध ही चालू स्थिति को संशोधित कर सकता है।
अधिक व्यापक उपयोग:
import { useState } from 'react'; import { useSequentialRequest } from './useSequentialRequest'; export default function Home() { const [data, setData] = useState(''); const run = useSequentialRequest(async (signal: AbortSignal, query: string) => fetch(`/api/hello?query=${query}`, { signal }).then((res) => res.text()), ); const handleInput = async (queryStr: string) => { try { const res = await run(queryStr); setData(res); } catch { // ignore errors } }; return ( { handleInput(e.target.value); }} />Response Data: {data}> ); }
आप इसे ऑनलाइन आज़मा सकते हैं: जैसे ही आप तेज़ी से टाइप करेंगे, पिछले अनुरोध रद्द कर दिए जाएंगे, और केवल नवीनतम प्रतिक्रिया दिखाई जाएगी।
यदि आपको यह उपयोगी लगा, कृपया वेब विकास के बारे में अधिक उपयोगी लेखों और उपकरणों के लिए मेरे न्यूज़लेटर की सदस्यता लेने पर विचार करें पढ़ने के लिए धन्यवाद!
अस्वीकरण: उपलब्ध कराए गए सभी संसाधन आंशिक रूप से इंटरनेट से हैं। यदि आपके कॉपीराइट या अन्य अधिकारों और हितों का कोई उल्लंघन होता है, तो कृपया विस्तृत कारण बताएं और कॉपीराइट या अधिकारों और हितों का प्रमाण प्रदान करें और फिर इसे ईमेल पर भेजें: [email protected] हम इसे आपके लिए यथाशीघ्र संभालेंगे।
Copyright© 2022 湘ICP备2022001581号-3