State Updates தொடர் ஒன்றை Queue செய்தல்
State variable set செய்வது மற்றொரு render-ஐ queue செய்யும். ஆனால் சில நேரங்களில், அடுத்த render-ஐ queue செய்வதற்கு முன் value மீது பல operations செய்ய விரும்பலாம். இதைச் செய்ய, React state updates-ஐ எப்படி batch செய்கிறது என்பதைப் புரிந்துகொள்வது உதவும்.
நீங்கள் கற்றுக்கொள்ள போவது
- ”Batching” என்றால் என்ன, பல state updates process செய்ய React அதை எப்படி பயன்படுத்துகிறது
- ஒரே state variable-க்கு பல updates-ஐ தொடர்ச்சியாக apply செய்வது எப்படி
React state updates-ஐ batch செய்கிறது
setNumber(number + 1)-ஐ மூன்று முறை call செய்வதால், “+3” button click செய்தால் counter மூன்று முறை increment ஆகும் என்று நீங்கள் எதிர்பார்க்கலாம்:
import { useState } from 'react'; export default function Counter() { const [number, setNumber] = useState(0); return ( <> <h1>{number}</h1> <button onClick={() => { setNumber(number + 1); setNumber(number + 1); setNumber(number + 1); }}>+3</button> </> ) }
ஆனால் முந்தைய section-இல் பார்த்தபடி, ஒவ்வொரு render-ன் state values fixed ஆக இருக்கும். ஆகவே முதல் render-ன் event handler-க்குள் number value எத்தனை முறை setNumber(1) call செய்தாலும் எப்போதும் 0 தான்:
setNumber(0 + 1);
setNumber(0 + 1);
setNumber(0 + 1);ஆனால் இங்கே இன்னொரு factor செயல்படுகிறது. உங்கள் state updates process செய்வதற்கு முன் event handlers-இல் உள்ள அனைத்து code-மும் run ஆகும் வரை React காத்திருக்கும். அதனால் தான் இந்த setNumber() calls அனைத்திற்குப் பிறகே re-render நடக்கிறது.
இது restaurant-இல் order எடுக்கும் waiter-ஐ நினைவூட்டலாம். உங்கள் முதல் dish சொன்னவுடனே waiter kitchen-க்கு ஓடமாட்டார்! அதற்கு பதிலாக, நீங்கள் order முடிக்க, அதை மாற்ற, அதே table-இல் உள்ள மற்றவர்களிடமிருந்தும் orders எடுக்க காத்திருப்பார்.

