React Kreairanje app -Kreiranje app mozemo uraditi na vise nacina, mi cemo raditi preko create react app komande u cmd-u, da bi to uradili potreban nam je up to date Node, otvorimo cmd, pozicioniramo se na zeljeni folder I unesmo komandu: npx create-react-app <ime_app>. NOTE: instalacija zna da potraje. -Kada otvorimo u vs code-u app, videcemo dosta fajlova I foldera, folder node_modules sadrzi sve dependecies I dosta zauzima(230MB), tako da Ninja je na githubu stavio sve sem tog modula, pa kada skinemo nesto sa githuba u terminalu je potrebno uneti npm install kako bi se instalirali moduli. Components & Templates -Komponente su blokovi za izgradnju I srce react aplikacije. Komponente ce sadrzati Template I JS (TS) logiku. Komponente u sustini predstavljaju funkciju I uvek mora nesto da vracaju I generalno ce to biti jsx template, I bitno je da na kraju komponente exportujemo komponentu da bi je koristili u drugim fajlovima. 1 Dynamic Values in Templates -Ovo je jako zgodna stvar, zamislimo da zelimo da stavimo naslov strane, mozemo da je hardkodiramo ali to nije dobro, dinamicke values u templates nam omogucavaju da stavimo promenljivu umesto imena a kasnije to promenljivi da dodelimo vrednost. Ovo je korisno kad povucemo podatke iz baze. Dinamicke vrednosti se pisu u {} zagradama, primer: <p> { <variable name> } </p> Multiple Components App.js je root komponenta, I ona je na vrhu, I sadrzi druge pod komponente, prakticno kreiramo stablo.Ako zelimo novu komponentu, onda je ulancamo u stablo. 2 -Setimo se onih simple java sniptes koji se definisu u vs code settings, e sada dolaze do izrazaja, kada zelimo da kreiramo novu komponentu, napravimo novi js file, I u prvoj liniji koda ukucamo sfc I pritisnemo taster tab, I onda nam se kreira vec arrow function za komponentu, jako ubrzava posao. -Ovako izgleda “nesting” komponenta, mozemo da napisemo ovako <Navbar /> ILI <Navbar > </Navbar> Adding styles & inline styles 3 -Obratiti paznju, svi stilovi su kao u css-u, par key-value, keys kada pisemo ovako dinamicki u js fajlu, nisu isti kao kada pisemo u css-u, u css-u bi backgroundColor bio, background-color, to je zato sto pisemo u js fajlu, takodje kada pisemo u js fajlu, ovaj key se pise kao camel case. Click events Kada imamo web sajt, postoje dosta event-a koji se desavaju, neki su: hover events, click events, form submissions events, keyboard events, scroll events, loading events itd. Sada cemo pokaziti jedan prost primer click event-a. Princip se svodi, da u komponenti, pre return dela, napravimo arrow funkciju koja ce da handluje event, nazovimo je recimo handleName(neka konvencija je da se svi handleri eventa, nazovu prvo handle pa onda ime koje ce dodatno da opise event), recimo ovako nesto(uokvireno zelenom bojom): 4 -Obratiti paznju na crvenu strelicu, kreirali smo button I dodali joj onClick proptery, medjutim potrebno je biti oprezan sa ovim, mi bi trebali tu da joj dodelimo referencu na handler funkcije, ovako kako smo uradili, mi smo odmah pozvali funkciju cim smo pokrenuli program, znaci resenje je izostaviti zagrade, znaci bice: <button onClick={handleClick}> Click me! </button> Znaci nema zagrada. -Ali sta ako zelimo da arrow funkcija koja handluje event ima parametre? **Resenje su anonimne funkcije! I to ovog oblika: Na ovaj nacin kreiramo funkciju koja ce da se trigeruje kada user klikne na button. 5 Tako da mozemo da uradimo nesto ovako: Na ovaj nacin se nece pozvati funkcija handleClickAgain kada se ucitava stranica, zato sto smo je wrapovali u anonimnu funkciju!! Event objects -To je ustvari parametar koji je uvek tu kada se trigeruje event. Kod event handlera taj parametar je uvek tu, samo sto smo ga izostavili kada smo pisali funkciju,a zapravo mozemo da stavimo kao parametar eksplicitno. Problem je kako pribaviti taj objekat kod handlera koji imaju parametre, kao npr kod handleClickAgain, zato sto nije referencirana kao funkcija? **Resenje je da anonimoj funkciji odmah prosledimo objekat event-a I to kasnije prosledimo handleru, resenje: 6 React dev tools -Ekstenzija koja pomaze pri development-u react aplikacija, kao na primer: Kreira nam Component tree, pri cemu nam olaksava da vidimo rezultat integracije komponenti na strani. I kada kliknemo na neku od komponenti, daje nam dodatne informacije o samoj komponenti. Using state(useState hook) -Pod state of component misli se na podatke koji se koriste u komponenti u datom trenutku. Ta stanja mogu biti nizovi, objekti, stringovi itd. -Stanja su zgodna ako recimo zelimo da kada korisnik nesto klikne, da se neki sadrzaj promeni, kao sada u primeru, gde cemo nakon klika dugmeta promeniti neki tekst na ekranu. -Na ovom primeru vidimo da kada kliknemo na dugme, trigeruje se event koji handluje funkcija handleClick u kojoj menjamo tekst u promenljivoj “name”, medjutim da li je to dovoljno da se taj tekst promeni I na ekranu? 7 -Odogovor je nije, efekat klika je da se zaista promeni vrednost u promenljivoj name, medjutim to se ne renderuje na ekranu, promnljiva zargonski receno nije “reactive”, odnosno sam React je ne posmatra I ne posmatra promene koje se dogadjaju nad njom koje bi trigerovale rerenderovanje. Znaci resenje je da podesimo da je promenljiva reaktivna, odnosno koristimo hook, ili preciznije receno useState. useState je funkcija, praksa je da naziv uvek krece sa use sto oznacava da se radi o useState hooks. -Da bi radili sa useState hooks, moramo ukljuciti biblioteku iz React-a,a to je: import { useState } from "react"; -Da bi napravili reactive value korisitmo useStates funkciju I dodelimo joj inicijalnu vrednost, na primer: useStates(‘mater’). Medjutim nije tu kraj, mi tu funkciju moramo da smestimo negde, tako da definisemo: const [<ime promenljive inicijalne vrednost>, <ime funkcije koju cemo koristiti kako bi promenili vrednost(dobra praksa je da ime te funkcije krece sa set<pa nastavak imena>)>] = useState(‘mater’), tako da ce finalni rezultat izgledati: const [name,setName]=useState(‘mater’); 8 Na ovaj nacin, kad god kliknemo na button, svaka promena ce se rerenderovati I prikazati na ekranu. Outputting Lists Ovo je izuzetno bitno, posto cemo cesto imati elemente koji se ponavljaju I slicno, u ovom slucaju zelimo da napravimo web sajt koji sadrzi blogove, a 9 predstavicemo ih preko array-a, postavlja se pitanje kako to napraviti a da ujedno bude I reactive(odnsono da se svaka promena da bude renderovana)? **Odgovor se nalazi u useState hooks, I funkciji map I property key. Na slici svetlo zelenom bojom obelezen je key, izuzetno bitna stvar, ona nam omogucava da kreiramo nesto nalik dom stablu(ako ne bas I dom stablo, tako React prati svaki element ovog niza, kreira stablo), tako da ako recimo promenimo tekst u blogu 1, ta promena ce se direktno odraziti na taj blog I renderovace se, a ne na neki drugi, zato nam je potreban taj key, koji ce da ima jedinstvenu vrednost, znaci NE SME BITI PREKLAPANJA vrednosti key-va. Props & Reusable Components -Ako imamo neku komponentu koju cemo da korisitmo na vise mesta, ono sto mozemo da napravimo je da kopiramo isti kod I da prilagodimo konkretnoj nameni, TO NIKAKO NE RADITI, zato su osmisljeni props I reusable components. Tako da ako imamo delove komponenti ili templejta koje se mogu iskoristiti na razlicitim mestima u web sajtu onda to mozemo napraviti da bude reusable component. -Cemu onda sluzi props? **Ono sto radimo kod reusable komponenti je da ih definisemo u posebnom fajlu, a da bi toj komponenti prosledili podatke onda koristimo props.Tako da prakticno props predstavljaju nacin da prenesemo vrednost sa jedne komponente(parent component) na drugu komponentu (child component). 10 -Prvo sto radimo je kreiranje reusable komponenti,odnosno novi fajl I napisemo template: -Zatim BlogList.js ukljucujemo u Home.js I prosledjujemo props-e: -DOBRA STVAR je sto na nekin nacin koriste hooks, tako da ako u home kompnenti promenimo tekst odmah ce se renderovati na strani! 11 Reusable components Dodatno pojasnjenje. Reusable components su jako znacajne kod serach mehanizma. 12 Functions as Props Pored podataka kao sto su strings, arrays I slicno, kao props mozemo proslediti I funkcije, to nam omogucava da iz child komponete imamo pristup podacima u parent komponenti, tako sto ce parent komponenta proslediti funkciju kao props a dete kada je bude pozvalo, pozvace se sama funkcija iz parent-a. Pogledajmo primer, napravili smo button u child komponenti koji ce da brise blog sa ekrana, medjutim ne moze tek tako da pristupi podacima iz parenta da bi se obrisalo, problem se resava kao na slici: 13 -Important note, da bi se promenio array, mora se pozvati funkcija setBlog definisana useState-om za konkretan array. useEffect Hook -Ovo je jos jedna vrsta hook-a, ranije smo videli koriscenje useState da bi kreirali neko stanje za komponentu, ali to je samo jedna od mnogih. -useEffect pokrece funkciju svaki put kada se komponenta renderuje(obratiti paznju, komponenta se renderuje inicijalno kada se pokrece I takodje kada se stanje promeni(recimo ono sa useState)). To moze biti korisno kada se fetch-uju podaci, kada komuniciramo sa autentifikacionim servisom itd. To se zove side effects react-a. -da bi se koristio useEffect Hook, potrebno je importovati biblioteku: import {useEffect} from ‘react’. - sintaksa: useEffect( () => { } ) 14 Obratiti paznju da je ne dodeljujemo promenljivoj, samo joj prosledjujemo funkciju u argumentu. Biti oprezan sa koriscenjem useState-a u useEffect hook-u! useEffect Hook Dependencies -Kao sto smo rekli, useEffect hook se poziva svaki put kada se renderuje komponenta, to nekad ne zelimo da se desi, odnosno da se ne poziva sa svakim renderovanjem, da bi to ostvarili potreban nam je dependecy array. -Dependecy array ( [] ) to je zapravo niz koji mozemo da prosledimo useEffect-u kao drugi argument, tj. : 15 -Ono sto mozemo uraditi je dodati dependcies u ovaj niz, tako da state value ce trigerovati pokretanje use effect funkcije, kada se state promeni, naravno za odgovarajuci state koji podesimo. Tako da na ovaj nacin useEffect se nece pozivati za sve promene statea, nego samo kada se promeni state name. 16 Using JSON server -Da ne bi pravili bazu, I kreirali api, koristicemo ovu “fake” DB. -Da bi pokrenuli bazu, otvoriti poseban termnal I uneti: npx json-server --watch <putanja> --port 8000, tj. npx json-server --watch data/db.json --port 8000. Conditional Loading Message -Dobar primer upotrebe ovog mehanizma je kada zelimo da prikazemo neke podatke korisniku, ali medjutim baza jos uvek nije zavrsila slanje svih podataka I nije prikazno na ekranu, ono sto mozemo da uradimo je da obavestimo korisnika da se podaci pribavljaju, za ovo ce nam biti potebni useState hooks I kondiocioni operatori, Pogledajmo sliku: 17 d-kreiramo state koji se zove isLoading, koji je podsen na true,a kako je true, onda ce uslov isPending && biti true, kada se svi podaci ucitaju, u samom fetch delu, ovaj state cemo postaviti na false, tako da se vise ne prikazuje poruka “Loading…”. NOTE: ovo je nastavak prethodnog zadatka, vise I fetchu videti u naslovu iznad. 18 Handling Fetch Errors Making custom hook -ovo nam omogucava da urednije pisemo kod, recimo za pribavljanje podataka, mozemo da napisemo kod u posebnom fajlu, I posle da to importujemo na mestima gde nam je potrebno, ovo nam omogucava stabilniji kod. -da bi napravili custom hook, napravimo poseban fajl, I funkciji koja krece sa nazivom use(inace nece da radi) I da napisemo logiku. 19 20 The React Router -Trenutno nasa aplikacija ima samo jednu stranicu, u realnosti imacemo mnogo vise, pa da bi koristili multiple pages, korisitmo react router. Postavlja se pitanje, sta tacno React Router radi? Zamislimo da imamo sajt, koji kada se pokrene, prvo se obrati serveru da dobije izgled pocetne strane, pa recimo kliknemo na neku opciju sajta recimo “Contacts”, sajt ce morati da se obrati serveru da posalje izgled te nove stranice koja sadriz kontakte, to je veoma sport proces, da bi se to izbeglo koristi se react route, odnosno na prvom ucitavanju sajta, obracamo se serveru da dobijemo inicijalni izgled sajta, ali server ce pored toga poslati I bundle, koji sadrzi iskompajlirane komponente sajta, pa tako, ako recimo korisnik zahteva “Contacts” sajt se nece obracati serveru za tu komponentu, vec browseru odosno react routeru. Sajt koji ne koristi react router: 21 Sajt koji koristi React Router: -Da bi koristili React Router, moramo da instaliramo taj paket, a za to nam je potreban npm, u terminalu unesemo: npm install react-router-dom@5 (ovo 5 je verzija), nakon instalacije, mozemo ga videti u package.json: 22 -Ono sto treba da se modifikuje je root komponenta: 23 Exact Match Routes -Ovde imamo primer dodavanja komponenti u routeru, medjutim na ovaj naicn kako je dodatao, ova create komponenta se nece nikad prikazati kada je pretrazujemo, recimo da smo u brosweru uneli: “localhost:3000/Create”, ipak ce se pozvati ova home komponenta(zaokruzeno zelenom bojom), zbog cega? Zato sto kada unesemo path, react router ce da pretrazuje ove putanje od top to down, pa prvu na koju naidje, on ce da tu uzme, medjutim, iako /create I / nisu isti, ipak ce da uzme / zato sto kao sto sam rekao uzima prvu na koju mu lici da je unesena u browseru, a posto mu ova zbog ovog znaka / odmah lici da je unesena putanja, on ce nju da uzme. 24 Da bi izbegli ovo, potrebno je uneti ispred property-ja path, kljucnu rec exact, tj. Medjutim kada god kliknemo na neko od dugmeta, I dalje se salje request serveru a ne react routeru, da bi se to resilo potreban nam je router links. Route links Da bi smo iskoritili da browser salje zahteve React Router-u umesto serveru, potrebno je da za button-ne koji su vezani za komponente, umesto <a></a> iskoristimo <Link> </Link>, a da bi iskoristili Link potrebno je importovati: 25 useEffect Cleanup -Ovo je potrebno da bi se fetch prekinuo, ovo je bitno ako podesimo neki button da kada kliknemo na njega fetch-ujemo podatke iz baze, I onda se predomislimo I kliknemo na neki drugi button tj. : Ako kliknemo na home(pribavljamo podatke) I zatim brzo kliknemo na New Blog, desice se ovaj error, jer fetche se prekinuo na pola izvrsenja, ono sto je potrebno da uradimo, je da abort-ujemo fetch, odnsono zaustavimo fetch. 26 -Bitno je proveriti ovaj if uslov, odnsono nazi ove greske(“AbortError”)! Route parameters -Nekad je potrebno da prosledimo dinamicke vrednosti kao deo Route, odnosno da imamo Route cije jedan deo promenljiv. Recimo da imamo /blogs/123, gde je ovo 123 ID bloga kojeg zelimo da renderujemo, ali ovo je fiksno dodeljen ID, sta ako zelimo da prikazemo blog sa ID-em 463 ili 674 itd. Zato su nam bitni Route Parameters, ovo 123 ili 463 itd. Mozemo da posmatramo kao promenljivu. Da bi napravili Route parametar, ono sto je potrebno da dodamo je /blogs/:<neko_ime>, kao npr /blogs/:id odnosno: 27 Tako da mozemo to kao id da prosledimo sta god pozelimo, recimo /blogs/123, /blogs/353 itd. Postavlja se pitanje kako da preuzmemo onda te vrednosti prosledjene kao parametar? Korisitmo hook. Pogledati sliku ispod. 28 Primer upotrebe Route Parametra, da nam kaze id bloga na kog smo kliknuli: 29 Reusing custom hooks 30