React 18, useSyncExternalStore என்ற புதிய hook-ஐ அறிமுகப்படுத்தியுள்ளது. இது React tree-க்கு வெளியே இருக்கும் எந்தவொரு மூலையிலிருந்தும் (browser APIs, WebSockets, அல்லது third-party stores) தரவுகளைப் படிப்பதற்கு components-களை அனுமதிக்கிறது. useState மற்றும் useEffect மூலம் தரவுகளைப் பிரதிபலிக்கும் பழைய முறையில் ஏற்பட்ட காட்சித் தடங்கல்களை (visual glitches) இது தவிர்க்கிறது. ஒரு திரையின் ஒரு பகுதி பழைய window அளவையும், மற்றொரு பகுதி புதிய அளவையும் காட்டி UI மின்னும் (flicker) நிலையை நீங்கள் பார்த்திருந்தால், இந்த hook அதற்கான தீர்வாகும்.
ஏன் வெளிப்புறத் தரவிற்கு (external state) ஒரு புதிய hook தேவை?
React components எப்போதும் அவற்றின் எல்லைக்கு அப்பாற்பட்ட விஷயங்களை (window object, Redux store, அல்லது WebSocket connection போன்றவை) subscribe செய்ய முடிந்தது. வழக்கமான அணுகுமுறை என்பது useEffect-க்குள் ஒரு subscription-ஐ அமைத்து, வரும் மதிப்புகளை setState மூலம் local state-க்குள் செலுத்தி, React-ஐ re-render செய்ய வைப்பதாகும். React ஒத்திசைவாக (synchronously) render செய்யும்போது இது நன்றாகச் செயல்படும். ஆனால் React 18, concurrent rendering-ஐ அறிமுகப்படுத்தியது; இதில் browser திரையில் தோன்றுவதற்கு முன்பே ஒரு component பலமுறை render செய்யப்படலாம். இந்த முறையில், “mirror-into-local-state” என்ற அணுகுமுறை tearing என்ற சிக்கலை உருவாக்கலாம்—அதாவது ஒரே render cycle-ன் போது UI-ன் வெவ்வேறு பகுதிகள் ஒரே வெளிப்புற மதிப்பின் வெவ்வேறு snapshots-களைப் படிக்கும் நிலை ஏற்படும்.
useSyncExternalStore, tearing சிக்கலைத் தடுக்கவே உருவாக்கப்பட்டது. இது வெளிப்புற மூலத்திடம் இருந்து ஒரு snapshot (தற்போதைய மதிப்பு) மற்றும் ஒரு subscribe function (மாற்றங்கள் குறித்து எவ்வாறு அறிவிக்கப்பட வேண்டும் என்பது) ஆகியவற்றைத் கோருகிறது. Component mount ஆகும்போது React subscribe-ஐ அழைக்கும், மேலும் unmount ஆகும்போது தானாகவே unsubscribe செய்துவிடும். getSnapshot-ஆல் பெறப்படும் snapshot எப்போது மாறினாலும், React முழு component tree-க்கும் ஒரே snapshot-ஐப் படிக்கும் வகையில் ஒரு render-ஐத் திட்டமிடுகிறது, இது தரவுத் தொடர்ச்சியினை (consistency) உறுதி செய்கிறது.
தேவைப்படும் இரண்டு முக்கியமான functions
| Function | செயல்பாடு |
|---|---|
| subscribe | வெளிப்புற மதிப்பு மாறும்போது அழைக்கப்பட வேண்டிய ஒரு callback-ஐப் பெறுகிறது. இது ஒரு unsubscribe function-ஐத் திருப்பித் தரும், அதை React cleanup செய்யும் போது அழைக்கும். |
| getSnapshot | வெளிப்புற மூலத்திலிருந்து தற்போதைய மதிப்பைத் திருப்பித் தரும். இது referentially stable ஆக இருக்க வேண்டும்—அதாவது ஒவ்வொரு render செய்யும் போதும் ஒரே function object ஆக இருக்க வேண்டும்— அப்போதுதான் React snapshot-களைச் சரியாக ஒப்பிட முடியும். |
Browser-ன் online நிலையைச் சரிபார்க்க ஒரு எளிய implementation இதோ:
function useOnlineStatus() {
return useSyncExternalStore(
(onChange) => {
window.addEventListener('online', onChange);
window.addEventListener('offline', onChange);
return () => {
window.removeEventListener('online', onChange);
window.removeEventListener('offline', onChange);
};
},
() => navigator.onLine
);
}
எந்தவொரு component useOnlineStatus()-ஐ அழைக்கும் போதும், navigator.onLine உண்மையில் மாறும்போது மட்டுமே React அதை re-render செய்யும், மேலும் ஒவ்வொரு render-ன் போதும் ஒரே மதிப்பே கிடைக்கும்.
Hook சரியாகச் செயல்படப் பின்பற்ற வேண்டிய விதிகள்
ஒரு component-க்குத் தேவையான மிகச்சிறிய தரவை மட்டும் திருப்பித் தரவும்.
வெளிப்புற store ஒரு பெரிய object-ஐக் கொண்டிருந்தாலும், ஒரு component ஒரு குறிப்பிட்ட field-ஐ மட்டுமே கவனித்தால், அந்த field-ஐ மட்டும் திருப்பித் தரவும். பெரிய தரவுகளைத் திருப்பித் தருவது தேவையற்ற re-renders-களை உண்டாக்கும்.getSnapshot-ஐ memoise செய்யவும்.
ஒவ்வொரு render செய்யும் போதும் நீங்கள் அந்த function-ஐ மீண்டும் உருவாக்கினால், React அதை ஒரு புதிய மூலமாகக் கருதி முடிவில்லாமல் loop செய்யக்கூடும். அதைuseCallback-க்குள் வைத்துப் பயன்படுத்தவும் அல்லது component-க்கு வெளியே வரையறுக்கவும்.ஒவ்வொரு முறையும் புதிய objects-களைத் திருப்பித் தருவதைத் தவிர்க்கவும்.
ஒரு புதிய object-ஐத் திருப்பித் தருவது (உதாரணமாக,{ count: store.getCount() }), ஒவ்வொரு render செய்யும் போதும் ஒரு புதிய reference-ஐ உருவாக்கும். இது snapshot மாறியிருப்பதாக React-ஐ நினைக்கச் செய்து, ஒரு முடிவில்லாத render loop-ஐத் தூண்டும். எனவே primitives, strings, numbers அல்லது memoised objects-களைப் பயன்படுத்தவும்.உள்நிலை component state-க்கு இதைப் பயன்படுத்த வேண்டாம்.
ஒரு component-க்குள் மட்டும் இருக்கும் தரவுகளுக்குuseStateதான் சரியான கருவி.useSyncExternalStoreபயன்படுத்துவது local state-க்குத் தேவையில்லாத கூடுதல் சுமையை (overhead) ஏற்படுத்தும்.
இதை எப்போது பயன்படுத்த வேண்டும்
- Browser APIs – window size, media queries,
navigator.onLine, battery status. - Framework-agnostic stores – Zustand, Redux, MobX, அல்லது subscription API-ஐக் கொண்ட எந்தவொரு custom store.
- React-க்கு வெளியே மாறும் Mutable sources – WebSocket messages, IndexedDB change events, Service Worker notifications.
உங்கள் தரவு மூலம் ஏற்கனவே React-க்குள் இருந்தால் (உதாரணமாக, ஒரு parent component-ன் state), useState அல்லது context-ஐயே பயன்படுத்தவும்.
சமூகம் (Community) கூறுவது என்ன
இதைத் தொடக்கத்திலேயே பயன்படுத்தத் தொடங்கியவர்கள், concurrent-rendering அமைப்பில் window-வை மாற்றும்போது ஏற்படும் flicker சிக்கலை useSyncExternalStore நீக்குவதாகக் கூறுகின்றனர். சில libraries ஏற்கனவே தங்கள் internal hooks-களை இந்த API-க்கு மாற்றியுள்ளன, இது React பதிப்புகளுக்கு இடையே மிகவும் நிலையான செயல்பாட்டை (predictable behavior) வழங்கும் என்று உறுதியளிக்கின்றன. ஆனால் இதில் ஒரு சிறிய சவால் உள்ளது: developers அந்த இரண்டு functions-களின் நிலைத்தன்மையைப் (stability) பற்றியும், ஒவ்வொரு முறையும் புதிய objects-களைத் திருப்பித் தராமல் இருப்பதைப் பற்றியும் கவனமாக இருக்க வேண்டும்.
அடுத்து கவனிக்க வேண்டியவை
React-ன் வரவிருக்கும் வெளியீடுகள் useSyncExternalStore-ஐச் சுற்றியுள்ள ஒப்பந்தத்தை (contract) இறுக்கப்படுத்தலாம், மேலும் பொதுவான browser APIs-களுக்கான உள்ளமைக்கப்பட்ட (built-in) உதவியாளர்களைச் சேர்க்கலாம். பழைய useEffect-ஐப் பிரதிபலிக்கும் முறைகள் (mirroring pattern) நீக்கப்படுவதைப் (deprecations) பற்றி அறிய அதிகாரப்பூர்வ React வலைப்பதிவைக் கவனியுங்கள். இதற்கிடையில், இந்த hook நிலையானது மற்றும் பொது API-ன் ஒரு பகுதியாகும், எனவே நீங்கள் ஏற்கனவே உள்ள external-state குறியீட்டைப் பாதுகாப்பாக மாற்றியமைக்கலாம் (refactor).
விரைவான சோதனை
window-size syncing, online/offline detection மற்றும் ஒரு எளிய Zustand store ஆகியவற்றை விளக்கும் நேரடி டெமோ (live demo) https://usesyncexternalstore.vercel.app/ இல் உள்ளது. விளக்கங்களுடன் கூடிய மூலக் குறியீடு (source code), https://github.com/dev48v/usesyncexternalstore இல் கிடைக்கிறது.
முக்கியக் குறிப்பு: useSyncExternalStore, React-ன் render cycle-க்கு வெளியே இருக்கும் எந்தவொரு மாற்றக்கூடிய தரவுக்கும் (mutable data) ஒரு நம்பகமான பாலத்தை வழங்குகிறது, இது tearing மற்றும் தேவையற்ற renders ஆகியவற்றைத் தடுக்கிறது. இதை வெளிப்புறத் தரவு ஆதாரங்களுக்கு (external sources) பயன்படுத்துங்கள், snapshot-ஐக் குறைவாகவும் நிலையானதாகவும் வைத்திருங்கள், மேலும் நிலைத்தன்மையை (consistency) உறுதி செய்யும் கடினமான பணிகளை React-விடமே விட்டுவிடுங்கள்.
