React - myšlení v reactu

03.03.2019 Programování #react #learning

React je v současné době důležitý způsob, jak budovat velké a rychlé webové aplikace s JavaScriptem.


Jedna z mnoha skvělých částí Reactu je, že nás nutí přemýšlet, jak stavět aplikace. V tomto dokumentu je nastínen postup myšlenkového procesu při vytváření tabulky s údaji o produktech s vyhledáváním, pomocí Reactu.

Začněte náčrtkem

Představte si, že již máte API JSON od vývojáře. Náčrtek aplikace by mohl vypadat následovně:

Mockup

Náš JSON by mohl vypadat následovně:

[
    {category: "Sporting Goods", price: "$49.99", stocked: true, name: "Football"},
    {category: "Sporting Goods", price: "$9.99", stocked: true, name: "Baseball"},
    {category: "Sporting Goods", price: "$29.99", stocked: false, name: "Basketball"},
    {category: "Electronics", price: "$99.99", stocked: true, name: "iPod Touch"},
    {category: "Electronics", price: "$399.99", stocked: false, name: "iPhone 5"},
    {category: "Electronics", price: "$199.99", stocked: true, name: "Nexus 7"}
    ];
    

Krok 1: Rozdělení uživatelského rozhraní do hierarchie komponent

První věc, kterou budeme chtít udělat, je vyznačit v náčrtku bloky ukazující konkrétní komponenty a dát jim jména. Lze například využít spolupráci s designérem, který mohl náčrtek poskytnout ve Photoshopu, který obsahuje dílčí vrstvy, které již mohou být pojmenovány, tak jakou se budou jmenovat dílčí komponenty v Ractu.

Ale jak poznáme, co by mělo být komponentou? Použijme při rozhodování podobnou techniku, jako bychom postupovali při vytváření nových funkcí nebo objektů. Jednou takovou technikou je zásada principu odpovědnosti, tj. komponenta by měla v ideálním případě dělat jen jednu věc. Mělo by tedy dojít k dekompozici na malé subkomponenty.

Vzhledem k tomu, že uživatelům často zobrazujeme datový model JSON, zjistíme, že pokud byl model správně sestaven, vaše uživatelské rozhraní (a tudíž i vaše struktura komponent) je bude pečlivě mapovat. To proto, že uživatelské rozhraní a datové modely mají tendenci dodržovat stejnou informační architekturu, což znamená, že práce rozdělující uživatelské rozhraní do komponent je často triviální. Stačí je rozdělit na součásti, které představují přesně jeden kus datového modelu.

Schéma komponenty

Zde uvidíte, že máme v naší jednoduché aplikaci pět komponent. Jsou vyznačeny kurzívou.

  1. FilterableProductTable (oranžová): obsahuje celý příklad
  2. SearchBar (modrá): přijímá všechny uživatelské vstupy
  3. ProductTable (zelená): zobrazuje a filtruje sběr dat na základě uživatelského vstupu
  4. ProductCategoryRow (tyrkysová): zobrazuje nadpis pro každou kategorii
  5. ProductRow(červená): zobrazí řádek pro každý produkt

Pokud se podíváte na ProductTable, vidíme, že hlavička tabulky (obsahující štítky "Name" a "Price") není její vlastní součástí. To je záležitost preference a měl by existovat argument, který to objasňuje. Pro tento příklad jsme to nechali jako součást,  ProductTable   protože je součástí renderovaných dat, za něž  ProductTable   odpovídá. Pokud se však tato hlavička stane složitou, měla by být vytvořena komponenta  ProductTableHeader .

Nyní, když jsme identifikovali komponenty, měli bychom je uspořádat do hierarchie. Komponenty, které se objevují v jiné komponentě, se v hierarchii zobrazí jako potomek:

  • FilterableProductTable
    • SearchBar
    • ProductTable
      • ProductCategoryRow
      • ProductRow

Krok 2: Vybudování statické verze v Reactu

GitHub

Nyní, když máme hierarchii komponent, je čas implementovat aplikaci. Nejjednodušší je vytvořit verzi, která bude mít svůj datový model a udělá uživatelské rozhraní, ale nemá interaktivitu. Nejlepší je oddělit tyto procesy, protože statická verze vyžaduje spoustu psaní a žádné myšlení a přidávání interaktivity vyžaduje hodně myšlení a ne moc psaní.

Chceme-li vytvořit statickou verzi aplikace, která vykresluje datový model, budeme chtít sestavit komponenty, které znovu používají další komponenty a předávají data pomocí prospProsp jsou způsob předávání dat z rodiče do potomka. Pokud jste obeznámeni s konceptem stavunepoužívejte stavy, pro sestavení statické verze. Stav je vyhrazen pouze pro interaktivitu, tj. data, která se mění v průběhu času. Jelikož se jedná o statickou verzi aplikace, nepotřebujeme ji.

Můžete sestavovat shora dolů nebo zdola nahoru. To znamená, že můžete začít budovat komponenty vyše v hierarchii (tj. začínat FilterableProductTable) nebo s těmi, které jsou niže ( ProductRow ). V jednodušších příkladech je obvykle snazší se pohybovat shora dolů a při větších projektech je snadnější jít nahoru a psát testy při vytváření.

Na konci tohoto kroku budeme mít knihovnu opakovaně použitelných komponent, které vykreslí datový model. Komponenty budou mít pouze metodu render(), protože to je statická verze vaší aplikace. Komponenta v horní části hierarchie ( FilterableProductTable ) bude mít datový model jako návrh. Pokud provedete změnu základního datového modelu a ReactDOM.render() znovu zavoláte, uživatelské rozhraní bude aktualizováno. Jednosměrný datový tok React (také nazývaný jednosměrná vazba) udržuje vše vcelku a rychle.

