अनावश्यक Re-renders से बचना
In this page:
// Keep state in the smallest component that needs it
function ChildWithState() {
const [value, setValue] = useState(initial);
return <input value={value} onChange={e => setValue(e.target.value)} />;
}
function Parent() {
return (
<div>
<ChildWithState />
<ExpensiveComponent />
</div>
);
}
Parent Re-renders Children तक क्यों Cascade होते हैं
Default रूप से, जब एक component re-render होता है, React इसके अंदर हर child को भी re-render करता है, इस बात के regardless कि उस child की अपनी props actually बदलीं या नहीं। यह usually fine है (React का diffing fast है), लेकिन expensive children के लिए, यह एक real bottleneck बन सकता है अगर parent बहुत frequently re-render हो।
उदाहरण: Why Parent Re-renders Cascade to Children
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
function Child() {
console.log("Child rendered");
return <p>I'm a child</p>;
}
function App() {
const [count, setCount] = React.useState(0);
return (
<div>
<button onClick={() => setCount(count + 1)}>Count: {count}</button>
<Child /> {/* re-renders every time App does, even with no props */}
</div>
);
}
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
</script>
</body>
</html>
State को Usage के पास रखना
State के एक piece को component tree में जितना possible हो नीचे रखना (जहां इसे actually पढ़ा/उपयोग किया जाता है उसके पास) यह limit करता है कि इसके बदलने पर app का कितना हिस्सा re-render होता है।
State को ज़रूरत से ज़्यादा ऊपर lift करने का मतलब है उस higher point और actual usage के बीच का हर component भी हर change पर re-render होता है।
उदाहरण: Keeping State Close to Where It's Used
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
// Better: input's state lives right where it's used, not lifted unnecessarily
function SearchBox() {
const [query, setQuery] = React.useState("");
return <input value={query} onChange={e => setQuery(e.target.value)} />;
}
function App() {
return <div><h1>App Title (never re-renders from typing)</h1><SearchBox /></div>;
}
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
</script>
</body>
</html>
Re-renders को Isolate करने के लिए Components Split करना
एक बड़े component को छोटे, focused pieces में तोड़ने का मतलब है एक state change सिर्फ उस specific piece को re-render करता है जो actually इस पर depend करता है, एक giant component के किसी छोटे internal change के लिए पूरी तरह re-render होने के बजाय।
उदाहरण: Splitting Components to Isolate Re-renders
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
function Counter() {
const [count, setCount] = React.useState(0);
return <button onClick={() => setCount(count + 1)}>Count: {count}</button>;
}
function StaticHeader() {
console.log("StaticHeader rendered"); // only logs once, isolated from Counter's re-renders
return <h1>My App</h1>;
}
function App() {
return <div><StaticHeader /><Counter /></div>;
}
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
</script>
</body>
</html>
- State को ज़रूरत से ज़्यादा ऊपर tree में store करना, बड़े sections को re-render करने का कारण बनते हुए उस change के लिए जिसकी सिर्फ एक छोटे हिस्से को ज़रूरत है।
- पूरी state object को एक prop के रूप में नीचे pass करना जब एक component सिर्फ एक field उपयोग करता है, unrelated field changes पर re-renders force करते हुए।
- Lists में key prop सही तरीके से उपयोग न करना, React को items unnecessarily re-create (update के बजाय) करने का कारण बनते हुए।
- एक component re-render होता है जब इसका अपना state बदलता है, इसका parent re-render होता है, या इसकी context value बदलती है।
- State को जितना possible हो इसके usage के पास रखना यह limit करता है कि किसी change पर tree का कितना हिस्सा re-render होता है।
- React.memo, useMemo, और useCallback specific unnecessary re-render chains तोड़ने के लिए targeted tools हैं।
- एक बड़े component को छोटों में split करना React.memo को उन parts को re-render करने से रोकने दे सकता है जो actually नहीं बदले।
कोई React-version restriction नहीं — ये general patterns हैं; React.memo को React 16.6+ चाहिए।
Chapter Quiz — Complete all 13 topics to unlock
0/13 topics done
Complete these topics first:
- Why Performance Matters
- Optimizing with React.memo
- Avoiding Unnecessary Re-renders
- Using the React Profiler
- Analyzing Bundle Size
- Image Optimization Techniques
- React as a PWA
- Creating a Production Build
- Environment Variables in React
- Deploying to Netlify
- Deploying to Vercel
- Basic CI/CD for React Apps
- SEO Basics for React SPAs