Action-objektin datan valmistelu Reduxissa

Puhuimme hiljattain siitä, että funktio createSlice odottaa yhtä argumenttia luodessa action.payload:ia. Toisaalta tämä yksinkertaistaa sen käyttöä, toisaalta se voi vaatia lisätoimia action-objektin sisällön valmistelussa.

Avataan sovelluksemme tuotteiden kanssa, ja siellä tiedosto NewProductForm.jsx. Kiinnittäkää huomiota seuraavaan koodiriviin:

NewProductForm.jsxdispatch(productAdded({
  id: nanoid(), name, desc, price, amount
}))

Tässä kokoamme payload-objektin suoraan React-komponentissa ja välitämme sen actioniin productAdded. Mutta entä jos meidän täytyy lähettää samanlainen action useista komponenteista tai datan kokoamisen logiikka osoittautuu monimutkaiseksi? Ideana komponenttimme ei pitäisi välitä siitä, miltä payload-objekti tässä actionissa näyttää. Lisäksi emme ole tyytyväisiä koodin jatkuvaan toistoon.

Nämä ongelmat voi taas auttaa meitä ratkaisemaan kuuluisa createSlice, koska reducerin kirjoittamisessa se sallii meille käyttää callback-funktiota prepare, johon voi kirjoittaa erilaista logiikkaa, generoida satunnaislukuja ja muuta. Tällöin reducerin kentän arvo voi olla esitetty seuraavanlaisena objektina:

jsx{reducer, prepare}

Avataan tiedostomme productsSlice.js ja muutetaan koodi reducerille productAdded. Nyt tämä koodinpala:

products/ProductSlice.jsproductAdded(state, action) {
  state.push(action.payload)
},

Vaihdamme seuraavaan, jossa funktio reducer hoitaa staten päivittämisen storeen, ja prepare - palauttaa payload-objektin generoidulla id:llä ja muilla datallamme:

products/ProductSlice.jsproductAdded: {
  reducer(state, action) {
    state.push(action.payload)
  },
  prepare(name, desc, price, amount) {
    return {
      payload: {
        id: nanoid(),
        name,
        desc,
        price,
        amount,
      },
    }
  },
},

Koska nyt aiomme generoida id:n täällä, emmekä komponentissa, lisätään nanoid importtiin:

products/ProductSlice.jsimport { createSlice, nanoid } from '@reduxjs/toolkit'

Lopuksi teemme muutokset tiedostoon NewProductForm.jsx. Rivin sijasta:

products/NewProductForm.jsxdispatch(productAdded({
  id: nanoid(), name, desc, price, amount
}))

Meillä on tällainen, jossa yksinkertaisesti pilkulla erotellen välitämme tarvitsemamme datan (älä unohda poistaa tästä tiedostosta nanoid importista):

products/NewProductForm.jsxdispatch(productAdded(name, desc, price, amount))

Käynnistetään sovellus, luodaan sitten uusi tuote ja varmistetaan, ettemme ole rikkoneet mitään.

Задание 1

Avaa opiskelijasovelluksesi. Tiedostossa StudentsSlice.js kirjoita uudelleen reducerisi studentAdded siten, että se on muodossa {reducer, prepare}, kuten oppitunnissa näytetään.

Задание 2

Tee vastaavat muutokset tiedostoon NewStudentForm.jsx, kuten oppitunnissa näytetään. Käynnistä sovellus ja varmista, että kaikki toimii kuten ennenkin.