చాలా ఫ్రంటెండ్ కోడ్ అసింక్రోనస్ (asynchronous) పనులను ఒకే రకమైనదిగా పరిగణిస్తుంది. మీరు ఒక Promise ని ప్రారంభిస్తారు, అది resolve అయ్యే వరకు వేచి ఉంటారు, ఫలితాన్ని లోకల్ స్టేట్ (local state) లోకి పంపిస్తారు, మరియు ఫ్రేమ్‌వర్క్ ఆ మార్పులను (diff) రీకన్సైల్ (reconcile) చేసేలా వదిలేస్తారు. ఈ పద్ధతి చాలా ఆకర్షణీయంగా అనిపిస్తుంది ఎందుకంటే ఇది అన్ని చోట్లా పనిచేస్తుంది: ఒక REST call, ఫారమ్ సబ్మిషన్, లేదా WebSocket message. ఇవన్నీ ఒకే useEffect లేదా ఈవెంట్ హ్యాండ్లర్‌లో వచ్చి చేరుతాయి, అన్నీ setState ద్వారా ప్రాసెస్ చేయబడతాయి, మరియు అన్నీ ఒకేలాంటి async ప్లాంబింగ్ లాగా కనిపిస్తాయి. ఈ ఏకరీతితనం (uniformity) ఒక ఉచ్చు. నిజమైన అప్లికేషన్‌లో, అన్ని అసింక్రోనస్ పనులు ఒకేలా ఉండవు. అలా ఉన్నట్లు నటించడం వల్ల మీ UI కాంపోనెంట్లు అనుకోకుండా డేటా ఆర్కిటెక్ట్‌లుగా మారిపోతాయి, ఇవి useEffect హుక్స్ మరియు అదృష్టం మీద ఆధారపడి అతుక్కుపోయి ఉంటాయి.

అసింక్రోనస్ ఆపరేషన్లు నిజానికి మూడు వేర్వేరు రకాలుగా విభజించబడతాయి. ఒక్కొక్కదానికి సమయం (time), క్యాషింగ్ (caching), మరియు ఓనర్‌షిప్ (ownership) తో వేర్వేరు సంబంధాలు ఉంటాయి. వాటిని గుర్తించడం నేర్చుకోవడమే ఫ్రంటెండ్ వేగంగా, కరెక్ట్‌గా మరియు స్థిరంగా ఉండటానికి సహాయపడుతుంది.

Queries: ఒక అడ్రస్ ఉన్న వాస్తవాలు

క్వెరీ (query) అనేది కేవలం ఒక fetch మాత్రమే కాదు. అది ఒక గుర్తించదగిన వాస్తవం కోసం చేసే అభ్యర్థన. మీరు /user/123 కోసం అడుగుతున్నారు, "ఏదో ఒక యూజర్ డేటా" కోసం కాదు. ఈ తేడా చాలా ముఖ్యం ఎందుకంటే ఐడెంటిటీ (identity) మాత్రమే క్యాషింగ్‌ను సాధ్యం చేస్తుంది. ఒకే స్క్రీన్‌పై ఉన్న రెండు కాంపోనెంట్లకు ఒకే యూజర్ రికార్డు అవసరమైతే, అవి ఒకే సమాధానాన్ని పంచుకోవాలి. ప్రతి కాంపోనెంట్ useState లో తన స్వంత లోకల్ కాపీని ఉంచుకున్నప్పుడు, మీరు మీ డేటా యొక్క నిజత్వాన్ని (truth) ముక్కలు చేస్తున్నారు. హెడర్‌లోని అవతార్ మరియు సైడ్‌బార్‌లోని పేరు వేర్వేరు సమయాల్లో ఫెచ్ చేయబడటం వల్ల లేదా ఒకటి ఫెయిల్ అయ్యి మరొకటి సక్సెస్ అవ్వడం వల్ల అవి ఒకదానికొకటి భిన్నంగా మారుతుంటాయి.

క్వెరీని ఒక యాక్షన్ (action) లా కాకుండా, ఒక రిసోర్స్ (resource) లా భావించండి. దానికి ఒక క్యాష్ కీ (cache key), ఫ్రెష్‌నెస్ పాలసీ (freshness policy), మరియు ఏదైనా ఒక కాంపోనెంట్ కంటే ఎక్కువ కాలం ఉండే లైఫ్‌సైకిల్ ఉంటుంది. బాగా నిర్మించబడిన క్వెరీ లేయర్ /projects?page=2 ని చదవడం /projects?page=3 ని చదవడం కంటే భిన్నమని అర్థం చేసుకుంటుంది. ప్రతి URL మరియు పారామీటర్ సెట్ ఒక అడ్రస్‌ను ఏర్పరుస్తుంది, మరియు ఆ అడ్రస్‌లోని డేటా పాతది (stale), కొత్తది (fresh), లేదా లేకపోవచ్చు (missing). ఈ బుక్‌కీపింగ్ (bookkeeping) బాధ్యత UI కి ఉండకూడదు. అది డేటా లేయర్‌ను user:123 కోసం అడిగి ఒక స్నాప్‌షాట్‌ను (snapshot) తీసుకోవాలి. ఆ స్నాప్‌షాట్ రెండు సెకన్ల క్రితం సర్వర్ నుండి వచ్చిందా లేదా రెండు మిల్లీ సెకన్ల క్రితం క్యాష్ నుండి వచ్చిందా అనేది కాంపోనెంట్‌కు అనవసరం.

