Hogyan különbözteti meg a React az osztályt a függvénytől?
2018 M12 2 • ☕️☕️☕️ 17 min read
Translated by readers into: Español • Français • Magyar • Slovenčina • 日本語 • 简体中文 • 繁體中文
Read the original • Improve this translation • View all translated posts
Vegyük ezt a Greeting
komponenst, ami függvényként van definiálva:
function Greeting() {
return <p>Hello</p>;
}
React-ben ugyanezt osztályként is definiálhatjuk
class Greeting extends React.Component {
render() {
return <p>Hello</p>;
}
}
(Egészen mostanáig ez volt az egyetlen módja, hogy éljünk az állapot (state) által nyújtott lehetőségekkel.
Amikor renderelni akarjuk a <Greeting />
komponenst, nem számít hogyan volt definiálva:
// Osztály vagy függvény - tökmindegy.
<Greeting />
De a React-nek igenis fontos ez a különbség!
Ha a Greeting
egy függvény, akkor a React-nek meg kell hívnia:
// Saját kód
function Greeting() {
return <p>Hello</p>;
}
// React kód
const result = Greeting(props); // <p>Hello</p>
De ha a Greeting
egy osztály, akkor a React-nek először létre kell hoznia egy példányt a new
operátorral és csak ez után hívja meg a render
metódust az imént létrehozott példányon.
// Saját kód
class Greeting extends React.Component {
render() {
return <p>Hello</p>;
}
}
// React kód
const instance = new Greeting(props); // Greeting {}
const result = instance.render(); // <p>Hello</p>
A React célja mindkét esetben az, hogy megkapja a renderelt elemet (a példánkban <p>Hello</p>
). De ennek a folyamatnak a lépései attől függenek, hogyan volt a Greeting
definiálva.
Hogyan tudja tehát a React, hogy egy komponens osztály vagy függvény?
Az előző poszthoz hasonlóan, nem kell mindezt tudni, ahhoz hogy hatékonyan használjuk a React-et. Én sem tudtam évekig. Kérek mindenkit, hogy ne csináljunk ebből egy intejú kérdést. Valójában ez a poszt inkább szól a JavaScript-ről mint a React-ről.
Ez a blog azoknak az érdeklődő olvasóknak szól, akik tudni akarják miért működik a React úgy ahogy. Magadra ismertél? Akkor ugorjunk neki együtt.
Hosszú lesz az út, öveket becsatolni! Ez a poszt nem a tartalmaz sok információt magáról a React-ről, de át fogjuk venni a new
, this
, class
, nyíl operátoros függvények, prototype
, __proto__
, instanceof
néhány tulajdonságát és hogy ezek hogyan függenek össze JavaScript-ben. Szerencsére ezeken nem kell túl sokat gondolkodni a React használata közben. Viszont ha te implementálod a React-et…
(Ha csak a válaszra vagy kíváncsi, görgess a legvégére.)
Először is azt kell megértenünk, miért fontos a függvényeket és az osztályokat külön kezelnünk. Figyeljük meg hogyan használjuk a new
operátort egy osztály létrehozásakor:
// Ha a Greeting egy függvény
const result = Greeting(props); // <p>Hello</p>
// Ha a Greeting egy osztály
const instance = new Greeting(props); // Greeting {}
const result = instance.render(); // <p>Hello</p>
Nézzük meg, hogy nagyjából mit csinál a new
operátor JavaScript-ben.
A múltban nem voltak osztályok a JavaScript-ben. Azonban egyszerű függvények segíségével ki lehetett fejezni hasonló kódolási mintákat. Konkrétan akármilyen függvényt lehet egy osztály konstruktorhoz hasonló szerepkörben használni, mindössze a new
operátorral kell meghívni:
// Egy egyszerű függvény
function Person(name) {
this.name = name;
}
var fred = new Person('Fred'); // ✅ Person {name: 'Fred'}
var george = Person('George'); // 🔴 Nem fog működni
Ez a kód még ma is érvényes! Próbáld ki DevTools-ban.
Ha new
és this
nélkül deklarálnánk és hívnánk meg, akkor a Person('Fred')
valami globális és hasznavehetetlen (mint például a window
vagy undefined
) dologra mutatna. A kódunk tehát hibát jelezne vagy váratlanul megváltoztatná a window.name
értékét.
A new
operátort egy függvény meghívása elé rakva azt fejezzük ki, hogy: “Figyelj JavaScript, tudom hogy a Person
csak egy függvény, de tegyünk úgy mintha egy osztály konstruktor lenne. Hozz létre egy {}
objektumot és a Person
függvényen belül lévő this
mutasson erre az objektumra, hogy hozzá tudjak rendelni olyan dolgokat, mint a this.name
. Aztán térj vissza ezzel az objektummal. ”
Ezt csinálja a new
operátor.
var fred = new Person('Fred'); // A `Person`-ban lévő `this` erre az objektumra utal
A new
operátor azt is lehetővé teszi, hogy minden amit a Person.prototype
-on definiálunk az a fred
objektum számára is elérhető lesz:
function Person(name) {
this.name = name;
}
Person.prototype.sayHi = function() { alert('Hi, I am ' + this.name);}var fred = new Person('Fred');
fred.sayHi();
Így lehetett osztályokat imitálni mielőtt azok megjelentek volna JavaScript-ben.
A new
operátor tehát nem egy újdonság JavaScript-ben. Az osztályok azonban újabb keletűek. A segítségükkel sokkal kifejezőbbé tudjuk tenni a korábbi kódunkat:
class Person {
constructor(name) {
this.name = name;
}
sayHi() {
alert('Hi, I am ' + this.name);
}
}
let fred = new Person('Fred');
fred.sayHi();
A fejlesztő szándékának megőrzése fontos egy programnyelv vagy egy API tervezésekor.
Ha írunk egy függvényt, a JavaScript nem tudja magától kitalálni, hogy azt úgy kell meghívnia, mint mondjuk az alert()
-et vagy konstruktorként, mint a new Person()
esetében. Egy olyan függvény esetében, mint a Person
, a new
elhagyása zavaros következményekkel jár.
Az osztály szintaxissal ki tudjuk fejezni, hogy: “Ez nem csak egy függvény - ez egy osztály és tartozik hozzá egy konstruktor”. Ha lefelejtjük a new
-t ennek a meghívásakor, a JavaScript hibát fog jelezni:
let fred = new Person('Fred');
// ✅ Ha a Person egy függvény: semmi gond
// ✅ Ha a Person egy osztály: szintén semmi gond
let george = Person('George'); // Hiányzó `new`
// 😳 Ha a Person egy konstruktor-szerű függvény: zavaros viselkedés
// 🔴 Ha a Person egy osztály: azonnali hibaüzenet
A hibákat ezáltal könnyebb korán észrevenni, semmint várni hogy bekövetkezzen valami rejtélyes bug, például hogy a this.name
a george.name
helyett a window.name
-et állítja be.
Ám ez azzal is jár, hogy a React-nak minden egyes osztály meghívása elé oda kell tennie a new
operátort. Nem hívhatja meg azokat egyszerű függvényként, mert a JavaScript hibát jelezne!
class Counter extends React.Component {
render() {
return <p>Hello</p>;
}
}
// 🔴 A React nem hívhatja meg így
const instance = Counter(props);
Ebből még baj lehet.
Mielőtt látnánk hogyan oldja meg a React ezt a problémát, jusson eszünkbe, hogy a legtöbb React felhasználó valamilyen fordítóprogramot használ - mint például a Babel - hogy az osztályokat és a többi modern funkciókat lefordítsák a régebbi böngészők számára. A tervezéskor tehát ezeket a fordítóprogramokat is figyelembe kell vennünk.
A Babel korai verzióiban az osztályokat meg lehetett hívni new
nélkül is. Ez azonban ki lett javítva - egy kis extra kód hozzáadásával:
function Person(name) {
// Leegyszerűsített Babel kód:
if (!(this instanceof Person)) {
throw new TypeError("Cannot call a class as a function");
}
// Saját kód:
this.name = name;
}
new Person('Fred'); // ✅ Oké
Person('George'); // 🔴 Nem lehet az osztályt függvényként meghívni
Hasonló kóddal már találkozhattál a bundle-ödben. Erre való az a sok _classCallCheck
függvény. (A bundle mérete csökkenthető ha az ilyen ellenőrzéseket nélkülöző “loose mode”-ot választjuk, de ez megnehezítheti a valós natív osztályokra való jövőbeli átállást.)
Most már tehát nagyjából értjük, hogy mi a különbség ha new
-val vagy anélkül hívunk meg valamit:
new Person() |
Person() |
|
---|---|---|
class |
✅ A this egy Person példányra mutat |
🔴 TypeError |
function |
✅ A this egy Person példányra mutat |
😳 A this vagy a window -ra mutat vagy undefined |
Ezért fontos, hogy a React helyesen hívja meg a komponenseket. Ha a komponens osztályként van definiálva a React-nak a new
operátorral kell meghívnia.
Akkor a React csupán ellenőrzi, hogy egy osztályról van szó vagy sem?
Ne olyan hevesen! Még ha meg is tudnánk különböztetni egy osztályt egy függvénytől JavaScript-ben, a Babel és a hozzá hasonló eszközök által fordított osztályok esetében ez akkor sem működne. A böngésző szemében ezek mindössze sima függvények. Nagy pech a React számára.
Oké, akkor a React nem tehetné oda new
kulcsszót minden egyes meghívás elé? Sajnos ez sem működne.
Ha a szokásos függvényeket a new
-val hívjuk meg, akkor egy objektum példány társul hozzájuk, amire a this
mutat. Ez kívánatos a konstruktor függvényeknél (mint például a korábbi Person
), de zavaró a függvény komponensek esetében:
function Greeting() {
// Nem várjuk el, hogy a `this` akármire mutasson
return <p>Hello</p>;
}
Ez még akár elviselhető is lenne. Van viszont két másik oka annak, hogy ez az ötlet nem működik.
Az első ok, amiért nem használhatjuk minden esetben a new
-t az az, hogy ha a natív (és nem a Babel által lefordított) nyíl operátoros függvényeket a new
kulcsszóval hívjuk meg, akkor hibaüzenetet kapunk:
const Greeting = () => <p>Hello</p>;
new Greeting(); // 🔴 A Greeting nem egy konstruktor
Ez a viselkedés szándékos és a nyíl operátoros függvények dizájnjából ered. A nyíl operátoros függvények egyik előnye ugyanis az, hogy nem rendelkeznek saját this
értékkel - ehelyett a this
-t a legközelebbi szabályos függvénytől veszik át:
class Friends extends React.Component {
render() { const friends = this.props.friends;
return friends.map(friend =>
<Friend
// `A `this` a `render` metódustól származik size={this.props.size} name={friend.name}
key={friend.id}
/>
);
}
}
Oké, szóval a nyíl operátoros függvények nem rendelkeznek saját this
-szel. Viszont ez azt jelenti, hogy teljesen használhatatlanok konstruktorként!
const Person = (name) => {
// 🔴 Ennek nincs értelme!
this.name = name;
}
Emiatt a JavaScript nem engedélyezi, hogy a nyíl operátoros függvényeket a new
kulcsszóval hívjuk meg. Ha mégis így teszünk, az valószínűleg nem volt szándékos és jobb is, ha minél hamarabb tudomást szerzünk róla. Hasonló okokból kifolyólag nem engedi a JavaScript az osztályok meghívását a new
operátor nélkül.
Ez így oké, viszont ez keresztülhúzza a számításainkat. A React nem hívhat meg mindent a new
kulcsszóval, mert a nyíl operátoros függvények esetében ez nem működne! A new
-val való meghívás helyett megpróbálhatnánk kiszűrni a nyíl operátoros függvényeket azáltal, hogy nekik nincs prototype
mezőjük:
(() => {}).prototype // undefined
(function() {}).prototype // {constructor: f}
De ez nem működne a Babel által fordított függvények esetében. Ez nem biztos, hogy olyan nagy ügy, van viszont egy másik ok, ami miatt ez a megközelítés egy zsákutca.
A másik ok amiért nem használhatjuk folyton a new
kulcsszót az az, hogy ez megakadályozná a React-et abban, hogy támogassa azokat a komponenseket, amik string-ekkel vagy más primitív típusokkal térnek vissza.
function Greeting() {
return 'Hello';
}
Greeting(); // ✅ 'Hello'
new Greeting(); // 😳 Greeting {}
Ez megint csak a new
operátor különös koncepciójából ered. Ahogy azt láttuk korábban a new
arra utasítja a JavaScript-et, hogy hozzon létre egy objektumot, a függvényen belül a this
mutasson erre az objektumra, végül pedig kapjuk meg ezt az objektumot a new
eredményeként.
Azonban a JavaScript azt is megengedi, hogy egy new
operátorral meghívott függvény felülírja a new
visszatérési értékét azáltal, hogy valami más objektummal tér vissza. Feltehetőleg ezt hasznosnak tekintették az olyan esetekben, amikor a példányok újrafelhasználásával összevontabb kódot szeretnénk írni:
// Szabadon definiálvavar zeroVector = null;function Vector(x, y) {
if (x === 0 && y === 0) {
if (zeroVector !== null) {
// Újrahasznosítva ugyanazt a példányt
return zeroVector; } zeroVector = this;
}
this.x = x;
this.y = y;
}
var a = new Vector(1, 1);
var b = new Vector(0, 0);
var c = new Vector(0, 0); // 😲 b === c
Azonban a new
teljesen figyelmen kívűl hagyja egy függvény visszatérési értékét abban az esetben, amikor az nem egy objektum. Ha egy string vagy egy szám a visszatérési érték az olyan, mintha nem is volna return
a függvényben.
function Answer() {
return 42;
}
Answer(); // ✅ 42
new Answer(); // 😳 Answer {}
Egyszerűen nincs rá mód, hogy olvassuk a primitív visszatérési értékeket (mint például string vagy szám) ha a függvény a new
kulcsszóval került meghívásra. Tehát ha a React mindig a new
-t használná képtelen lenne azokat a komponenseket támogatni, amelyek egy string-et eredményeznek!
Mivel ez elfogadhatatlan szükségünk van egy kompromisszumra.
Mit is tudunk eddig? A React-nek az osztályokat (beleértve a Babel outputot) a new
-val együtt, a normál és a nyíl operátoros függvényeket (beleértve a Babel outputot) viszont a new
nélkül kell meghívnia. Ezeket viszont nem lehet megbízható módon megkülönböztetni.
Ha nem tudjuk ezt az általános problémát megoldani, egy specifikusabbat meg tudnánk?
Amikor egy komponenst osztályként definiálunk a legtöbbször a React.Component
osztályt szeretnénk bővíteni, hogy hozzáférjünk olyan beépített metódusokhoz, mint például a this.setState()
. Ahelyett, hogy megpróbálnánk azonosítani az összes osztályt, nem tudnánk csak a React.Component
utódosztályait kiszűrni?
Spoiler: a React pontosan ezt csinálja.
Talán a helyes módszer, hogy megállapítsuk a Greeting
komponensről hogy egy React osztály-e az, hogy megvizsgáljuk a Greeting.prototype instanceof React.Component
igazságértékét:
class A {}
class B extends A {}
console.log(B.prototype instanceof A); // true
Tudom mire gondoltok. Mi folyik itt? Hogy ezt megválaszoljuk, meg kell értenünk a JavaScript prototípusokat.
Talán ismerős lehet a “prototípus lánc”. Minden JavaScript objektum rendelkezhet egy “prototípussal”. Amikor azt írjuk, hogy fred.sayHi()
, viszont a fred
objektum közvetlenül nem rendelkezik ezzel a metódussal, akkor szétnézünk fred
prototípusában, hátha ott van a sayHi
definiálva. Ha ott sem találjuk, akkor továbbmegyünk a láncban következő prototípusra - fred
prototípusának a prototípusára. És így tovább.
Zavaró módon egy osztály vagy egy függvény prototype
mezője nem az adott elem prototípusára mutat. Nem viccelek.
function Person() {}
console.log(Person.prototype); // 🤪 Nem a Person prototípusa
console.log(Person.__proto__); // 😳 A Person prototípusa
A “prototípus lánc” tehát inkább úgy néz ki, hogy __proto__.__proto__.__proto__
semmint hogy prototype.prototype.prototype
. Évekbe tartott hogy ezt megértsem.
Akkor visztont mire mutat a prototype
mező egy függvény vagy osztály esetében? Hát a __proto__
-ra, amivel minden olyan objektum rendelkezik, ami egy függvénytől vagy egy osztálytól származik és a new
operátorral került meghívásra!
function Person(name) {
this.name = name;
}
Person.prototype.sayHi = function() {
alert('Hi, I am ' + this.name);
}
var fred = new Person('Fred'); // A `fred.__proto__` immár a `Person.prototype`-ra mutat
A JavaScript tehát ezt a __proto__
láncot használja a változók megkeresésére:
fred.sayHi();
// 1. fred rendelkezik saját sayHi metódussal? Nem.
// 2. fred.__proto__ rendelkezik saját sayHi metódussal? Igen. Hívjuk meg!
fred.toString();
// 1. fred rendelkezik saját toString metódussal? Nem.
// 2. fred.__proto__ rendelkezik saját toString metódussal? Nem.
// 3. fred.__proto__.__proto__ rendelkezik saját toString metódussal? Igen. Hívjuk meg!
A gyakorlatban szinte sosem kell a __proto__
-hoz közvetlenül hozzányúlnunk, kivéve ha a prototípus lánchoz köthető hibát keresünk. Ha azt szeretnénk, hogy a fred.__proto__
-nak legyen hozzáférése valamihez, azt a Person.prototype
-on kell beállítanunk. Legalábbis eredetileg így kellett.
A böngészők eredetileg nem is férhettek volna hozzá a __proto__
mezőhöz, mivel a prototípus láncot egy belső koncepciónak szánták. De néhány böngésző mégis hozzáfért, így a __proto__
akaratlanul, de mégis standarddá vált (viszont mára elevult és a Object.getPrototypeOf()
vette át a helyét).
Akárhogy is, én még mindig nagyon furcsának találom, hogy egy mező amit prototype
-nak hívnak nem az adott érték prototípusra utal (például a fred.prototype
nincs definiálva, mert a fred
nem egy függvény). Személy szerint én azt gondolom, hogy ez fő oka annak, hogy még a tapasztalt fejlesztők is gyakran félreértik a JavaScript prototípusokat.
Hosszú egy poszt, mi? Körülbelül 80%-nál tartunk. Kitartás.
Tudjuk tehát, hogy amikor azt írjuk, hogy obj.foo
, akkor a JavaScript valójában megnézi, hogy a foo
definiálva van-e az obj
-en, obj.__proto__
-n, obj.__proto__.__proto__
-n és így tovább.
Az osztályok esetében ennek a mechanizmusnak nem vagyunk közvetlenül kitéve, de az extends
ugyanúgy működik a jó öreg prototípus láncon is. Így férnek hozzá a React osztályaink olyan metódusokhoz, mint a setState
:
class Greeting extends React.Component { render() {
return <p>Hello</p>;
}
}
let c = new Greeting();
console.log(c.__proto__); // Greeting.prototype
console.log(c.__proto__.__proto__); // React.Component.prototype
console.log(c.__proto__.__proto__.__proto__); // Object.prototypec.render(); // Megtalálva a c.__proto__ -n (Greeting.prototype)
c.setState(); // Megtalálva a c.__proto__.__proto__ -n (React.Component.prototype)
c.toString(); // Megtalálva a c.__proto__.__proto__.__proto__ -n (Object.prototype)
Más szavakkal, amikor osztályokat használunk, egy példány __proto__
lánca “tükrözi” az oszály hierarchiát:
// `extends` lánc
Greeting
→ React.Component
→ Object (implicit módon)
// `__proto__` lánc
new Greeting()
→ Greeting.prototype
→ React.Component.prototype
→ Object.prototype
2 Chainz.
Mivel a __proto__
letükrözi az osztály hierarchiát, megnézhetjük, hogy a Greeting
a React.Component
bővítménye-e, kezdve a Greeting.prototype
-nál majd tovább követve a __proto__
láncot:
// `__proto__` lánc
new Greeting()
→ Greeting.prototype // 🕵️ Itt kezdünk → React.Component.prototype // ✅ Megvan! → Object.prototype
Szerencsére az x instanceof Y
pontosan ezt a fajta keresést hajtja végre. Ez az x.__proto__
láncot követve kutat az Y.prototype
után.
Ezt normális esetben arra használjuk, hogy megmondjuk valamiről hogy egy osztály példánya-e:
let greeting = new Greeting();
console.log(greeting instanceof Greeting); // true
// greeting (🕵️ Itt kezdünk)
// .__proto__ → Greeting.prototype (✅ Megvan!)
// .__proto__ → React.Component.prototype
// .__proto__ → Object.prototype
console.log(greeting instanceof React.Component); // true
// greeting (🕵️ Itt kezdünk)
// .__proto__ → Greeting.prototype
// .__proto__ → React.Component.prototype (✅ Megvan!)
// .__proto__ → Object.prototype
console.log(greeting instanceof Object); // true
// greeting (🕵️ Itt kezdünk)
// .__proto__ → Greeting.prototype
// .__proto__ → React.Component.prototype
// .__proto__ → Object.prototype (✅ Megvan!)
console.log(greeting instanceof Banana); // false
// greeting (🕵️ Itt kezdünk)
// .__proto__ → Greeting.prototype
// .__proto__ → React.Component.prototype
// .__proto__ → Object.prototype (🙅 Nem találtuk sehol!)
De ugyanúgy működne, ha azt akarnánk meghatározni, hogy egy osztály egy másik osztály bővítménye-e:
console.log(Greeting.prototype instanceof React.Component);
// greeting
// .__proto__ → Greeting.prototype (🕵️ Itt kezdünk)
// .__proto__ → React.Component.prototype (✅ Megvan!)
// .__proto__ → Object.prototype
Ez az a módszer, amivel meg tudjuk határozni, hogy valami egy React komponens osztály vagy pedig egy szokványos függvény.
A React azonban nem így csinálja. 😳
Ezt az instanceof
-ot használó megoldás egyik ellentmondásossága, hogy nem működik ha a React több példánya is jelen van az oldalon és az a komponens amit éppen ellenőrzünk egy másik React példány React.Component
-jétől örököl. Többfajta React példány ötvözése egy projekten belül sok okból kifolyólag sem jó ötlet, de a múltban megpróbáltuk elkerülni az ezzel járó problémákat, ha lehetséges volt. (A Hooks-szal azonban, lehet hogy muszáj lesz megszabadulnunk a duplikácikótól.)
Egy másik lehetséges heurisztika, ha ellenőriznénk, hogy a render
metódus definiálva van-e a prototípuson. Azonban régebben nem volt tiszta, hogy a komponens API hogyan fog fejlődni. Minden ellenőrzésnek van egy ára, így nem akartunk egynél többet elvégezni. Ez akkor sem működne ha a render
egy példány metódusként lenne definiálva, az osztály attribútumok szintaxisához hasonlóan.
Ellenben a React inkább egy speciális flag-et rendelt a bázis komponenshez. A React ellenőrzi, hogy megvan-e ez a flag, és innen tudja, hogy valami egy React komponens-e vagy sem.
Eredetileg ez a flag a bázis React.Component
osztályon magán volt:
// Inside React
class Component {}
Component.isReactClass = {};
// Ellenőrizhetjük így
class Greeting extends Component {}
console.log(Greeting.isReactClass); // ✅ Igen
Ám néhány konkrét osztály implementáció nem tartalmazott másolatokat a statikus tulajdonságokról (vagy maga módosította a __proto__
-t, ami nem volt a standard része), így ez a flag elveszett.
A React ezért rakta át ezt a flag-et inkább a React.Component.prototype
-ra:
// React kód
class Component {}
Component.prototype.isReactComponent = {};
// Így tudjuk ellenőrizni
class Greeting extends Component {}
console.log(Greeting.prototype.isReactComponent); // ✅ Igen
És lényegében ez minden.
Felmerülhet a kérdés, hogy ez miért egy objektum egy egyszerű boolean helyett. A gyakorlatban nem számít sokat, de a Jest korábbi verzióiban (mielőtt a Jest jó lett™️) az automocking alapból be volt kapcsolva. Ezek a generált teszt objektumok (mock-ok) nélkülöztek minden primitív adatmezőt, lehetetlenné téve az ellenőrzést. Köszi Jest.
Az isReactComponent
ellenőrzése mindmáig a React része.
Ha nem a React.Component
-et bővítjük, akkor a React nem fogja megtalálni az isReactComponent
-et a prototípuson és ezért nem is fogja osztályként kezelni. Most már tudjuk hogy a Cannot call a class as a function
hibaüzenetre a legtöbb szavazatot kapó válasz miért az, hogy adjuk hozzá a komponenshez az extends React.Component
-et. Végezetül van egy figyelmeztetés is, ami jelzi ha a prototype.render
létezik, de a prototype.isReactComponent
nem.
Úgy vélhetitek, hogy ebben a történet kicsit sok a beetetést. Maga a megoldás rendkívül egyszerű, mégis azért tettem meg ezt a hatalmas kerülőutat, hogy elmagyarázzam a React miért ezt a megoldást választotta és milyen más alternatívák merültek fel.
Tapasztalatom szerint ez gyakran megesik az API könyvtárakkal. Ha azt várjuk el egy API-tól, hogy egyszerűen lehessen használni akkor figyelembe kell venni a nyelv szemantikáját (valószínűleg több nyelvét is, beleértve a lehetséges jövőbeli irányvonalakat is), a lefutás gyorsaságát, a munkakörnyezetet fordítási műveletekkel és azok nélkül, az ökoszisztéma és a programcsomagok állapotát és számos más tényezőt. A végső megoldás nem mindig a legelegánsabb is, viszont muszáj használhatónak lennie.
Ha a végső API sikeres, a felhasználónak soha nem kell ezen a procedúrán rágódnia. Ehelyett fókuszálhatnak inkább az appokra.
De ha kíváncsi vagy… nem árt ha tudod, hogy működnek a dolgok.