set-state-in-render
Render நடக்கும் போது state-ஐ unconditionally அமைப்பதை எதிர்த்து validate செய்கிறது; இது கூடுதல் renders மற்றும் infinite render loops ஏற்படுத்தக்கூடும்.
விதி விவரங்கள்
Render நடக்கும் போது setState-ஐ unconditionally அழைப்பது, தற்போதைய render முடிவதற்கு முன் மற்றொரு render-ஐ trigger செய்கிறது. இது உங்கள் app crash ஆகும் infinite loop ஒன்றை உருவாக்கும்.
பொதுவான மீறல்கள்
செல்லாதது
// ❌ Unconditional setState directly in render
function Component({value}) {
const [count, setCount] = useState(0);
setCount(value); // Infinite loop!
return <div>{count}</div>;
}செல்லுபடியாகும்
// ✅ Derive during render
function Component({items}) {
const sorted = [...items].sort(); // Just calculate it in render
return <ul>{sorted.map(/*...*/)}</ul>;
}
// ✅ Set state in event handler
function Component() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(count + 1)}>
{count}
</button>
);
}
// ✅ Derive from props instead of setting state
function Component({user}) {
const name = user?.name || '';
const email = user?.email || '';
return <div>{name}</div>;
}
// ✅ Conditionally derive state from props and state from previous renders
function Component({ items }) {
const [isReverse, setIsReverse] = useState(false);
const [selection, setSelection] = useState(null);
const [prevItems, setPrevItems] = useState(items);
if (items !== prevItems) { // This condition makes it valid
setPrevItems(items);
setSelection(null);
}
// ...
}Troubleshooting
State-ஐ prop ஒன்றுடன் sync செய்ய வேண்டும்
Render ஆன பிறகு state-ஐ “fix” செய்ய முயல்வது ஒரு பொதுவான பிரச்சினை. Counter ஒன்று max prop-ஐ விட அதிகமாகாமல் இருக்க வேண்டும் என்று வைத்துக்கொள்ளுங்கள்:
// ❌ Wrong: clamps during render
function Counter({max}) {
const [count, setCount] = useState(0);
if (count > max) {
setCount(max);
}
return (
<button onClick={() => setCount(count + 1)}>
{count}
</button>
);
}count max-ஐ கடந்தவுடன் infinite loop trigger ஆகும்.
அதற்கு பதிலாக, இந்த logic-ஐ event-க்கு (state முதலில் அமைக்கப்படும் இடம்) நகர்த்துவது பெரும்பாலும் சிறந்தது. உதாரணமாக, state update செய்யும் தருணத்திலேயே maximum-ஐ enforce செய்யலாம்:
// ✅ Clamp when updating
function Counter({max}) {
const [count, setCount] = useState(0);
const increment = () => {
setCount(current => Math.min(current + 1, max));
};
return <button onClick={increment}>{count}</button>;
}இப்போது setter click-க்கு பதிலாக மட்டுமே இயங்கும்; React render-ஐ வழக்கம்போல் முடிக்கும்; count ஒருபோதும் max-ஐ கடக்காது.
அரிதான சில நிலைகளில், முந்தைய renders-இலிருந்து கிடைக்கும் தகவலின் அடிப்படையில் state-ஐ adjust செய்ய வேண்டியிருக்கலாம். அத்தகைய நிலைகளில், state-ஐ conditionally அமைக்கும் இந்த pattern-ஐப் பின்பற்றுங்கள்.