దీని వల్ల కలిగే పరిణామాలు తక్షణమే కనిపిస్తాయి. మీరు ప్రతి రీడ్‌ను కాంపోనెంట్ లోపల ఒక ఇంపరేటివ్ ఫెచ్ (imperative fetch) లా పరిగణించినప్పుడు, మీరు డూప్లికేషన్ నివారణను (deduplication) కోల్పోతారు. బ్యాక్‌గ్రౌండ్ రిఫ్రెష్ (background refresh) సామర్థ్యాన్ని కోల్పోతారు. బ్యాక్‌గ్రౌండ్‌లో డేటాను వాలిడేట్ చేస్తున్నప్పుడు, క్యాష్ చేసిన డేటాను తక్షణమే చూపించే సామర్థ్యాన్ని కోల్పోతారు. ఒక క్వెరీకి మీ UI ట్రీ బయట ఒక నివాసం ఉండాలి.

Mutations: ప్రపంచాన్ని మార్చడం

క్వెరీలు ప్రపంచం గురించి అడిగితే, మ్యుటేషన్లు (mutations) దానిని మారుస్తాయి. అసలైన నెట్‌వర్క్ రిక్వెస్ట్—POST, PUT, లేదా DELETE—సాధారణంగా సులభమైన భాగం. సర్వర్ "OK" అని చెప్పిన తర్వాత జరిగే ప్రతిదీ కష్టమైన భాగం.

ఒక యూజర్ తన డిస్‌ప్లే పేరును అప్‌డేట్ చేసినట్లు అనుకుందాం. మ్యుటేషన్ అనేది ఒకే ఒక రిక్వెస్ట్. కానీ దాని ప్రభావం (blast radius) అంతటా ఉంటుంది. ప్రొఫైల్ పేజీలో పాత పేరు ఉంటుంది. నావిగేషన్ బార్‌లో పాత పేరు కనిపిస్తుంది. కామెంట్ హిస్టరీ కూడా దానిని సూచించవచ్చు. మీ మ్యుటేషన్ కోడ్ ఒక లోకల్ isLoading ఫ్లాగ్‌ను మార్చడం మరియు ఒక స్టేట్‌ను అప్‌డేట్ చేయడం తప్ప మరేమీ చేయకపోతే, మీ అప్లికేషన్ తనను తాను మోసం చేసుకుంటున్నట్లే. UI లోని కొన్ని భాగాలు మార్పు జరిగినట్లు నటిస్తాయి. మరికొన్ని భాగానికి అసలు ఏమీ మారలేదని తెలియదు.

ఒక మ్యుటేషన్ డేటా గ్రాఫ్ (data graph) పై దాని ప్రభావాన్ని స్పష్టంగా చెప్పాలి. ఏ క్వెరీలను ఇప్పుడు ఇన్వాలిడ్ (invalid) గా పరిగణించాలి, ఏ క్యాష్ కీలను మళ్ళీ ఫెచ్ (refetch) చేయాలి మరియు ఏ సంబంధాలు మారాయి అనేది అది సిస్టమ్‌కు చెప్పాలి. ఇది క్వెరీ కంటే ప్రాథమికంగా భిన్నమైనది. క్వెరీ అనేది కేవలం చదవడానికి మాత్రమే (read-only) మరియు పంచుకోదగినది. మ్యుటేషన్ అనేది రైట్-ఫోకస్డ్ (write-focused) మరియు ఇప్పటికే ఉన్న క్యాష్‌లను దెబ్బతీస్తుంది. వీటిని ఒకే అబ్‌స్ట్రాక్షన్‌గా మార్చడం వల్ల డెవలపర్లు రాండమ్ కాంపోనెంట్లలో మాన్యువల్‌గా refetch() ని పిలవాల్సి వస్తుంది, లేదా అంతకంటే దారుణంగా, లోకల్ స్టేట్‌ను సర్వర్‌తో సింక్ (sync) చేయడానికి ట్రీ అంతటా useEffect హుక్స్‌ను వాడాల్సి వస్తుంది.

ఓనర్‌షిప్ మోడల్ కూడా భిన్నంగా ఉంటుంది. క్వెరీలను సాధారణంగా క్యాష్ (cache) యాజమాన్యంలో ఉంటాయి. మ్యుటేషన్ అనేది దానిని ప్రేరేపించిన యూజర్ యాక్షన్ (user action) యాజమాన్యంలో ఉంటుంది. దానికి ఒక పెండింగ్ స్టేట్ (pending state), ఎర్రర్ స్టేట్ (error state), మరియు అవసరమైతే రోల్ బ్యాక్ (roll back) చేయాల్సిన ఆప్టిమిస్టిక్ వాల్యూ (optimistic value) ఉంటుంది.