Redux Fundamentals, 3. rész: Állapot, műveletek és reduktorok #

Amit megtudsz

  • Az alkalmazás adatait tartalmazó állapotértékek meghatározása
  • Hogyan határozhat meg olyan műveletobjektumokat, amelyek leírják az alkalmazásban történéseket
  • Hogyan írhatunk olyan redukciós függvényeket, amelyek kiszámítják a frissített állapotot a meglévő állapot és műveletek alapján
  • Ismerkedés a kulcsfontosságú Redux-kifejezésekkel és fogalmakkal, mint például az "akciók", "reduktorok", "áruház" és "diszpécser". (Lát 2. rész: Redux fogalmak és adatfolyam a kifejezések magyarázatához.)

Bevezetés #

A 2. részben: A Redux fogalmai és az adatáramlás azt vizsgáltuk, hogy a Redux miként segíthet karbantartható alkalmazások felépítésében azáltal, hogy egyetlen központi helyet biztosít számunkra a globális alkalmazás állapotának megadásához. Beszéltünk olyan alapvető Redux-fogalmakról is, mint az akcióobjektumok diszpécserezése és az új állapotértékeket visszaadó szűkítőfunkciók használata.

Most, hogy van némi fogalma arról, hogy mik ezek a darabok, itt az ideje, hogy ezeket az ismereteket a gyakorlatba is átültesse. Készítünk egy kis példaprogramot, hogy lássuk, hogyan működnek együtt ezek a darabok.

A példaalkalmazás nem teljes gyártásra kész projektként értendő. A cél az, hogy segítsen megtanulni az alapvető Redux API-kat és használati szokásokat, és néhány korlátozott példával jó irányba mutasson. Emellett néhány korai darabot, amelyet építünk, később frissítjük, hogy jobb módokat mutassunk be a dolgok elvégzésére. Kérjük, olvassa el az egész oktatóanyagot, hogy megtekinthesse az összes használt fogalmat.

Projektbeállítás #

Ehhez az oktatóanyaghoz készítettünk egy előre konfigurált indítóprojektet, amely már be van állítva a React-ben, tartalmaz néhány alapértelmezett stílust és egy hamis REST API-t, amely lehetővé teszi számunkra, hogy tényleges API-kéréseket írjunk az alkalmazásunkba. Ezt fogja használni a tényleges alkalmazáskód megírásához.

A kezdéshez megnyithatja és elágazhatja ezt a CodeSandbox-ot:

Ugyanezt a projektet klónozhatja ebből a Github repo-ból is. A repó klónozása után telepítheti a projekt eszközeit az npm telepítésével, és elindíthatja az npm start paranccsal .

Ha szeretné megtekinteni a végleges verzióját, amit építeni fogunk, akkor nézze meg a tutorial-steps ág, vagy nézze meg a végleges verziót ebben a CodeSandboxban.

Új Redux + React projekt létrehozása #

Miután befejezte ezt az oktatóanyagot, valószínűleg megpróbálkozik saját projektjeivel. Az új Redux + React projekt létrehozásának leggyorsabb módja a Redux sablonok használata a Create-React-App számára. A Redux Toolkit és a React-Redux már konfigurálva van, az 1. részben látott "számláló" alkalmazáspélda modernizált változatának felhasználásával. Ez lehetővé teszi, hogy rögtön beírja a tényleges alkalmazáskódot anélkül, hogy hozzá kellene adnia a Redux csomagokat és be kellene állítania a bolt.

Ha meg szeretné tudni a Redux hozzáadásának konkrét részleteit egy projekthez, olvassa el ezt a magyarázatot:

Részletes magyarázat: Redux hozzáadása egy React projekthez

A CRA Redux sablonja a Redux Toolkit és a React-Redux már be van állítva. Ha a nulláról állít be új projektet a sablon nélkül, kövesse az alábbi lépéseket:

  • Adja hozzá a @ reduxjs/toolkit és a reakció-redux csomagokat
  • Hozzon létre egy Redux tárolót az RTK configureStore API segítségével, és adja át legalább egy reduktor funkciót
  • Importálja a Redux tárolót az alkalmazás belépési fájljába (például src/index.js)
  • Csomagolja be a Root React komponenst a

komponens a React-Redux-től, például:

A kezdeti projekt feltárása #

Ez a kezdeti projekt a standard Create-React-App projekt sablonon alapszik, néhány módosítással.

Vessünk egy gyors pillantást arra, hogy mit tartalmaz a kezdeti projekt:

