React frontend

Millal kasutada Reacti?

React on JavaScripti framework, mis hõlbustab veebirakenduste arendust. See aitab koodi taaskasutada läbi componentide ning lihtsustab keeruliste kasutajaliideste loomist.

Enne Reactiga alustamist on kasulik omada baasteadmisi HTML-ist ja CSS-ist, kuna need on Reacti põhikomponendid.

Kui midagi jääb segaseks, siis saate vaadata antud demo projekti koodi githubis.

Projekti seadistus

  1. Kloonige enda Gitlabi iti0105-2024 repo oma eelistatud IDE-sse.

alt text
  1. Veenduge, et teie iti0105-2024 repo on tühi (ilma HTML või CSS failideta). Varasemad failid saate mujale kopeerida.

  2. Enne projekti seadistamist installige Node.js ja npm, kui olete need installinud, võiksite kontrollida olemasolu IDE terminalist järgnevate käskudega.

node -v
npm -v
  1. IDE terminalist, jooksutage järgnevat käsku.

npm create vite@latest frontend -- --template react
  1. Nüüd tekkis teie projekti frontend nimeline kaust, mille sees on Reacti projekt, paneme selle tööle. (NB! Projekti kaustas on .gitignore fail, mida ei tasu katsuda. See hoolitseb selle eest, et te ebavajalikud failid giti ei pushiks.)

    Selle jaoks teeme terminalis eraldi järgnevad käsud cd frontend (viib frontend kausta), npm install (tõmbab vajalikud package-d) ja npm run dev (käivitab lokaalselt lehe).

    Edaspidi, kui on vaja käivitada projekt lokaalselt, siis piisab npm run dev käsust, kui olete frontend kaustas terminalis. Kuid kui vahepeal on keegi tiimiliikmetest tõmmanud uusi library-si või package-id, siis tuleb enne sisestada ka npm install käsk, sest siis tõmmatakse ka teie arvutisse vajalikud package-d, et projekti käivitada.

    Teie projekt on nüüd saadaval veebibrauseris aadressil http://localhost:5173/

  2. Soovitame kustutada frontend/src kaustast App.css faili, et projekti oleks lihtsam hallata. Olles frontend kaustas jõuame src kausta käsuga cd src.

  3. Soovitame ka lisada meie poolt loodud stiilid index.css faili, et hoida lehte puhtana ja teil oleks lihtsam aru saada, et mis toimub. Hiljem võite seda enda maitse järgi muuta. index.css faili nimi ei pea selline olema, aga tavaliselt index tähistab "peamist" faili. Näiteks kui olete veebilehti teinud puhta HTML ja CSS-iga, siis teate, et tihti nimetatakse avalehte index.html. Siin on põhjus umbes sarnane. Kuna kustutasite App.css faili ära ning tekitasite index.css, siis tuleb failis App.jsx asendada koodirida import ./App.css koodireaga import ./index.css.

/* Lisame lehele ka lühikese CSS Reset-i */
/* https://stackoverflow.com/questions/11578819/css-reset-what-exactly-does-it-do */
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html,
body {
  height: 100%;
}

body {
  line-height: 1.5;
  font-family: sans-serif;
}

img,
picture,
video,
canvas {
  max-width: 100%;
  display: block;
}

button,
input,
textarea,
select {
  font: inherit;
}

a {
  text-decoration: none;
  color: inherit;
}

/* Siit maalt algavad meie lehe stiilid */
body {
  background-color: lightgray;
}

.navbar {
  background-color: gray;
  display: flex;
  justify-content: center;
  gap: 16px;
  padding: 4px;
}

Uue componenti loomine

Component on lihtsalt öeldes mingi element veebilehest, mis omakorda võib tehtud olla teistest componentitest. Ehk näiteks veebilehel saab olla üks component menüü riba, mille sees omakorda componentideks on nupud. Mida rohkem teha veebileht lahti tükkideks ehk componentideks, seda kergem on seda tulevikus hallata ja ümber disainida. Aga siiski tuleks luua componente ratsionaalsuse piires, igat teksti ja pealkirja pole mõtet ka componentiks teha. Componentid aitavad koodi taaskasutada, näiteks saab luua ühe nupu componenti ning seda hiljem kasutada nii mitmes kohas kui ise soovid. Lisaks kui tekib soov nuppu muuta, siis seda tuleb teha ainult ühes kohas ning kõik nupud muutuvad korraga.

  1. Paremaks projekti organiseerimiseks, looge src kausta pages kaust, sinna hakkate lisama enda lehti.

  2. Looge pages kausta sisse Home.jsx nimeline fail (hea tava on hoida funktsiooni ja faili nime samana, aga seda ei pea tegema, kuid siiski soovitame teil hoida samana). Mille sisu on järgnev:

