![]()
A magasabb rendű alkatrészek (HOC) egyfajta React komponensek, amelyek segítenek a logika újrafelhasználásában az alkalmazásban. A terminológia összetettnek tűnhet, de a HOC-kat könnyű kezelni, és egyszerűbbé teheti a kódbázis fenntartását.
A Magasabb rendű alkatrész a gyermek alkatrészeit mindig további funkciókkal csomagolja be. A HOC olyan funkcióként definiálható, amely egy komponenst paraméterként fogad el. Ezután visszatér a új komponens, amely általában a bemeneti komponenst extra kellékekkel csomagolja.
Egyszerű példa
A legjobb módja annak, hogy megbecsüljük a HOC-k értelmét, ha látjuk őket működésben. Vegyünk egy egyszerű fizetési rendszert, ahol a felhasználó kosarának állapotát központilag tároljuk az alkalmazáson belül. Példáink szerint a Redux mint állami üzlet, de ez csak szemléltető célokra szolgál.
Tegyük fel, hogy ez az objektum képviseli alkalmazásunk állapotát:
{
checkout: {
items: [
{
label: "Product 1",
price: 150.00,
quantity: 2
},
{
label: "Product 2",
price: 75.00,
quantity: 1
}
]
}
}
Van egy egyszerű tömbünk, amely a felhasználó kosarában található elemeket ábrázolja. Pénztári összetevőink ebből az állapotból további értékeket fognak származtatni, például a teljes rendelési értéket és az alkalmazandó adókat.
A fizetési rendszerünknek valószínűleg meg kell mutatnia a teljes értéket több független összetevőn belül. Lehet, hogy van egy oldalsáv widget, amely megmutatja a kosarat, a pénztár utáni felülvizsgálati képernyőt és a szállítási költség kalkulátort. Egy naiv rendszer, amely egyszerűen átadta a pénztár tételeit kellékként, megkockáztathatja a logika megkettőzését – minden egyes alkatrésznek ki kell dolgoznia a teljes rendelési értéket.
A HOC bemutatása
Nézzük meg, hogyan segíthet a HOC:
import React from "react"; import {connect} from "react-redux"; const withCheckout = ComponentToWrap => { const ComponentWithCheckout = class extends React.Component { render() { return ( <ComponentToWrap checkoutItems={this.props.checkout.items} checkoutTotal={this.total} {...this.props} /> ); } get total() { const prices = this.props.checkout.items.map(i => (i.quantity * i.price)); return prices.reduce((a, b) => (a + b), 0); } } return connect(({checkout}) => ({checkout}))(ComponentWithCheckout); } export default withCheckout;
A fájl egyetlen függvényt exportál, withCheckout, amely a React komponenst veszi egyetlen paraméternek (ComponentToWrap). A függvényen belül létrehozunk egy új névtelen osztályt, amely maga is React komponens.
Ez az új komponens render metódus létrehozza a ComponentToWrap átmentünk a függvénybe. Most lehetőségünk van meghatározni a példány kellékeit. A pénztár tételek tömböt továbbítjuk checkoutItems és az előre kiszámított teljes értéket elérhetővé teszi checkoutTotal.
A HOC-nak továbbított támaszokat továbbítják a belső alkatrészhez, biztosítva, hogy az az összes szükséges adatot megkapja. A függvény az újonnan létrehozott névtelen osztályt adja vissza, amely készen áll az egész alkalmazás megjelenítésére.
Használjuk a connect a metódusa react-redux így a checkout a HOC-on belüli prop megkapja a checkout kulcs a Redux üzletünk állapotában. Ez a megvalósítás részletei – a HOC fenntarthatja a saját állapotát, vagy elérhet más szolgáltatásokat az alkalmazáson belül.
A HOC használata
Itt az ideje, hogy használatba vegyük a HOC-t.
import React from "react"; import withCheckout from "./withCheckout.js"; class CheckoutReviewScreen extends React.Component { render() { return ( <h1>Checkout</h1> <h2>{this.props.checkoutTotal}</h2> ); } } export default withCheckout(CheckoutReviewScreen);
Feltételezzük, hogy withCheckout A HOC mappába menti withCheckout.js ugyanabban a könyvtárban, mint az új fizetési ellenőrző képernyő komponensünk. Azáltal, hogy becsomagoljuk az alkatrészt a miénkkel withCheckout HOC, elérhetjük és megjeleníthetjük a teljes rendelési értéket. Nem kell magunknak kiszámítanunk, vagy az alkalmazás állapotában tárolnunk. Ha valaha is frissíteni akartuk a teljes összeg kiszámításának módját (például rögzített kezelési költség hozzáadásával), akkor csak egy helyen kell változtatnunk – a HOC-on belül.
Most már renderelhet <CheckoutReviewScreen /> bárhol az alkalmazásodban. A becsomagolt példánkat nem kell átadni semmilyen kelléknek, mivel az adatokat a Redux üzletünkből szerzi be. Mert be van csomagolva withCheckout, maga burkolva a Redux-ékkel connect, az ellenőrző képernyő automatikusan megkapja a checkoutTotal prop, amely összegzi az összes elem árát az alkalmazás állapotában.
Most érdemes megemlíteni, hogyan neveztük el a HOC-t: withCheckout. Megállapodás szerint a HOC neveknek általában a with előtag, mert hozzáadnak valamit az általuk becsomagolt alkatrészekhez. Esetünkben a HOC kényelmes hozzáférést biztosít pénztárunk kosarához, amelyet egyébként minden egyes alkatrészen belül végrehajtanunk kellene.
A HOC előnyei
A HOC használatával elvonatkoztathatja az összetevőkből a gyakori viselkedéseket, minimalizálva a kódduplikációt és növelve a fenntarthatóságot. A HOC-k lehetővé teszik a függőség-injektálás egy formáját. Segítenek az összetevők egyszerűbb megőrzésében, mivel lehetővé teszik, hogy többet továbbítsanak a külvilágtól.
A HOC-k gyakoriak a React ökoszisztémán belül. Valójában láttunk egyet ebben a cikkben – connect(), része react-redux, amely feliratkozik a komponenseire a Redux állapotváltozásokra.
A HOC-k azért népszerűek, mert olyan kód-újrafelhasználási módszert kínálnak, amely nem rontja meg az összetevők önzárását. A minta kihasználja a React összetételét, hogy extra funkciókat csatolhasson mellékhatások veszélye nélkül.
Az alkalmazás bármelyik összetevőjét átadhatja withCheckout anélkül, hogy bármit is eltörne – a HOC csak néhány extra támaszt rögzít. Ezért olyan fontos, hogy a HOC-k továbblépjenek összes az általuk kapott kellékek ({...this.props} példánkban). Nem tehetnek semmit, ami zavarhatja a burkolt alkatrész normál működését.
Úgy érezheti, hogy az alkatrészei most függenek a HOC-tól. Ez nem így van. Exportálhatja az összetevő egy második verzióját, amely nincs becsomagolva, így a fogyasztók választhatnak, hogy melyiket használják.
Az Ön alkatrésze csak bizonyos ragaszkodásokhoz ragaszkodik – checkoutTotal a mi esetünkben. Ezt megadhatja a HOC, vagy átadhat egy értéket, bárhol is jelenítjük meg az alkatrészt. A HOC egyszerűbbé teszi a fejlesztést, de alapvetően nem változtatta meg renderelt komponenseink jellegét.
