React உங்கள் components கணிக்கக்கூடியதாக (predictable) இருக்க வேண்டும் என்று விரும்புகிறது. அதற்கு ஒரே மாதிரியான state மற்றும் props-களைக் கொடுத்தால், அது ஒவ்வொரு முறையும் ஒரே மாதிரியான UI-ஐக் காட்ட வேண்டும். ஆனால் பெரும்பாலான நிஜ உலகப் பயன்பாடுகள் (real applications) அந்த எல்லைக்குள் மட்டும் இயங்க முடியாது. அவற்றுக்கு வெளி உலகத்தோடு தொடர்பு கொள்ள வேண்டியிருக்கும். ஒரு dashboard-க்குச் சர்வரிலிருந்து புதிய எண்கள் தேவைப்படலாம். ஒரு chat widget செய்திகளுக்காகக் காத்திருக்க வேண்டியிருக்கலாம். ஒரு timer ஓடிக்கொண்டிருக்க வேண்டும். இந்தச் செயல்பாடுகள் side effects ஆகும், மேலும் அவை React-ன் render cycle-க்கு வெளியே அமைகின்றன. உங்கள் component நேர்மையாக (honest) இருப்பதற்காக, அந்தச் சிக்கலான மற்றும் கணிக்க முடியாத வேலைகளை நீங்கள் useEffect hook-ல் வைக்க வேண்டும்.

Side Effects: useEffect-க்குள் எவை இடம்பெற வேண்டும்

JSX-ஐத் தாண்டி வெளி உலகத்தோடு தொடர்பு கொள்ளும் எதையும் ஒரு side effect எனலாம். React-ன் render phase தூய்மையாக (pure) இருக்க வேண்டும். நீங்கள் தரவை எடுக்கத் தொடங்கும்போது (fetching data), global variables-களில் எழுதும்போது அல்லது DOM-க்கு listeners-களை இணைக்கும்போது, நீங்கள் தூய்மையான எல்லையைத் தாண்டிச் செல்கிறீர்கள் என்று அர்த்தம்.

பொதுவான உதாரணங்கள்:

  • ஒரு API-லிருந்து தரவை எடுத்தல் (Fetching data)
  • Timers அல்லது intervals-களை அமைத்தல்
  • window அல்லது document-க்கு event listeners-களைச் சேர்த்தல்
  • Browser tab தலைப்பைத் திருத்துதல்
  • WebSockets-உடன் இணைத்தல்

இந்தத் பணிகள் அனைத்தும் ஒரு பொதுவான பண்பைப் பகிர்ந்து கொள்கின்றன: அவை உங்கள் component-ன் return statement-க்குள்ளோ அல்லது முக்கிய render logic-க்குள்ளோ இருக்கக்கூடாது. setInterval போன்ற ஒரு browser API-யை render body-க்குள் நேரடியாக அழைக்க முயற்சித்தால், அது ஒவ்வொரு render செய்யும் போதும் இயங்கும், இது நகல் (duplicate) timers-களை உருவாக்கி குழப்பமான நடத்தையை ஏற்படுத்தும். இந்த வேலையைத் தனிமைப்படுத்தவும், சரியான நேரத்தில் அதை இயக்கவும் useEffect உருவாக்கப்பட்டுள்ளது.

Dependency Array எவ்வாறு நேரத்தைக் கட்டுப்படுத்துகிறது

useEffect-ன் இரண்டாவது argument dependency array ஆகும், இது class components-லிருந்து மாறுபடும் டெவலப்பர்களுக்குப் பெரும் குழப்பத்தை ஏற்படுத்தும் விஷயமாகும். தற்போதைய render-க்குப் பிறகு உங்கள் effect-ஐத் தவிர்க்க வேண்டுமா அல்லது இயக்க வேண்டுமா என்பதைத் தீர்மானிக்க React கவனிக்கும் மாறிகளின் தொகுப்பாக இதை நினைத்துக் கொள்ளுங்கள்.

நீங்கள் மீண்டும் மீண்டும் பயன்படுத்தும் மூன்று முறைகள் உள்ளன:

Dependency array இல்லவே இல்லை. நீங்கள் array-ஐத் தவிர்த்தால், முதல் render உட்பட ஒவ்வொரு render-க்குப் பிறகும் effect இயங்க வேண்டும் என்று React கருதும். இது அரிதாகவே உங்களுக்குத் தேவைப்படும். உங்கள் effect ஒரு network request அல்லது ஒரு கனமான DOM operation-ஐச் செய்கிறது என்றால், ஒவ்வொரு keystroke அல்லது state மாற்றத்தின் போதும் அதை இயக்குவது செயல்திறனை (performance) வெகுவாகக் குறைக்கும். ஏதேனும் ஒரு prop அல்லது state மாறியிருக்கலாம், ஆனால் அவை எவை என்று உங்களால் குறிப்பிட முடியாது எனும் போது மட்டுமே இந்த முறையைப் பயன்படுத்தவும்.

ஒரு வெற்று array []. component mount ஆகி DOM தயாரானவுடன், effect ஒருமுறை மட்டுமே இயங்க வேண்டும் என்று இது React-க்குக் கூறுகிறது. ஆரம்பக்கட்ட தரவுத் தேவைகளுக்கு (initial data fetches) இதுவே சரியான இடம். உதாரணமாக, உங்கள் component ஒரு பயனர் சுயவிவரத் தரவை (user profile data) ஏற்றினால், அந்தப் பக்கம் தோன்றும் போது அந்தத் தேவை சரியாக ஒருமுறை மட்டுமே நடக்க வேண்டும் என்று நீங்கள் விரும்புவீர்கள்; பயனர் பக்கத்தின் கீழே உள்ள ஒரு form-உடன் தொடர்பு கொள்ளும் போதெல்லாம் அது நடக்கக்கூடாது.

குறிப்பிட்ட மாறிகளைக் கொண்ட array [count]. இது ஒரு துல்லியமான கருவி. இந்த dependencies-களின் தற்போதைய மதிப்புகளை அவற்றின் கடந்த render மதிப்புகளுடன் React ஒப்பிடுகிறது. அவற்றில் ஏதேனும் ஒன்று மாறினால், effect இயங்கும். பட்டியலில் உள்ள எதுவும் மாறவில்லை என்றால், React அந்த effect-ஐத் தவிர்த்துவிடும்.

நீங்கள் browser tab தலைப்பை ஒரு state variable-உடன் இணைக்கிறீர்கள் என்றால், அந்த variable-ஐ dependency array-ல் வைக்க வேண்டும். அப்போது அந்த மதிப்பு மாறும்போது மட்டுமே React தலைப்பைத் திருத்தும். அதைத் தவிர்த்தால், தலைப்பு பழையதாகவே (stale) இருக்கும். தொடர்பில்லாத state variables-களை இதில் சேர்த்தால், முக்கியமில்லாத மாற்றங்களுக்காகத் தலைப்பைத் திருத்தி உங்கள் கணினி வளங்களை (cycles) வீணாக்குவீர்கள்.

Cleanup என்பது கட்டாயமானது

சில effects தடம் பதித்துவிடும். ஒரு timer தொடர்ந்து எண்ணிக்கொண்டே இருக்கும். ஒரு event listener தொடர்ந்து இயங்கிக்கொண்டே இருக்கும். ஒரு WebSocket திறந்தே இருக்கும். உங்கள் component unmount ஆகும்போது, அல்லது ஒரு effect-ன் dependencies மாறியதால் அது மீண்டும் இயங்கும்போது கூட, முந்தைய effect-ன் எஞ்சிய பகுதிகளை React தானாகவே சுத்தம் செய்யாது. அது உங்கள் வேலை.

useEffect-க்குள் ஒரு function-ஐத் திருப்பி அனுப்புவதன் (return) மூலம் நீங்கள் ஒரு cleanup function-ஐ உருவாக்கலாம். அடுத்த effect-ஐப் பயன்படுத்துவதற்கு முன்பும், component திரையை விட்டு மறையும் போதும் React இந்த cleanup function-ஐ அழைக்கும்.

பின்வருவனவற்றிற்கு நீங்கள் cleanup-ஐப் பயன்படுத்த வேண்டும்:

  • clearInterval அல்லது clearTimeout மூலம் intervals அல்லது timeouts-களை நீக்குதல்
  • window, document, அல்லது வெளிப்புற nodes-களுக்குச் சேர்க்கப்பட்ட event listeners-களை அகற்றுதல்
  • Data streams அல்லது services-லிருந்து விலகுதல் (Unsubscribing)

இதைத் தவறவிட்டால், memory leaks ஏற்படும். ஒரு component mount ஆகி, ஒரு scroll listener-ஐ இணைக்கிறது, பின்னர் unmount ஆகிறது, ஆனால் அந்த listener அப்படியே இருக்கும். Browser அந்த callback மற்றும் அது குறிப்பிடும் DOM nodes-களைத் தன் நினைவகத்தில் வைத்திருக்கும். காலப்போக்கில், குறிப்பாக அதிகப்படியான navigation கொண்ட single-page applications-களில், இந்த நிழல்கள் (ghosts) குவிந்து tab-ஐ மெதுவாக்கும். இதற்குத் தீர்வு பொதுவாகச் சில வரிகள் மட்டுமே: நீங்கள் எதைச் சேர்த்தீர்களோ அதை நீக்கும் ஒரு function-ஐ return செய்யுங்கள்.

Production-க்குச் செல்லும் பொதுவான தவறுகள்

Even experienced developers reach for useEffect when a simpler option exists. Here are three patterns that should raise a red flag during code review.

Infinite loops. Never update a state variable inside useEffect if that same variable sits in your dependency array, unless you have a gate condition that breaks the cycle. If you read count, increment it, and list count as a dependency, React sees the change, re-renders, runs the effect again, increments again, and locks the browser.

Unnecessary effects. Do not use useEffect to calculate a value from existing props or state. If you can derive it directly during render, just do it. Derived values belong in the component body or in a memoized calculation with useMemo. Moving them into an effect splits your logic across render and effect phases for no benefit and makes the code harder to follow.

The wrong tool for user actions. `use