Ha most betölti az alkalmazást, üdvözlő üzenetet kell látnia, de az alkalmazás többi része egyébként üres.

Ezzel kezdjük!

A Todo példaalkalmazás indítása

Példapéldánk egy kis "todo" alkalmazás lesz. Valószínűleg láttál már olyan Todo alkalmazás-példákat - ezek jó példákat mutatnak be, mert bemutatják nekünk, hogyan tegyünk olyan dolgokat, mint például az elemek listájának nyomon követése, a felhasználói bevitel kezelése és az UI frissítése, amikor ezek az adatok megváltoznak, amelyek mind történnek normális alkalmazás.

Követelmények meghatározása #

Kezdjük azzal, hogy kitaláljuk az alkalmazás kezdeti üzleti követelményeit:

  • A felhasználói felületnek három fő részből kell állnia:
    • Egy beviteli mező, amely lehetővé teszi a felhasználó számára, hogy beírjon egy új témakör szövegét
    • Az összes létező aktuális elem listája
    • Lábléc szakasz, amely megmutatja a nem befejezett feladatok számát és a szűrési lehetőségeket
  • A Todo listaelemeknek rendelkezniük kell egy jelölőnégyzettel, amely átváltja a "kész" állapotukat. Szintén képesnek kell lenniünk színkódolt kategória címke hozzáadására egy előre definiált színlista számára, és törölni a konkrét elemeket.
  • A számlálónak pluralizálnia kell az aktív feladatok számát: "0 elem", "1 elem", "3 elem" stb.
  • Gomboknak kell lenniük az összes feladat befejezettként való megjelölésére, és az összes elkészített feladat törlésével azok eltávolításával
  • Kétféle módon kell szűrni a megjelenített feladatokat a listában:
    • Szűrés az "Összes", "Aktív" és "Befejezett" feladatok megjelenítése alapján
    • Szűrés egy vagy több szín kiválasztása alapján, és minden olyan Todo megjelenítése, amelynek címkéje megfelel ezeknek a színeknek

A későbbiekben még néhány követelményt felveszünk, de ez elég a kezdéshez.

A végcél egy olyan alkalmazás, amelynek így kell kinéznie:

rész

Az állami értékek megtervezése #

A React és Redux egyik alapelve az a felhasználói felületének az állapotán kell alapulnia. Tehát az alkalmazás megtervezésének egyik megközelítése az, hogy először át kell gondolni az alkalmazás működésének leírásához szükséges összes állapotot. Célszerű megpróbálni a felhasználói felületet a lehető legkevesebb értékkel leírni az állapotban, így kevesebb adatra van szüksége a nyomon követéshez és a frissítéshez.

Fogalmilag két fő szempontja van ennek az alkalmazásnak:

  • Az aktuális aktuális elemek tényleges listája
  • Az aktuális szűrési lehetőségek

Ugyancsak nyomon kell követnünk azokat az adatokat, amelyeket a felhasználó az "Add Todo" beviteli mezőbe gépel, de ez kevésbé fontos, és ezt később kezeljük.

Minden egyes tárgyhoz el kell tárolnunk néhány információt:

  • A felhasználó által beírt szöveg
  • A logikai zászló azt mondja, hogy befejeződött-e vagy sem
  • Egyedi azonosító érték
  • Színkategória, ha be van jelölve

Szűrési viselkedésünk valószínűleg leírható néhány felsorolt ​​értékkel:

  • Befejezett állapot: "Összes", "Aktív" és "Befejezett"
  • Színek: "piros", "sárga", "zöld", "kék", "narancs", "lila"

Ezeket az értékeket megnézve azt is mondhatjuk, hogy a todosok "alkalmazás állapota" (az alapadatok, amelyekkel az alkalmazás működik), míg a szűrési értékek "felhasználói felület állapota" (olyan állapot, amely leírja, hogy az alkalmazás mit csinál jól Most). Hasznos lehet átgondolni ezeket a különféle kategóriákat, hogy megértsük, hogyan használják a különböző állapotokat.

Az államszerkezet megtervezése #

Redux-szel, alkalmazásunk állapotát mindig egyszerű JavaScript objektumokban és tömbökben tartjuk. Ez azt jelenti, hogy nem tehet más dolgokat a Redux állapotba - nincs osztálypéldány, beépített JS típus, például Map/Set Promise/Date, függvények vagy bármi más, ami nem egyszerű JS adat.

A gyökér Redux állapot értéke szinte mindig sima JS objektum, benne lévő más adatokkal.