Jednoduše se podívejte na dokumenty React, pokud potřebujete pomoc při provádění tohoto kroku.

Krok 3: Identifikujte minimálně (ale kompletně) reprezentaci stavu UI

Chceme-li, aby UI bylo interaktivní, musíme mít možnost spustit změny v datovém modelu. React to snadno realizuje stavem.

Chceme-li správně sestavit aplikaci, musíte nejprve uvažovat o minimální množině změnitelných stavů, které aplikace potřebuje. Zjistíme absolutní minimální zastoupení stavu, který aplikace potřebuje, a vypočteme vše, co potřebujete na vyžádání. Například pokud vytváříte seznam TODO, stačí držet pole položek TODO; nezachovávejme samostatnou proměnnou stavu pro počet. Místo toho, když chceme vykreslit počet TODO, jednoduše zadejme délku pole položek TODO.

Přemýšlejme o všech částech dat v naší aplikaci.

  • Původní seznam produktů
  • Text hledání, který uživatel zadal
  • Hodnota zaškrtávacího políčka
  • Filtrovaný seznam produktů

Pojďme projít každým a zjistíme, který z nich je stav. Jednoduše položme tři otázky týkající se jednotlivých dat:

  1. Je to předáno od rodiče přes props? Pokud ano, pravděpodobně to není stav.
  2. Zůstává v průběhu času beze změny? Pokud ano, pravděpodobně to není stav.
  3. Můžeme jej vypočítat na základě jiných stavů nebo props v komponentě? Pokud ano, není to stav.

Původní seznam produktů je předán jako props, takže to není stav. Hledaný text a zaškrtávací políčko se zdají být stavem, protože se s časem mění a nelze je vypočítat z čehokoliv. A nakonec filtrovaný seznam produktů není stav, protože může být vypočítán kombinací původního seznamu produktů s vyhledávacím textem a hodnotou zaškrtávacího políčka.

Takže konečně stavem je:

  • Text hledání, který uživatel zadal
  • Hodnota zaškrtávacího políčka

Krok 4: Určete, kde se má stav nacházet

GitHub

OK, takže jsme zjistili, jaká je minimální sada stavů aplikace. Dále musíme určit, která komponenta mění tento stav.

Nezapomeňte: V Reactu je vše o jednosměrném toku dat dolů v hierarchii komponent. Nemusí být okamžitě jasné, která komponenta by měla vlastnit, jaký stav. To je často nejnáročnější část, která je pro nově uživatele pochopitelná, a proto postupujme takto:

Pro každý stav ve vaší aplikaci:

  • Identifikujte každou komponentu, která vykresluje něco založené na daném stavu.
  • Najděte společnou komponentu vlastníka (jedna komponenta nad všemi komponentami, které potřebují stav).
  • Buď společný vlastník nebo jiná komponenta výše v hierarchii by měla vlastnit stav.
  • Pokud nemůžeme najít komponentu, kde má smysl vlastnit stav, vytvořme novou komponentu jednoduše pro přidržení stavu a přidejme jej někde v hierarchii nad společnou komponentou vlastníka.

Projděme tuto strategii pro naši aplikaci:

  • ProductTable potřebuje filtrovat produktový seznam podle stavu SearchBar a potřebuje zobrazit vyhledávací text a kontrolovaný stav.
  • Součást společného vlastníka je FilterableProductTable.
  • Je koncepčně důležité, aby text filtru a kontrolovaná hodnota žily FilterableProductTable

Cool, tak jsme se rozhodli, že náš stav žije FilterableProductTable. Za prvé, přidejme vlastnost instance this.state = {filterText: '', inStockOnly: false}, aby FilterableProductTable‚ s constructor odrážel počáteční stav vaší žádosti. Pak se projít filterText inStockOnly aby ProductTable SearchBar jako props. Nakonec použijme tyto props k filtrování řádků ProductTable a nastavení hodnot polí formuláře v SearchBar.

Můžeme začít vidět, jak se bude aplikace chovat: nastavme filterText na "ball" a aktualizujme aplikaci. Uvidíme, že tabulka dat je správně aktualizována.

Krok 5: Přidání inverzního datového toku

GitHub

Dosud jsme vytvořili aplikaci, která se správně vykresluje jako funkce props a stavů plynoucích z hierarchie. Nyní je čas podpořit datové proudy jiným způsobem: komponenty formuláře hluboko v hierarchii potřebují aktualizovat stav v FilterableProductTable.

Pokud se pokusíte zaškrtnout v aktuální verzi příkladu, uvidíme, že React ignoruje vstup. Toto je záměrné, protože jsme nastavili value prop, input aby se vždy rovnal state průchodu FilterableProductTable.

Přemýšlejme o tom, co chceme dělat. Chceme se ujistit, že kdykoli uživatel změní formulář, aktualizujeme stav, aby odrážel vstup uživatele. Vzhledem k tomu, že součásti by měl pouze aktualizovat svůj vlastní stav, FilterableProductTable předají zpětné volání, SearchBar které budou spouštěny při každém aktualizaci stavu. Tuto onChange událost můžeme použít na vstupy, které je třeba o ní informovat. Volané FilterableProductTable budou volány setState() a aplikace bude aktualizována.

Ačkoli to zní složitě, je to opravdu jen pár řádků kódu. A je skutečně jasné, jak vaše data proudí po celé aplikaci.