Oliomuuttujan tallennus state-tilamuuttujaan

Edellä toteutimme napautusten tallennuksen tilamuuttujaan. Pelissä joudumme tallentamaan napautusten lisäksi useampi muu asia tilamuuttujiin. Tämä onnistuu luomalla jokaiselle tallennettavalle asialle oma tilamuuttujansa, mutta jokainen niistä pitäisi erikseen välittää niitä tietoja tarvitseville alikomponenteille. Toisin sanoen ennen pitkään tilamuuttujien lisäämiselle tulee raja vastaan koodin ylläpidettävyyden näkökulmasta.

Seuraavaksi ratkaisemme tämän asian muuttamalla toteuttamamme tilamuuttujan tallentamaan yksittäisen luvun sijasta oliomuuttujan, joka voi sisältää useamman tiedon. Ensimmäisessä vaiheessa tallennamme oliomuuttujaan napautusten määrän (clicks), käytettävissä olevan saldon (balance), yksittäisellä napautuksessa kasvatettava määrä (increase) ja ostettavien lisäosien määrä (itemstobuy). Näistä arvoista ainoastaan clicks-arvoa päivitetään, muiden arvojen päivitys toteutetaan myöhemmissä vaiheissa.

Avaa src-kansiossa oleva App.jsx-tiedosto ja muuta funktion alussa esitelty useState-muuttuja seuraavanlaiseksi:

  // Luodaan tilamuuttuja, johon tallennetaan pelin laskennalliset tiedot.
  const [stats, setStats] = useState({clicks: 0, balance: 0, increase: 1, itemstobuy: 0});

Tämä rivi on rakenteeltaan samanlainen. useState-funktion palauttamat muuttuja ja asetusfunktio tallennetaan eri nimillä. Lisäksi alkuarvoksi asetetaan oliorakenne.

Oliorakenteisen tilamuuttujan päivittäminen on aavistuksen haasteellisempaa kuin tavallisen muuttujan päivittäminen. Ennen arvon päivittämistä oliosta täytyy tehdä kopio, jonka arvoja muokataan. Muokkaa handleClick-funktio seuraavanlaiseksi:

  const handleClick = () => {
    // Tehdään kopio stats-tilamuuttujasta.
    let newstats = {...stats}
    // Kasvatetaan napautusten lukumäärää yhdellä.
    newstats.clicks = newstats.clicks + 1;
    // Tallennetaan päivitetty stats-muuttuja.
    setStats(newstats); 
  }

Oliorakenteesta voi tehdä kopion useammalla eri tavalla. Tässä käytetty menetelmä soveltuu yksitasoiseen rakenteseen.

{...stats} avaa stats-oliorakenteen auki eli ottaa sen jokaisen alkion omaksi arvokseen. Lopputuloksena syntyy alkuperäisen muuttujan kopio.

Muokkaa vielä funktion return-lausen seuraavanlaiseksi:

  return (
    <div className="root">
      <div className="root_content">
        <div className="container clicker">
          <Header>lemon clicker</Header>
          <Balance total={stats.clicks} />
          <Lemon onClick={handleClick} />
          <Booster value={stats.increase} />
        </div>
      </div>
      <Menu items={stats.itemstobuy} />
    </div>
  )

Sisältö ei rakenteellisesti muuttunut mihinkään, ainoastaan komponenteille välitettävät tiedot haetaan tilamuuttujasta.

Näiden muutosten jälkeen sovelluksen toiminnassa ei tapahtunut muutosta.

Sovelluksen tiedot haetaan tilamuuttujasta

Muutosten vienti versiohallintaan

Viedään viimeisimmät muutokset versiohallintaan.

git add .
git commit -m "muuttaa state-muuttujan tallennusmuodon"

muuttaa state-muuttujan tallennusmuodon -commit