React Hooks -funktiot
Olemme aikaisemmin käyttäneet tämän projektin aikana useamman kerran useState-funktiota, joka on React-kirjaston eniten käytetty Hooks-funktio.
Hooks-funktioiden tavoitteena on paketoida jokin usein tarvittava toiminnallisuus yhdeksi kokonaisuudeksi, jota voi sitten hyödyntää aina kun on tarve.
Hooksit ovat oikeastaan ihan tavallisia JavaScript-funktioita, joilla on kaksi lisäsääntöä:
- Hooks-funktioita saa kutsua ainoastaan koodin päätasolla eli niitä ei saa kutsua silmukoiden tai ehtorakenteiden sisältä.
- Hooks-funktioita saa kutsua ainoastaan Reactin (funktio)komponenteista tai itse tehdyistä Hooks-funktioista.
Näiden lisäksi Hooks-funktiot tulee nimetä niin, että ne alkavat sanalla use
.
useLocalStorage-funktion esittely
Seuraavaksi toteutamme oman Hooks-funktion, joka hoitaa taustalle tietojen säilömisen. Lisää src/utils-kansioon uusi tiedosto, anna sen nimeksi useLocalStorage.js
ja liitä sen sisällöksi seuraava ohjelmakoodi, joka pohjautuu Using localStorage with React Hooks-sivulla olevaan koodiin.
import { useEffect, useState } from "react";
// Muuttaa muuttujan JSON-merkkijonoksi.
const decode = (value) => {
return JSON.stringify(value);
}
// Purkaa JSON-merkkijonon muuttujaksi.
const encode = (value) => {
return JSON.parse(value);
}
const useLocalStorage = (key, defaultState) => {
// Tilamuuttujan määrittely, arvoksi haetaan joko
// localStorage-muuttujan arvo tai alkuarvo.
const [value, setValue] = useState(
encode(localStorage.getItem(key) || null) || defaultState
);
// Tallennetaan tilamuuttuja localStorageen aina,
// kun arvo muuttuu.
useEffect(() => {
localStorage.setItem(key, decode(value));
}, [value]);
// Alkuarvojen palautusfunktio.
const resetValue = () => {
setValue(defaultState);
}
return [value, setValue, resetValue];
}
export default useLocalStorage;
Aivan ensimmäiseksi tuodaan React-kirjastosta useState
- ja useEffect
-funktiot, joita koodissa tullaan hyödyntämään.
Esitellään decode
- ja encode
-apufunktiot, joita käytetään muuttamaan ja purkamaan localStorage-taltioon tallennettavaa tietoa. Koska localStorage-taltioon voi talletaan ainoastaan merkkijonoja, on esimerkiksi stats-oliomuuttuja ja storeitems-taulukkomuuttuja muunnettava merkkijonomuotoon. Tämä onnistuu funktioissa käytettävillä JSON.stringify
- ja JSON.parse
-funktioilla. Näistä ensimmäinen muuttaa olio- tai taulukkomuuttujan merkkijonomuotoiseksi, kun jälkimmäinen puolestaan purkaa merkkijonomuotoisen merkinnän olio- tai taulukkomuuttujaksi.
Seuraavaksi esitellään useLocalStorage
-funktio, joka saa kutsuttaessa kaksi parametria: key
ja defaultState
.
Funktion ensimmäisenä vaiheena on tilamuuttujan alustaminen useState
-funktiolla. Tilamuuttujan alkuarvoksi määritellään joko localStorage
-taltioon tallennettu arvo tai defaultState
-parametrin kautta tullut arvo riippuen siitä kumpi löytyy ensin. Funktiokutsujen sisällä olevat or-operaatiot (||
) valitsevat aina käytettäväksi arvoksi ensimmäisen, joka voidaan ajatella muuksi kuin tyhjäksi.
Funktion toisena vaiheena luodaan efektitoiminnallisuus useEffect
-funktion avulla. Sen avulla voi määritellä toiminnan, joka suoritetaan aina kun jonkin muuttujan arvo päivittyy. Funktiolle annetaan kutsussa kaksi parametria: funktio ja taulukko. Suoritetta toiminta määritellään funktion sisällö ja seurattava(t) muuttuja(t) määritellään taulukossa.
Tässä ohjelmakoodissa useEffect
-toiminnan seurattavaksi muuttujaksi määritellään value
-muuttuja. Aina, kun seurattavan muuttujan arvo muuttuu, suoritetaan funktion sisällä oleva ohjelmakoodi, joka tallentaa value
-arvon localStorage
-taltioon.
Funktion kolmantena vaiheena esitellään resetValue
-funktio, jonka avulla tallennetun arvon voi palauttaa alkutilanteeseen.
Aivan lopuksi funktio palauttaa taulukossa kolme asiaa:
- tilamuuttujan,
- funktion, jolla tilamuuttujan arvo päivitetään ja
- funktion, jolla tilamuuttujan arvo palautetaan alkuarvoon.
Tiivistetysti voidaan todeta, että edellä esitelty funktio, toimii pääpiirteissään samalla tavalla kuin useState
-funktio. Keskeinen ero on se, että tekemämme funktio osaa säilyttää tiedon sivulatausten välillä ja sen arvo voidaan tarvittaessa palauttaa alkuarvoon.
useLocalStorage-funktion hyödyntäminen
Otetaan seuraavaksi edellä toteuttamamme useLocalStorage
-funktio käyttöön. Muokkaa src-kansiossa olevaa App.jsx-tiedostoa seuraavasti.
-
Lisää tiedoston alkuun seuraava import-rivi:
import useLocalStorage from './utils/useLocalStorage';
-
Muuta
App
-funktion alussa olevat olevat useState-alustukset seuraavanlaisiksi:// Luodaan taltio, johon tallennetaan pelin laskennalliset tiedot. const [stats, setStats, resetStats] = useLocalStorage('lemon-stats',initialstats); // Luodaan taltio, johon tallennetaan tuotelista. const [storeitems,setStoreitems, resetStoreitems] = useLocalStorage('lemon-items',items);
useLocalStorage
-funktion toiminta on käytännössä hyvin samanlainen, kuinuseState
-funktion toiminta. Alustuksessa määritelläänkey
-arvo, jolla muuttujan tiedot tallennetaan localStorage-taltioon.Testaus
Kokeile pelin toimintaa pelaamalla ja välillä uudelleenlataamalla sivun selaimessa.
Sovellus muistaa nyt pelin tilanteen sivulatausten välillä. Myös pelin tietojen nollaus toimii mainiosti, mutta käytetään siihen
useLocalStorage
-funktion palauttamia reset-funktiota. -
Muuta
handleReset
-funktio seuraavanlaiseksi:const handleReset = () => { // Palautetaan taltiot alkuarvoihin. resetStats(); resetStoreitems(); }
Nyt sovellus toimii kokonaisuudessaan suunnitelman mukaisesti. Seuraavaksi paketoimme sovelluksen julkaisukuntoon ja julkaisemme sen.
Muutosten vienti versiohallintaan
Viedään viimeisimmät muutokset versiohallintaan.
git add .
git commit -m "lisää tallennuksen localStorage-taltioon"