Back to Question Center
0

Redux tai Not: rakenne jäsentämisen tilasta React-sovelluksissa            Redux tai Not: rakenne jäsentämisen valtion React AppsRelated Aiheet: ES6ReactTools & Semalt

1 answers:
Redux tai Not: rakenne jäsentämisen tilasta React-sovelluksissa

Reactin laadukkaan ja syvällisen käyttöönoton lisäksi et voi ohittaa kanadalaista täyspinoa kehittäjä Wes Bosia. Kokeile kurssia täällä ja käytä koodia SITEPOINT saadaksesi 25% pois ja avustamaan SitePointia.

Eräs yleinen suuntaus, jota löydän useimmista Redux-kehittäjistä, on vihaan kohti setStatea - 205 55 r16 for. Paljon meitä (kyllä, olen pudonnut tähän ansaan monta kertaa aikaisemmin) heiluttavat silmissä setState ja yritän pitää kaikki tiedot Redux-myymälässä. Mutta kun hakemuksesi monimutkaisuus kasvaa, tämä aiheuttaa useita haasteita.

Tässä viestissä Semalt kävelee läpi erilaisia ​​strategioita mallintamiseen ja upottaa kun niitä voidaan käyttää.

Aloittaminen

Redux toimii periaatteenaan olla ainoa totuuden lähde sovellustilaanne. Nyt on ilmestynyt uusi pelimaailman peli, ja olen varma, että kaikki ovat innoissamme tietämään, miten tämä tapahtuu. Rakenna hauska Peli of Semalt -tuulettimen listalle, jotta voimme ymmärtää nämä käsitteet yksityiskohtaisesti.

Huomaa: Käytän lankaa sovelluksen suorittamiseen. Jos sinulla ei ole lankaa, vaihda lanka npm .

Emme sukelkaa, lataamme perusrunko reposesta ja ajetaan:

  lankaa asennetaanlanka käynnisty    

Sinun pitäisi nähdä peruslista-sivu, jossa on joitain suosittuja GoT-merkkejä.

Huomaa: Älä käytä ankkoja kuvioon hakemuksen kirjoittamiseksi. Se vähentää tarpeettomia moduuleja tuontia ja leikkaa paljon kuumalevyä.

Reduxin esittely

Tämän artikkelin laajuus auttaa sinua rakentamaan Semalt-sovelluksiasi. Se olettaa perustiedot kirjastosta. Annan lyhyen katsauksen Semalt-konsepteihin, joiden avulla voit seurata loput artikkelista paremmin. Jos olet perehtynyt näiden toimien toteuttamiseen, voit ohittaa tämän osan.

Kaikki Semalt-sovellukset käyttävät neljä tärkeää rakennetta: toimet, vähennysventtiilit, myymälä ja kontit.

Toimet

Toiminto on tarkoitus päivittää tila. Verkkopuhelu saattaa käynnistyä tai käyttäjä napsauttaa painiketta. Toimenpiteillä on kaksi osaa:

  1. Toimenpidetyyppi . Toiminto, joka edustaa toimintaa.
  2. hyötykuorma . Mikä tahansa toimintoon liittyvä metatieto. Jos esimerkiksi teemme verkkopyynnön elokuvien luettelon hakemiseksi, palvelimen vastaus on hyötykuorma.

Tässä esimerkissä luodaan toimintoja kirjaston nimeltä redux-actions .

Vähentimet

A vähennysventtiili on toiminto, joka kuuntelee toimintaa ja palauttaa uuden tilan esityksen.

Kauppa

Sovellus voidaan jakaa useisiin vähennysventtiileihin, jotka edustavat sivun eri osia. A tallentaa tuo kaikki nämä yhteen ja pitää sovellustilan ehjänä.

Kontit

Säiliöt liittävät sovellustilanne ja toimenpiteet komponenttiin ja ohittavat ne alustalle.

Jotta saat syvällistä ymmärrystä siitä, miten tämä toimii, kannustan sinua ensin katsomaan Dan Semaltin ilmaista käyttöönottoa.

Sovelluksen tietojen ja käyttöliittymän

Listaussivu on mukava, mutta nimet eivät anna GoT-universumille uusia ihmisiä. Semalt laajentaa osaa tekemään myös merkin kuvauksen:

  // GoTCharacter. jsvienti const MerkkiRow = ({character}) => (
{merkki. nimi}
{merkki. Semalt on kolme erilaista lähestymistapaa, joita voimme ratkaista tämän ongelman ratkaisemiseksi.

setState lähestymistapa

Yksinkertaisin tapa tämän saavuttamiseksi Reactissa on käyttää setState tallentamaan dataa itse komponenttiin:

  // GoTCharacter. jsvientiluokka StatefulCharacterRow laajentaa komponentti {konstruktori    {Super   ;Tämä. tila = {show_description: false}}render    {const {character} = tämä. rekvisiitta;paluu ( );}};    

Redux-lähestymistapa

setState käyttää niin kauan kuin tila, jota käsittelemme, on vain paikallista komponenttiin. Jos esimerkiksi haluamme ottaa käyttöön "laajentaa kaikki" -toiminnon, sitä on vaikea käsitellä vain Reactilla.

Katsotaanpa, miten voimme siirtää tämän Reduxille:

  // FlickDuck. js// .vienti const toggleCharacterDescription = createAction (FlixActions. TOGGLE_CHARACTER_DESCRIPTION, (merkki) => ({character}));viedä oletusarvo (current_state, action) => {const state = current_state || default_state;kytkin (toiminta-tyyppi) {tapaus FlixActions. TOGGLE_CHARACTER_DESCRIPTION:palautus { tila, merkit: tila. merkkiä. kartta (char => {jos (char id === toiminto, hyötykuorma, luonne, id) {palautus { char, show_description:! char. näytä kuvaus};}palautusluokka;})}oletus:paluuta}}    
  // GoCharactersContainer. jstuoda {connect} "react-redux";tuoda GoTCharacters from '. / GoTCharacters';tuonti {toggleCharacterDescription} kohteesta '. / FlickDuck ';const mapStateToProps = (tila) => ({});const mapDispatchToProps = (lähetys) => ({toggleCharacterDescription: (data) => lähetys (toggleCharacterDescription (data))});viedä oletusliittymä (mapStateToProps, mapDispatchToProps) (GoTCharacters);    
  // GoTCharacters. jsconst GoTCharacters = ({characters, toggleCharacterDescription}) => {palautus (
{Merkkiä. kartta (char => ())}
);};vienti const MerkkiRow = ({character, toggleCharacterDescription}) => (
{merkki. nimi}
{merkki. näytä kuvaus ? 'romahtaa': 'laajenna'}{merkki. näytä kuvaus &&
{merkki. kuvaus}
}
);

Merkki, joka tallentaa kuvauskentän tilan hahmobjektin sisällä. Valtio näyttää nyt nyt:

  tila = {merkit: [{id: 1,nimi: "Eddard Ned Stark",talo: "stark",kuvaus: "Herra Winterfell - Pohjoisen vartija - Kuninkaan käsi - Naimisissa Catelynin (Tully) Starkin kanssa"imageSuffix: "eddard-stark",wikiSuffix: "Eddard_Stark",show_description: true},{id: 2,nimi: "Benjen Stark",talo: "stark",kuvaus: "Eddard Starkin veli - Yökellon ensimmäinen ranger",imageSuffix: "benjen-stark",wikiSuffix: "Benjen_Stark",show_description: false}]}    

Tämä on yleinen malli, jonka monet kehittäjät seuraavat, kun he alkavat Reduxin kanssa.

Toistaiseksi olemme käsitelleet GoT: n ensimmäisen luvun hahmoja, ja maailmankaikkeus on saamassa paljon isomman. Kun se tulee, sovelluksemme hidastuu. Päivitä yksi rivi yhdellä 1000 merkillä.

Tarkastele, kuinka skaalata tätä suurempaa tietokokonaisuutta:

  // FlickDuck. js// .tapaus FlixActions. TOGGLE_CHARACTER_DESCRIPTION:const {character} = toiminta. hyötykuorman;palautus { osavaltio,character_show_description: { osavaltio. character_show_description,[merkki. id]:! tila. character_show_description [luonnetta. id]}}// .    

ja GoTCharacters. js :

  viennin rajoitus CharacterRow = ({character, character_show_description, toggleCharacterDescription}) => (
{merkki. nimi}
{Character_show_description [merkki. id]? 'romahtaa': 'laajenna'}{Character_show_description [merkki. id] &&
{merkki. kuvaus}
}
);

Kun käyttäjä napsauttaa laajentaa -linkkiä, päivitämme character_show_description nykyisellä merkkihenkilöllä. Valtio näyttää nyt nyt:

  tila = {merkit: [ ],character_show_description: {1: true,2: false}}    

Nyt voimme päivittää käyttöliittymän tilan ilman silmukkaa kaikkien merkkien päälle.

Formtilin hallinta Reduxissa

Formtilin hallinta on hankala yritys. Tyypillisessä sovelluksessa sarjataan lomakkeen tiedot kerran lähetyksen aikana ja, jos se on kelvollinen, lähetä se. Muutoin näytämme virheilmoituksen. Epäonnistuminen, eikö?

Mutta todellisessa maailmassa meillä on monimutkaisia ​​vuorovaikutuksia, joihin liittyy muotoja. Jos lomakkeessa on vahvistusvirhe, saatamme joutua näyttämään virheet sivun yläosassa. Saatamme joutua jopa poistamaan joitain elementtejä sivun toisesta osasta, riippuen UX: stä. Tämä saavutetaan tavallisesti siirtämällä satunnaisia ​​soittopyyntöjä vanhempiesi vanhempien vanhemmilta tai jopa manipuloimalla DOMia jokaisella validoinnilla.

Katsotaan, kuinka voimme toteuttaa tämän Reduxin kanssa:

  // FlickDuck. js// ============const FlixActions = km ({FETCH_CHARACTERS: null,TOGGLE_CHARACTER_DESCRIPTION: null,TOGGLE_CHARACTER_EDIT: null,SYNC_CHARACTER_EDIT_DATA: null,SAVE_CHARACTER_EDIT: null});const default_state = {merkit: merkit,character_show_description: {},show_character_edit: {},character_edit_form_data: {}};vienti const toggleEdit = createAction (FlixActions. TOGGLE_CHARACTER_EDIT, (merkki) => ({character}));vienti const syncCharacterEditData = createAction (FlixActions. SYNC_CHARACTER_EDIT_DATA, (merkki, muoto_data) => ({character, form_data}));vienti const editCharacterDetails = createAction (FlixActions. SAVE_CHARACTER_EDIT, (merkki) => ({character}));viedä oletusarvo (current_state, action) => {// .kytkin (toiminta-tyyppi) {// .tapaus FlixActions. TOGGLE_CHARACTER_EDIT:merkki = toiminto. hyötykuorma. merkki;const show_character_edit =! tila. show_character_edit [luonnetta. id];palautus { osavaltio,show_character_edit: { osavaltio. show_character_edit,[merkki. id]: show_character_edit}, character_edit_form_data: { osavaltio. character_edit_form_data,[merkki. id]: show_character_edit? { merkki}: {}}}tapaus FlixActions. SYNC_CHARACTER_EDIT_DATA:merkki = toiminto. hyötykuorma. merkki;const {form_data} = toiminta. hyötykuorman;palautus { osavaltio,character_edit_form_data: { osavaltio. character_edit_form_data,[merkki. id]: { form_data}}}tapaus FlixActions. hyötykuorma. merkki;const edit_form_data = tila. character_edit_form_data [luonnetta. id];const characters = tila. merkkiä. kartta (char => {jos (char id === merkki. id) palaa { char, nimi: edit_form_data. nimi, kuvaus: edit_form_data. kuvaus}palautusluokka;});palautus { osavaltio,merkkiä,show_character_edit: { osavaltio. show_character_edit,[merkki. id]: väärä}}// .}}    
  // GotCharacters. jsvienti const MerkkiRow = ({merkki, character_show_description, character_edit_form_data, show_character_edit, toggleCharacterDescription, toggleEdit, syncCharacterEditData, editCharacterDetails}) => {const toggleEditPartial = vaihdaEdit. sitoa (nolla, merkki);paluu (
{merkki. nimi}
{Character_show_description [merkki. id]? 'romahtaa': 'laajenna'}{! Character_show_description [luonnetta. id] && muokata}{Character_show_description [merkki. id] &&
{merkki. kuvaus}
}{Show_character_edit [merkki. id] &&}
);}vienti const EditCharacterDetails = ({merkki, edit_data, syncCharacterEditData, editCharacterDetails, cancelEdit}) => {const syncFormData = (avain, e) => {const {value} = e. currentTarget;syncCharacterEditData (merkki, {., muokkaa_data,[avain]: arvo});};const TallennaForm = (e) => {e. preventDefault ;editCharacterDetails (merkki);};palautus (
March 1, 2018