ரியாக்ட்டின் useCallback ஹூக்கின் பொதுவான சார்புப் பிழைகளைப் புரிந்துகொண்டு, உலகளாவிய பார்வையாளர்களுக்காக திறமையான மற்றும் விரிவாக்கக்கூடிய பயன்பாடுகளை உருவாக்குங்கள்.
ரியாக்ட் useCallback சார்புகள்: உலகளாவிய டெவலப்பர்களுக்கான செயல்திறன் மேம்படுத்தல் தவறுகளை வழிநடத்துதல்
தொடர்ந்து மாறிவரும் முன்-இறுதி மேம்பாட்டு உலகில், செயல்திறன் மிக முக்கியமானது. பயன்பாடுகள் சிக்கலானதாகவும், உலகளாவிய பார்வையாளர்களைச் சென்றடையும் போதும், பயனர் அனுபவத்தின் ஒவ்வொரு அம்சத்தையும் மேம்படுத்துவது அவசியமாகிறது. பயனர் இடைமுகங்களை உருவாக்குவதற்கான ஒரு முன்னணி ஜாவாஸ்கிரிப்ட் நூலகமான ரியாக்ட், இதை அடைய சக்திவாய்ந்த கருவிகளை வழங்குகிறது. இவற்றில், useCallback
ஹூக், செயல்பாடுகளை நினைவில் கொள்வதற்கும் (memoizing), தேவையற்ற மறு-ரெண்டர்களைத் தடுப்பதற்கும், செயல்திறனை அதிகரிப்பதற்கும் ஒரு முக்கிய வழிமுறையாக விளங்குகிறது. இருப்பினும், எந்தவொரு சக்திவாய்ந்த கருவியைப் போலவே, useCallback
அதன் சொந்த சவால்களுடன் வருகிறது, குறிப்பாக அதன் சார்பு வரிசை (dependency array) தொடர்பானது. இந்த சார்புகளை தவறாக நிர்வகிப்பது நுட்பமான பிழைகள் மற்றும் செயல்திறன் பின்னடைவுகளுக்கு வழிவகுக்கும், இது மாறுபட்ட நெட்வொர்க் நிலைமைகள் மற்றும் சாதனத் திறன்களைக் கொண்ட சர்வதேச சந்தைகளைக் குறிவைக்கும்போது இன்னும் மோசமாகலாம்.
இந்த விரிவான வழிகாட்டி, useCallback
சார்புகளின் நுணுக்கங்களை ஆராய்ந்து, பொதுவான தவறுகளை விளக்கி, உலகளாவிய டெவலப்பர்கள் அவற்றைத் தவிர்க்க செயல்படக்கூடிய உத்திகளை வழங்குகிறது. சார்பு மேலாண்மை ஏன் முக்கியமானது, டெவலப்பர்கள் செய்யும் பொதுவான தவறுகள் மற்றும் உங்கள் ரியாக்ட் பயன்பாடுகள் உலகம் முழுவதும் செயல்திறன் மிக்கதாகவும், வலுவானதாகவும் இருப்பதை உறுதி செய்வதற்கான சிறந்த நடைமுறைகளை நாங்கள் ஆராய்வோம்.
useCallback மற்றும் மெமோயைசேஷன்-ஐப் புரிந்துகொள்ளுதல்
சார்புப் பிழைகளை ஆராய்வதற்கு முன், useCallback
-இன் முக்கிய கருத்தைப் புரிந்துகொள்வது அவசியம். அதன் மையத்தில், useCallback
என்பது ஒரு ரியாக்ட் ஹூக் ஆகும், இது ஒரு கால்பேக் செயல்பாட்டை நினைவில் கொள்கிறது (memoizes). மெமோயைசேஷன் என்பது ஒரு விலை உயர்ந்த செயல்பாட்டு அழைப்பின் முடிவு தற்காலிகமாக சேமிக்கப்பட்டு (cached), அதே உள்ளீடுகள் மீண்டும் வரும்போது சேமிக்கப்பட்ட முடிவு திருப்பி அனுப்பப்படும் ஒரு நுட்பமாகும். ரியாக்ட்டில், இது ஒரு செயல்பாடு ஒவ்வொரு ரெண்டரிலும் மீண்டும் உருவாக்கப்படுவதைத் தடுப்பதாகும், குறிப்பாக அந்தச் செயல்பாடு மெமோயைசேஷன் பயன்படுத்தும் ஒரு குழந்தை கூறுக்கு (child component) ஒரு ப்ராப்பாக (prop) அனுப்பப்படும்போது (React.memo
போல).
ஒரு பெற்றோர் கூறு (parent component) ஒரு குழந்தை கூறினை (child component) ரெண்டர் செய்யும் ஒரு சூழ்நிலையைக் கவனியுங்கள். பெற்றோர் கூறு மறு-ரெண்டர் ஆனால், அதற்குள் வரையறுக்கப்பட்ட எந்தவொரு செயல்பாடும் மீண்டும் உருவாக்கப்படும். இந்தச் செயல்பாடு குழந்தை கூறுக்கு ஒரு ப்ராப்பாக அனுப்பப்பட்டால், குழந்தை அதை ஒரு புதிய ப்ராப்பாகக் கருதி, செயல்பாட்டின் தர்க்கம் மற்றும் நடத்தை மாறாவிட்டாலும், தேவையற்ற முறையில் மறு-ரெண்டர் ஆகலாம். இங்குதான் useCallback
உதவுகிறது:
const memoizedCallback = useCallback( () => { doSomething(a, b); }, [a, b], );
இந்த எடுத்துக்காட்டில், a
அல்லது b
-இன் மதிப்புகள் மாறினால் மட்டுமே memoizedCallback
மீண்டும் உருவாக்கப்படும். இது ரெண்டர்களுக்கு இடையில் a
மற்றும் b
ஒரே மாதிரியாக இருந்தால், அதே செயல்பாட்டுக் குறிப்பு (function reference) குழந்தை கூறுக்கு அனுப்பப்படுவதை உறுதி செய்கிறது, இது அதன் மறு-ரெண்டரைத் தடுக்கக்கூடும்.
உலகளாவிய பயன்பாடுகளுக்கு மெமோயைசேஷன் ஏன் முக்கியமானது?
உலகளாவிய பார்வையாளர்களைக் குறிவைக்கும் பயன்பாடுகளுக்கு, செயல்திறன் பரிசீலனைகள் மிகவும் முக்கியத்துவம் பெறுகின்றன. மெதுவான இணைய இணைப்புகள் அல்லது குறைந்த சக்தி வாய்ந்த சாதனங்களைக் கொண்ட பிராந்தியங்களில் உள்ள பயனர்கள், திறமையற்ற ரெண்டரிங் காரணமாக குறிப்பிடத்தக்க தாமதம் மற்றும் மோசமான பயனர் அனுபவத்தை உணரலாம். useCallback
மூலம் கால்பேக்குகளை நினைவில் கொள்வதன் மூலம், நாம்:
- தேவையற்ற மறு-ரெண்டர்களைக் குறைத்தல்: இது உலாவி செய்ய வேண்டிய வேலையின் அளவை நேரடியாகப் பாதிக்கிறது, இது வேகமான பயனர் இடைமுகப் புதுப்பிப்புகளுக்கு வழிவகுக்கிறது.
- நெட்வொர்க் பயன்பாட்டை மேம்படுத்துதல்: குறைவான ஜாவாஸ்கிரிப்ட் இயக்கம், குறைந்த தரவு நுகர்வுக்கு வழிவகுக்கும், இது மீட்டர் இணைப்புகளில் உள்ள பயனர்களுக்கு முக்கியமானது.
- பதிலளிக்கும் திறனை மேம்படுத்துதல்: செயல்திறன் மிக்க ஒரு பயன்பாடு அதிக பதிலளிக்கும் தன்மையைக் கொண்டதாக உணர்கிறது, இது பயனரின் புவியியல் இருப்பிடம் அல்லது சாதனத்தைப் பொருட்படுத்தாமல், அதிக பயனர் திருப்திக்கு வழிவகுக்கிறது.
- திறமையான ப்ராப் அனுப்புதலை இயக்குதல்: மெமோ செய்யப்பட்ட குழந்தை கூறுகளுக்கு (
React.memo
) அல்லது சிக்கலான கூறு மரங்களுக்குள் கால்பேக்குகளை அனுப்பும்போது, நிலையான செயல்பாட்டுக் குறிப்புகள் தொடர்ச்சியான மறு-ரெண்டர்களைத் தடுக்கின்றன.
சார்பு வரிசையின் முக்கிய பங்கு
useCallback
-இன் இரண்டாவது வாதம் சார்பு வரிசை (dependency array) ஆகும். இந்த வரிசை, கால்பேக் செயல்பாடு எந்த மதிப்புகளைச் சார்ந்துள்ளது என்பதை ரியாக்டிடம் கூறுகிறது. வரிசையில் உள்ள சார்புகளில் ஒன்று கடைசி ரெண்டரிலிருந்து மாறியிருந்தால் மட்டுமே ரியாக்ட் நினைவில் கொள்ளப்பட்ட கால்பேக்கை மீண்டும் உருவாக்கும்.
பொதுவான விதி இதுதான்: ஒரு மதிப்பு கால்பேக்கிற்குள் பயன்படுத்தப்பட்டு, ரெண்டர்களுக்கு இடையில் மாறக்கூடியதாக இருந்தால், அது சார்பு வரிசையில் சேர்க்கப்பட வேண்டும்.
இந்த விதியைப் பின்பற்றத் தவறினால் இரண்டு முக்கிய சிக்கல்கள் ஏற்படலாம்:
- பழைய நிலைத் தரவுகள் (Stale Closures): கால்பேக்கிற்குள் பயன்படுத்தப்படும் ஒரு மதிப்பு சார்பு வரிசையில் *சேர்க்கப்படவில்லை* என்றால், அந்த கால்பேக் கடைசியாக உருவாக்கப்பட்ட ரெண்டரில் இருந்து அந்த மதிப்பின் குறிப்பைத் தக்க வைத்துக் கொள்ளும். இந்த மதிப்பை புதுப்பிக்கும் அடுத்தடுத்த ரெண்டர்கள், நினைவில் கொள்ளப்பட்ட கால்பேக்கிற்குள் பிரதிபலிக்காது, இது எதிர்பாராத நடத்தைக்கு வழிவகுக்கும் (எ.கா., பழைய ஸ்டேட் மதிப்பைப் பயன்படுத்துதல்).
- தேவையற்ற மறுஉருவாக்கங்கள்: கால்பேக்கின் தர்க்கத்தைப் பாதிக்காத சார்புகள் *சேர்க்கப்பட்டால்*, கால்பேக் தேவைக்கு அதிகமாக மீண்டும் உருவாக்கப்படலாம், இது
useCallback
-இன் செயல்திறன் நன்மைகளை இல்லாமல் செய்துவிடும்.
பொதுவான சார்புப் பிழைகள் மற்றும் அவற்றின் உலகளாவிய தாக்கங்கள்
useCallback
சார்புகளுடன் டெவலப்பர்கள் செய்யும் மிகவும் பொதுவான தவறுகளையும், அவை உலகளாவிய பயனர் தளத்தை எவ்வாறு பாதிக்கலாம் என்பதையும் ஆராய்வோம்.
பிழை 1: சார்புகளை மறந்துவிடுதல் (பழைய நிலைத் தரவுகள்)
இதுவே மிகவும் அடிக்கடி நிகழும் மற்றும் சிக்கலான பிழையாகும். டெவலப்பர்கள் பெரும்பாலும் கால்பேக் செயல்பாட்டிற்குள் பயன்படுத்தப்படும் மாறிகளை (ப்ராப்கள், ஸ்டேட், கான்டெக்ஸ்ட் மதிப்புகள், மற்ற ஹூக் முடிவுகள்) சேர்க்க மறந்துவிடுகிறார்கள்.
உதாரணம்:
import React, { useState, useCallback } from 'react';
function Counter() {
const [count, setCount] = useState(0);
const [step, setStep] = useState(1);
// Pitfall: 'step' is used but not in dependencies
const increment = useCallback(() => {
setCount(prevCount => prevCount + step);
}, []); // Empty dependency array means this callback never updates
return (
Count: {count}
);
}
பகுப்பாய்வு: இந்த எடுத்துக்காட்டில், increment
செயல்பாடு step
ஸ்டேட்டைப் பயன்படுத்துகிறது. இருப்பினும், சார்பு வரிசை காலியாக உள்ளது. பயனர் "Increase Step" பொத்தானைக் கிளிக் செய்யும்போது, step
ஸ்டேட் புதுப்பிக்கப்படுகிறது. ஆனால் increment
ஒரு காலி சார்பு வரிசையுடன் நினைவில் கொள்ளப்பட்டுள்ளதால், அது அழைக்கப்படும்போது எப்போதும் step
-இன் ஆரம்ப மதிப்பைப் (1) பயன்படுத்துகிறது. பயனர், ஸ்டெப் மதிப்பை அதிகரித்திருந்தாலும், "Increment" பொத்தானைக் கிளிக் செய்வது கணக்கை 1 ஆல் மட்டுமே அதிகரிப்பதை கவனிப்பார்.
உலகளாவிய தாக்கம்: இந்த பிழை சர்வதேச பயனர்களுக்கு குறிப்பாக எரிச்சலூட்டுவதாக இருக்கலாம். அதிக தாமதம் (latency) உள்ள ஒரு பகுதியில் உள்ள ஒரு பயனரைக் கற்பனை செய்து பாருங்கள். அவர்கள் ஒரு செயலைச் செய்துவிட்டு (ஸ்டெப்பை அதிகரிப்பது போல), அடுத்த "Increment" செயல் அந்த மாற்றத்தைப் பிரதிபலிக்கும் என்று எதிர்பார்ப்பார்கள். பழைய நிலைத் தரவுகள் காரணமாக பயன்பாடு எதிர்பாராத விதமாக நடந்துகொண்டால், அது குழப்பத்திற்கும், பயன்பாட்டை கைவிடுவதற்கும் வழிவகுக்கும், குறிப்பாக அவர்களின் முதன்மை மொழி ஆங்கிலம் அல்லாமலும், பிழைச் செய்திகள் (ஏதேனும் இருந்தால்) சரியாக மொழிபெயர்க்கப்படாமலும் அல்லது தெளிவாக இல்லாமலும் இருந்தால்.
பிழை 2: அதிகப்படியான சார்புகளைச் சேர்த்தல் (தேவையற்ற மறுஉருவாக்கங்கள்)
இதற்கு நேர்மாறாக, கால்பேக்கின் தர்க்கத்தை உண்மையில் பாதிக்காத அல்லது ஒவ்வொரு ரெண்டரிலும் சரியான காரணம் இல்லாமல் மாறும் மதிப்புகளை சார்பு வரிசையில் சேர்ப்பது. இது கால்பேக் மிகவும் அடிக்கடி மீண்டும் உருவாக்கப்படுவதற்கு வழிவகுக்கும், இது useCallback
-இன் நோக்கத்தையே தோற்கடித்துவிடும்.
உதாரணம்:
import React, { useState, useCallback } from 'react';
function Greeting({ name }) {
// This function doesn't actually use 'name', but let's pretend it does for demonstration.
// A more realistic scenario might be a callback that modifies some internal state related to the prop.
const generateGreeting = useCallback(() => {
// Imagine this fetches user data based on name and displays it
console.log(`Generating greeting for ${name}`);
return `Hello, ${name}!`;
}, [name, Math.random()]); // Pitfall: Including unstable values like Math.random()
return (
{generateGreeting()}
);
}
பகுப்பாய்வு: இந்த செயற்கையான எடுத்துக்காட்டில், Math.random()
சார்பு வரிசையில் சேர்க்கப்பட்டுள்ளது. Math.random()
ஒவ்வொரு ரெண்டரிலும் ஒரு புதிய மதிப்பைத் தருவதால், name
ப்ராப் மாறியதா என்பதைப் பொருட்படுத்தாமல், generateGreeting
செயல்பாடு ஒவ்வொரு ரெண்டரிலும் மீண்டும் உருவாக்கப்படும். இது இந்த விஷயத்தில் useCallback
-ஐ மெமோயைசேஷனுக்கு பயனற்றதாக ஆக்குகிறது.
ஒரு பொதுவான நிஜ உலக சூழ்நிலையில், பெற்றோர் கூறின் ரெண்டர் செயல்பாட்டிற்குள் நேரடியாக உருவாக்கப்படும் ஆப்ஜெக்ட்கள் அல்லது வரிசைகள் இதில் அடங்கும்:
import React, { useState, useCallback } from 'react';
function UserProfile({ user }) {
const [message, setMessage] = useState('');
// Pitfall: Inline object creation in parent means this callback will re-create often.
// Even if 'user' object content is the same, its reference might change.
const displayUserDetails = useCallback(() => {
const details = { userId: user.id, userName: user.name };
setMessage(`User ID: ${details.userId}, Name: ${details.userName}`);
}, [user, { userId: user.id, userName: user.name }]); // Incorrect dependency
return (
{message}
);
}
பகுப்பாய்வு: இங்கு, user
ஆப்ஜெக்ட்டின் பண்புகள் (id
, name
) மாறாமல் இருந்தாலும், பெற்றோர் கூறு ஒரு புதிய ஆப்ஜெக்ட் லிட்டரலை (எ.கா., <UserProfile user={{ id: 1, name: 'Alice' }} />
) அனுப்பினால், user
ப்ராப்பின் குறிப்பு மாறும். user
மட்டுமே சார்பாக இருந்தால், கால்பேக் மீண்டும் உருவாக்கப்படும். நாம் ஆப்ஜெக்ட்டின் பண்புகளையோ அல்லது ஒரு புதிய ஆப்ஜெக்ட் லிட்டரலையோ ஒரு சார்பாகச் சேர்க்க முயன்றால் (தவறான சார்பு எடுத்துக்காட்டில் காட்டப்பட்டுள்ளது போல), அது இன்னும் அடிக்கடி மறுஉருவாக்கங்களை ஏற்படுத்தும்.
உலகளாவிய தாக்கம்: செயல்பாடுகளை அதிகமாக உருவாக்குவது, நினைவகப் பயன்பாட்டை அதிகரிக்கவும், குப்பை சேகரிப்பு சுழற்சிகளை (garbage collection cycles) அடிக்கடி ஏற்படுத்தவும் வழிவகுக்கும், குறிப்பாக உலகின் பல பகுதிகளில் பொதுவான வள-கட்டுப்படுத்தப்பட்ட மொபைல் சாதனங்களில். செயல்திறன் தாக்கம் பழைய நிலைத் தரவுகளைப் போல கடுமையாக இல்லாவிட்டாலும், இது ஒட்டுமொத்தமாக ஒரு திறமையற்ற பயன்பாட்டிற்கு பங்களிக்கிறது, இது பழைய வன்பொருள் அல்லது மெதுவான நெட்வொர்க் நிலைமைகளைக் கொண்ட பயனர்களை பாதிக்கக்கூடும், அவர்களால் அத்தகைய கூடுதல் சுமையை ஏற்க முடியாது.
பிழை 3: ஆப்ஜெக்ட் மற்றும் வரிசை சார்புகளைத் தவறாகப் புரிந்துகொள்வது
பிரிமிடிவ் மதிப்புகள் (ஸ்ட்ரிங், எண்கள், பூலியன்கள், நல், வரையறுக்கப்படாதவை) மதிப்பால் ஒப்பிடப்படுகின்றன. இருப்பினும், ஆப்ஜெக்ட்கள் மற்றும் வரிசைகள் குறிப்பால் (reference) ஒப்பிடப்படுகின்றன. இதன் பொருள், ஒரு ஆப்ஜெக்ட் அல்லது வரிசை ஒரே உள்ளடக்கத்தைக் கொண்டிருந்தாலும், அது ரெண்டரின் போது உருவாக்கப்பட்ட ஒரு புதிய நிகழ்வாக இருந்தால், ரியாக்ட் அதை ஒரு சார்பு மாற்றமாகக் கருதும்.
உதாரணம்:
import React, { useState, useCallback } from 'react';
function DataDisplay({ data }) { // Assume data is an array of objects like [{ id: 1, value: 'A' }]
const [filteredData, setFilteredData] = useState([]);
// Pitfall: If 'data' is a new array reference on each render, this callback re-creates.
const processData = useCallback(() => {
const processed = data.map(item => ({ ...item, processed: true }));
setFilteredData(processed);
}, [data]); // If 'data' is a new array instance each time, this callback will re-create.
return (
{filteredData.map(item => (
- {item.value} - {item.processed ? 'Processed' : ''}
))}
);
}
function App() {
const [randomNumber, setRandomNumber] = useState(0);
// 'sampleData' is re-created on every render of App, even if its content is the same.
const sampleData = [
{ id: 1, value: 'Alpha' },
{ id: 2, value: 'Beta' },
];
return (
{/* Passing a new 'sampleData' reference every time App renders */}
);
}
பகுப்பாய்வு: App
கூறில், sampleData
நேரடியாக கூறுவின் உடற்பகுதிக்குள் அறிவிக்கப்பட்டுள்ளது. App
மறு-ரெண்டர் ஆகும் ஒவ்வொரு முறையும் (எ.கா., randomNumber
மாறும் போது), sampleData
-க்கு ஒரு புதிய வரிசை நிகழ்வு உருவாக்கப்படுகிறது. இந்த புதிய நிகழ்வு பின்னர் DataDisplay
-க்கு அனுப்பப்படுகிறது. இதன் விளைவாக, DataDisplay
-ல் உள்ள data
ப்ராப் ஒரு புதிய குறிப்பைப் பெறுகிறது. data
என்பது processData
-வின் சார்பு என்பதால், உண்மையான தரவு உள்ளடக்கம் மாறாவிட்டாலும், App
-இன் ஒவ்வொரு ரெண்டரிலும் processData
கால்பேக் மீண்டும் உருவாக்கப்படுகிறது. இது மெமோயைசேஷனை பயனற்றதாக்குகிறது.
உலகளாவிய தாக்கம்: நிலையற்ற இணையம் உள்ள பகுதிகளில் உள்ள பயனர்கள், நினைவில் கொள்ளப்படாத தரவுக் கட்டமைப்புகள் அனுப்பப்படுவதால், பயன்பாடு தொடர்ந்து கூறுகளை மறு-ரெண்டர் செய்தால், மெதுவான ஏற்றுதல் நேரங்கள் அல்லது பதிலளிக்காத இடைமுகங்களை அனுபவிக்கலாம். பயனர்கள் மாறுபட்ட நெட்வொர்க் நிலைமைகளில் இருந்து பயன்பாட்டை அணுகும்போது, ஒரு சுமூகமான அனுபவத்தை வழங்குவதற்கு தரவு சார்புகளை திறமையாகக் கையாள்வது முக்கியம்.
திறமையான சார்பு நிர்வாகத்திற்கான உத்திகள்
இந்தப் பிழைகளைத் தவிர்க்க, சார்புகளை நிர்வகிப்பதில் ஒரு ஒழுக்கமான அணுகுமுறை தேவை. இதோ சில பயனுள்ள உத்திகள்:
1. ரியாக்ட் ஹூக்ஸிற்கான ESLint பிளகினைப் பயன்படுத்தவும்
ரியாக்ட் ஹூக்ஸிற்கான அதிகாரப்பூர்வ ESLint பிளகின் ஒரு இன்றியமையாத கருவியாகும். இது exhaustive-deps
என்ற விதியை உள்ளடக்கியது, இது உங்கள் சார்பு வரிசைகளை தானாகவே சரிபார்க்கிறது. உங்கள் கால்பேக்கிற்குள் சார்பு வரிசையில் பட்டியலிடப்படாத ஒரு மாறியைப் பயன்படுத்தினால், ESLint உங்களை எச்சரிக்கும். இது பழைய நிலைத் தரவுகளுக்கு எதிரான முதல் பாதுகாப்பு அரணாகும்.
நிறுவல்:
உங்கள் திட்டத்தின் டெவ் சார்புகளில் eslint-plugin-react-hooks
-ஐச் சேர்க்கவும்:
npm install eslint-plugin-react-hooks --save-dev
# or
yarn add eslint-plugin-react-hooks --dev
பின்னர், உங்கள் .eslintrc.js
(அல்லது அதுபோன்ற) கோப்பை உள்ளமைக்கவும்:
module.exports = {
// ... other configs
plugins: [
// ... other plugins
'react-hooks'
],
rules: {
// ... other rules
'react-hooks/rules-of-hooks': 'error', // Checks rules of Hooks
'react-hooks/exhaustive-deps': 'warn' // Checks effect dependencies
}
};
இந்த அமைப்பு ஹூக்ஸ் விதிகளைச் செயல்படுத்தி, விடுபட்ட சார்புகளை முன்னிலைப்படுத்தும்.
2. எதைச் சேர்க்கிறீர்கள் என்பதில் கவனமாக இருங்கள்
உங்கள் கால்பேக் *உண்மையில்* எதைப் பயன்படுத்துகிறது என்பதை கவனமாகப் பகுப்பாய்வு செய்யுங்கள். மாறும்போது, கால்பேக் செயல்பாட்டின் புதிய பதிப்பை அவசியமாக்கும் மதிப்புகளை மட்டுமே சேர்க்கவும்.
- ப்ராப்கள்: கால்பேக் ஒரு ப்ராப்பைப் பயன்படுத்தினால், அதைச் சேர்க்கவும்.
- ஸ்டேட்: கால்பேக் ஸ்டேட் அல்லது ஸ்டேட் செட்டர் செயல்பாட்டைப் பயன்படுத்தினால் (
setCount
போல), ஸ்டேட் மாறி நேரடியாகப் பயன்படுத்தப்பட்டால் அதைச் சேர்க்கவும், அல்லது செட்டர் நிலையானதாக இருந்தால் அதைச் சேர்க்கவும். - கான்டெக்ஸ்ட் மதிப்புகள்: கால்பேக் ரியாக்ட் கான்டெக்ஸ்டில் இருந்து ஒரு மதிப்பைப் பயன்படுத்தினால், அந்த கான்டெக்ஸ்ட் மதிப்பைச் சேர்க்கவும்.
- வெளியே வரையறுக்கப்பட்ட செயல்பாடுகள்: கால்பேக், கூறிற்கு வெளியே வரையறுக்கப்பட்ட அல்லது தானே நினைவில் கொள்ளப்பட்ட மற்றொரு செயல்பாட்டை அழைத்தால், அந்தச் செயல்பாட்டை சார்புகளில் சேர்க்கவும்.
3. ஆப்ஜெக்ட்கள் மற்றும் வரிசைகளை நினைவில் கொள்ளுதல் (Memoizing)
நீங்கள் ஆப்ஜெக்ட்கள் அல்லது வரிசைகளை சார்புகளாக அனுப்ப வேண்டியிருந்து, அவை இன்லைனில் உருவாக்கப்பட்டால், அவற்றை useMemo
பயன்படுத்தி நினைவில் கொள்ளவும். இது அடிப்படைத் தரவு உண்மையிலேயே மாறும்போது மட்டுமே குறிப்பு மாறுவதை உறுதி செய்கிறது.
உதாரணம் (பிழை 3-லிருந்து மேம்படுத்தப்பட்டது):
import React, { useState, useCallback, useMemo } from 'react';
function DataDisplay({ data }) {
const [filteredData, setFilteredData] = useState([]);
// Now, 'data' reference stability depends on how it's passed from parent.
const processData = useCallback(() => {
console.log('Processing data...');
const processed = data.map(item => ({ ...item, processed: true }));
setFilteredData(processed);
}, [data]);
return (
{filteredData.map(item => (
- {item.value} - {item.processed ? 'Processed' : ''}
))}
);
}
function App() {
const [dataConfig, setDataConfig] = useState({ items: ['Alpha', 'Beta'], version: 1 });
// Memoize the data structure passed to DataDisplay
const memoizedData = useMemo(() => {
return dataConfig.items.map((item, index) => ({ id: index, value: item }));
}, [dataConfig.items]); // Only re-creates if dataConfig.items changes
return (
{/* Pass the memoized data */}
);
}
பகுப்பாய்வு: இந்த மேம்படுத்தப்பட்ட எடுத்துக்காட்டில், App
, memoizedData
-வை உருவாக்க useMemo
-வைப் பயன்படுத்துகிறது. dataConfig.items
மாறினால் மட்டுமே இந்த memoizedData
வரிசை மீண்டும் உருவாக்கப்படும். இதன் விளைவாக, DataDisplay
-க்கு அனுப்பப்படும் data
ப்ராப், பொருட்கள் மாறாத வரை ஒரு நிலையான குறிப்பைக் கொண்டிருக்கும். இது DataDisplay
-ல் உள்ள useCallback
-ஐ processData
-வை திறம்பட நினைவில் கொள்ள அனுமதிக்கிறது, தேவையற்ற மறுஉருவாக்கங்களைத் தடுக்கிறது.
4. இன்லைன் செயல்பாடுகளைக் கவனத்துடன் பரிசீலிக்கவும்
ஒரே கூறிற்குள் மட்டுமே பயன்படுத்தப்படும் மற்றும் குழந்தை கூறுகளில் மறு-ரெண்டர்களைத் தூண்டாத எளிய கால்பேக்குகளுக்கு, உங்களுக்கு useCallback
தேவைப்படாமல் இருக்கலாம். பல சந்தர்ப்பங்களில் இன்லைன் செயல்பாடுகள் முற்றிலும் ஏற்றுக்கொள்ளத்தக்கவை. useCallback
-இன் கூடுதல் சுமை, அந்தச் செயல்பாடு கீழ் அனுப்பப்படாமலோ அல்லது கடுமையான குறிப்பு சமத்துவம் தேவைப்படும் வகையில் பயன்படுத்தப்படாமலோ இருந்தால், சில நேரங்களில் அதன் நன்மையை விட அதிகமாக இருக்கலாம்.
இருப்பினும், மேம்படுத்தப்பட்ட குழந்தை கூறுகளுக்கு (React.memo
) கால்பேக்குகளை அனுப்பும்போது, சிக்கலான செயல்பாடுகளுக்கான நிகழ்வு கையாள்பவர்கள், அல்லது அடிக்கடி அழைக்கப்பட்டு மறைமுகமாக மறு-ரெண்டர்களைத் தூண்டக்கூடிய செயல்பாடுகளுக்கு, useCallback
அவசியமாகிறது.
5. நிலையான `setState` செட்டர்
ரியாக்ட், ஸ்டேட் செட்டர் செயல்பாடுகள் (எ.கா., setCount
, setStep
) நிலையானவை மற்றும் ரெண்டர்களுக்கு இடையில் மாறாது என்று உத்தரவாதம் அளிக்கிறது. இதன் பொருள், உங்கள் லிண்டர் வலியுறுத்தாவிட்டால் (exhaustive-deps
முழுமைக்காக அவ்வாறு செய்யலாம்), அவற்றை உங்கள் சார்பு வரிசையில் சேர்க்கத் தேவையில்லை. உங்கள் கால்பேக் ஒரு ஸ்டேட் செட்டரை மட்டுமே அழைத்தால், நீங்கள் அதை ஒரு காலி சார்பு வரிசையுடன் நினைவில் கொள்ளலாம்.
உதாரணம்:
const increment = useCallback(() => {
setCount(prevCount => prevCount + 1);
}, []); // setCount நிலையானது என்பதால் இங்கே காலி வரிசையைப் பயன்படுத்துவது பாதுகாப்பானது
6. ப்ராப்களில் இருந்து வரும் செயல்பாடுகளைக் கையாளுதல்
உங்கள் கூறு ஒரு கால்பேக் செயல்பாட்டை ஒரு ப்ராப்பாகப் பெற்றால், மற்றும் உங்கள் கூறு இந்த ப்ராப் செயல்பாட்டை அழைக்கும் மற்றொரு செயல்பாட்டை நினைவில் கொள்ள வேண்டுமானால், நீங்கள் ப்ராப் செயல்பாட்டை சார்பு வரிசையில் *கட்டாயம்* சேர்க்க வேண்டும்.
function ChildComponent({ onClick }) {
const handleClick = useCallback(() => {
console.log('Child handling click...');
onClick(); // onClick ப்ராப்பைப் பயன்படுத்துகிறது
}, [onClick]); // onClick ப்ராப்பைச் சேர்க்க வேண்டும்
return ;
}
பெற்றோர் கூறு ஒவ்வொரு ரெண்டரிலும் onClick
-க்கு ஒரு புதிய செயல்பாட்டுக் குறிப்பை அனுப்பினால், ChildComponent
-இன் handleClick
-ம் அடிக்கடி மீண்டும் உருவாக்கப்படும். இதைத் தடுக்க, பெற்றோர் கூறும் அது அனுப்பும் செயல்பாட்டை நினைவில் கொள்ள வேண்டும்.
உலகளாவிய பார்வையாளர்களுக்கான மேம்பட்ட பரிசீலனைகள்
உலகளாவிய பார்வையாளர்களுக்காக பயன்பாடுகளை உருவாக்கும்போது, செயல்திறன் மற்றும் useCallback
தொடர்பான பல காரணிகள் இன்னும் முக்கியத்துவம் பெறுகின்றன:
- சர்வதேசமயமாக்கல் (i18n) மற்றும் உள்ளூர்மயமாக்கல் (l10n): உங்கள் கால்பேக்குகள் சர்வதேசமயமாக்கல் தர்க்கத்தை (எ.கா., தேதிகள், நாணயங்களை வடிவமைத்தல், அல்லது செய்திகளை மொழிபெயர்த்தல்) கொண்டிருந்தால், வட்டார அமைப்புகள் அல்லது மொழிபெயர்ப்பு செயல்பாடுகள் தொடர்பான எந்த சார்புகளும் சரியாக நிர்வகிக்கப்படுவதை உறுதிசெய்யவும். வட்டார மாற்றங்கள், அவற்றைச் சார்ந்திருக்கும் கால்பேக்குகளை மீண்டும் உருவாக்க வேண்டியிருக்கலாம்.
- நேர மண்டலங்கள் மற்றும் பிராந்தியத் தரவு: நேர மண்டலங்கள் அல்லது பிராந்திய-குறிப்பிட்ட தரவுகளை உள்ளடக்கிய செயல்பாடுகளுக்கு, இந்த மதிப்புகள் பயனர் அமைப்புகள் அல்லது சர்வர் தரவைப் பொறுத்து மாறக்கூடியதாக இருந்தால், சார்புகளை கவனமாகக் கையாள வேண்டியிருக்கலாம்.
- முற்போக்கு வலை பயன்பாடுகள் (PWAs) மற்றும் ஆஃப்லைன் திறன்கள்: இடைப்பட்ட இணைப்பு உள்ள பகுதிகளில் உள்ள பயனர்களுக்காக வடிவமைக்கப்பட்ட PWA-க்களுக்கு, திறமையான ரெண்டரிங் மற்றும் குறைந்தபட்ச மறு-ரெண்டர்கள் முக்கியமானவை. நெட்வொர்க் வளங்கள் குறைவாக இருக்கும்போதும் ஒரு சுமூகமான அனுபவத்தை உறுதி செய்வதில்
useCallback
ஒரு முக்கிய பங்கு வகிக்கிறது. - பிராந்தியங்கள் முழுவதும் செயல்திறன் சுயவிவரம் (Performance Profiling): செயல்திறன் தடைகளைக் கண்டறிய ரியாக்ட் டெவ்டூல்ஸ் ப்ரொஃபைலரைப் பயன்படுத்தவும். உங்கள் பயன்பாட்டின் செயல்திறனை உங்கள் உள்ளூர் மேம்பாட்டு சூழலில் மட்டும் சோதிக்காமல், உங்கள் உலகளாவிய பயனர் தளத்தைப் பிரதிநிதித்துவப்படுத்தும் நிலைமைகளையும் (எ.கா., மெதுவான நெட்வொர்க்குகள், குறைந்த சக்தி வாய்ந்த சாதனங்கள்) உருவகப்படுத்தவும். இது
useCallback
சார்பு தவறான மேலாண்மை தொடர்பான நுட்பமான சிக்கல்களைக் கண்டறிய உதவும்.
முடிவுரை
useCallback
என்பது ரியாக்ட் பயன்பாடுகளை மேம்படுத்துவதற்கும், செயல்பாடுகளை நினைவில் கொள்வதற்கும், தேவையற்ற மறு-ரெண்டர்களைத் தடுப்பதற்கும் ஒரு சக்திவாய்ந்த கருவியாகும். இருப்பினும், அதன் செயல்திறன் முற்றிலும் அதன் சார்பு வரிசையின் சரியான நிர்வாகத்தைப் பொறுத்தது. உலகளாவிய டெவலப்பர்களுக்கு, இந்த சார்புகளை மாஸ்டர் செய்வது என்பது சிறிய செயல்திறன் ஆதாயங்களைப் பற்றியது மட்டுமல்ல; இது ஒவ்வொருவருக்கும், அவர்களின் இருப்பிடம், நெட்வொர்க் வேகம், அல்லது சாதனத் திறன்களைப் பொருட்படுத்தாமல், ஒரு சீரான வேகமான, பதிலளிக்கக்கூடிய, மற்றும் நம்பகமான பயனர் அனுபவத்தை உறுதி செய்வதாகும்.
ஹூக்ஸ் விதிகளுக்கு விடாமுயற்சியுடன் கட்டுப்பட்டு, ESLint போன்ற கருவிகளைப் பயன்படுத்தி, மற்றும் பிரிமிடிவ் மற்றும் ரெஃபரன்ஸ் வகைகள் சார்புகளை எவ்வாறு பாதிக்கின்றன என்பதை மனதில் கொண்டு, நீங்கள் useCallback
-இன் முழு சக்தியையும் பயன்படுத்தலாம். உங்கள் கால்பேக்குகளைப் பகுப்பாய்வு செய்யவும், தேவையான சார்புகளை மட்டுமே சேர்க்கவும், மற்றும் தேவைப்படும்போது ஆப்ஜெக்ட்கள்/வரிசைகளை நினைவில் கொள்ளவும் நினைவில் கொள்ளுங்கள். இந்த ஒழுக்கமான அணுகுமுறை மேலும் வலுவான, அளவிடக்கூடிய, மற்றும் உலகளவில் செயல்திறன் மிக்க ரியாக்ட் பயன்பாடுகளுக்கு வழிவகுக்கும்.
இந்த நடைமுறைகளை இன்றே செயல்படுத்தத் தொடங்குங்கள், உலக அரங்கில் உண்மையிலேயே ஜொலிக்கும் ரியாக்ட் பயன்பாடுகளை உருவாக்குங்கள்!