കെണിയിൽ നിന്ന് രക്ഷപ്പെടാം: React Hooks-ലെ Stale Closures പരിഹരിക്കാം
React-ൽ സ്റ്റേൽ ക്ലോഷറുകൾ (Stale closures) നിശബ്ദമായ ഡാറ്റാ നഷ്ടത്തിന് കാരണമാകുന്നു.
ഒരു ബാക്ക്ഗ്രൗണ്ട് ടൈമർ ഉള്ള ഒരു ഡാഷ്ബോർഡ് നിങ്ങൾ നിർമ്മിക്കുന്നു എന്ന് കരുതുക. ഓരോ 5 സെക്കൻഡിലും ഡാറ്റ ഓട്ടോമാറ്റിക്കായി സേവ് ചെയ്യാൻ നിങ്ങൾ ഒരു useEffect ഹുക്കിനുള്ളിൽ setInterval ഉപയോഗിക്കുന്നു.
ഇൻ്റർവൽ പ്രവർത്തിക്കുമ്പോൾ ഒരു ബഗ് സംഭവിക്കുന്നു. ഉപയോക്താവ് ഒരു മുഴുവൻ പേജ് ടൈപ്പ് ചെയ്തിട്ടുണ്ടെങ്കിൽ പോലും, അത് ഒരു ശൂന്യമായ ഡോക്യുമെന്റ് ആണ് സേവ് ചെയ്യുന്നത്. ഇൻ്റർവൽ പഴയ അവസ്ഥയിൽ തന്നെ തങ്ങിനിൽക്കുന്നു. ഇത് നിങ്ങളുടെ സ്റ്റേറ്റിന്റെ (state) പഴയ പതിപ്പാണ് ഉപയോഗിക്കുന്നത്.
പ്രശ്നം
useEffect പ്രവർത്തിക്കുമ്പോൾ, അത് അതിന്റെ സ്കോപ്പിലുള്ള (scope) വേരിയബിളുകളെ ക്യാപ്ചർ ചെയ്യുന്നു.
- നിങ്ങൾ സ്റ്റേറ്റിനെ dependency array-യിൽ ഉൾപ്പെടുത്തിയില്ലെങ്കിൽ, ഇൻ്റർവൽ ആദ്യത്തെ റെൻഡറിലെ (render) സ്റ്റേറ്റ് ഉപയോഗിക്കും.
- നിങ്ങൾ സ്റ്റേറ്റിനെ dependency array-യിൽ ചേർത്താൽ, ഓരോ കീസ്ട്രോക്കിലും React ഇൻ്റർവൽ വീണ്ടും തുടങ്ങും. ഇത് പെർഫോമൻസിനെ ബാധിക്കുകയും നിങ്ങളുടെ ടൈമിംഗിനെ തകരാറിലാക്കുകയും ചെയ്യും.
പരിഹാരം: Mutable Ref Pattern
നിങ്ങൾ ടൈമറിനെ ഡാറ്റയിൽ നിന്ന് വേർതിരിക്കണം. നിങ്ങളുടെ ഏറ്റവും പുതിയ സ്റ്റേറ്റിന്റെ ഒരു കോൺസ്റ്റന്റ് റെഫറൻസ് (constant reference) സൂക്ഷിക്കാൻ useRef ഹുക്ക് ഉപയോഗിക്കുക. ഇത് റീ-റെൻഡറുകൾ (re-renders) ഒഴിവാക്കുകയും നിങ്ങളുടെ ഇൻ്റർവലിനെ സ്ഥിരതയുള്ളതാക്കുകയും ചെയ്യുന്നു.
ഇത് എങ്ങനെ നടപ്പിലാക്കാം:
- നിങ്ങളുടെ ഏറ്റവും പുതിയ സ്റ്റേറ്റ് സൂക്ഷിക്കാൻ ഒരു ref നിർമ്മിക്കുക.
- നിങ്ങളുടെ സ്റ്റേറ്റ് മാറുന്നതിനനുസരിച്ച് ആ ref അപ്ഡേറ്റ് ചെയ്യാൻ ഒരു
useEffectഉപയോഗിക്കുക. - ഇൻ്റർവൽ ഒരു തവണ മാത്രം പ്രവർത്തിക്കുന്നതിനായി ഒരു empty dependency array ഉപയോഗിച്ച് അത് ആരംഭിക്കുക.
- നിങ്ങളുടെ ഇൻ്റർവൽ callback-നുള്ളിൽ ref ആക്സസ് ചെയ്യുക.
ഈ രീതി നിങ്ങളുടെ ബാക്ക്ഗ്രൗണ്ട് ടാസ്ക്കുകൾ എപ്പോഴും പുതിയ ഡാറ്റ ഉപയോഗിക്കുന്നുവെന്ന് ഉറപ്പാക്കുന്നു. ഇത് നിങ്ങളുടെ UI വേഗതയുള്ളതാക്കുകയും ഡാറ്റ സുരക്ഷിതമായി സൂക്ഷിക്കുകയും ചെയ്യുന്നു.
ഉറവിടം: https://dev.to/iprajapatiparesh/escaping-the-trap-fixing-stale-closures-in-react-hooks-4gg7