Illustrated by Rachel Lee Nabors
இதனால் பல state variables-ஐ, பல components-இலிருந்தும் கூட, அதிகமான re-renders trigger செய்யாமல் update செய்யலாம். ஆனால் இதன் அர்த்தம், உங்கள் event handler மற்றும் அதில் உள்ள code அனைத்தும் முடியும் வரை UI update ஆகாது என்பதும். Batching என்று அழைக்கப்படும் இந்த behavior, உங்கள் React app-ஐ மிகவும் வேகமாக run செய்யும். சில variables மட்டும் update ஆன “half-finished” renders போன்ற confusing நிலைகளை கையாள வேண்டியதையும் இது தவிர்க்கிறது.
Clicks போன்ற பல intentional events முழுவதும் React batch செய்யாது; ஒவ்வொரு click தனியாக handle செய்யப்படும். பொதுவாக safe ஆனபோது மட்டுமே React batching செய்கிறது என்று நம்பலாம். உதாரணமாக, முதல் button click form-ஐ disable செய்தால், இரண்டாவது click அதை மீண்டும் submit செய்யாது என்பதை இது உறுதிசெய்கிறது.
அடுத்த render-க்கு முன் அதே state-ஐ பல முறை update செய்தல்
இது uncommon use case; ஆனால் அடுத்த render-க்கு முன் அதே state variable-ஐ பல முறை update செய்ய விரும்பினால், setNumber(number + 1) போன்ற next state value pass செய்வதற்கு பதிலாக, queue-இல் முந்தைய value அடிப்படையில் next state-ஐ கணக்கிடும் function pass செய்யலாம், உதாரணமாக setNumber(n => n + 1). இது state value-ஐ replace செய்வதற்கு பதிலாக “state value மீது ஏதாவது செய்” என்று React-க்கு சொல்லும் வழி.
இப்போது counter-ஐ increment செய்து பாருங்கள்:
import { useState } from 'react'; export default function Counter() { const [number, setNumber] = useState(0); return ( <> <h1>{number}</h1> <button onClick={() => { setNumber(n => n + 1); setNumber(n => n + 1); setNumber(n => n + 1); }}>+3</button> </> ) }
இங்கே, n => n + 1 ஒரு updater function என்று அழைக்கப்படுகிறது. அதை state setter-க்கு pass செய்தால்:
- Event handler-இல் உள்ள மற்ற code அனைத்தும் run ஆன பிறகு process செய்ய React இந்த function-ஐ queue செய்கிறது.
- அடுத்த render போது, React queue-ஐ கடந்து சென்று final updated state-ஐ உங்களுக்கு தருகிறது.
setNumber(n => n + 1);
setNumber(n => n + 1);
setNumber(n => n + 1);Event handler execute செய்யும் போது React இந்த lines of code-ஐ எப்படி process செய்கிறது:
setNumber(n => n + 1):n => n + 1ஒரு function. React அதை queue-க்கு add செய்கிறது.setNumber(n => n + 1):n => n + 1ஒரு function. React அதை queue-க்கு add செய்கிறது.setNumber(n => n + 1):n => n + 1ஒரு function. React அதை queue-க்கு add செய்கிறது.
அடுத்த render போது useState call செய்யும்போது, React queue-ஐ process செய்கிறது. முந்தைய number state 0; ஆகவே முதல் updater function-க்கு n argument ஆக React அதையே pass செய்கிறது. பின்னர் உங்கள் முந்தைய updater function-ன் return value-ஐ அடுத்த updater-க்கு n ஆக pass செய்கிறது; இவ்வாறு தொடர்கிறது:
| queued update | n | returns |
|---|---|---|
n => n + 1 | 0 | 0 + 1 = 1 |
n => n + 1 | 1 | 1 + 1 = 2 |
n => n + 1 | 2 | 2 + 1 = 3 |
React 3-ஐ final result ஆக store செய்து, அதை useState-இலிருந்து return செய்கிறது.
அதனால் தான் மேலுள்ள example-இல் “+3” click செய்தால் value சரியாக 3 அளவுக்கு increment ஆகிறது.
State replace செய்த பிறகு update செய்தால் என்ன நடக்கும்
இந்த event handler பற்றி என்ன? அடுத்த render-இல் number என்னாக இருக்கும் என்று நினைக்கிறீர்கள்?
<button onClick={() => {
setNumber(number + 5);
setNumber(n => n + 1);
}}>import { useState } from 'react'; export default function Counter() { const [number, setNumber] = useState(0); return ( <> <h1>{number}</h1> <button onClick={() => { setNumber(number + 5); setNumber(n => n + 1); }}>Number-ஐ அதிகரிக்கவும்</button> </> ) }
இந்த event handler React-க்கு செய்யச் சொல்வது:
setNumber(number + 5):number0, ஆகவேsetNumber(0 + 5). React அதன் queue-க்கு “5ஆக replace செய்” என்பதைக் add செய்கிறது.setNumber(n => n + 1):n => n + 1ஒரு updater function. React அந்த function-ஐ அதன் queue-க்கு add செய்கிறது.
அடுத்த render போது, React state queue-ஐ process செய்கிறது:
| queued update | n | returns |
|---|---|---|
”5 ஆக replace செய்” | 0 (பயன்படுத்தப்படாது) | 5 |
n => n + 1 | 5 | 5 + 1 = 6 |
React 6-ஐ final result ஆக store செய்து, அதை useState-இலிருந்து return செய்கிறது.
State update செய்த பிறகு replace செய்தால் என்ன நடக்கும்
இன்னொரு example முயற்சிப்போம். அடுத்த render-இல் number என்னாக இருக்கும் என்று நினைக்கிறீர்கள்?
<button onClick={() => {
setNumber(number + 5);
setNumber(n => n + 1);
setNumber(42);
}}>import { useState } from 'react'; export default function Counter() { const [number, setNumber] = useState(0); return ( <> <h1>{number}</h1> <button onClick={() => { setNumber(number + 5); setNumber(n => n + 1); setNumber(42); }}>Number-ஐ அதிகரிக்கவும்</button> </> ) }
இந்த event handler execute செய்யும் போது React இந்த lines of code-ஐ process செய்வது:
setNumber(number + 5):number0, ஆகவேsetNumber(0 + 5). React அதன் queue-க்கு “5ஆக replace செய்” என்பதைக் add செய்கிறது.setNumber(n => n + 1):n => n + 1ஒரு updater function. React அந்த function-ஐ அதன் queue-க்கு add செய்கிறது.setNumber(42): React அதன் queue-க்கு “42ஆக replace செய்” என்பதைக் add செய்கிறது.
அடுத்த render போது, React state queue-ஐ process செய்கிறது:
| queued update | n | returns |
|---|---|---|
”5 ஆக replace செய்” | 0 (பயன்படுத்தப்படாது) | 5 |
n => n + 1 | 5 | 5 + 1 = 6 |
”42 ஆக replace செய்” | 6 (பயன்படுத்தப்படாது) | 42 |
பின்னர் React 42-ஐ final result ஆக store செய்து, அதை useState-இலிருந்து return செய்கிறது.
சுருக்கமாக, setNumber state setter-க்கு நீங்கள் pass செய்வதை இவ்வாறு சிந்திக்கலாம்:
- Updater function (எ.கா.
n => n + 1) queue-க்கு add செய்யப்படும். - வேறு எந்த value-யும் (எ.கா. number
5) ஏற்கனவே queued ஆனதை ignore செய்து “5ஆக replace செய்” என்பதைக் queue-க்கு add செய்கிறது.
Event handler முடிந்த பிறகு, React re-render trigger செய்யும். Re-render போது, React queue-ஐ process செய்யும். Updater functions rendering போது run ஆகின்றன; ஆகவே updater functions pure ஆக இருக்க வேண்டும் மற்றும் result-ஐ மட்டும் return செய்ய வேண்டும். அவற்றுக்குள் state set செய்யவோ மற்ற side effects run செய்யவோ முயற்சிக்க வேண்டாம். Strict Mode-இல், பிழைகளை கண்டுபிடிக்க உதவ React ஒவ்வொரு updater function-ஐயும் இரண்டு முறை run செய்யும் (ஆனால் இரண்டாவது result-ஐ discard செய்யும்).
Naming conventions
Updater function argument-ஐ தொடர்புடைய state variable-ன் முதல் எழுத்துகளால் name செய்வது பொதுவானது:
setEnabled(e => !e);
setLastName(ln => ln.reverse());
setFriendCount(fc => fc * 2);மேலும் verbose code விரும்பினால், setEnabled(enabled => !enabled) போல முழு state variable name-ஐ repeat செய்வது அல்லது setEnabled(prevEnabled => !prevEnabled) போல prefix பயன்படுத்துவது மற்றொரு common convention.
Recap
- State set செய்வது existing render-இல் variable-ஐ மாற்றாது; அது புதிய render ஒன்றை request செய்கிறது.
- Event handlers run ஆகி முடிந்த பிறகு React state updates-ஐ process செய்கிறது. இதுவே batching என்று அழைக்கப்படுகிறது.
- ஒரே event-இல் ஒரு state-ஐ பல முறை update செய்ய,
setNumber(n => n + 1)updater function பயன்படுத்தலாம்.
Challenge 1 of 2: Request counter-ஐ சரிசெய்யுங்கள்
User ஒரே நேரத்தில் art item-க்கு பல orders submit செய்ய உதவும் art marketplace app-இல் நீங்கள் வேலை செய்கிறீர்கள். User “Buy” button அழுத்தும் ஒவ்வொரு முறையும், “Pending” counter ஒன்று அதிகரிக்க வேண்டும். மூன்று seconds பிறகு, “Pending” counter குறைய வேண்டும்; “Completed” counter அதிகரிக்க வேண்டும்.
ஆனால் “Pending” counter intended போல நடக்கவில்லை. “Buy” அழுத்தும்போது, அது -1 ஆக குறைகிறது (இது சாத்தியமாக இருக்கக்கூடாது!). நீங்கள் வேகமாக இரண்டு முறை click செய்தால், இரண்டு counters-உம் unpredictable ஆக நடக்கிறது போல தெரிகிறது.
இது ஏன் நடக்கிறது? இரண்டு counters-யையும் சரிசெய்யுங்கள்.
import { useState } from 'react'; export default function RequestTracker() { const [pending, setPending] = useState(0); const [completed, setCompleted] = useState(0); async function handleClick() { setPending(pending + 1); await delay(3000); setPending(pending - 1); setCompleted(completed + 1); } return ( <> <h3> Pending: {pending} </h3> <h3> Completed: {completed} </h3> <button onClick={handleClick}> வாங்கு </button> </> ); } function delay(ms) { return new Promise(resolve => { setTimeout(resolve, ms); }); }