function Home() {
  return (
    <div>
      <h2>Koduleht</h2>
      <p>Muu kirjeldav tekst!</p>
    </div>
  );
}

export default Home;

export default Home see rida eksportib failist componenti välja, et see oleks kättesaadav teistest failidest. Eksporditava componenti nimi peab olema sama, mis funktsiooni nimi nagu on siin mõlema nimi Home.

NB! Iga Reacti component sisaldab JavaScripti (välimine function, return, export jne) ja HTML-i (sisemine <div>, <h2> jne). Praegu on teil vaja keskenduda ainult HTML osale.

  1. Eelnevalt loodud Home.jsx kuvamiseks, lisame selle App.jsx faili.

    Tühjendage olemasolev App.jsx fail ja lisage järgnev sisu:

import Home from "./pages/Home";

function App() {
  return (
    <div>
      <Home />
    </div>
  );
}

export default App;

Nüüd peaksite avalehel nägema enda <Home> componenti sisu. Lehel peaksite nägema tekste "Koduleht" ja "Muu kirjeldav tekst".

App.jsx on nö kõige "kõrgemal" asuv component ehk selle sisse tuleb kogu veebileht. Selle faili nime me ei soovita muuta.

Uue alamlehe lisamine

  1. Alamlehtede lisamiseks, nagu www.veebileht.ee/meist või www.veebileht.ee/kontakt, tuleb projektile lisada üks package. Selleks jooksutage projektiga seotud terminalis, frontend kaustas npm install react-router-dom. See käsk tõmbab react-router-dom package, mis aitab luua lehele navigeerimise süsteemi.

    NB! Kui üks tiimi liige installib projektile uue package'i, peavad järgmisel korral teised tiimiliikmed enne npm run dev käsku jooksutama npm install käsku.

  2. Teeme uue alamlehe, nimega Meist. Selle jaoks lisage src/pages kausta Meist.jsx fail, järgneva sisuga:

    function Meist() {
      return (
        <div>
          <h2>Meist</h2>
          <p>Tekst teie endi kohta!</p>
        </div>
      );
    }
    
    export default Meist;
    
  3. Loome valmis ka lehe päise/headeri, et alamlehtede vahel liikuda. Selleks lisage src/pages kausta Header.jsx fail, järgneva sisuga:

    import { Link } from "react-router-dom"; // Et kasutada eri failides <Link> tööriista, peate selle iga kord importima
    
    function Header() {
      return (
        <div className="navbar">
          {/* Linki sees to="" väärtus peab klappima App.jsx failis oleva Route path="" sisuga. */}
          <Link to="/">Avaleht</Link>
          <Link to="/meist">Meist</Link>
        </div>
      );
    }
    
    export default Header;
    
  4. Lisage App.jsx faili router, mis võimaldab alamlehtede vahel liikuda:

    import { Route, BrowserRouter as Router, Routes } from "react-router-dom";
    import Header from "./pages/Header";
    import Home from "./pages/Home";
    import Meist from "./pages/Meist";
    
    function App() {
      return (
        <Router>
          <Header />
          <Routes>
            {/* Siia saate lisada uusi alamlehti */}
            <Route path="/" element={<Home />} />
            <Route path="/meist" element={<Meist />} />
          </Routes>
        </Router>
      );
    }
    
    export default App;
    

    Nüüd saate navigeerida avalehe ja meist lehe vahel.

Componentide taaskasutatavus

Nüüd näitame teile, kuidas luua ühte componenti, milles saab olla erinev sisu. Samuti saab seda componenti mugavalt taaskasutada. Näiteks järgnevad 2 dünaamilist infokaarti saab lehele lisada kahe koodireaga.

