React Native में useMemo हुक कंपोनेंट के री-रेंडर के बीच गणनाओं के परिणाम को मेमोइज़ करता है, महंगे ऑपरेशनों के बार-बार निष्पादन को रोकता है। useCallback के विपरीत, जो एक फ़ंक्शन को मेमोइज़ करता है, useMemo लौटाए गए मान को संरक्षित करता है और इसे केवल तभी पुनर्गणना करता है जब निर्दिष्ट निर्भरताएँ बदलती हैं। React Docs, 2024 के अनुसार, मेमोइज़ेशन विशेष रूप से बड़े ऐरे और जटिल डेटा ट्रांसफ़ॉर्मेशन वाली गणनाओं के लिए प्रभावी है। React Native में, हर अनावश्यक री-रेंडर JavaScript और नेटिव थ्रेड्स के बीच ब्रिज कनेक्शन पर अतिरिक्त लोड बनाता है, इसलिए useMemo का सही उपयोग सीधे एनिमेशन की स्मूथनेस और इंटरफ़ेस की प्रतिक्रिया गति को प्रभावित करता है।
मुख्य बातें
useMemo — React की मानक लाइब्रेरी का एक हुक है, जो बिना अतिरिक्त पैकेज के React Native में उपलब्ध है। यह पास किए गए फ़ंक्शन द्वारा लौटाए गए मान को मेमोइज़ करता है और बाद के री-रेंडर पर इस मान का पुन: उपयोग करता है जब तक कि ऐरे में निर्दिष्ट निर्भरताएँ नहीं बदलतीं।
हुक का नाम memoization से लिया गया है — एक ऑप्टिमाइज़ेशन तकनीक जिसमें एक महंगे फ़ंक्शन का परिणाम कैश में संग्रहीत किया जाता है। समान आर्गुमेंट के साथ बाद के कॉल पर, पुनर्गणना के बजाय कैश किया गया मान लौटाया जाता है।
React Native के संदर्भ में, आर्किटेक्चरल विशेषताओं के कारण मेमोइज़ेशन विशेष रूप से महत्वपूर्ण है। प्रत्येक कंपोनेंट री-रेंडर JavaScript — नेटिव ब्रिज के माध्यम से डेटा भेजता है, जिसमें समय लगता है। यदि किसी कंपोनेंट में महंगी गणनाएँ (सूची फ़िल्टरिंग, सॉर्टिंग, फ़ॉर्मेटिंग) हैं, तो प्रत्येक री-रेंडर उन्हें दोहराएगा, JS थ्रेड को ब्लॉक करेगा और फ्रेम ड्रॉप का कारण बनेगा।
React Native Performance Docs, 2024 के अनुसार, बाधा अक्सर नेटिव कंपोनेंट्स का रेंडरिंग नहीं, बल्कि री-रेंडर के बीच JavaScript लॉजिक का निष्पादन होती है। useMemo इसी समस्या का समाधान करता है।
useMemo एक फ़ंक्शन और एक निर्भरता ऐरे लेता है, और एक मेमोइज़्ड मान लौटाता है। React पिछले मान और निर्भरता ऐरे को संग्रहीत करता है। प्रत्येक री-रेंडर पर, React Object.is का उपयोग करके वर्तमान निर्भरताओं की पिछली निर्भरताओं से तुलना करता है। यदि कम से कम एक निर्भरता बदली है, तो फ़ंक्शन फिर से निष्पादित होता है और परिणाम संग्रहीत होता है।
useMemo का सिग्नेचर वेब और React Native में पूरी तरह समान है। पहला आर्गुमेंट बिना पैरामीटर वाला फ़ंक्शन है जो मेमोइज़ किए जाने वाले मान को लौटाता है। दूसरा निर्भरता ऐरे है, जिसके बदलने पर मान की पुनर्गणना होगी।
import React, { useMemo } from 'react';
const sortedList = useMemo(() => {
return items.sort((a, b) => a.name.localeCompare(b.name));
}, [items]);
इस उदाहरण में, sortedList केवल तब पुनर्गणना होती है जब items ऐरे का रेफ़रेंस बदलता है। यदि ऐरे की सामग्री बदली लेकिन रेफ़रेंस वही रहा (म्यूटेशन), तो useMemo परिवर्तनों का पता नहीं लगाएगा — यह एक महत्वपूर्ण सीमा है।
React निर्भरताओं की तुलना के लिए Object.is एल्गोरिदम का उपयोग करता है, जो सख्त समानता === के समान काम करता है लेकिन NaN को सही ढंग से संभालता है (+0 और -0 को भिन्न माना जाता है)। इसका मतलब है कि प्रिमिटिव प्रकारों (स्ट्रिंग, संख्याएँ, बूलियन) के लिए तुलना मान द्वारा काम करती है, जबकि ऑब्जेक्ट और ऐरे के लिए — रेफ़रेंस द्वारा।
// Object.is({'a': 1}, {'a': 1}) -> false (different refs)
// Object.is(42, 42) -> true (primitive by value)
// Object.is(NaN, NaN) -> true (correct handling of NaN)
इस तंत्र को समझना महत्वपूर्ण है: यदि आप प्रत्येक री-रेंडर पर निर्भरताओं में एक नया ऑब्जेक्ट पास करते हैं, तो मेमोइज़ेशन बेकार होगा क्योंकि निर्भरताएँ हर बार बदली हुई मानी जाएँगी।
useMemo तीन परिदृश्यों में उचित है: महंगी गणनाएँ, चाइल्ड कंपोनेंट्स को स्थिर props पास करना, और ऑब्जेक्ट की रेफ़रेंशियल आइडेंटिटी बनाए रखना। React Native में, मोबाइल एप्लिकेशन की आर्किटेक्चर के कारण ये तीनों परिदृश्य नियमित रूप से होते हैं।
यदि कोई कंपोनेंट बड़े डेटा ऐरे (फ़िल्टरिंग, सॉर्टिंग, ग्रुपिंग) या संसाधन-गहन गणितीय संक्रियाओं को प्रोसेस करता है, तो useMemo प्रत्येक री-रेंडर पर इन गणनाओं को दोहराने से रोकता है। मोबाइल एप्लिकेशन में, एक विशिष्ट उदाहरण सूची में प्रदर्शित करने से पहले API से डेटा को फ़ॉर्मेट करना है।
जब कोई चाइल्ड कंपोनेंट React.memo में लिपटा होता है, तो वह केवल अपने props बदलने पर ही री-रेंडर होता है। यदि पैरेंट के अंदर useMemo के बिना कोई prop ऑब्जेक्ट बनाया जाता है, तो पैरेंट के प्रत्येक री-रेंडर पर एक नया रेफ़रेंस बनेगा, और चाइल्ड कंपोनेंट अनावश्यक रूप से री-रेंडर होगा, जिससे React.memo का लाभ समाप्त हो जाता है।
React Native में, स्टाइल अक्सर props पर निर्भर करते हैं — उदाहरण के लिए, तत्व की चौड़ाई स्क्रीन आकार के आधार पर गणना की जाती है। useMemo ऐसे डायनामिक स्टाइल की गणना केवल तब करने की अनुमति देता है जब इनपुट पैरामीटर बदलते हैं।
useMemo कोई सार्वभौमिक ऑप्टिमाइज़ेशन उपकरण नहीं है। कई परिदृश्यों में यह कोई लाभ नहीं देता और निर्भरताओं को संग्रहीत करने और तुलना करने के ओवरहेड के कारण प्रदर्शन को खराब भी कर सकता है। React Native में, जहाँ मेमोरी का हर बाइट महत्वपूर्ण है, बिना प्रभाव मापे useMemo का आँख बंद करके उपयोग करना एक एंटी-पैटर्न है।
हुक तीन मुख्य मामलों में कोई लाभ नहीं देता। पहला, यदि गणना तुच्छ है (सरल जोड़, स्ट्रिंग संयोजन), तो useMemo की लागत स्वयं गणना की लागत से अधिक होती है। दूसरा, यदि निर्भरताएँ हर रेंडर पर बदलती हैं — फ़ंक्शन फिर भी निष्पादित होगा, और मेमोइज़ेशन केवल अतिरिक्त काम जोड़ता है। तीसरा, यदि कंपोनेंट शायद ही कभी रेंडर होता है, तो कैश भंडारण का ओवरहेड उचित नहीं है।
Kent C. Dodds, 2023 के अनुसार, useMemo जोड़ने से पहले, React DevTools Profiler या React Native में अंतर्निहित Performance Monitor का उपयोग करके समस्या को मापना चाहिए। यदि कंपोनेंट का री-रेंडर 1 ms से कम समय लेता है, तो मेमोइज़ेशन आवश्यक नहीं है।
useMemo और useCallback — React के दो मेमोइज़ेशन हुक हैं जिन्हें अक्सर भ्रमित किया जाता है। अंतर इस बात में है कि वे क्या संरक्षित करते हैं: useMemo फ़ंक्शन के निष्पादन का परिणाम (कोई भी मान) लौटाता है, जबकि useCallback स्वयं फ़ंक्शन लौटाता है। दोनों निर्भरता ऐरे लेते हैं, लेकिन सिंटैक्स भिन्न है।
| विशेषता | useMemo | useCallback |
|---|---|---|
| लौटाता है | फ़ंक्शन निष्पादन का परिणाम | फ़ंक्शन का रेफ़रेंस |
| पहला आर्गुमेंट | मान लौटाने वाला फ़ंक्शन | मेमोइज़ किया जाने वाला फ़ंक्शन |
| विशिष्ट उपयोग | गणनाओं को कैश करना | चाइल्ड कंपोनेंट्स के लिए स्थिर कॉलबैक |
| समतुल्यता | useMemo(() => fn, deps) | useCallback(fn, deps) === useMemo(() => fn, deps) |
व्यवहार में, useCallback उन मामलों के लिए useMemo के ऊपर सिंटैक्टिक शुगर है जब आपको किसी फ़ंक्शन को मेमोइज़ करने की आवश्यकता होती है। React Native में, दोनों हुक समान रूप से उपयोग किए जाते हैं: useMemo — डेटा के लिए (फ़ॉर्मेटेड टेक्स्ट, गणना किए गए स्टाइल), useCallback — इवेंट हैंडलर के लिए (onPress, onChangeText)।
React Native एप्लिकेशन में useMemo के उपयोग के दो वास्तविक परिदृश्य देखें। पहला है खोज क्वेरी द्वारा संपर्क सूची को फ़िल्टर करना, दूसरा है स्क्रीन आकार के आधार पर डायनामिक स्टाइल की गणना करना।
इस उदाहरण में, useMemo बड़ी संपर्क सूची के प्रत्येक री-रेंडर पर बार-बार फ़िल्टरिंग को रोकता है यदि न तो खोज क्वेरी और न ही स्रोत डेटा बदला है।
const ContactList = ({ contacts, searchQuery }) => {
const filteredContacts = useMemo(() => {
if (!searchQuery.trim()) return contacts;
const query = searchQuery.toLowerCase();
return contacts.filter((c) =>
c.name.toLowerCase().includes(query) ||
c.phone.includes(query)
);
}, [contacts, searchQuery]);
return (
<FlatList
data={filteredContacts}
renderItem={renderContact}
keyExtractor={(item) => item.id}
/>
);
};
useMemo के बिना, फ़िल्टरिंग प्रत्येक रेंडर पर निष्पादित होगी, जिसमें एनिमेशन या कंपोनेंट के अन्य भागों में स्थिति परिवर्तनों के कारण होने वाले रेंडर भी शामिल हैं। useMemo के साथ, फ़िल्टरिंग केवल तब चलती है जब contacts या searchQuery बदलता है।
React Native में, स्टाइल अक्सर स्क्रीन आयामों या कंपोनेंट props पर निर्भर करते हैं। useMemo ऐसे स्टाइल ऑब्जेक्ट की एक बार गणना करने और निर्भरताएँ बदलने तक उसका पुन: उपयोग करने की अनुमति देता है।
const Card = ({ title, isSelected }) => {
const cardStyle = useMemo(() => ({
backgroundColor: isSelected ? '#e3f2fd' : '#ffffff',
borderWidth: isSelected ? 2 : 1,
padding: 16,
}), [isSelected]);
return (
<View style={cardStyle}>
<Text>{title}</Text>
</View>
);
};
यह दृष्टिकोण सुनिश्चित करता है कि cardStyle ऑब्जेक्ट तब तक स्थिर (समान रेफ़रेंस) रहे जब तक isSelected नहीं बदलता। यदि Card React.memo में लिपटा है, तो यह पैटर्न चाइल्ड एलिमेंट्स के अनावश्यक री-रेंडर को रोकता है।
अक्सर पूछे जाने वाले प्रश्न
useMemo एक मेमोइज़्ड मान लौटाता है — पहले आर्गुमेंट के रूप में पास किए गए फ़ंक्शन के निष्पादन का परिणाम। बाद के री-रेंडर पर, React कैश किया गया मान लौटाता है यदि निर्भरताएँ नहीं बदली हैं।
useMemo फ़ंक्शन निष्पादन का परिणाम लौटाता है (कोई भी मान: संख्या, ऑब्जेक्ट, JSX), जबकि useCallback स्वयं फ़ंक्शन लौटाता है। ध्यान दें कि useCallback(fn, deps), useMemo(() => fn, deps) के समतुल्य है।
useMemo तुच्छ गणनाओं (जोड़, संयोजन), दुर्लभ री-रेंडर, हर रेंडर पर बदलने वाली निर्भरताओं और प्रिमिटिव प्रकारों के लिए बेकार है। useMemo जोड़ने से पहले हमेशा प्रदर्शन मापें।
हाँ, यदि अनावश्यक रूप से उपयोग किया जाए। React पिछले मानों को मेमोरी में संग्रहीत करता है और प्रत्येक रेंडर पर निर्भरताओं की तुलना करता है। सरल गणनाओं के लिए, इन संक्रियाओं का ओवरहेड मेमोइज़ेशन के लाभ से अधिक होता है।
कंपोनेंट रेंडर समय मापने के लिए React DevTools Profiler का उपयोग करें। React Native में, डेवलपर मेनू के माध्यम से Performance Monitor भी उपलब्ध है। यदि री-रेंडर 1 ms से कम समय लेता है — useMemo आवश्यक नहीं है।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें