Thunkin toiminnan tulosten näyttäminen komponentissa Reduxissa

Edellisellä oppitunnilla lähetimme POST-pyynnön käyttämällä thunkia addProduct. Näytetään nyt sen toiminnan tulokset komponentissa.

Avataan tuotesovelluksemme ja sen sisällä tiedosto NewProductForm.jsx, koska tämä komponentti vastaa uuden tuotteen lisäämisestä. Katsotaan import-rivejä. Korvataan actionin productAdded import thunkin addProduct importilla:

products/NewProductForm.jsximport { addProduct } from './productsSlice'

Nyt, koska emme seuraa slaysissä pyynnön 'pending' statusta, tehdään niin, että käyttäjä voi painaa tuotteen tallennuspainiketta vain kerran, sillä emme tarvitse samoja toistuvia pyyntöjä. Tehdään tätä varten toinen paikallinen tila:

products/NewProductForm.jsxconst [requestStatus, setRequestStatus] = useState('idle')

Seuraavaksi, käsittelijöiden jälkeen ja ennen funktiota onSaveProductClick kirjoitetaan koodi, jossa tarkistamme, onko kaikki lomakkeen kentät täytetty ja onko pyynnön tila 'idle':

products/NewProductForm.jsxconst canBeSaved =
  [name, desc, price, amount, sellerId].every(Boolean) &&
  requestStatus === 'idle'

Sitten muutamme koodin onSaveProductClick varten. Ensinnäkin se on asynkroninen funktio ja se suoritetaan, jos yllä oleva ehto pätee:

products/NewProductForm.jsxconst onSaveProductClick = async () => {
  if (canBeSaved) {}
}

Vaikka emme slaysissä seuraa statusta 'rejected', voimme silti tulostaa konsoliin virheen käyttämällä try-catch -rakennetta. Lisäämme tähän myös finally -osan, jotta pyynnön suorituksen jälkeen asetamme paikallisen tilan takaisin arvoon 'idle':

products/NewProductForm.jsxconst onSaveProductClick = async () => {
  if (canBeSaved) {
    try {
    } catch (err) {
      console.error('save product error: ', err)
    } finally {
      setRequestStatus('idle')
    }
  }
}

Käsiteltyämme catch- ja finally -lohkot, kirjoitetaan koodi try -lohkoon. Tässä asetamme paikallisen tilan arvoon 'in pogress', kunnes saamme vastauksen thunkin toiminnan tuloksena, jonka jälkeen lähetämme thunkin addProduct. try-catch -rakenteen käyttämisen mahdollistaa vastauksen tyypistä riippuen RTK:n funktio unwrap, jonka se lisää palautettuun promiseen. Sitten, jos pyyntö onnistui, asetamme paikalliset tilat niiden alkuperäisiin tiloihin. Koko koodi onSaveProductClick -funktiolle näyttää tältä:

products/NewProductForm.jsxconst onSaveProductClick = async () => {
  if (canBeSaved) {
    try {
      setRequestStatus('in progress')
      await dispatch(
        addProduct({ name, desc, price, amount, seller: sellerId })).unwrap()
      setName('')
      setDesc('')
      setPrice(0)
      setAmount(0)
      setSellerId('')
    } catch (err) {
      console.error('save product error: ', err)
    } finally {
      setRequestStatus('idle')
    }
  }
}

Käynnistetään sovelluksemme ja yritetään lisätä uusi tuote. Kuten näette, onnistuneen pyynnön tapauksessa kentät tyhjennetään ja uusi tuote lisätään tuotelistaan. Kurkkaa myös selaimen Redux DevTools -sovellukseen ja selaile sen välilehtiä, katso actioneita ja miten tilasi muuttuu.

Задание 1

Avaa opiskelijasovelluksesi. Avaa sen sisällä tiedosto NewStudentForm.jsx. Lisää toinen paikallinen tila requestStatus, ja aseta sen alkuarvo 'idle'. Tutkittuasi oppitunnin materiaalin, luo muuttuja canBeSaved, jonka avulla uuden opiskelijatietojen tallennuspainike toimii/ei toimi, riippuen requestStatus -arvosta ja kenttien täyttötilasta.

Задание 2

Kirjoita asynkroninen koodi onSaveStudentClick -funktiolle, joka muuttaa requestStatus -arvoa tilanteen mukaan, lähettää thunkin addProduct uuden opiskelijan tiedoilla, tyhjentää kentät onnistuneen pyynnön tapauksessa ja tulostaa konsoliin virheen epäonnistuessa, kuten oppitunnilla näytettiin. Käytä tähän try-catch -rakennetta ja RTK:n unwrap -funktiota.

Задание 3

Käynnistä sovelluksesi, lisää uusi opiskelija ja varmista, että kaikki toimii.