Join the discussion
Comments
Loading comments...
Cookie preferences
We use essential cookies for sign-in and preferences. With your permission, we also use basic analytics to improve lessons.
Join the discussion
Loading comments...
We use essential cookies for sign-in and preferences. With your permission, we also use basic analytics to improve lessons.
React.memo कैसे shallow comparison से अनावश्यक री-रेंडर रोकता है।
Default में, React एक component को तब भी re-render करता है जब उसका parent re-render होता है — भले ही component के अपने props बदले न हों। React.memo एक higher-order component है जो एक functional component को wrap करता है और उसके render output को memoize करता है। यह previous और new props का shallow comparison करता है, और यदि वे equal हैं तो re-rendering skip करता है।
जब parent component की state बदलती है, React parent का function call करता है। फिर यह return किए गए सभी JSX children process करता है — उनके functions भी call करता है, भले ही उनके props identical हों। यह tree में cascade होता है।
React.memo(Component) एक नया component return करता है। Component का function call करने से पहले, React check करता है कि नए props पिछले props के shallowly equal हैं या नहीं। यदि हाँ, React previous render output reuse करता है — function call पूरी तरह skip करते हुए।
प्रत्येक prop key के लिए, React oldProp === newProp compare करता है। Primitives (string, number, boolean) value से compare होते हैं। Objects और functions reference से compare होते हैं — props में एक नया object literal '{''}' हमेशा equality check fail करता है।
React.memo(Component, arePropsEqual) एक दूसरा argument accept करता है — एक custom comparison function। Re-render skip करने के लिए true return करें (props equal हैं), allow करने के लिए false। Deep equality checks या specific props ignore करने के लिए useful।
React.memo केवल prop changes से caused re-renders skip करता है। यदि component useContext() call करता है, तो यह still re-render होगा जब context value बदलती है — React.memo के बावजूद।
HOC जो component का render output memoize करता है। Props पिछले render के shallowly equal होने पर re-render skip करता है।
Object.is() से प्रत्येक prop compare करता है। Primitives के लिए effective। Objects और functions को renders के पार same reference maintain करनी होगी।
जब React.memo determine करता है कि props equal हैं, यह previous render output return करता है और component function call skip करता है।
Renders के पार same object/function reference रखना। Non-primitive props के साथ React.memo को correctly काम करने के लिए required।
एक re-render जहाँ output पिछले render के identical है। React.memo इन्हें prevent करता है जब props logically नहीं बदले।
1// Without memo — re-renders every time parent renders2function ExpensiveList({ items }) {3 return items.map(item => <Item key={item.id} {...item} />);4}56// With memo — skips re-render if items reference is stable7const ExpensiveList = React.memo(function ExpensiveList({ items }) {8 return items.map(item => <Item key={item.id} {...item} />);9});1011function Parent() {12 const [count, setCount] = useState(0);1314 // ❌ New array every render — memo never helps15 const items = [{ id: 1, name: 'Apple' }];1617 // ✅ Stable reference — memo works as expected18 const items = useMemo(() => [{ id: 1, name: 'Apple' }], []);1920 return (21 <>22 <button onClick={() => setCount(c => c + 1)}>Count: {count}</button>23 <ExpensiveList items={items} /> {/* skips re-render when only count changes */}24 </>25 );26}
Complex components वाले large React trees में, unnecessary re-renders real performance problems में accumulate हो जाते हैं — slow interactions, dropped frames, laggy animations। React.memo आपको specific components को re-render होने से surgically prevent करने देता है, expensive subtrees को stable रखते हुए बाकी app freely update होती है।
A Slack-like app renders a message list. When a user types in the input box, the entire list of 1000+ message components re-renders because the parent (ChatRoom) updates on every keystroke.
Each keystroke updates the parent's `inputValue` state, triggering a re-render. Without React.memo, all 1000 Message components re-render even though none of their props changed. Each Message component does string formatting and date calculations — the combined cost creates visible lag.
Wrap Message in React.memo: `const Message = React.memo(({ text, author, timestamp }) => { ... })`. Since the message props are primitive values (strings, numbers), React.memo's shallow comparison correctly identifies that nothing changed. The 1000 messages are skipped entirely — only the input re-renders.
Takeaway: React.memo shines when a parent re-renders frequently but a child's props rarely change. The ideal candidates are list items, complex charts, and any component with expensive rendering where the parent updates for unrelated reasons.
A MapWidget receives a `coordinates` object `{ lat: 40.7, lng: -74.0 }`. Despite wrapping in React.memo, it still re-renders because the parent creates a new coordinates object each render.
React.memo uses shallow comparison by default: `oldCoords !== newCoords` is always true because each render creates a new object, even if lat/lng values are identical. Shallow comparison checks reference equality, not value equality.
Provide a custom comparison: `React.memo(MapWidget, (prev, next) => prev.coordinates.lat === next.coordinates.lat && prev.coordinates.lng === next.coordinates.lng)`. Now React.memo compares the actual values instead of the object reference. Alternatively, flatten the props: `<MapWidget lat={40.7} lng={-74.0} />` — primitives compare by value automatically.
Takeaway: Use custom areEqual functions for components that receive objects or arrays as props and can't be easily memoized upstream. But first, consider if you can flatten the props to primitives or memoize the object with useMemo in the parent — these are simpler and more maintainable.