கோட் ஸ்ப்ளிட்டிங்கிற்கு அப்பாற்பட்ட டேட்டா ஃபெட்சிங்கிற்காக ரியாக்ட் சஸ்பென்ஸை ஆராயுங்கள். Fetch-As-You-Render, பிழை கையாளுதல் மற்றும் உலகளாவிய பயன்பாடுகளுக்கான முறைகளைப் புரிந்து கொள்ளுங்கள்.
ரியாக்ட் சஸ்பென்ஸ் ரிசோர்ஸ் லோடிங்: நவீன டேட்டா ஃபெட்சிங் முறைகளில் தேர்ச்சி பெறுதல்
இணைய மேம்பாட்டின் மாறும் உலகில், பயனர் அனுபவம் (UX) மிக முக்கியமானது. நெட்வொர்க் நிலைமைகள் அல்லது சாதன திறன்களைப் பொருட்படுத்தாமல், பயன்பாடுகள் வேகமாகவும், பதிலளிக்கக்கூடியதாகவும், மகிழ்ச்சிகரமாகவும் இருக்கும் என்று எதிர்பார்க்கப்படுகிறது. ரியாக்ட் டெவலப்பர்களுக்கு, இது பெரும்பாலும் சிக்கலான ஸ்டேட் மேலாண்மை, சிக்கலான லோடிங் இண்டிகேட்டர்கள் மற்றும் டேட்டா ஃபெட்சிங் வாட்டர்ஃபால்களுக்கு எதிரான ஒரு நிலையான போராட்டமாக மொழிபெயர்க்கப்படுகிறது. இங்குதான் ரியாக்ட் சஸ்பென்ஸ் வருகிறது, இது ஒரு சக்திவாய்ந்த, பெரும்பாலும் தவறாகப் புரிந்து கொள்ளப்பட்ட அம்சம், இது நாம் ஒத்திசைவற்ற செயல்பாடுகளை, குறிப்பாக டேட்டா ஃபெட்சிங்கை கையாள்வதை அடிப்படையில் மாற்றியமைக்க வடிவமைக்கப்பட்டுள்ளது.
ஆரம்பத்தில் React.lazy()
உடன் கோட் ஸ்ப்ளிட்டிங்கிற்காக அறிமுகப்படுத்தப்பட்டாலும், சஸ்பென்ஸின் உண்மையான ஆற்றல், API-லிருந்து வரும் டேட்டா உட்பட *எந்த* ஒத்திசைவற்ற ரிசோர்ஸையும் ஏற்றுவதை ஒருங்கிணைக்கும் திறனில் உள்ளது. இந்த விரிவான வழிகாட்டி, ரியாக்ட் சஸ்பென்ஸின் ரிசோர்ஸ் லோடிங்கிற்கான ஆழமான ஆய்வை மேற்கொள்ளும், அதன் முக்கிய கருத்துக்கள், அடிப்படை டேட்டா ஃபெட்சிங் முறைகள் மற்றும் செயல்திறன் மிக்க மற்றும் மீள்திறன் கொண்ட உலகளாவிய பயன்பாடுகளை உருவாக்குவதற்கான நடைமுறைப் பரிசீலனைகளை ஆராயும்.
ரியாக்டில் டேட்டா ஃபெட்சிங்கின் பரிணாமம்: இம்பரேடிவ் முதல் டிக்ளரேடிவ் வரை
பல ஆண்டுகளாக, ரியாக்ட் காம்போனென்ட்களில் டேட்டா ஃபெட்சிங் முதன்மையாக ஒரு பொதுவான முறையை நம்பியிருந்தது: API அழைப்பைத் தொடங்க useEffect
ஹூக்கைப் பயன்படுத்துதல், useState
உடன் லோடிங் மற்றும் பிழை நிலைகளை நிர்வகித்தல், மற்றும் இந்த நிலைகளின் அடிப்படையில் நிபந்தனையுடன் ரெண்டரிங் செய்தல். இது செயல்பட்டாலும், இந்த அணுகுமுறை பெரும்பாலும் பல சவால்களுக்கு வழிவகுத்தது:
- லோடிங் ஸ்டேட் பெருக்கம்: டேட்டா தேவைப்படும் கிட்டத்தட்ட ஒவ்வொரு காம்போனென்ட்டிற்கும் அதன் சொந்த
isLoading
,isError
, மற்றும்data
ஸ்டேட்கள் தேவைப்பட்டன, இது மீண்டும் மீண்டும் வரும் பாய்லர்பிளேட்டிற்கு வழிவகுத்தது. - வாட்டர்ஃபால்கள் மற்றும் ரேஸ் கண்டிஷன்கள்: நெஸ்டட் காம்போனென்ட்கள் டேட்டாவை ஃபெட்ச் செய்வது பெரும்பாலும் தொடர்ச்சியான கோரிக்கைகளுக்கு (வாட்டர்ஃபால்கள்) வழிவகுத்தது, அங்கு ஒரு பெற்றோர் காம்போனென்ட் டேட்டாவை ஃபெட்ச் செய்து, பின்னர் ரெண்டர் செய்து, பின்னர் ஒரு சைல்ட் காம்போனென்ட் அதன் டேட்டாவை ஃபெட்ச் செய்யும், இப்படியே தொடரும். இது ஒட்டுமொத்த சுமை நேரங்களை அதிகரித்தது. பல கோரிக்கைகள் தொடங்கப்பட்டு, பதில்கள் வரிசை மாறி வரும்போது ரேஸ் கண்டிஷன்களும் ஏற்படக்கூடும்.
- சிக்கலான பிழை கையாளுதல்: பல காம்போனென்ட்களில் பிழை செய்திகளையும் மீட்பு தர்க்கத்தையும் விநியோகிப்பது சிக்கலானதாக இருக்கலாம், இதற்கு ப்ராப் டிரில்லிங் அல்லது குளோபல் ஸ்டேட் மேலாண்மை தீர்வுகள் தேவைப்பட்டன.
- விரும்பத்தகாத பயனர் அனுபவம்: பல ஸ்பின்னர்கள் தோன்றி மறைவது, அல்லது திடீர் உள்ளடக்க மாற்றங்கள் (லேஅவுட் ஷிப்ட்கள்), பயனர்களுக்கு ஒரு குழப்பமான அனுபவத்தை உருவாக்கக்கூடும்.
- டேட்டா மற்றும் ஸ்டேட்டிற்கான ப்ராப் டிரில்லிங்: பெறப்பட்ட டேட்டா மற்றும் தொடர்புடைய லோடிங்/பிழை நிலைகளை பல அடுக்கு காம்போனென்ட்கள் வழியாக அனுப்புவது ஒரு பொதுவான சிக்கல் மூலமாக மாறியது.
சஸ்பென்ஸ் இல்லாமல் ஒரு பொதுவான டேட்டா ஃபெட்சிங் சூழ்நிலையை கவனியுங்கள்:
import React, { useState, useEffect } from 'react';
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const fetchUser = async () => {
try {
setIsLoading(true);
const response = await fetch(`/api/users/${userId}`);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
setUser(data);
} catch (e) {
setError(e);
} finally {
setIsLoading(false);
}
};
fetchUser();
}, [userId]);
if (isLoading) {
return <p>பயனர் சுயவிவரம் ஏற்றப்படுகிறது...</p>;
}
if (error) {
return <p style={"color: red;"}>பிழை: {error.message}</p>;
}
if (!user) {
return <p>பயனர் டேட்டா எதுவும் கிடைக்கவில்லை.</p>;
}
return (
<div>
<h2>பயனர்: {user.name}</h2>
<p>மின்னஞ்சல்: {user.email}</p>
<!-- மேலும் பயனர் விவரங்கள் -->
</div>
);
}
function App() {
return (
<div>
<h1>பயன்பாட்டிற்கு வரவேற்கிறோம்</h1>
<UserProfile userId={"123"} />
</div>
);
}
இந்த முறை பரவலாக உள்ளது, ஆனால் இது காம்போனென்ட்டை அதன் சொந்த ஒத்திசைவற்ற நிலையை நிர்வகிக்க கட்டாயப்படுத்துகிறது, இது பெரும்பாலும் UI மற்றும் டேட்டா ஃபெட்சிங் தர்க்கத்திற்கு இடையே ஒரு இறுக்கமான பிணைப்புக்கு வழிவகுக்கிறது. சஸ்பென்ஸ் ஒரு மிகவும் டிக்ளரேடிவ் மற்றும் நெறிப்படுத்தப்பட்ட மாற்றீட்டை வழங்குகிறது.
கோட் ஸ்ப்ளிட்டிங்கிற்கு அப்பால் ரியாக்ட் சஸ்பென்ஸைப் புரிந்துகொள்வது
பெரும்பாலான டெவலப்பர்கள் முதலில் React.lazy()
மூலம் கோட் ஸ்ப்ளிட்டிங்கிற்காக சஸ்பென்ஸை சந்திக்கிறார்கள், அங்கு அது ஒரு காம்போனென்ட்டின் கோடை அது தேவைப்படும் வரை ஏற்றுவதை தாமதப்படுத்த அனுமதிக்கிறது. உதாரணமாக:
import React, { Suspense, lazy } from 'react';
const LazyComponent = lazy(() => import('./MyHeavyComponent'));
function App() {
return (
<Suspense fallback={<div>காம்போனென்ட் ஏற்றப்படுகிறது...</div>}>
<LazyComponent />
</Suspense>
);
}
இந்த சூழ்நிலையில், MyHeavyComponent
இன்னும் ஏற்றப்படவில்லை என்றால், <Suspense>
பவுண்டரி lazy()
ஆல் எறியப்பட்ட ப்ராமிஸைப் பிடித்து, காம்போனென்ட்டின் கோட் தயாராகும் வரை fallback
-ஐக் காண்பிக்கும். இங்கு முக்கிய உள்ளுணர்வு என்னவென்றால், சஸ்பென்ஸ் ரெண்டரிங்கின் போது எறியப்பட்ட ப்ராமிஸ்களைப் பிடிப்பதன் மூலம் செயல்படுகிறது.
இந்த பொறிமுறை கோட் லோடிங்கிற்கு மட்டும் பிரத்தியேகமானது அல்ல. ரெண்டரிங்கின் போது அழைக்கப்படும் எந்தவொரு செயல்பாடும், ஒரு ப்ராமிஸை எறிந்தால் (எ.கா., ஒரு ரிசோர்ஸ் இன்னும் கிடைக்காததால்), அதை காம்போனென்ட் ட்ரீயில் மேலே உள்ள ஒரு சஸ்பென்ஸ் பவுண்டரி பிடிக்க முடியும். ப்ராமிஸ் தீர்க்கப்படும்போது, ரியாக்ட் காம்போனென்ட்டை மீண்டும் ரெண்டர் செய்ய முயற்சிக்கிறது, மற்றும் ரிசோர்ஸ் இப்போது கிடைத்தால், ஃபால்பேக் மறைக்கப்பட்டு, உண்மையான உள்ளடக்கம் காட்டப்படும்.
டேட்டா ஃபெட்சிங்கிற்கான சஸ்பென்ஸின் முக்கிய கருத்துக்கள்
டேட்டா ஃபெட்சிங்கிற்காக சஸ்பென்ஸைப் பயன்படுத்த, நாம் சில முக்கிய கொள்கைகளைப் புரிந்து கொள்ள வேண்டும்:
1. ஒரு ப்ராமிஸை எறிதல்
ப்ராமிஸ்களைத் தீர்க்க async/await
பயன்படுத்தும் பாரம்பரிய ஒத்திசைவற்ற கோட் போலல்லாமல், சஸ்பென்ஸ் டேட்டா தயாராக இல்லை என்றால் ஒரு ப்ராமிஸை *எறியும்* ஒரு செயல்பாட்டை நம்பியுள்ளது. ரியாக்ட் அத்தகைய ஒரு செயல்பாட்டை அழைக்கும் ஒரு காம்போனென்ட்டை ரெண்டர் செய்ய முயற்சிக்கும்போது, டேட்டா இன்னும் நிலுவையில் இருந்தால், ப்ராமிஸ் எறியப்படுகிறது. ரியாக்ட் பின்னர் அந்த காம்போனென்ட் மற்றும் அதன் சைல்ட் காம்போனென்ட்களின் ரெண்டரிங்கை 'இடைநிறுத்தி', அருகிலுள்ள <Suspense>
பவுண்டரியைத் தேடுகிறது.
2. சஸ்பென்ஸ் பவுண்டரி
<Suspense>
காம்போனென்ட் ப்ராமிஸ்களுக்கான ஒரு பிழை பவுண்டரியாக செயல்படுகிறது. இது ஒரு fallback
ப்ராப்பை எடுக்கிறது, இது அதன் சைல்ட் காம்போனென்ட்கள் (அல்லது அவற்றின் வம்சாவளியினர்) சஸ்பெண்ட் ஆகும்போது (அதாவது, ஒரு ப்ராமிஸை எறியும்போது) ரெண்டர் செய்ய வேண்டிய UI ஆகும். அதன் சப்-ட்ரீக்குள் எறியப்பட்ட அனைத்து ப்ராமிஸ்களும் தீர்க்கப்பட்டவுடன், ஃபால்பேக் உண்மையான உள்ளடக்கத்தால் மாற்றப்படுகிறது.
ஒரு ஒற்றை சஸ்பென்ஸ் பவுண்டரி பல ஒத்திசைவற்ற செயல்பாடுகளை நிர்வகிக்க முடியும். உதாரணமாக, ஒரே <Suspense>
பவுண்டரிக்குள் இரண்டு காம்போனென்ட்கள் இருந்தால், ஒவ்வொன்றும் டேட்டாவை ஃபெட்ச் செய்ய வேண்டும் என்றால், *இரண்டு* டேட்டா ஃபெட்ச்களும் முடியும் வரை ஃபால்பேக் காண்பிக்கப்படும். இது பகுதி UI-ஐக் காண்பிப்பதைத் தவிர்த்து, மேலும் ஒருங்கிணைக்கப்பட்ட லோடிங் அனுபவத்தை வழங்குகிறது.
3. கேச்/ரிசோர்ஸ் மேனேஜர் (பயனர் நிலப் பொறுப்பு)
முக்கியமாக, சஸ்பென்ஸ் தானாக டேட்டா ஃபெட்சிங் அல்லது கேச்சிங்கை கையாளாது. இது வெறும் ஒரு ஒருங்கிணைப்பு பொறிமுறை. சஸ்பென்ஸை டேட்டா ஃபெட்சிங்கிற்காக வேலை செய்ய வைக்க, உங்களுக்கு ஒரு லேயர் தேவை:
- டேட்டா ஃபெட்சைத் தொடங்குவது.
- முடிவை (தீர்க்கப்பட்ட டேட்டா அல்லது நிலுவையில் உள்ள ப்ராமிஸ்) கேச் செய்வது.
- ஒரு ஒத்திசைவான
read()
முறையை வழங்குவது, இது கேச் செய்யப்பட்ட டேட்டாவை உடனடியாகத் திருப்பும் (கிடைத்தால்) அல்லது நிலுவையில் உள்ள ப்ராமிஸை எறியும் (இல்லை என்றால்).
இந்த 'ரிசோர்ஸ் மேனேஜர்' பொதுவாக ஒவ்வொரு ரிசோர்ஸின் நிலையை (நிலுவையில், தீர்க்கப்பட்டது, அல்லது பிழை) சேமிக்க ஒரு எளிய கேச் (எ.கா., ஒரு மேப் அல்லது ஒரு ஆப்ஜெக்ட்) பயன்படுத்தி செயல்படுத்தப்படுகிறது. நீங்கள் இதை விளக்க நோக்கங்களுக்காக கைமுறையாக உருவாக்கலாம் என்றாலும், ஒரு உண்மையான பயன்பாட்டில், நீங்கள் சஸ்பென்ஸுடன் ஒருங்கிணைக்கும் ஒரு வலுவான டேட்டா ஃபெட்சிங் லைப்ரரியைப் பயன்படுத்துவீர்கள்.
4. கன்கரண்ட் மோட் (ரியாக்ட் 18-ன் மேம்பாடுகள்)
சஸ்பென்ஸை ரியாக்ட்டின் பழைய பதிப்புகளில் பயன்படுத்தலாம் என்றாலும், அதன் முழு சக்தி கன்கரண்ட் ரியாக்ட் மூலம் கட்டவிழ்த்து விடப்படுகிறது (ரியாக்ட் 18-ல் createRoot
மூலம் இயல்பாக இயக்கப்படுகிறது). கன்கரண்ட் மோட் ரியாக்ட்டை ரெண்டரிங் வேலையை குறுக்கிட, இடைநிறுத்த, மற்றும் மீண்டும் தொடங்க அனுமதிக்கிறது. இதன் பொருள்:
- தடுக்காத UI புதுப்பிப்புகள்: சஸ்பென்ஸ் ஒரு ஃபால்பேக்கைக் காட்டும்போது, ரியாக்ட் சஸ்பெண்ட் ஆகாத UI-இன் மற்ற பகுதிகளை ரெண்டரிங் செய்வதைத் தொடரலாம், அல்லது பிரதான த்ரெட்டைத் தடுக்காமல் பின்னணியில் புதிய UI-ஐத் தயாரிக்கலாம்.
- டிரான்சிஷன்கள்:
useTransition
போன்ற புதிய API-கள் சில புதுப்பிப்புகளை 'டிரான்சிஷன்கள்' என்று குறிக்க உங்களை அனுமதிக்கின்றன, இவற்றை ரியாக்ட் குறுக்கிட்டு, அவசரமற்றதாக மாற்றலாம், டேட்டா ஃபெட்சிங்கின் போது மென்மையான UI மாற்றங்களை வழங்குகிறது.
சஸ்பென்ஸுடன் கூடிய டேட்டா ஃபெட்சிங் முறைகள்
சஸ்பென்ஸின் வருகையுடன் டேட்டா ஃபெட்சிங் முறைகளின் பரிணாமத்தை ஆராய்வோம்.
முறை 1: ஃபெட்ச்-தென்-ரெண்டர் (சஸ்பென்ஸ் ரேப்பிங்குடன் கூடிய பாரம்பரிய முறை)
இது கிளாசிக் அணுகுமுறை, இதில் டேட்டா ஃபெட்ச் செய்யப்பட்டு, பின்னர் மட்டுமே காம்போனென்ட் ரெண்டர் செய்யப்படுகிறது. டேட்டாவிற்காக 'த்ரோ ப்ராமிஸ்' பொறிமுறையை நேரடியாகப் பயன்படுத்தாவிட்டாலும், *இறுதியில்* டேட்டாவை ரெண்டர் செய்யும் ஒரு காம்போனென்ட்டை ஒரு ஃபால்பேக்கை வழங்க சஸ்பென்ஸ் பவுண்டரியில் ரேப் செய்யலாம். இது சஸ்பென்ஸை ஒரு பொதுவான லோடிங் UI ஒருங்கிணைப்பாளராகப் பயன்படுத்துவதைப் பற்றியது, அதன் உள் டேட்டா ஃபெட்சிங் இன்னும் பாரம்பரிய useEffect
அடிப்படையிலானது என்றாலும் கூட.
import React, { Suspense, useState, useEffect } from 'react';
function UserDetails({ userId }) {
const [user, setUser] = useState(null);
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
const fetchUserData = async () => {
setIsLoading(true);
const res = await fetch(`/api/users/${userId}`);
const data = await res.json();
setUser(data);
setIsLoading(false);
};
fetchUserData();
}, [userId]);
if (isLoading) {
return <p>பயனர் விவரங்கள் ஏற்றப்படுகின்றன...</p>;
}
return (
<div>
<h3>பயனர்: {user.name}</h3>
<p>மின்னஞ்சல்: {user.email}</p>
</div>
);
}
function App() {
return (
<div>
<h1>ஃபெட்ச்-தென்-ரெண்டர் எடுத்துக்காட்டு</h1>
<Suspense fallback={<div>ஒட்டுமொத்த பக்கம் ஏற்றப்படுகிறது...</div>}>
<UserDetails userId={"1"} />
</Suspense>
</div>
);
}
நன்மைகள்: புரிந்துகொள்ள எளிமையானது, பின்தங்கிய இணக்கத்தன்மை கொண்டது. ஒரு குளோபல் லோடிங் ஸ்டேட்டைச் சேர்க்க ஒரு விரைவான வழியாகப் பயன்படுத்தலாம்.
தீமைகள்: UserDetails
-க்குள் இருக்கும் பாய்லர்பிளேட்டை அகற்றாது. காம்போனென்ட்கள் டேட்டாவை வரிசையாக ஃபெட்ச் செய்தால் வாட்டர்ஃபால்களுக்கு இன்னும் வாய்ப்புள்ளது. டேட்டாவிற்காக சஸ்பென்ஸின் 'த்ரோ-அண்ட்-கேட்ச்' பொறிமுறையை உண்மையில் பயன்படுத்தாது.
முறை 2: ரெண்டர்-தென்-ஃபெட்ச் (ரெண்டரின் உள்ளே ஃபெட்சிங், தயாரிப்புக்கு அல்ல)
இந்த முறை முதன்மையாக சஸ்பென்ஸுடன் நேரடியாக என்ன செய்யக் கூடாது என்பதை விளக்குவதற்காக உள்ளது, ஏனெனில் இது கவனமாக கையாளப்படாவிட்டால் முடிவற்ற சுழற்சிகள் அல்லது செயல்திறன் சிக்கல்களுக்கு வழிவகுக்கும். இது ஒரு காம்போனென்ட்டின் ரெண்டர் கட்டத்தில் நேரடியாக டேட்டாவை ஃபெட்ச் செய்ய அல்லது ஒரு சஸ்பெண்ட் செய்யும் செயல்பாட்டை அழைக்க முயற்சிப்பதை உள்ளடக்கியது, *சரியான* கேச்சிங் பொறிமுறை இல்லாமல்.
// சரியான கேச்சிங் லேயர் இல்லாமல் இதை தயாரிப்பில் பயன்படுத்த வேண்டாம்
// இது நேரடி 'throw' கருத்துரீதியாக எப்படி வேலை செய்யக்கூடும் என்பதற்கான ஒரு விளக்கத்திற்காக மட்டுமே.
let fetchedData = null;
let dataPromise = null;
function fetchDataSynchronously(url) {
if (fetchedData) {
return fetchedData;
}
if (!dataPromise) {
dataPromise = fetch(url)
.then(res => res.json())
.then(data => { fetchedData = data; dataPromise = null; return data; })
.catch(err => { dataPromise = null; throw err; });
}
throw dataPromise; // இங்குதான் சஸ்பென்ஸ் செயல்படுகிறது
}
function UserDetailsBadExample({ userId }) {
const user = fetchDataSynchronously(`/api/users/${userId}`);
return (
<div>
<h3>பயனர்: {user.name}</h3>
<p>மின்னஞ்சல்: {user.email}</p>
</div>
);
}
function App() {
return (
<div>
<h1>ரெண்டர்-தென்-ஃபெட்ச் (விளக்கத்திற்காக, நேரடியாகப் பரிந்துரைக்கப்படவில்லை)</h1>
<Suspense fallback={<div>பயனர் ஏற்றப்படுகிறார்...</div>}>
<UserDetailsBadExample userId={"2"} />
</Suspense>
</div>
);
}
நன்மைகள்: ஒரு காம்போனென்ட் எப்படி நேரடியாக டேட்டாவைக் 'கேட்டு', தயாராக இல்லை என்றால் சஸ்பெண்ட் ஆகலாம் என்பதைக் காட்டுகிறது.
தீமைகள்: தயாரிப்புக்கு மிகவும் சிக்கலானது. இந்த கைமுறை, குளோபல் fetchedData
மற்றும் dataPromise
அமைப்பு எளிமையானது, பல கோரிக்கைகள், செல்லாததாக்குதல், அல்லது பிழை நிலைகளை வலுவாகக் கையாளாது. இது 'ப்ராமிஸை-எறி' கருத்தின் ஒரு பழமையான விளக்கம், பின்பற்ற வேண்டிய ஒரு முறை அல்ல.
முறை 3: ஃபெட்ச்-ஆஸ்-யூ-ரெண்டர் (சிறந்த சஸ்பென்ஸ் முறை)
இது சஸ்பென்ஸ் டேட்டா ஃபெட்சிங்கிற்காக உண்மையில் சாத்தியமாக்கும் முன்னுதாரண மாற்றம். ஒரு காம்போனென்ட் அதன் டேட்டாவை ஃபெட்ச் செய்வதற்கு முன்பு ரெண்டர் செய்ய காத்திருப்பதற்குப் பதிலாக, அல்லது எல்லா டேட்டாவையும் முன்பே ஃபெட்ச் செய்வதற்குப் பதிலாக, ஃபெட்ச்-ஆஸ்-யூ-ரெண்டர் என்பது நீங்கள் டேட்டாவை ஃபெட்ச் செய்ய *முடிந்தவரை விரைவில்* தொடங்குவதாகும், பெரும்பாலும் ரெண்டரிங் செயல்முறைக்கு *முன்பு* அல்லது *ஒரே நேரத்தில்*. காம்போனென்ட்கள் பின்னர் டேட்டாவை ஒரு கேச்சிலிருந்து 'படிக்கின்றன', டேட்டா தயாராக இல்லை என்றால், அவை சஸ்பெண்ட் ஆகின்றன. முக்கிய யோசனை டேட்டா ஃபெட்சிங் தர்க்கத்தை காம்போனென்ட்டின் ரெண்டரிங் தர்க்கத்திலிருந்து பிரிப்பதாகும்.
ஃபெட்ச்-ஆஸ்-யூ-ரெண்டரை செயல்படுத்த, உங்களுக்கு ஒரு பொறிமுறை தேவை:
- காம்போனென்ட்டின் ரெண்டர் செயல்பாட்டிற்கு வெளியே ஒரு டேட்டா ஃபெட்சைத் தொடங்குங்கள் (எ.கா., ஒரு ரூட் நுழையும்போது, அல்லது ஒரு பட்டன் கிளிக் செய்யப்படும்போது).
- ப்ராமிஸ் அல்லது தீர்க்கப்பட்ட டேட்டாவை ஒரு கேச்சில் சேமிக்கவும்.
- காம்போனென்ட்கள் இந்த கேச்சிலிருந்து 'படிக்க' ஒரு வழியை வழங்கவும். டேட்டா இன்னும் கிடைக்கவில்லை என்றால், படித்தல் செயல்பாடு நிலுவையில் உள்ள ப்ராமிஸை எறிகிறது.
இந்த முறை வாட்டர்ஃபால் சிக்கலைத் தீர்க்கிறது. இரண்டு வெவ்வேறு காம்போனென்ட்களுக்கு டேட்டா தேவைப்பட்டால், அவற்றின் கோரிக்கைகள் இணையாகத் தொடங்கப்படலாம், மற்றும் UI *இரண்டும்* தயாரானவுடன் மட்டுமே தோன்றும், இது ஒரு ஒற்றை சஸ்பென்ஸ் பவுண்டரியால் ஒருங்கிணைக்கப்படுகிறது.
கைமுறை செயலாக்கம் (புரிதலுக்காக)
அடிப்படை இயக்கவியலைப் புரிந்துகொள்ள, ஒரு எளிமைப்படுத்தப்பட்ட கைமுறை ரிசோர்ஸ் மேனேஜரை உருவாக்குவோம். ஒரு உண்மையான பயன்பாட்டில், நீங்கள் ஒரு பிரத்யேக லைப்ரரியைப் பயன்படுத்துவீர்கள்.
import React, { Suspense } from 'react';
// --- எளிய கேச்/ரிசோர்ஸ் மேனேஜர் --- //
const cache = new Map();
function createResource(promise) {
let status = 'pending';
let result;
let suspender = promise.then(
(r) => {
status = 'success';
result = r;
},
(e) => {
status = 'error';
result = e;
}
);
return {
read() {
if (status === 'pending') {
throw suspender;
} else if (status === 'error') {
throw result;
} else if (status === 'success') {
return result;
}
},
};
}
function fetchData(key, fetcher) {
if (!cache.has(key)) {
cache.set(key, createResource(fetcher()));
}
return cache.get(key);
}
// --- டேட்டா ஃபெட்சிங் செயல்பாடுகள் --- //
const fetchUserById = (id) => {
console.log(`பயனர் ${id}-ஐ ஃபெட்ச் செய்கிறது...`);
return new Promise(resolve => setTimeout(() => {
const users = {
'1': { id: '1', name: 'ஆலிஸ் ஸ்மித்', email: 'alice@example.com' },
'2': { id: '2', name: 'பாப் ஜான்சன்', email: 'bob@example.com' },
'3': { id: '3', name: 'சார்லி பிரவுன்', email: 'charlie@example.com' }
};
resolve(users[id]);
}, 1500));
};
const fetchPostsByUserId = (userId) => {
console.log(`பயனர் ${userId}-க்கான பதிவுகளை ஃபெட்ச் செய்கிறது...`);
return new Promise(resolve => setTimeout(() => {
const posts = {
'1': [{ id: 'p1', title: 'எனது முதல் பதிவு' }, { id: 'p2', title: 'பயண சாகசங்கள்' }],
'2': [{ id: 'p3', title: 'கோடிங் நுண்ணறிவுகள்' }],
'3': [{ id: 'p4', title: 'உலகளாவிய போக்குகள்' }, { id: 'p5', title: 'உள்ளூர் உணவு' }]
};
resolve(posts[userId] || []);
}, 2000));
};
// --- காம்போனென்ட்கள் --- //
function UserProfile({ userId }) {
const userResource = fetchData(`user-${userId}`, () => fetchUserById(userId));
const user = userResource.read(); // பயனர் டேட்டா தயாராக இல்லை என்றால் இது சஸ்பெண்ட் செய்யும்
return (
<div>
<h3>பயனர்: {user.name}</h3>
<p>மின்னஞ்சல்: {user.email}</p>
</div>
);
}
function UserPosts({ userId }) {
const postsResource = fetchData(`posts-${userId}`, () => fetchPostsByUserId(userId));
const posts = postsResource.read(); // போஸ்ட்களின் டேட்டா தயாராக இல்லை என்றால் இது சஸ்பெண்ட் செய்யும்
return (
<div>
<h4>{userId} எழுதிய பதிவுகள்:</h4>
<ul>
{posts.map(post => (
<li key={post.id}>{post.title}</li>
))}
{posts.length === 0 && <li>பதிவுகள் எதுவும் இல்லை.</li>}
</ul>
</div>
);
}
// --- அப்ளிகேஷன் --- //
let initialUserResource = null;
let initialPostsResource = null;
function prefetchDataForUser(userId) {
initialUserResource = fetchData(`user-${userId}`, () => fetchUserById(userId));
initialPostsResource = fetchData(`posts-${userId}`, () => fetchPostsByUserId(userId));
}
// App காம்போனென்ட் ரெண்டர் ஆவதற்கு முன்பே சில டேட்டாவை முன்-பெறுங்கள்
prefetchDataForUser('1');
function App() {
return (
<div>
<h1>சஸ்பென்ஸுடன் ஃபெட்ச்-ஆஸ்-யூ-ரெண்டர்</h1>
<p>இது டேட்டா ஃபெட்சிங் எப்படி இணையாக நடக்கலாம், சஸ்பென்ஸால் ஒருங்கிணைக்கப்படலாம் என்பதைக் காட்டுகிறது.</p>
<Suspense fallback={<div>பயனர் சுயவிவரம் மற்றும் பதிவுகள் ஏற்றப்படுகின்றன...</div>}>
<UserProfile userId={"1"} />
<UserPosts userId={"1"} />
</Suspense>
<h2>மற்றொரு பகுதி</h2>
<Suspense fallback={<div>வேறு பயனர் ஏற்றப்படுகிறார்...</div>}>
<UserProfile userId={"2"} />
</Suspense>
</div>
);
}
இந்த எடுத்துக்காட்டில்:
createResource
மற்றும்fetchData
செயல்பாடுகள் ஒரு அடிப்படை கேச்சிங் பொறிமுறையை அமைக்கின்றன.UserProfile
அல்லதுUserPosts
resource.read()
-ஐ அழைக்கும்போது, அவை உடனடியாக டேட்டாவைப் பெறுகின்றன அல்லது ப்ராமிஸ் எறியப்படுகிறது.- அருகிலுள்ள
<Suspense>
பவுண்டரி ப்ராமிஸ்(களை)ப் பிடித்து அதன் ஃபால்பேக்கைக் காட்டுகிறது. - முக்கியமாக, நாம்
App
காம்போனென்ட் ரெண்டர் ஆவதற்கு *முன்பே*prefetchDataForUser('1')
-ஐ அழைக்கலாம், இது டேட்டா ஃபெட்சிங்கை இன்னும் முன்னதாகவே தொடங்க அனுமதிக்கிறது.
ஃபெட்ச்-ஆஸ்-யூ-ரெண்டருக்கான லைப்ரரிகள்
ஒரு வலுவான ரிசோர்ஸ் மேனேஜரை கைமுறையாக உருவாக்குவதும் பராமரிப்பதும் சிக்கலானது. அதிர்ஷ்டவசமாக, பல முதிர்ந்த டேட்டா ஃபெட்சிங் லைப்ரரிகள் சஸ்பென்ஸை ஏற்றுக்கொண்டுள்ளன அல்லது ஏற்றுக்கொண்டு வருகின்றன, போரில் சோதிக்கப்பட்ட தீர்வுகளை வழங்குகின்றன:
- ரியாக்ட் குவெரி (டான்ஸ்டாக் குவெரி): சஸ்பென்ஸ் ஆதரவுடன் ஒரு சக்திவாய்ந்த டேட்டா ஃபெட்சிங் மற்றும் கேச்சிங் லேயரை வழங்குகிறது. இது
useQuery
போன்ற ஹூக்குகளை வழங்குகிறது, அவை சஸ்பெண்ட் ஆகலாம். இது REST API-களுக்கு சிறந்தது. - SWR (ஸ்டேல்-வைல்-ரிவாலிடேட்): மற்றொரு பிரபலமான மற்றும் இலகுரக டேட்டா ஃபெட்சிங் லைப்ரரி, இது சஸ்பென்ஸை முழுமையாக ஆதரிக்கிறது. REST API-களுக்கு ஏற்றது, இது டேட்டாவை விரைவாக (ஸ்டேல்) வழங்குவதிலும் பின்னர் பின்னணியில் அதை மறுமதிப்பீடு செய்வதிலும் கவனம் செலுத்துகிறது.
- அப்போலோ கிளையண்ட்: ஒரு விரிவான கிராஃப்QL கிளையண்ட், இது கிராஃப்QL குவெரிகள் மற்றும் மியூட்டேஷன்களுக்கு வலுவான சஸ்பென்ஸ் ஒருங்கிணைப்பைக் கொண்டுள்ளது.
- ரிலே: பேஸ்புக்கின் சொந்த கிராஃப்QL கிளையண்ட், சஸ்பென்ஸ் மற்றும் கன்கரண்ட் ரியாக்ட்டிற்காக ஆரம்பத்திலிருந்தே வடிவமைக்கப்பட்டது. இதற்கு ஒரு குறிப்பிட்ட கிராஃப்QL ஸ்கீமா மற்றும் தொகுப்பு படி தேவைப்படுகிறது, ஆனால் ஒப்பற்ற செயல்திறன் மற்றும் டேட்டா நிலைத்தன்மையை வழங்குகிறது.
- Urql: சஸ்பென்ஸ் ஆதரவுடன் ஒரு இலகுரக மற்றும் மிகவும் தனிப்பயனாக்கக்கூடிய கிராஃப்QL கிளையண்ட்.
இந்த லைப்ரரிகள் ரிசோர்ஸ்களை உருவாக்குதல் மற்றும் நிர்வகித்தல், கேச்சிங், மறுமதிப்பீடு, ஆப்டிமிஸ்டிக் புதுப்பிப்புகள், மற்றும் பிழை கையாளுதல் ஆகியவற்றின் சிக்கல்களை சுருக்கி, ஃபெட்ச்-ஆஸ்-யூ-ரெண்டரை செயல்படுத்துவதை மிகவும் எளிதாக்குகின்றன.
முறை 4: சஸ்பென்ஸ்-அறிந்த லைப்ரரிகளுடன் ப்ரீஃபெட்சிங்
ப்ரீஃபெட்சிங் என்பது ஒரு சக்திவாய்ந்த மேம்படுத்தலாகும், இதில் நீங்கள் ஒரு பயனர் எதிர்காலத்தில் தேவைப்படக்கூடிய டேட்டாவை, அவர்கள் அதை வெளிப்படையாகக் கோருவதற்கு முன்பே முன்கூட்டியே ஃபெட்ச் செய்கிறீர்கள். இது உணரப்பட்ட செயல்திறனை வியத்தகு முறையில் மேம்படுத்தலாம்.
சஸ்பென்ஸ்-அறிந்த லைப்ரரிகளுடன், ப்ரீஃபெட்சிங் தடையின்றி ஆகிறது. ஒரு இணைப்பு மீது ஹோவர் செய்வது அல்லது ஒரு பட்டன் மீது மவுஸை வைப்பது போன்ற, UI-ஐ உடனடியாக மாற்றாத பயனர் தொடர்புகளில் நீங்கள் டேட்டா ஃபெட்ச்களைத் தூண்டலாம்.
import React, { Suspense } from 'react';
import { QueryClient, QueryClientProvider, useQuery } from '@tanstack/react-query';
// இவை உங்கள் API அழைப்புகள் என்று வைத்துக்கொள்ளுங்கள்
const fetchProductById = async (id) => {
console.log(`தயாரிப்பு ${id}-ஐ ஃபெட்ச் செய்கிறது...`);
return new Promise(resolve => setTimeout(() => {
const products = {
'A001': { id: 'A001', name: 'குளோபல் விட்ஜெட் எக்ஸ்', price: 29.99, description: 'சர்வதேச பயன்பாட்டிற்கான ஒரு பல்துறை விட்ஜெட்.' },
'B002': { id: 'B002', name: 'யுனிவர்சல் கேட்ஜெட் ஒய்', price: 149.99, description: 'முன்னணி கேட்ஜெட், உலகளவில் விரும்பப்படுகிறது.' },
};
resolve(products[id]);
}, 1000));
};
const queryClient = new QueryClient({
defaultOptions: {
queries: {
suspense: true, // எல்லா குவெரிகளுக்கும் சஸ்பென்ஸை இயல்பாக இயக்குங்கள்
},
},
});
function ProductDetails({ productId }) {
const { data: product } = useQuery({
queryKey: ['product', productId],
queryFn: () => fetchProductById(productId),
});
return (
<div style={{"border": "1px solid #ccc", "padding": "15px", "margin": "10px 0"}}>
<h3>{product.name}</h3>
<p>விலை: ${product.price.toFixed(2)}</p>
<p>{product.description}</p>
</div>
);
}
function ProductList() {
const handleProductHover = (productId) => {
// பயனர் ஒரு தயாரிப்பு இணைப்பின் மீது ஹோவர் செய்யும்போது டேட்டாவை முன்-பெறுங்கள்
queryClient.prefetchQuery({
queryKey: ['product', productId],
queryFn: () => fetchProductById(productId),
});
console.log(`தயாரிப்பு ${productId}-ஐ முன்-பெறுகிறது`);
};
return (
<div>
<h2>கிடைக்கும் தயாரிப்புகள்:</h2>
<ul>
<li>
<a href="#" onMouseEnter={() => handleProductHover('A001')}
onClick={(e) => { e.preventDefault(); /* வழிநடத்துங்கள் அல்லது விவரங்களைக் காட்டுங்கள் */ }}
>குளோபல் விட்ஜெட் எக்ஸ் (A001)</a>
</li>
<li>
<a href="#" onMouseEnter={() => handleProductHover('B002')}
onClick={(e) => { e.preventDefault(); /* வழிநடத்துங்கள் அல்லது விவரங்களைக் காட்டுங்கள் */ }}
>யுனிவர்சல் கேட்ஜெட் ஒய் (B002)</a>
</li>
</ul>
<p>ப்ரீஃபெட்சிங் செயல்பாட்டைக் காண ஒரு தயாரிப்பு இணைப்பின் மீது ஹோவர் செய்யுங்கள். நெட்வொர்க் ட్యాபைத் திறந்து கவனிக்கவும்.</p>
</div>
);
}
function App() {
const [showProductA, setShowProductA] = React.useState(false);
const [showProductB, setShowProductB] = React.useState(false);
return (
<QueryClientProvider client={queryClient}>
<h1>ரியாக்ட் சஸ்பென்ஸுடன் ப்ரீஃபெட்சிங் (ரியாக்ட் குவெரி)</h1>
<ProductList />
<button onClick={() => setShowProductA(true)}>குளோபல் விட்ஜெட் எக்ஸ்-ஐக் காட்டு</button>
<button onClick={() => setShowProductB(true)}>யுனிவர்சல் கேட்ஜெட் ஒய்-ஐக் காட்டு</button>
{showProductA && (
<Suspense fallback={<p>குளோபல் விட்ஜெட் எக்ஸ் ஏற்றப்படுகிறது...</p>}>
<ProductDetails productId="A001" />
</Suspense>
)}
{showProductB && (
<Suspense fallback={<p>யுனிவர்சல் கேட்ஜெட் ஒய் ஏற்றப்படுகிறது...</p>}>
<ProductDetails productId="B002" />
</Suspense>
)}
</QueryClientProvider>
);
}
இந்த எடுத்துக்காட்டில், ஒரு தயாரிப்பு இணைப்பின் மீது ஹோவர் செய்வது `queryClient.prefetchQuery`-ஐத் தூண்டுகிறது, இது பின்னணியில் டேட்டா ஃபெட்சைத் தொடங்குகிறது. பயனர் பின்னர் தயாரிப்பு விவரங்களைக் காட்ட பட்டனைக் கிளிக் செய்தால், ப்ரீஃபெட்சிலிருந்து டேட்டா ஏற்கனவே கேச்சில் இருந்தால், காம்போனென்ட் சஸ்பெண்ட் ஆகாமல் உடனடியாக ரெண்டர் ஆகும். ப்ரீஃபெட்ச் இன்னும் செயல்பாட்டில் இருந்தால் அல்லது தொடங்கப்படவில்லை என்றால், டேட்டா தயாராகும் வரை சஸ்பென்ஸ் ஃபால்பேக்கைக் காண்பிக்கும்.
சஸ்பென்ஸ் மற்றும் பிழை பவுண்டரிகளுடன் பிழை கையாளுதல்
சஸ்பென்ஸ் 'லோடிங்' நிலையை ஒரு ஃபால்பேக்கைக் காண்பிப்பதன் மூலம் கையாளுகிறது என்றாலும், அது 'பிழை' நிலைகளை நேரடியாகக் கையாளாது. ஒரு சஸ்பெண்ட் செய்யும் காம்போனென்ட்டால் எறியப்பட்ட ப்ராமிஸ் நிராகரிக்கப்பட்டால் (அதாவது, டேட்டா ஃபெட்சிங் தோல்வியுற்றால்), இந்த பிழை காம்போனென்ட் ட்ரீயில் மேல்நோக்கிப் பரவும். இந்த பிழைகளை நளினமாகக் கையாண்டு, பொருத்தமான UI-ஐக் காட்ட, நீங்கள் பிழை பவுண்டரிகளை பயன்படுத்த வேண்டும்.
ஒரு பிழை பவுண்டரி என்பது ஒரு ரியாக்ட் காம்போனென்ட் ஆகும், இது componentDidCatch
அல்லது static getDerivedStateFromError
லைஃப்சைக்கிள் முறைகளை செயல்படுத்துகிறது. இது அதன் சைல்ட் காம்போனென்ட் ட்ரீயில் எங்கும் ஜாவாஸ்கிரிப்ட் பிழைகளைப் பிடிக்கிறது, இதில் சஸ்பென்ஸ் பொதுவாகப் பிடிக்கும் ப்ராமிஸ்களால் எறியப்பட்ட பிழைகளும் அடங்கும்.
import React, { Suspense, useState } from 'react';
import { QueryClient, QueryClientProvider, useQuery } from '@tanstack/react-query';
// --- பிழை பவுண்டரி காம்போனென்ட் --- //
class MyErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false, error: null };
}
static getDerivedStateFromError(error) {
// அடுத்த ரெண்டர் ஃபால்பேக் UI-ஐக் காண்பிக்கும் வகையில் நிலையை புதுப்பிக்கவும்.
return { hasError: true, error };
}
componentDidCatch(error, errorInfo) {
// நீங்கள் ஒரு பிழை அறிக்கை சேவைக்கு பிழையை பதிவு செய்யலாம்
console.error("ஒரு பிழை பிடிபட்டது:", error, errorInfo);
}
render() {
if (this.state.hasError) {
// நீங்கள் எந்தவொரு தனிப்பயன் ஃபால்பேக் UI-ஐயும் ரெண்டர் செய்யலாம்
return (
<div style={{"border": "2px solid red", "padding": "20px", "margin": "20px 0", "background": "#ffe0e0"}}>
<h2>ஏதோ தவறு நடந்துவிட்டது!</h2>
<p>{this.state.error && this.state.error.message}</p>
<p>தயவுசெய்து பக்கத்தை புதுப்பிக்க முயற்சிக்கவும் அல்லது ஆதரவைத் தொடர்பு கொள்ளவும்.</p>
<button onClick={() => this.setState({ hasError: false, error: null })}>மீண்டும் முயற்சிக்கவும்</button>
</div>
);
}
return this.props.children;
}
}
// --- டேட்டா ஃபெட்சிங் (பிழைக்கான வாய்ப்புடன்) --- //
const fetchItemById = async (id) => {
console.log(`பொருள் ${id}-ஐ ஃபெட்ச் செய்ய முயற்சிக்கிறது...`);
return new Promise((resolve, reject) => setTimeout(() => {
if (id === 'error-item') {
reject(new Error('பொருளை ஏற்ற முடியவில்லை: நெட்வொர்க் அணுக முடியாதது அல்லது பொருள் காணப்படவில்லை.'));
} else if (id === 'slow-item') {
resolve({ id: 'slow-item', name: 'மெதுவாக வழங்கப்பட்டது', data: 'இந்த பொருள் சிறிது நேரம் எடுத்தது ஆனால் வந்துவிட்டது!', status: 'success' });
} else {
resolve({ id, name: `பொருள் ${id}`, data: `பொருள் ${id}-க்கான டேட்டா` });
}
}, id === 'slow-item' ? 3000 : 800));
};
const queryClient = new QueryClient({
defaultOptions: {
queries: {
suspense: true,
retry: false, // விளக்கத்திற்காக, மறுமுயற்சியை முடக்கவும், அதனால் பிழை உடனடியாக வரும்
},
},
});
function DisplayItem({ itemId }) {
const { data: item } = useQuery({
queryKey: ['item', itemId],
queryFn: () => fetchItemById(itemId),
});
return (
<div>
<h3>பொருள் விவரங்கள்:</h3>
<p>ஐடி: {item.id}</p>
<p>பெயர்: {item.name}</p>
<p>டேட்டா: {item.data}</p>
</div>
);
}
function App() {
const [fetchType, setFetchType] = useState('normal-item');
return (
<QueryClientProvider client={queryClient}>
<h1>சஸ்பென்ஸ் மற்றும் பிழை பவுண்டரிகள்</h1>
<div>
<button onClick={() => setFetchType('normal-item')}>சாதாரண பொருளை ஃபெட்ச் செய்</button>
<button onClick={() => setFetchType('slow-item')}>மெதுவான பொருளை ஃபெட்ச் செய்</button>
<button onClick={() => setFetchType('error-item')}>பிழைப் பொருளை ஃபெட்ச் செய்</button>
</div>
<MyErrorBoundary>
<Suspense fallback={<p>சஸ்பென்ஸ் வழியாக பொருள் ஏற்றப்படுகிறது...</p>}>
<DisplayItem itemId={fetchType} />
</Suspense>
</MyErrorBoundary>
</QueryClientProvider>
);
}
உங்கள் சஸ்பென்ஸ் பவுண்டரியை (அல்லது சஸ்பெண்ட் ஆகக்கூடிய காம்போனென்ட்களை) ஒரு பிழை பவுண்டரியுடன் ரேப் செய்வதன் மூலம், டேட்டா ஃபெட்சிங்கின் போது ஏற்படும் நெட்வொர்க் தோல்விகள் அல்லது சர்வர் பிழைகள் பிடிக்கப்பட்டு, நளினமாகக் கையாளப்படுவதை உறுதிசெய்கிறீர்கள், இது முழு பயன்பாடும் செயலிழப்பதைத் தடுக்கிறது. இது ஒரு வலுவான மற்றும் பயனர் நட்பு அனுபவத்தை வழங்குகிறது, பயனர்கள் சிக்கலைப் புரிந்துகொண்டு, மீண்டும் முயற்சிக்க அனுமதிக்கிறது.
சஸ்பென்ஸுடன் ஸ்டேட் மேலாண்மை மற்றும் டேட்டா செல்லாததாக்குதல்
ரியாக்ட் சஸ்பென்ஸ் முதன்மையாக ஒத்திசைவற்ற ரிசோர்ஸ்களின் ஆரம்ப லோடிங் நிலையை மட்டுமே கையாளுகிறது என்பதைத் தெளிவுபடுத்துவது முக்கியம். இது கிளையண்ட்-சைட் கேச்சை நிர்வகிப்பதில்லை, டேட்டா செல்லாததாக்குதலைக் கையாள்வதில்லை, அல்லது மியூட்டேஷன்கள் (உருவாக்கு, புதுப்பி, நீக்கு செயல்பாடுகள்) மற்றும் அவற்றின் தொடர்ச்சியான UI புதுப்பிப்புகளை ஒருங்கிணைப்பதில்லை.
இங்குதான் சஸ்பென்ஸ்-அறிந்த டேட்டா ஃபெட்சிங் லைப்ரரிகள் (ரியாக்ட் குவெரி, SWR, அப்போலோ கிளையண்ட், ரிலே) இன்றியமையாததாகின்றன. அவை சஸ்பென்ஸை பூர்த்தி செய்கின்றன:
- வலுவான கேச்சிங்: அவை ஃபெட்ச் செய்யப்பட்ட டேட்டாவின் ஒரு அதிநவீன இன்-மெமரி கேச்சை பராமரிக்கின்றன, கிடைத்தால் உடனடியாக அதை வழங்குகின்றன, மற்றும் பின்னணி மறுமதிப்பீட்டைக் கையாளுகின்றன.
- டேட்டா செல்லாததாக்குதல் மற்றும் ரீஃபெட்சிங்: அவை கேச் செய்யப்பட்ட டேட்டாவை 'ஸ்டேல்' என்று குறிக்க மற்றும் அதை ரீஃபெட்ச் செய்ய (எ.கா., ஒரு மியூட்டேஷனுக்குப் பிறகு, ஒரு பயனர் தொடர்புக்குப் பிறகு, அல்லது விண்டோ ஃபோகஸில்) பொறிமுறைகளை வழங்குகின்றன.
- ஆப்டிமிஸ்டிக் புதுப்பிப்புகள்: மியூட்டேஷன்களுக்கு, அவை ஒரு API அழைப்பின் எதிர்பார்க்கப்படும் முடிவின் அடிப்படையில் UI-ஐ உடனடியாக (ஆப்டிமிஸ்டிக்காக) புதுப்பிக்க உங்களை அனுமதிக்கின்றன, பின்னர் உண்மையான API அழைப்பு தோல்வியுற்றால் திரும்பப் பெறுகின்றன.
- குளோபல் ஸ்டேட் ஒத்திசைவு: உங்கள் பயன்பாட்டின் ஒரு பகுதியிலிருந்து டேட்டா மாறினால், அந்த டேட்டாவைக் காண்பிக்கும் அனைத்து காம்போனென்ட்களும் தானாகவே புதுப்பிக்கப்படுவதை அவை உறுதிசெய்கின்றன.
- மியூட்டேஷன்களுக்கான லோடிங் மற்றும் பிழை நிலைகள்:
useQuery
சஸ்பெண்ட் ஆகலாம் என்றாலும்,useMutation
பொதுவாக மியூட்டேஷன் செயல்முறைக்குisLoading
மற்றும்isError
நிலைகளை வழங்குகிறது, ஏனெனில் மியூட்டேஷன்கள் பெரும்பாலும் ஊடாடும் மற்றும் உடனடி பின்னூட்டம் தேவைப்படும்.
ஒரு வலுவான டேட்டா ஃபெட்சிங் லைப்ரரி இல்லாமல், இந்த அம்சங்களை ஒரு கைமுறை சஸ்பென்ஸ் ரிசோர்ஸ் மேனேஜரின் மேல் செயல்படுத்துவது ஒரு குறிப்பிடத்தக்க முயற்சியாக இருக்கும், அடிப்படையில் உங்கள் சொந்த டேட்டா ஃபெட்சிங் கட்டமைப்பை உருவாக்க வேண்டியிருக்கும்.
நடைமுறைப் பரிசீலனைகள் மற்றும் சிறந்த நடைமுறைகள்
டேட்டா ஃபெட்சிங்கிற்காக சஸ்பென்ஸை ஏற்றுக்கொள்வது ஒரு குறிப்பிடத்தக்க கட்டடக்கலை முடிவு. ஒரு உலகளாவிய பயன்பாட்டிற்கான சில நடைமுறைப் பரிசீலனைகள் இங்கே:
1. எல்லா டேட்டாவிற்கும் சஸ்பென்ஸ் தேவையில்லை
சஸ்பென்ஸ் ஒரு காம்போனென்ட்டின் ஆரம்ப ரெண்டரிங்கில் நேரடியாக பாதிக்கும் முக்கியமான டேட்டாவிற்கு ஏற்றது. முக்கியமற்ற டேட்டா, பின்னணி ஃபெட்ச்கள், அல்லது வலுவான காட்சி தாக்கம் இல்லாமல் சோம்பேறித்தனமாக ஏற்றக்கூடிய டேட்டாவிற்கு, பாரம்பரிய useEffect
அல்லது ப்ரீ-ரெண்டரிங் இன்னும் பொருத்தமானதாக இருக்கலாம். சஸ்பென்ஸின் அதிகப்படியான பயன்பாடு ஒரு குறைவான நுணுக்கமான லோடிங் அனுபவத்திற்கு வழிவகுக்கும், ஏனெனில் ஒரு ஒற்றை சஸ்பென்ஸ் பவுண்டரி அதன் *அனைத்து* சைல்ட் காம்போனென்ட்களும் தீர்க்கப்படும் வரை காத்திருக்கும்.
2. சஸ்பென்ஸ் பவுண்டரிகளின் நுணுக்கம்
உங்கள் <Suspense>
பவுண்டரிகளை சிந்தனையுடன் வைக்கவும். உங்கள் பயன்பாட்டின் உச்சியில் ஒரு ஒற்றை, பெரிய பவுண்டரி முழு பக்கத்தையும் ஒரு ஸ்பின்னரின் பின்னால் மறைக்கக்கூடும், இது வெறுப்பூட்டக்கூடும். சிறிய, மிகவும் நுணுக்கமான பவுண்டரிகள் உங்கள் பக்கத்தின் வெவ்வேறு பகுதிகள் சுயாதீனமாக ஏற்ற அனுமதிக்கின்றன, இது ஒரு மேலும் முற்போக்கான மற்றும் பதிலளிக்கக்கூடிய அனுபவத்தை வழங்குகிறது. உதாரணமாக, ஒரு பயனர் சுயவிவர காம்போனென்ட்டைச் சுற்றி ஒரு பவுண்டரி, மற்றும் பரிந்துரைக்கப்பட்ட தயாரிப்புகளின் பட்டியலைச் சுற்றி மற்றொரு பவுண்டரி.
<div>
<h1>தயாரிப்பு பக்கம்</h1>
<Suspense fallback={<p>முக்கிய தயாரிப்பு விவரங்கள் ஏற்றப்படுகின்றன...</p>}>
<ProductDetails id="prod123" />
</Suspense>
<hr />
<h2>தொடர்புடைய தயாரிப்புகள்</h2>
<Suspense fallback={<p>தொடர்புடைய தயாரிப்புகள் ஏற்றப்படுகின்றன...</p>}>
<RelatedProducts category="electronics" />
</Suspense>
</div>
இந்த அணுகுமுறை, தொடர்புடைய தயாரிப்புகள் இன்னும் ஏற்றப்பட்டாலும் கூட பயனர்கள் முக்கிய தயாரிப்பு விவரங்களைக் காண முடியும் என்பதைக் குறிக்கிறது.
3. சர்வர்-சைட் ரெண்டரிங் (SSR) மற்றும் ஸ்ட்ரீமிங் HTML
ரியாக்ட் 18-ன் புதிய ஸ்ட்ரீமிங் SSR API-கள் (renderToPipeableStream
) சஸ்பென்ஸுடன் முழுமையாக ஒருங்கிணைக்கப்பட்டுள்ளன. இது உங்கள் சர்வர் HTML-ஐ அது தயாரானவுடன் அனுப்ப அனுமதிக்கிறது, பக்கத்தின் பகுதிகள் (டேட்டா-சார்ந்த காம்போனென்ட்கள் போன்றவை) இன்னும் ஏற்றப்பட்டாலும் கூட. சர்வர் ஒரு ப்ளேஸ்ஹோல்டரை (சஸ்பென்ஸ் ஃபால்பேக்கிலிருந்து) ஸ்ட்ரீம் செய்யலாம், பின்னர் டேட்டா தீர்க்கப்படும்போது உண்மையான உள்ளடக்கத்தை ஸ்ட்ரீம் செய்யலாம், ஒரு முழு கிளையண்ட்-சைட் ரீ-ரெண்டர் தேவையில்லாமல். இது மாறுபட்ட நெட்வொர்க் நிலைமைகளில் உள்ள உலகளாவிய பயனர்களுக்கு உணரப்பட்ட லோடிங் செயல்திறனை கணிசமாக மேம்படுத்துகிறது.
4. படிப்படியான தழுவல்
சஸ்பென்ஸைப் பயன்படுத்த உங்கள் முழு பயன்பாட்டையும் மீண்டும் எழுத வேண்டியதில்லை. நீங்கள் அதை படிப்படியாக அறிமுகப்படுத்தலாம், அதன் டிக்ளரேடிவ் லோடிங் முறைகளிலிருந்து அதிகம் பயனடையும் புதிய அம்சங்கள் அல்லது காம்போனென்ட்களிலிருந்து தொடங்கலாம்.
5. கருவிகள் மற்றும் பிழைதிருத்தம்
சஸ்பென்ஸ் காம்போனென்ட் தர்க்கத்தை எளிமைப்படுத்தினாலும், பிழைதிருத்தம் வித்தியாசமாக இருக்கலாம். ரியாக்ட் டெவ்டூல்ஸ் சஸ்பென்ஸ் பவுண்டரிகள் மற்றும் அவற்றின் நிலைகள் பற்றிய நுண்ணறிவுகளை வழங்குகிறது. நீங்கள் தேர்ந்தெடுத்த டேட்டா ஃபெட்சிங் லைப்ரரி அதன் உள் நிலையை எப்படி வெளிப்படுத்துகிறது என்பதைப் பற்றி அறிந்து கொள்ளுங்கள் (எ.கா., ரியாக்ட் குவெரி டெவ்டூல்ஸ்).
6. சஸ்பென்ஸ் ஃபால்பேக்களுக்கான காலக்கெடு
மிக நீண்ட லோடிங் நேரங்களுக்கு, உங்கள் சஸ்பென்ஸ் ஃபால்பேக்கிற்கு ஒரு காலக்கெடுவை அறிமுகப்படுத்த விரும்பலாம், அல்லது ஒரு குறிப்பிட்ட தாமதத்திற்குப் பிறகு ஒரு விரிவான லோடிங் இண்டிகேட்டருக்கு மாறலாம். ரியாக்ட் 18-ல் உள்ள useDeferredValue
மற்றும் useTransition
ஹூக்குகள் இந்த மிகவும் நுணுக்கமான லோடிங் நிலைகளை நிர்வகிக்க உதவலாம், புதிய டேட்டா ஃபெட்ச் செய்யப்படும்போது UI-இன் 'பழைய' பதிப்பைக் காட்ட அல்லது அவசரமற்ற புதுப்பிப்புகளை ஒத்திவைக்க உங்களை அனுமதிக்கிறது.
ரியாக்டில் டேட்டா ஃபெட்சிங்கின் எதிர்காலம்: ரியாக்ட் சர்வர் காம்போனென்ட்கள் மற்றும் அதற்கு அப்பால்
ரியாக்டில் டேட்டா ஃபெட்சிங்கின் பயணம் கிளையண்ட்-சைட் சஸ்பென்ஸுடன் முடிவடையாது. ரியாக்ட் சர்வர் காம்போனென்ட்கள் (RSC) ஒரு குறிப்பிடத்தக்க பரிணாமத்தைக் குறிக்கின்றன, இது கிளையண்ட் மற்றும் சர்வர் இடையேயான கோடுகளை மங்கச் செய்து, டேட்டா ஃபெட்சிங்கை மேலும் மேம்படுத்தும் என்று உறுதியளிக்கிறது.
- ரியாக்ட் சர்வர் காம்போனென்ட்கள் (RSC): இந்த காம்போனென்ட்கள் சர்வரில் ரெண்டர் ஆகின்றன, அவற்றின் டேட்டாவை நேரடியாக ஃபெட்ச் செய்கின்றன, பின்னர் தேவையான HTML மற்றும் கிளையண்ட்-சைட் ஜாவாஸ்கிரிப்டை மட்டுமே பிரவுசருக்கு அனுப்புகின்றன. இது கிளையண்ட்-சைட் வாட்டர்ஃபால்களை நீக்குகிறது, பண்டில் அளவுகளைக் குறைக்கிறது, மற்றும் ஆரம்ப சுமை செயல்திறனை மேம்படுத்துகிறது. RSC-கள் சஸ்பென்ஸுடன் கைகோர்த்து வேலை செய்கின்றன: சர்வர் காம்போனென்ட்கள் அவற்றின் டேட்டா தயாராக இல்லை என்றால் சஸ்பெண்ட் ஆகலாம், மற்றும் சர்வர் ஒரு சஸ்பென்ஸ் ஃபால்பேக்கை கிளையண்டிற்கு ஸ்ட்ரீம் செய்யலாம், இது டேட்டா தீர்க்கப்படும்போது மாற்றப்படுகிறது. இது சிக்கலான டேட்டா தேவைகளைக் கொண்ட பயன்பாடுகளுக்கு ஒரு கேம்-சேஞ்சர், இது ஒரு தடையற்ற மற்றும் அதிக செயல்திறன் மிக்க அனுபவத்தை வழங்குகிறது, குறிப்பாக வெவ்வேறு புவியியல் பகுதிகளில் மாறுபட்ட லேட்டன்சியுடன் உள்ள பயனர்களுக்கு நன்மை பயக்கும்.
- ஒருங்கிணைந்த டேட்டா ஃபெட்சிங்: ரியாக்ட்டிற்கான நீண்டகால பார்வை ஒரு ஒருங்கிணைந்த டேட்டா ஃபெட்சிங் அணுகுமுறையை உள்ளடக்கியது, அங்கு முக்கிய கட்டமைப்பு அல்லது நெருக்கமாக ஒருங்கிணைக்கப்பட்ட தீர்வுகள் சர்வர் மற்றும் கிளையண்ட் இரண்டிலும் டேட்டாவை ஏற்றுவதற்கு முதல்-தர ஆதரவை வழங்குகின்றன, அனைத்தும் சஸ்பென்ஸால் ஒருங்கிணைக்கப்படுகின்றன.
- தொடர்ச்சியான லைப்ரரி பரிணாமம்: டேட்டா ஃபெட்சிங் லைப்ரரிகள் தொடர்ந்து உருவாகும், கேச்சிங், செல்லாததாக்குதல், மற்றும் நிகழ்நேர புதுப்பிப்புகளுக்கு இன்னும் அதிநவீன அம்சங்களை வழங்கும், சஸ்பென்ஸின் அடிப்படை திறன்களின் மீது கட்டமைக்கப்படும்.
ரியாக்ட் தொடர்ந்து முதிர்ச்சியடையும்போது, சஸ்பென்ஸ் அதிக செயல்திறன் மிக்க, பயனர் நட்பு, மற்றும் பராமரிக்கக்கூடிய பயன்பாடுகளை உருவாக்குவதற்கான புதிரின் ஒரு மையப் பகுதியாக இருக்கும். இது டெவலப்பர்களை ஒரு மிகவும் டிக்ளரேடிவ் மற்றும் மீள்திறன் கொண்ட வழியில் ஒத்திசைவற்ற செயல்பாடுகளைக் கையாளத் தள்ளுகிறது, சிக்கலை தனிப்பட்ட காம்போனென்ட்களிலிருந்து ஒரு நன்கு நிர்வகிக்கப்பட்ட டேட்டா லேயருக்கு நகர்த்துகிறது.
முடிவுரை
ரியாக்ட் சஸ்பென்ஸ், ஆரம்பத்தில் கோட் ஸ்ப்ளிட்டிங்கிற்கான ஒரு அம்சமாக இருந்தது, டேட்டா ஃபெட்சிங்கிற்கான ஒரு மாற்றும் கருவியாக மலர்ந்துள்ளது. ஃபெட்ச்-ஆஸ்-யூ-ரெண்டர் முறையை ஏற்றுக்கொண்டு, சஸ்பென்ஸ்-அறிந்த லைப்ரரிகளைப் பயன்படுத்துவதன் மூலம், டெவலப்பர்கள் தங்கள் பயன்பாடுகளின் பயனர் அனுபவத்தை கணிசமாக மேம்படுத்தலாம், லோடிங் வாட்டர்ஃபால்களை நீக்கி, காம்போனென்ட் தர்க்கத்தை எளிமைப்படுத்தி, மென்மையான, ஒருங்கிணைக்கப்பட்ட லோடிங் நிலைகளை வழங்கலாம். வலுவான பிழை கையாளுதலுக்கான பிழை பவுண்டரிகள் மற்றும் ரியாக்ட் சர்வர் காம்போனென்ட்களின் எதிர்கால வாக்குறுதியுடன் இணைந்து, சஸ்பென்ஸ் செயல்திறன் மிக்க மற்றும் மீள்திறன் கொண்டவை மட்டுமல்லாமல், உலகெங்கிலும் உள்ள பயனர்களுக்கு இயல்பாகவே மிகவும் மகிழ்ச்சிகரமான பயன்பாடுகளை உருவாக்க எங்களுக்கு அதிகாரம் அளிக்கிறது. சஸ்பென்ஸ்-இயக்கப்படும் டேட்டா ஃபெட்சிங் முன்னுதாரணத்திற்கு மாறுவதற்கு ஒரு கருத்தியல் சரிசெய்தல் தேவைப்படுகிறது, ஆனால் குறியீடு தெளிவு, செயல்திறன் மற்றும் பயனர் திருப்தி ஆகியவற்றின் அடிப்படையில் கிடைக்கும் நன்மைகள் கணிசமானவை மற்றும் முதலீட்டிற்கு தகுதியானவை.