../_images/image-1.png ../_images/image-3.png
  1. Looge src kausta sisse components kaust. Sinna sisse hakkate enda taaskasutatavaid componente lisama, alustades ContactCard.jsx failist.

    function ContactCard() {
      return (
        <div>
          <h4>Mathias</h4>
          <p>Vanus: 21</p>
        </div>
      );
    }
    
    export default ContactCard;
    
  2. Et kuvada loodud componenti Meist lehel, lisame Meist.jsx faili algusesse import ContactCard from "../components/ContactCard"; ja keskele, HTML osa sisse <ContactCard/> component.

    import ContactCard from "../components/ContactCard";
    
    function Meist() {
      return (
        <div>
          <h2>Meist</h2>
          <p>Tekst teie endi kohta!</p>
          <ContactCard />
        </div>
      );
    }
    
    export default Meist;
    
  3. Aga sooviks, et kaart näeks parem välja, selle jaoks lisame CSS stiile. Anname klassile nime className abil.

    function ContactCard() {
      return (
        <div className="contact-card">
          <h4>Mathias</h4>
          <p>Vanus: 21</p>
        </div>
      );
    }
    
    export default ContactCard;
    

    Nüüd saame index.css faili lisada meie klassi nime kohta stiilid.

    .contact-card {
      background-color: gray;
      padding: 6px 20px;
      border-radius: 8px;
      width: fit-content;
      margin-top: 8px;
    }
    
  4. Hetkel mitu korda <ContactCard> componenti kasutades, oleks meil alati sama sisu. Muudame selle dünaamiliseks Reacti propside abil. Printsiip on sarnane nagu nt Pythoni funktsioonides, lisame componentile parameetrid name ja age ning kasutame neid HTML-i sees.

    function ContactCard({ name, age }) {
      return (
        <div className="contact-card">
          <h4>{name}</h4>
          <p>Vanus: {age}</p>
        </div>
      );
    }
    
    export default ContactCard;
    
  5. Nüüd peame Meist.jsx failis olevale <ContactCard> componentile argumendid sisse andma, seda saame teha järgnevalt.

    import ContactCard from "../components/ContactCard";
    
    function Meist() {
      return (
        <div>
          <h2>Meist</h2>
          <p>Tekst teie endi kohta!</p>
          <ContactCard name={"Mathias"} age={21} />
          <ContactCard name={"Martin"} age={20} />
        </div>
      );
    }
    
    export default Meist;
    

    Nüüd peaks lehel näha olema teie poolt sisestatud andmetega <ContactCard> componentid.

Mock data

Kui hakkame backendist andmeid frontendi tooma, tulevad need tavaliselt listina. Seetõttu on kasulik hoida ka oma staatilisi andmeid listis, et backendi ühendamine oleks hiljem lihtsam ja kiirem protsess.

Samuti saame kasutada map() funktsiooni, et loopida üle listi ja ei pea iga kord käsitsi componente, nagu siinkohal <ContactCard>, välja kirjutama.

<ContactCard name={"Mathias"} age={21} />
<ContactCard name={"Martin"} age={20} />
  1. Impordi useState ja loo list algandmetega: Mis on useState?

    // Fail Meist.jsx
    import { useState } from "react";
    import ContactCard from "../components/ContactCard";
    
    function Meist() {
      const [contacts, setContacts] = useState([
        { name: "Mathias", age: 21 },
        { name: "Martin", age: 20 },
      ]);
    
      return (
        <div>
          <h2>Meist</h2>
          <p>Tekst teie endi kohta!</p>
          <ContactCard name={"Mathias"} age={21} />
          <ContactCard name={"Martin"} age={20} />
        </div>
      );
    }
    
    export default Meist;
    
    const [contacts, setContacts] = useState([{ name: "Mathias", age: 21 },{ name: "Martin", age: 20 },])
    

    Selle reaga me loome muutuja contacts ja selle muutuja muutmiseks funktsiooni setContacts(). useState() sulgude vahele tuleb contacts muutuja algväärtus ehk selleks on list [{ name: "Mathias", age: 21 },{ name: "Martin", age: 20 }]. Näiteks kui tahaksime nüüd muuta contacts väärtust, siis tuleks teha seda nii setContacts([{ name: "Kaido", age: 32 },{ name: "Merily", age: 30 }]). React-is on tavaks see, et kui lood muutuja nimega x, siis muutujat muuteva funktsiooni nimi on setX ehk "set" tuleb ette.

  2. Loopi üle listi, map() funktsiooni abil ja renderda <ContactCard> componendid:

    // Fail Meist.jsx
    import { useState } from "react";
    import ContactCard from "../components/ContactCard";
    
    function Meist() {
      const [contacts, setContacts] = useState([
        { name: "Mathias", age: 21 },
        { name: "Martin", age: 20 },
      ]);
    
      return (
        <div>
          <h2>Meist</h2>
          <p>Tekst teie endi kohta!</p>
          {contacts.map((contact) => (
            <ContactCard name="{contact.name}" age="{contact.age}" />
          ))}
        </div>
      );
    }
    
    export default Meist;
    

Kokkuvõte

NB! Soovitame teil nüüd mõned nädalad projekti ise edasi arendada. Saate lisada rohkem alamlehti ja neid disainida. Kindlasti looge erinevaid componente, et mitmekesi koos arendamine oleks sujuvam ja kood oleks taaskasutatavam.

Küsimuste tekkimisel proovige alguses vastuseid leida internetist, kuna see arendab teid kõige rohkem. Spetsiifiliselt Reacti kohta õppimiseks on hea materjal nende enda lehel asuv dokumentatsioon.