Ezen információk alapján képesnek kell lennünk leírni, hogy milyen értékekkel kell rendelkeznünk Redux állapotunkban:

  • Először szükségünk van egy tömb Todo objektumra. Minden elemnek tartalmaznia kell ezeket a mezőket:
    • id: egyedi szám
    • szöveg: a felhasználó által beírt szöveg
    • elkészült: logikai zászló
    • szín: Opcionális színkategória
  • Ezután le kell írnunk a szűrési lehetőségeket. Szükségünk van:
    • Az aktuális "befejezett" szűrőérték
    • Az aktuálisan kiválasztott színkategóriák tömbje

Tehát íme, hogyan nézhet ki példa alkalmazásunk állapotára:

Fontos megjegyezni rendben van, ha más állapotértékek vannak a Reduxon kívül!. Ez a példa elég kicsi ahhoz, hogy valójában minden állapotunk meg legyen a Redux üzletben, de mint később látni fogjuk, bizonyos adatokat valóban nem kell a Redux-ban tárolni (például "nyitva van ez a legördülő menü?" "egy űrlapbevitel aktuális értéke").

Műveletek tervezése #

Műveletek sima JavaScript objektumok, amelyek típusmezővel rendelkeznek. Mint korábban említettük, úgy gondolhat egy cselekvésre, mint olyan eseményre, amely leírja az alkalmazásban történt eseményeket.

Ugyanúgy, ahogyan az alkalmazás követelményei alapján terveztük meg az állapotstruktúrát, képesnek kell lenniünk néhány olyan művelet felsorolására is, amelyek leírják a történteket:

  • Adjon hozzá egy új bejegyzést a felhasználó által beírt szöveg alapján
  • A Todo állapotának be- és kikapcsolása
  • Válasszon színkategóriát a kisgyermek számára
  • Törölj mindent
  • Jelöld az összeset befejezettként
  • Az összes törlése befejezte az összeset
  • Válasszon egy másik "befejezett" szűrőértéket
  • Adjon hozzá egy új színszűrőt
  • Távolítsa el a színszűrőt

Rendszerint minden, a történések leírásához szükséges extra adatot betesszük az action.payload mezőbe. Ez lehet szám, karakterlánc vagy több mezőt tartalmazó objektum.

A Redux áruház nem érdekli, hogy mi az action.type mező tényleges szövege. Saját kódja azonban az action.type fájlt fogja megnézni, hogy szükséges-e frissítés. A hibakeresés során gyakran meg fogja nézni a Redux DevTools kiterjesztés művelettípusú karaktersorozatait, hogy lássa, mi történik az alkalmazásban. Tehát próbáljon olyan művelettípusokat választani, amelyek olvashatók és világosan leírják a történteket - sokkal könnyebb lesz megérteni a dolgokat, ha később ránézünk!

A lehetséges események listája alapján létrehozhatunk egy listát azokról a műveletekről, amelyeket alkalmazásunk használni fog:

Ebben az esetben a műveleteknek elsődlegesen egyetlen darab adata van darabonként, ezért ezt közvetlenül az action.payload mezőbe tehetjük. Feloszthattuk volna a színszűrő viselkedését két műveletre, az egyik a "hozzáadott" és a másik az "eltávolított" műveletekre, de ebben az esetben ezt egy műveletként hajtjuk végre, benne egy külön mezővel, hogy kimutassuk, hogy lehetnek objektumaink egy akció hasznos terhe.

Mint az állami adatok, az akcióknak tartalmazniuk kell a legkevesebb információt a történtek leírásához.

Reduktorok írása #

Most, hogy tudjuk, milyen az államszerkezetünk és a cselekedeteink, itt az ideje megírni az első reduktort.

Reduktorok olyan függvények, amelyek az aktuális állapotot és egy műveletet argumentumként veszik fel, és új állapot eredményt adnak vissza. Más szavakkal, (állapot, cselekvés) => newState .

A gyökér reduktor létrehozása #

A Redux alkalmazásnak valójában csak egy reduktor funkciója van: a "root reducer" funkció amelyet később adsz át a createStore-nak. Ez az egy gyökércsökkentő funkció felelős az összes küldött műveletért, és minden alkalommal kiszámítja, hogy mi legyen az egész új állapot eredménye.

Kezdjük azzal, hogy létrehozunk egy reducer.js fájlt az src mappában, az index.js és az App.js mellett .

Minden reduktornak szüksége van valamilyen kezdeti állapotra, ezért hozzáadunk néhány hamis todo bejegyzést a kezdéshez. Ezután írhatunk egy vázlatot a szűkítő funkció belsejében lévő logikához: