49
SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET Preddiplomski sveučilišni studij računarstva Završni rad KLIJENTSKI DIO JEDNOSTRANIČNE WEB APLIKACIJE Rijeka, rujan 2016. Tina Gojak 0069064669

SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

  • Upload
    others

  • View
    0

  • Download
    0

Embed Size (px)

Citation preview

Page 1: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

SVEUČILIŠTE U RIJECI

TEHNIČKI FAKULTET

Preddiplomski sveučilišni studij računarstva

Završni rad

KLIJENTSKI DIO JEDNOSTRANIČNE WEB APLIKACIJE

Rijeka, rujan 2016.

Tina Gojak

0069064669

Page 2: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

SVEUČILIŠTE U RIJECI

TEHNIČKI FAKULTET

Preddiplomski sveučilišni studij računarstva

Završni rad

KLIJENTSKI DIO JEDNOSTRANIČNE WEB APLIKACIJE

Mentor: izv. prof. dr. sc. Miroslav Joler

Rijeka, rujan 2016.

Tina Gojak

0069064669

Page 3: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

ZADATAK

Page 4: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

IZJAVA O SAMOSTALNOJ IZRADI RADA

Izjavljujem da sam samostalno izradila ovaj rad.

Rijeka, rujan 2016. ___________________

Tina Gojak

Page 5: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

Zahvala:

Zahvaljujem svima koji su mi svojim savjetima, preporukama i podrškom pomogli

tijekom studija i pri izradi ovog završnog rada.

Posebna zahvala dr. sc. Damiru Arbuli na vođenju i asistenciji tijekom izrade rada

te brzom odgovaranju na pozive u pomoć.

Također, kolegi i prijatelju Leu Brdaru zahvaljujem na suradnji i strpljenju na

našim brojnim zajedničkim projektima.

Page 6: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

SADRŽAJ

Sadržaj ............................................................................................................................................ 6

1. UVOD ..................................................................................................................................... 1

1.1. Problem i predmet istraživanja ......................................................................................... 1

1.2. Struktura rada ................................................................................................................... 1

2. JEDNOSTRANIČNE APLIKACIJE ...................................................................................... 2

2.1. Tehnički pristup ................................................................................................................ 4

2.1.1. Arhitektura poslužitelja ............................................................................................. 4

2.1.2. JavaScript .................................................................................................................. 4

2.1.3. JSX ............................................................................................................................ 5

2.1.4. AJAX ......................................................................................................................... 6

2.1.5. XMLHttpRequest ...................................................................................................... 6

3. REACT.JS KNJIŽNICA ZA RAZVOJ JEDNOSTRANIČNIH APLIKACIJA .................... 7

3.1. Ključna svojstva ............................................................................................................... 8

3.1.1. Jednosmjeran tok podataka ....................................................................................... 8

3.1.2. Virtualni DOM .......................................................................................................... 8

3.2. React komponente ............................................................................................................ 9

3.3. React DevTools .............................................................................................................. 11

4. REDUX KNJIŽNICA ZA UPRAVLJANJE STANJEM JEDNOSTRANIČNE .....................

APLIKACIJE ....................................................................................................................... 13

4.1. Redux elementi ............................................................................................................... 13

4.1.1. Akcije ...................................................................................................................... 13

4.1.2. Kreatori akcija ......................................................................................................... 14

4.1.3. Reduktori ................................................................................................................. 14

4.1.4. Spremište ................................................................................................................. 15

4.2. Tok podataka .................................................................................................................. 15

4.3. Redux DevTools ............................................................................................................. 16

4.4. Povezivanje Reduxa s Reactom ...................................................................................... 18

Page 7: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

5. DODATNI ALATI ZA RAZVOJ JEDNOSTRANIČNE APLIKACIJE ............................. 21

5.1. npm alat za upravljanje JavaScript programskim paketima ........................................... 21

5.2. Webpack module bundler ............................................................................................... 21

5.3. Babel ............................................................................................................................... 22

6. DJANGO ONLINE JUDGE ................................................................................................. 24

6.1. Postavljanje okruženja .................................................................................................... 24

6.2. Struktura aplikacije ......................................................................................................... 25

6.3. Akcije i tok podataka ...................................................................................................... 30

6.4. Autentikacija korisnika ................................................................................................... 33

7. PREDNOSTI I NEDOSTACI PREBACIVANJA APLIKACIJSKE LOGIKE ......................

NA KLIJENTA ..................................................................................................................... 37

7.1. Prednosti ......................................................................................................................... 37

7.2. Nedostaci ........................................................................................................................ 38

7.3. Zaključak analize ............................................................................................................ 39

ZAKLJUČAK ............................................................................................................................... 40

LITERATURA I IZVORI ............................................................................................................. 41

SAŽETAK ..................................................................................................................................... 42

Abstract ......................................................................................................................................... 42

Page 8: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

1

1. UVOD

1.1.Problem i predmet istraživanja

Model poslužitelja i klijenta je raširena i uvriježena struktura aplikacija koja raspodjeljuje

zadatke i teret između pružatelja resursa ili usluga – poslužitelja (engl. server) i potražitelja –

klijenta (engl. client). Klijent i poslužitelj komuniciraju putem mreže tako da poslužitelj dijeli

svoje resurse s klijentom, a klijent zahtijeva resurse ili usluge od poslužitelja.

U modernim jednostraničnim web aplikacijama tradicionalna arhitektura klijenta i

poslužitelja izmijenjena je na način da klijent preuzima puno više odgovornosti. Većina (ili sva)

aplikacijska logika prebačena je na klijenta, što poslužitelja svodi na jednostavno sučelje za dohvat

podataka.

Cilj ovog završnog rada je izrada klijentskog dijela jednostranične web aplikacije Django

Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja

aplikacijske logike na klijenta.

1.2. Struktura rada

Rad se sastoji od 7 poglavlja, od kojih prvih 5 služe kao teorijski pregled i uvod u

tehnologije i alate koji se koriste u praktičnom dijelu završnog rada. U šestom poglavlju opisana

je aplikacija izrađena kao praktični dio rada, a sedmo, zaključno poglavlje navodi prednosti i

nedostatke korištenog pristupa izradi web aplikacije.

Page 9: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

2

2. JEDNOSTRANIČNE APLIKACIJE

Jednostranične aplikacije (Single Page Application – SPA) su web aplikacije ili web

stranice koje nastoje korisniku pružiti iskustvo slično desktop aplikacijama. Za razliku od

tradicionalnih web aplikacija u kojima se svakim zahtjevom prema poslužitelju stvara i dostavlja

u obliku odgovora nova HTML stranica, u SPA se HTML stranica koja sadrži aplikaciju učitava

samo jednom, prilikom inicijalnog pokretanja aplikacije, a sve daljnje promjene sučelja, kao

odgovor na korisnikove radnje, su parcijalne. Aplikacijska logika uglavnom je prebačena na

klijentsku stranu, što omogućuje brze male promjene stanja, budući da svaka promjena ne

zahtijeva dohvaćanje podataka s poslužitelja. Također, ubrzava interakciju s komponentama

stranice koje utječu na samo mali dio stranice (npr. otvaranje izbornika, odabir iz izbornika...) i ne

mapiraju se u URL-ove (engl. Uniform Resource Locator – web adresa). Za takvu responzivnost

aplikacije zaslužni su AJAX (engl. Asynchronous JavaScript and XML – asinkroni JavaScript i

XML) i HTML5 (engl. Hyper Text Markup Language 5 – peta verzija jezika korištenog za pisanje

web stranica), kao i JavaScript s klijentske strane. Svakom promjenom aplikacija dolazi u novo

stanje koje se može usporediti s web stranicom (engl. webpage) na tradicionalnom web sjedištu

(engl. website) te je moguće navigirati između stanja.

Na slici 2.1. ilustrirana je razlika u komunikaciji s poslužiteljem kod tradicionalnih web

aplikacija i SPA. Kod tradicionalnih stranica, nakon svakog poziva aplikacije poslužitelju, on

odgovara novom HTML stranicom, što izaziva osvježenje (engl. refresh) stranice u pregledniku.

Kod SPA, nakon što se aplikacija prvi put učita, sva se komunikacija odvija kroz AJAX pozive,

na koje poslužitelj odgovara uglavnom u JSON (engl. JavaScript Object Notation) ili XML (engl.

Extensible Markup Language) formatu. Zatim aplikacija koristi dobivene podatke za dinamičko

ažuriranje stranice, bez njenog ponovnog učitavanja. [1]

Page 10: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

3

Slika 2.1. Životni ciklus web aplikacije

Osim responzivnosti aplikacije, odnosno kraćih i time bržih odgovora, prednost SPA je

odvajanje aplikacijske (AJAX zahtjev i JSON odgovor) i prezentacijske (HTML markup) logike.

Time je olakšano projektiranje i održavanje svakog sloja za sebe, s budući da je u dobro

projektiranoj SPA moguće promijeniti HTML markup bez promjene koda koji implementira

aplikacijsku logiku.

U čistoj SPA sva se interakcija s korisničkim sučeljem odvija isključivo na klijentu. Sučelje

je implementirano koristeći standardne web tehnologije kao što su JavaScript, HTML i CSS.

Nakon početnog učitavanja stranice, poslužitelj služi isključivo kao uslužni sloj, a klijent treba

znati samo koje HTTP zahtjeve treba slati, bez ikakvog znanja kako poslužitelj implementira

dohvat i održavanje podataka odnosno resursa.

Page 11: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

4

2.1. Tehnički pristup

U ovom će se poglavlju opisati tehnike koje pregledniku omogućuju održavanje

jedinstvene stranice, čak i kada je potrebna komunikacija s poslužiteljem.

2.1.1. Arhitektura poslužitelja

Komunikacija s poslužiteljem se odvija u pozadini, a s obzirom na ulogu poslužitelja u

aplikaciji, razlikujemo tri vrste SPA [2]:

Arhitektura "tankog" poslužitelja (Thin server architecture) - aplikacijska logika u

potpunosti je prebačena na klijenta, čime je uloga poslužitelja svedena na jednostavno

sučelje za dohvat podataka. Tako se nastoji smanjiti kompleksnost sustava u cjelini.

Ovakve se aplikacije smatraju „čistim“ jednostraničnim aplikacijama.

Arhitektura "debelog" poslužitelja s očuvanjem stanja (Thick stateful server architecture)

- poslužitelj čuva potrebna stanja u memoriji klijenta i kada dobije zahtjev, pošalje

odgovarajući odgovor koji ažurira stanje klijenta, a u isto vrijeme se ažurira i stanje na

poslužitelju. Većina aplikacijske logike izvodi se na poslužitelju, što znači da je

poslužitelju potrebno više memorije, ali konačna aplikacija je pojednostavljena jer su

podaci i stanje korisničkog sučelja spremljeni na isto mjesto u memoriji poslužitelja, bez

potrebe za dodatnom komunikacijom između klijenta i poslužitelja.

Arhitektura "debelog" poslužitelja bez očuvanja stanja (Thick stateless server architecture)

- u ovoj varijanti "debelog" poslužitelja, poslužitelj ne čuva stanje klijenta, već mu klijent

šalje svoje stanje, uglavnom AJAX zahtjevom. Zatim poslužitelj rekonstruira stanje dijela

stranice koji treba ažurirati i vraća klijentu odgovarajući kod koji će ga dovesti u novo

stanje. Ovim pristupom je potrebno poslužitelju slati više podataka i može zahtijevati više

resursa za obradu zahtjeva, ali budući da se na poslužitelju ne čuvaju specifični podaci za

svakog klijenta, AJAX zahtjevi mogu biti poslani na više čvorova bez potrebe za sesijama.

2.1.2. JavaScript

JavaScript (JS) je objektno-orijentirani programski jezik, najpoznatiji kao skriptni jezik za

razvoj web aplikacija, iako se koristi i u drugim okruženjima. Izvodi se na klijentskoj strani, u

Page 12: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

5

interpreteru ugrađenom u web preglednik i uglavnom kontrolira kako će stranica, odnosno

korisničko sučelje reagirati na određeni događaj.

Standard na kojem je baziran naziva se ECMAScript. Od 2012., svi moderni web

preglednici u potpunosti podržavaju ECMAScript 5.1., a od 2015. se primjenjuje ECMAScript 6

ili ES6, koji je trenutno prihvaćen u razvoju jednostraničnih aplikacija, jer ima mnoge korisne

značajke koje olakšavaju i ubrzavaju pisanje koda.

Razvijeno je više JavaScript radnih okvira koji podržavaju razvoj jednostraničnih

aplikacija. Najrašireniji su AngularJS, Ember.js, Meteor.js i React.js. U praktičnom dijelu ovog

završnog rada korišten je React.js radni okvir te je detaljno opisan u poglavlju React.

2.1.3. JSX

JSX (engl. Java Serialization to XML) je predprocesor koji dodaje XML sintaksu u

JavaScript. Uobičajeno ga je koristiti pri razvoju React aplikacija, iako je moguće koristiti i čisti

JavaScript. JSX pruža jednostavnost i eleganciju React kodu, jer nudi poznatu i sažetu sintaksu za

kreiranje strukture stabla, koja se koristi u Reactu. Također, prilikom prevođenja u JavaScript

provodi se optimizacija koja osigurava da se nastali kod pokreće brže nego što bi se pokretao

ekvivalentni kod napisan direktno u JavaScriptu.

Na nastavku je prikazan React element HelloMessage napisan u JSX-u, a zatim njegov

ekvivalent u JavaScriptu.

// hello.jsx

var HelloMessage = React.createClass({

render: function() {

return <div>Hello World!</div>

}

})

// hello.js

var HelloMessage = React.createClass({

displayName: "HelloMessage",

render: function() {

return React.createElement("div", null, "Hello World!")

}

})

Page 13: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

6

2.1.4. AJAX

AJAX, skraćeno za Asynchronous JavaScript and XML, je skup tehnika korištenih od

strane klijenta pri razvoju asinkronih web aplikacija. Omogućuje aplikacijama da asinkrono

dohvaćaju podatke s poslužitelja u pozadini, bez utjecaja na trenutni izgled i ponašanje stranice,

pri čemu koristi poseban oblik zahtjeva imena XMLHttpRequest. AJAX odvaja prezentacijski sloj

od sloja za razmjenu podataka kako bi se web stranice mogle mijenjati dinamički, odnosno bez

potrebe za ponovnim učitavanjem cijele stranice.

2.1.5. XMLHttpRequest

XMLHttpRequest ili kraće XHR je aplikacijsko programsko sučelje (engl. Application

Programming Interface – API) u formi objekta čije metode prenose podatke između web

preglednika i web poslužitelja. Zahtjev se odvija u pozadini (asinkron je) i uglavnom vraća XML

ili JSON podatke pomoću kojih se izmjenjuju dijelovi stranice, bez potrebe za osvježenjem cijele

stranice.

Page 14: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

7

3. REACT.JS KNJIŽNICA ZA RAZVOJ JEDNOSTRANIČNIH

APLIKACIJA

React (React.js ili ReactJS) je JavaScript knjižnica otvorenog koda (open-source) koja nudi

pregled podataka koji se generiraju kao HTML. Specifičnosti Reacta su:

- pisanje komponenti koje se prikazuju kao posebne HTML oznake (tags),

- "nizvodni tok podataka" (engl. "data flows down"), odnosno nemogućnost komponenti

da izmijene svoje nadkomponente,

- jasno razdvajanje komponenti koje je vrlo korisno za razvoj modernih jednostraničnih

aplikacija (SPA), budući da je glavna ideja da komponente budu ponovno iskoristive u

različitim aplikacijama, i kada se podaci koje prikazuju promijene.

Tradicionalno, korisnička sučelja web aplikacija grade se pomoću HTML predložaka

(engl. templates), koji definiraju sve mogućnosti koje se nude za izradu korisničkog sučelja. React

za izgradnju komponenti koristi pravi i potpuni programski jezik, JavaScript, koji ima nekoliko

prednosti nad korištenjem predložaka. JavaScript je fleksibilan i moćan programski jezik koji ima

mogućnost izgradnje apstraktnih klasa, što je od izuzetne važnosti pri izradi velikih aplikacija, a

sjedinjenje prezentacijskih dijelova s odgovarajućom logikom olakšava održavanje i proširenje

React koda.

Prednosti Reacta najviše se ističu kada se podaci koje prikazuje mijenjaju tijekom vremena.

U tradicionalnim JavaScript aplikacijama, nakon svake promjene podataka potrebno je napraviti

odgovarajuće promjene u DOM-u. React eliminira potrebu za ručnim izmjenama. Kada se

komponenta prvi put inicijalizira, poziva se render metoda koja generira jedan prikaz. Kada se

podaci promijene, ponovno se poziva render metoda, ali React uspoređuje prethodni poziv s

trenutnim i generira minimalni set promjena koje će se primijeniti na DOM. Ovaj se proces naziva

reconciliation. Budući da je takvo generiranje jako brzo, nije potrebno eksplicitno definirati

podatkovno uparivanje (engl. data bindings - procesi koji povezuju korisničko sučelje s

aplikacijskom logikom). [3]

Page 15: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

8

3.1. Ključna svojstva

3.1.1. Jednosmjeran tok podataka

Komponentama su u oznakama (HTML tag) proslijeđena svojstva (engl. propertises,

skraćeno props), skup nepromjenjivih vrijednosti koje komponenta može koristiti. Iako ih ne može

direktno mijenjati, može poslati funkciju povratnog poziva (engl. callback function) koja može

promijeniti vrijednosti. Mehanizam se opisuje kao jednosmjeran tok podataka, ili "properties flow

down; actions flow up"; svojstva se prosljeđuju isključivo niz hijerarhijsko stablo komponenata, a

akcije se prosljeđuju uz stablo.

Slika 3.1. Jednosmjeran tok podataka u React aplikaciji

3.1.2. Virtualni DOM

Objektni model dokumenta (engl. Document Object Model - DOM) je sučelje za dohvat i

modifikaciju XML/HTML informacija određene stranice, a ima oblik strukturnog stabla

dokumenata. Kada se želi dinamički promijeniti sadržaj web stranice, mijenja se DOM.

Struktura stabla omogućuje lako kretanje do čvorova, ali ne nužno i brzo, budući da DOM

stabla mogu biti golema, a SPA zahtijevaju često i neprestano mijenjanje DOM stabla. React

olakšava posao na dva načina:

Deklarativnost – umjesto ručnog prolaženja kroz DOM stablo, dovoljno je deklarirati kako

bi komponenta trebala izgledati, a React u pozadini odrađuje posao, koristeći HTML DOM

API metode

Virtualni DOM (Virtual DOM)

Page 16: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

9

Virtualni DOM je apstrakcija HTML DOM-a, odvojena od implementacijskih detalja

specifičnih za web preglednik. Može ga se promatrati kao Reactovu lokalnu, pojednostavljenu

verziju HTML DOM-a, a omogućuje Reactu brzinu unutar tog apstraktnog sloja, bez potrebe za

"pravim" DOM operacijama, koje su često spore i ovise o web pregledniku. Kod se zatim može

pisati kao da se cijela stranica učitava pri svakoj promjeni, a React zapravo iščita što se zaista

promijenilo i generira samo te komponente. Cijena implementacije virtualnog DOM-a je veličina

aplikacije. Postoje alati koji je mogu minimizirati, ali pritom oduzimaju neke funkcionalnosti. [4]

3.2. REACT KOMPONENTE

Ideja Reacta je da se aplikacija razloži u više nezavisnih komponenata. Idealno, svaka bi

komponenta trebala odrađivati samo jednu zadaću. Ako naraste, trebala bi se razložiti u više

manjih komponenata.

Proces izgradnje aplikacije može ići odozdo prema gore ili odozgo prema dolje. Kod

manjih aplikacija, uglavnom je jednostavnije raditi odozgo prema dolje, ali kod većih je bolji

pristup odozdo prema dolje i odmah testirati dijelove aplikacije.

Za uvođenje interaktivnosti u aplikaciju, potrebno je mijenjati pozadinski model podataka.

React za to koristi stanje (engl. state). Stanje bi uvijek trebalo sadržavati minimalnu količinu

podataka, a sve što može, računati u trenutku kada je potrebno. Na primjer, za neku listu podataka

nije potrebno čuvati varijablu s brojem članova liste, već se članovi mogu prebrojati u trenutku

kada je taj podatak potreban.

Potrebno je odrediti koje će komponente sadržavati stanje. Većina komponenti trebala bi

biti bez stanja, kako bi se stanje postavilo na najlogičnije mjesto i kako bi se minimalizirala

redundantnost. Takve komponente preuzimaju potrebne podatke putem proslijeđenih svojstava

(props), od drugih komponenti koje ih pozivaju (tzv. roditeljske komponente – engl. parent

components). Roditeljske se komponente nalaze više u hijerarhiji i inkapsuliraju svu interakcijsku

logiku, a njihova "djeca" (engl. children components) generiraju podatke.

Komponente koje bi trebale imati stanje su one koje odgovaraju na unos korisnika, zahtjev

sa poslužitelja ili zahtijevaju prolaz određenog vremena. Stanje bi trebalo sadržavati podatke koje

bi komponenta mogla promijeniti u s ciljem promjene korisničkog sučelja; radi se o minimalnoj

količini podataka dovoljnoj za prikaz stanja korisničkog sučelja. Stanje ne bi trebalo sadržavati

duplikat podataka iz svojstava (props) (ako je moguće, svojstva bi trebala biti jedini izvor

Page 17: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

10

podataka), druge React komponente (njih se definira unutar render() metode) i izračunate

podatke (svi bi izračuni trebali ići unutar render() ).

Funkcija render()može vratiti samo jedan čvor iz stabla elemenata. Ako komponenta

vraća više elemenata (npr. naslov i podnaslov), potrebno ih je spojiti u jedan div, span ili sličan

HTML element.

Na slici 3.2. prikazan je primjer jedne vrlo jednostavne aplikacije i komponente od kojih

se sastoji – svaka je komponenta uokvirena određenom bojom. Aplikacija sadrži tablicu proizvoda

koju je moguće pretraživati te je podijeljena na:

- TablicaProizvodaSPretraživanjem (narančasto) – objedinjuje sve druge elemente

- TrakaPretraživanja (plavo) – prima korisnički unos

- TablicaProizvoda (zeleno) - prikazuje filtrirane podatke, temeljene na korisničkom unosu

- KategorijaProizvoda (žuto) – prikazuje red tablice s naslovom kategorije

- Proizvod (crveno) – prikazuje red tablice za jedan proizvod

Slika 3.2. Prikaz React komponenti na primjeru tablice proizvoda

Page 18: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

11

Na temelju prikazanih okvira moguće je proizvesti hijerarhiju komponenata. Okvir koji se

nalazi unutar drugog okvira trebao bi se u hijerarhiji prikazati kao njegovo dijete:

- TablicaProizvodaSPretraživanjem

- TrakaPretraživanja

- TablicaProizvoda

- KategorijaProizvoda

- Proizvod

Od izvedenih komponenti, samo TablicaProizvodaSPretraživanjem prima stanje, kao

vrhovna komponenta aplikacije. Sve ostale komponente primaju isključivo svojstva, proslijeđena

od strane TablicaProizvodaSPretraživanjem. TrakaPretraživanja prima korisnički unos i šalje

povratni poziv komponenti TablicaProizvodaSPretraživanjem u kojem je obavještava da se stanje

treba promijeniti. [5]

3.3. React DevTools

React Development Tools je alat za pomoć pri razvijanju React aplikacija, dostupan kao

proširenje u Chrome i Firefox preglednicima. Na slici 3.3. prikazan je primjer korištenja React

Development Tools.

Slika 3.3. React DevTools

Page 19: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

12

React DevTools se prikazuje kao dodatna kartica u već postojećim DevTools korištenog

preglednika. Omogućuje pregled hijerarhije komponenata u aplikaciji, kao i proučavanje i

uređivanje njihovih stanja i svojstava.

Na slici 3.3. prikazana je NReact kartica u kojoj su ispisana svojstva (Props) i stanje (State)

odabranog elementa <Todos>. Vidljivo je da sadrži polje s 3 objekta te je moguće proučiti svaki

objekt i izmijeniti njegova svojstva.

Page 20: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

13

4. REDUX KNJIŽNICA ZA UPRAVLJANJE STANJEM

JEDNOSTRANIČNE APLIKACIJE

Redux je JavaScript knjižnica za upravljanje stanjem aplikacije s minimalnim API-jem i

predvidivim ponašanjem. Sprema stanje aplikacije u stablo objekata unutar jedinstvenog spremišta

(engl. store). Jedini mogući način za promjenu stanja je odašiljanje akcije, objekta koji opisuje

događaj, a funkcija naziva reduktor definira točno kako akcija mijenja stablo stanja.

Umjesto direktne izmjene trenutnog stanja, reduktor uzima staro stanje i na njega

primjenjuje odaslanu akciju kako bi vratio novo stanje aplikacije. Dakle, stanje Redux aplikacije

se nikada ne mijenja, već se svaki put izrađuje kopija starog stanja koja se zatim dovodi u novo

stanje. Tijekom izrade aplikacije, kreće se s jednim „korijenskim“ reduktorom (engl. root reducer),

koji se po potrebi, kako aplikacija raste, dijeli u više manjih reduktora namijenjenih za pojedine

dijelove stabla stanja.

Iako se može koristiti sam za sebe, kao i s drugim Javascript knjižnicama, Redux radi

posebno dobro s React radnim okvirom (engl. framework), budući da on omogućuje opisivanje UI

kao funkcije stanja, a Redux kao odgovor na akcije ažurira stanje. Poseban paket react-redux je

dostupan kao poveznica između Reduxa i Reacta.

4.1. Redux elementi

4.1.1. Akcije

Akcije (engl. actions) prenose podatke iz aplikacije u spremište, i jedini su izvor

informacija za spremište. Šalju se funkcijom store.dispatch(). Obični su JavaScript objekti i

moraju imati svojstvo type koje opisuje vrstu akcije koja se izvodi, a tipično se definiraju kao

konstante vrste string (znakovni niz). Osim obaveznog svojsta type, struktura akcije je

proizvoljna, ali preporuča se da prenose minimalnu količinu podataka. Na primjer, dovoljno je

prenijeti samo identifikacijsko svojstvo (id) objekta, a ne cijeli objekt.

Page 21: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

14

4.1.2. Kreatori akcija

Kreatori akcija (engl. action creators) su funkcije koje kreiraju akcije te u Redux aplikaciji

jednostavno vraćaju akciju. Kada je potrebno odaslati akciju, kreator akcije se proslijeđuje

dispatch() funkciji, ili se definira vezani kreator akcije (engl. bound action creator), koji

uključuje dispatch() funkciju.

4.1.3. Reduktori

Akcije prenose informaciju da se nešto dogodilo, ali ne definiraju kako događaj utječe na

stanje aplikacije. Za to su zaslužni reduktori.

Reduktor je funkcija koja prima prethodno stanje i akciju te iz njih kreira novo stanje. Bitno

je da su reduktori uvijek „čiste“ funkcije (za isti ulaz uvijek daju isti izlaz). Unutar njih se nikada

ne bi smjelo mijenjati vlastite argumente, izvoditi pozive API-ju ili preusmjeravanja (engl. routing

transitions) te pozivati „nečiste“ funkcije (npr. Date.now() ili Math.random()).

Bitno je napomenuti da se stanje aplikacije nikada ne mijenja direktno, već se kreira kopija

na koju se primjenjuje akcija kako bi se dobilo novo stanje. U slučaju da je došlo do neke pogreške

ili se funkcija iz bilo kojeg razloga ne može provesti, definira se slučaj u kojem se vraća staro,

nepromijenjeno stanje.

Kao što akcije kao argument primaju minimalnu količinu podataka, tako reduktori ne

trebaju primiti cijelo stanje. Dovoljno im je proslijediti dio stanja koje je potrebno izmijeniti, a

zatim se dijelovi ukomponiraju u globalno stanje. Funkcija combineReducers() poziva sve

reduktore, svakog sa svojim djelićem stanja, i kombinira njihove rezultate u jedinstveni objekt.

Rezultat funkcije se uglavnom sprema u varijablu koja se naziva korijenski reduktor (engl.

rootReducer). Ovakvo logičko razdvajanje reduktora naziva se kompozicija reduktora (engl.

reducer composition).

Page 22: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

15

4.1.4. Spremište

Store je objekt koji kombinira akcije i reduktore te ih povezuje sa stanjem. Njegovi su

zadaci da:

Čuva stanje aplikacije,

Omogućuje pristup stanju pomoću getState() funkcije,

Omogućuje nadogradnju stanja pomoću dispatch(action),

Registrira listenere (funkcije koje „osluškuju“ stanje i reagiraju na promjene) pomoću

funkcije subscribe(listener),

Uklanja registraciju listenera pomoću funkcije koju vraća subscribe(listener).

Aplikacija ima jedan jedinstveno spremište. Ako je potrebno razdvojiti dio logike za

rukovanje podacima, ne radi se više spremišta, već se rade novi reduktori (kompozicija reduktora).

Spremište se kreira funkcijom createStore(), kojoj se kao argument prosljeđuje

rootReducer, a opcionalno i početno stanje aplikacije. Ovo je korisno kada je potrebno uskladiti

stanje klijenta s Redux aplikacijom na poslužitelju.

4.2. Tok podataka

Redux arhitektura zasniva se na strogo jednosmjernom toku podataka, što znači da svi

podaci unutar aplikacije imaju isti životni ciklus pa je logika aplikacije predvidiva i jednostavna

za razumijevanje. Također, pridonosi normalizaciji podataka, da bi se izbjeglo slučajno stvaranje

više međusobno nezavisnih, nepotrebnih kopija istih podataka.

Za razliku od dvosmjernog toka podataka, u kojem su elementi korisničkog sučelja (engl.

User Interface – UI) dinamički povezani s modelom podataka (engl. model data) tako da svaka

promjena korisničkog sučelja automatski mijenja model podataka i obrnuto, u jednosmjernom toku

podataka model je jedini izvor podataka. U Redux aplikacijama ovaj se model naziva spremište

(engl. store). Promjene korisničkog sučelja ne mijenjaju izravno stanje, već odašilju poruke

spremištu i samo spremište ima mogućnost mijenjanja stanja aplikacije. Na slici 4.1. prikazan je

tok podataka Redux aplikacije.

Page 23: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

16

Slika 4.1. Tok podataka u Redux aplikaciji

Životni ciklus svake Redux aplikacije slijedi 4 koraka:

1. Poziva se funkcija store.dispatch(action) koja opisuje što se dogodilo.

2. Spremište poziva reduktor funkciju s trenutnim stanjem i prethodno odaslanom akcijom

kao argumentima te reduktor pomoću njih određuje novo stanje.

3. Korijenski reduktor po potrebi kombinira rezultate drugih reduktora kako bi kreirao

jedinstveno stablo stanja (ako je korištena funkcija combineReducers() ).

4. Spremište sprema stablo stanja koje je vratio korijenski reduktor kao trenutno stanje

aplikacije. Ako postoje funkcije "pretplaćene" na promjene stanja (listener funkcije

registrirane pomoću store.subscribe(listener) ), one se sada pozivaju, a korisničko

sučelje se ažurira da bi prikazalo najnovije stanje.

4.3. Redux DevTools

Redux DevTools je alat za pomoć pri razvoju Redux aplikacija, dostupan kao proširenje u

Chrome i Firefox preglednicima. Sprema svaku izvedenu akciju i stanje u povijest aplikacije.

Najvažnija svojstva su:

- omogućuje proučavanje stanja i akcija,

- omogućuje "povratak kroz vrijeme" poništavanjem izvedenih akcija,

- moguće je poništiti neku staru akciju bez utjecaja na one izvedene kasnije,

- u slučaju promjene koda reduktora preispituje svaku već izvedenu akciju,

Page 24: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

17

- ako reduktor zakaže, prikazuje točnu akciju pri kojoj se to dogodilo, i grešku koja je

pritom javljena.

Na slici je prikazan primjer korištenja Redux DevTools; prikazane su dvije izvedene akcije

(ADD_TODO) i odgovarajuće promjene stanja (engl. store mutations). Opcija disable poništava

pojedinu akciju, Reset vraća aplikaciju u početno stanje, Commit pretvara trenutno stanje u početno

stanje i briše sve spremljene akcije, a Revert vraća u posljednje commitano stanje.

Slika 4.2. Redux DevTools

Page 25: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

18

4.4. Povezivanje Reduxa s Reactom

Kako bi se Redux aplikacija povezala s React komponentama, potrebno je instalirati paket

react-redux, koristeći naredbu npm install --save react-redux .

Ovaj paket poveznica potiče razdvajanje React komponenti u prezentacijske i logičke

(engl. presentational and container components). Upravo kako im nazivi govore, prezentacijske

komponente trebale bi isključivo opisivati kako što izgleda i biti nezavisne o ostatku aplikacije, a

logičke komponente bi trebale definirati kako što funkcionira. Kod nekih je komponenti teško

razdvojiti prezentaciju od logike, pa je moguće ostaviti ih zajedno, posebno ako se radi o jako

malim komponentama. Pregled glavnih značajki komponenti dan je u tablici, a širi opis u nastavku.

Prezentacijske komponente imaju sljedeća svojstva:

Opisuju kako stvari izgledaju.

Mogu sadržavati druge prezentacijske i logičke komponente i uglavnom sadrže DOM

markup i vlastite stilove.

Dozvoljavaju preuzimanje putem this.props.children.

Ne ovise o ostatku aplikacije, poput akcija i spremišta.

Ne definiraju kako se podaci učitavaju ili izmjenjuju.

Primaju podatke i povratne pozive (engl. callbacks) isključivo preko svojstava

Uglavnom nemaju vlastito stanje (ako imaju, to je stanje korisničkog sučelja).

Logičke komponente:

Opisuju kako stvari funkcioniraju

Mogu sadržavati druge prezentacijske i logičke komponente, ali uglavnom nemaju DOM

markup ni vlastite stilove.

Dobavljaju podatke i opisuju ponašanje prezentacijskih ili drugih logičkih komponenti.

Pozivaju akcije i prosljeđuju ih prezentacijskim komponentama kao povratne pozive.

Često sadrže stanje i služe kao izvor podataka.

Uglavnom se ne pišu ručno, već se kreiraju pomoću "komponenti višeg reda", poput

connect() funkcije u Reduxu. [6]

Page 26: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

19

Tablica 4.1. Glavne značajke prezentacijskih i logičkih komponenti [7]

Components Containers

Svrha Kako što izgleda (markup,

stilovi) Kako što funkcionira

Svjesne Reduxa Ne Da

Način čitanja podataka Iz svojstava (props) Iz Redux spremišta

(subscribe to state)

Način promjene podataka Povratni pozivi iz svojstava Odašilju akcije

Način kreiranja Pišu se ručno Uglavnom ih generira React

Redux

Logička komponenta mogla bi se opisati i kao obična React komponenta koja poziva

funkciju store.subscribe() kako bi očitala dio stabla stanja i proslijedila svojstva

prezentacijskoj komponenti koju generira. Takva bi se komponenta mogla definirati i ručno, ali

Redux nudi funkciju connect(), koja optimizira izvođenje i sprječava nepotrebna ponavljanja

generiranja aplikacije. Funkcija prima dva ili tri argumenta. Prvi je funkcija mapStateToProps()

koja iz stabla stanja dohvaća potrebne podatke koji se prosljeđuju prezentacijskoj komponenti.

Drugi je argument funkcija mapDispatchToProps(), samo ako komponenta odašilje neku akciju,

a treći je sama prezentacijska komponenta koja prikazuje podatke koji su dohvaćeni.

import { connect } from 'react-redux'

const VisibleTodoList = connect(

mapStateToProps,

mapDispatchToProps

)(TodoList)

export default VisibleTodoList

Page 27: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

20

Prednosti razdvajanja komponenti:

Razdvojenost problema - pridonosi boljem razumijevanju aplikacije i korisničkog sučelja.

Iskoristivost koda - prezentacijske komponente se mogu koristi s potpuno različitim

izvorima podataka.

Skrivanje logike - mijenjajući isključivo prezentacijske komponente, moguće je urediti i

prilagoditi korisničko sučelje prema želji, bez zadiranja u aplikacijsku logiku.

Komponente koje definiraju raspored, poput navigacijskih okna, zaglavlja i podnožja,

mogu se opisati samo jednom i zatim koristiti na različitim dijelovima aplikacije, bez

nepotrebnog ponavljanja istog koda.

Page 28: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

21

5. DODATNI ALATI ZA RAZVOJ JEDNOSTRANIČNE APLIKACIJE

5.1. npm alat za upravljanje JavaScript programskim paketima

Node.js je okruženje otvorenog koda (engl. open-source) za razvoj različitih aplikacija i

alata, primarno koristeći JavaScript programski jezik i kolekciju "modula" koji odrađuju jezgrene

funkcionalnosti. Koristi se za izgradnju mrežnih programa i alata, poput web poslužitelja.

Među brojnim funkcionalnostima, nudi i alat za upravljanje paketima, npm. Koristi se za

instalaciju Node.js programa iz npm registra, organizaciju i instalaciju te upravljanje drugim

Node.js programima. Omogućuje jednostavno upravljanje međuzavisnim klijentskim resursima te

organizaciju JavaScript modula.

Npm registar sadrži sve pakete potrebne za razvoj React i Redux aplikacija. Sve zavisnosti,

odnosno paketi instalirani tijekom razvoja aplikacije, zapisuju se u datoteku package.json.

package.json tako služi kao dokumentacija o zavisnostima projekta, omogućuje definiranje

verzije paketa o kojoj ovisi i olakšava reprodukciju istog projekta. Kreira se naredbom npm init.

Konzola zatim traži unos osnovnih podataka o projektu (ime, verzija, opis, ulazna datoteka,

skripte, autor, licenca) i kreira package.json dokument.

Definiraju se dvije grupe paketa – dependencies (paketi potrebni projektu u produkciji) i

devDependencies (paketi potrebni samo tijekom razvoja i testiranja). Paketi se mogu unositi

ručno, ali puno ih je jednostavnije i pametnije zapisivati automatski, prilikom instalacije paketa,

korištenjem zastavica --save ili --save-dev.

npm install <package_name> --save -> dodaje zavisnost u dependencies

npm install <package_name> --save-dev -> dodaje zavisnost u devDependencies

5.2. Webpack module bundler

Webpack je alat koji uzima JSX, React dokumente i sve njihove zavisnosti te ih kompajlira

u jedan JavaScript dokument (engl. bundle – paket, snop) namijenjen web pregledniku.

Omogućuje zapis svih željenih postavki u jedan dokument (webpack.config.js) iz kojeg se

zatim cijela klijentska strana aplikacije može izgraditi samo jednom naredbom. Minimum

informacija koje webpack.config.js zahtijeva su ulazne i izlazne točke. U varijabli APP_DIR

Page 29: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

22

zapisan je put do direktorija u kojem se nalazi kod React aplikacije, a BUILD_DIR sadrži direktorij

u koji će se spremiti generirani paket. Slično, varijabla entry definira koji dokument služi kao

ulazna točka aplikacije, a output definira naziv i lokaciju paketa.

// webpack.config.js

var webpack = require('webpack');

var path = require('path');

var BUILD_DIR = path.resolve(__dirname, 'src/client/public');

var APP_DIR = path.resolve(__dirname, 'src/client/app');

var config = {

entry: APP_DIR + '/index.jsx',

output: {

path: BUILD_DIR,

filename: 'bundle.js'

}

};

module.exports = config;

5.3. Babel

Pri izgradnji React i Redux aplikacija, uvriježeno je i korisno koristiti JSX sintaksu i ES6

standard koji, međutim, nisu podržani u svim preglednicima. Stoga je potreban alat koji će prevesti

JSX i ES6 kod u klasični JavaScript, podržan u svim preglednicima, a Babel je upravo to.

Babel je paket koji učitava odgovarajuće priključke (engl. plug-ins) za prijevod ES6 i JSX

sintakse. Instaliraju se pomoću npm-a:

npm i babel-loader babel-preset-es2015 babel-preset-react -S

Zatim je potrebno kreirati datoteku .babelrc u kojoj će pisati da babel-loader treba koristiti

upravo instalirane priključke:

{

"presets" : ["es2015", "react"]

}

Page 30: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

23

Konačno, u webpack.config.js potrebno je reći Webpacku da koristi babel-loader dok

kreira paket:

// već postojeći kod ....

var config = {

// već postojeći kod ....

module : {

loaders : [

{

test : /\.jsx?/,

include : APP_DIR,

loader : 'babel'

}

]

}

}

Za svaki loader definira se koje vrste datoteka treba obrađivati. U ovom slučaju, babel će

obraditi .js i .jsx datoteke iz direktorija APP_DIR.

Page 31: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

24

6. DJANGO ONLINE JUDGE

Praktični zadatak za završni rad bila je izrada klijentskog dijela jednostranične aplikacije

Django Online Judge koristeći ReactJS radni okvir. Prilikom izrade, Reactu je pridružen Redux.

Redux kontrolira promjene stanja, a React generira poglede stanja (engl. views).

6.1. Postavljanje okruženja

Prvi je korak instalacija potrebnih alata. Za početak, potrebno je instalirati npm kao

upravitelja JavaScript programskim paketima i Webpack za kreiranje paketa. Od ostalih paketa,

neki su instalirani unaprijed jer se znalo/očekivalo da će biti potrebni, a neki su se dodali tijekom

razvoja aplikacije. Konačna lista, iz package.json:

"devDependencies": {

"babel-core": "^6.7.6",

"babel-loader": "^6.2.4",

"babel-plugin-transform-class-properties": "^6.3.13",

"babel-plugin-transform-decorators-legacy": "^1.3.4",

"babel-preset-es2015": "^6.6.0",

"babel-preset-react": "^6.5.0",

"babel-preset-stage-0": "^6.3.13",

"history": "^2.1.1",

"jquery": "^2.2.3",

"react": "^15.0.1",

"react-dom": "^15.0.1",

"react-hot-loader": "^1.3.0",

"react-router": "^2.3.0",

"redux-devtools": "^3.3.1",

"redux-devtools-dock-monitor": "^1.1.1",

"redux-devtools-log-monitor": "^1.0.11",

"webpack": "^1.13.0",

"webpack-bundle-tracker": "0.0.93",

"webpack-dev-server": "^1.14.1"

},

"dependencies": {

"babel-plugin-transform-object-rest-spread": "^6.8.0",

"express": "^4.13.4",

"express-stormpath": "^3.1.2",

"humps": "^1.1.0",

Page 32: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

25

"isomorphic-fetch": "^2.2.1",

"lodash": "^4.13.1",

"normalizr": "^2.1.0",

"react-bootstrap": "^0.28.5",

"react-redux": "^4.4.5",

"react-router-redux": "^4.0.4",

"redux": "^3.5.2",

"redux-logger": "^2.6.1",

"redux-thunk": "^2.1.0"

}

}

Korišteni uređivač teksta je Sublime, koji ima mogućnost instalacije Babel proširenja za

tumačenje JSX sintakse i odgovarajuće označavanje teksta, kako bi pisanje koda bilo

jednostavnije.

6.2. Struktura aplikacije

Aplikacija se sastoji od više komponenata. Kao što je opisano u poglavljima o Reactu i

Reduxu, definiraju se:

Prezentacijske komponente

Logičke komponente

Akcije

Reduktori

Spremište

Za jasniji pregled strukture, svaka je vrsta komponenti spremljena u svoj direktorij, a dio

prezentacijskih komponenti je izdvojen u direktorij pages. To su komponente više u hijerarhiji,

koje predstavljaju logičku podjelu aplikacije po podacima koje prikazuju – Contests, Challenges,

Problems, te Login i App kao početni ulaz u aplikaciju. Slika 5.1. prikazuje organizaciju direktorija

i komponenata aplikacije Django Online Judge.

Page 33: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

26

Slika 5.1. Organizacija direktorija i komponenata u aplikaciji Django Online Judge

Index.js je ulazna točka aplikacije, što je definirano u datoteci webpack.config.js. Sadrži

funkciju ReactDOM.render() koja uzima dva argumenta – React element koji se generira

(Provider) i DOM element u kojem će se generirati. DOM element se u ovom slučaju nalazi po

svojstvu id="app" pa u HTML dokumentu u kojem će se generirati mora postojati odgovarajući

element. U Django Online Judge, budući da se koristi webpack koji kreira paket koji objedinjuje

cijeli kod aplikacije, potrebno je učitati taj paket (bundle skripta).

// index.js

ReactDOM.render(

<Provider store={store}>

<Router history={history}>

<Route path="/login" component={LoginApp} />

<Route path="/" component={App} onEnter={requireAuth} />

<Route path="/contest/" component={ContestApp}

onEnter={requireAuth} />

/* … */

</Router>

</Provider>,

document.getElementById('app')

)

Page 34: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

27

<!-- index.html -->

<body>

<div id="app"></div>

<script src="/bundles/dev.min.js"></script>

</body>

Komponenta App je korijen aplikacije (engl. root component). Stoga mora biti

inkapsulirana u element Provider. Provider omogućuje svim logičkim komponentama pristup

spremištu bez da ga eksplicitno prosljeđuje, koristeći React context – svojstvo koje omogućuje

prosljeđivanje svojstava niz stablo komponenti bez stalnog prosljeđivanja svojstava.

Komponenta usmjernik (Router) iz paketa react-router uključuje povijest kretanja koja

prati promjene u adresnoj traci preglednika i sprema URL-ove kao lokacijske objekte koje

usmjernik može koristiti za određivanje ruta i generaciju pravilnog skupa komponenti. Povijest

Django Online Judge aplikacije definirana je u konstanti history kao spoj browserHistory i

spremišta.

const history = syncHistoryWithStore(browserHistory, store)

Povijest preglednika (engl. browser history) jedna je od tri najčešće korištene vrste

povijesti, uz hashHistory i createMemoryHistory, te je preporučena vrsta za korištenje uz React

Router.

Browser history koristi History API ugrađen u preglednik kako bi manipulirao URL-ovima

i kreirao prave URL-ove oblika example.com/some/path.

React-router-redux knjižnica olakšava usmjeravanje spremajući podatak o lokaciji u

spremište pomoću funkcije syncHistoryWithStore(). Time je omogućeno spremanje i

ponavljanje korisničkih akcija.

Primjer logičke komponente u Django Online Judge aplikaciji je ContestListContainer.

Funkcija mapStateToProps() kao argument prima stanje iz kojeg očitava i definira polje objekata

contests. Funkcija mapDispatchToProps() definira akciju koja će biti odaslana u slučaju nekog

događaja. Zatim se u funkciji connect() proslijeđuje te podatke prezentacijskoj komponenti

ContestList kako bi se kreirala nova logička komponenta.

Page 35: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

28

// ContestListContainer.js

const mapStateToProps = (state) => {

const contestsArr = Object.keys(state.entities.contests).map

(key => state.entities.contests[key])

/* …još koda…*/

}

const mapDispatchToProps = (dispatch) => {

return {

onContestClick: (name) => {

dispatch(openContest(name))

},

}

}

const ContestListContainer = connect(

mapStateToProps,

mapDispatchToProps

)(ContestList)

export default ContestListContainer

Prezentacijska komponenta ContestList određuje kako će se primljeno polje objekata

generirati, odnosno prikazati na korisničkom sučelju. Kreira tablicu koja će sadržavati listu

contests, ali ne ispisuje ih direktno, već poziva drugu prezentacijsku komponentu,

ContestInList, zaduženu za prikaz pojedinog contest kao jednog retka u tablici. To je primjer

razdvajanja komponenti na način da svaka komponenta odrađuje minimalni zadatak. Svaki

contest unutar polja sadrži jedinstveno identifikacijsko svojstvo (key) pomoću kojeg se

prosljeđuje u ContestInList.

// ContestList.js

const ContestList = ({ contests, onContestClick }) => (

<table>

<tbody>

{

contests.map(contest =>

<ContestInList

key={contest.name}

{...contest}

Page 36: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

29

onClick={() => onContestClick(contest.name)}

/>

)}

</tbody>

</table>

)

ContestInList kao svojstva prima name, start i finish. Ne zna otkud su ti podaci došli

niti ih može promijeniti, samo određuje kako će se generirati – definira jedan redak tablice u kojem

će se primljeni podaci ispisati. Osim toga, za svako primljeno svojstvo definira vrstu podatka koji

sadrži (propType). React.PropTypes služi za validaciju podataka kako bi se osiguralo da se

koriste pravilno. Ako se proslijedi nepravilna vrijednost, React javlja grešku koja se ispisuje u

konzoli.

// ContestInList.js

const ContestInList = ({ name, start, finish, onContestClick, onResultsClick })

=> {

return (

<tr>

<td><Glyphicon glyph="time" /></td>

<td onClick={onContestClick}>{name}</td>

<td>{start} - {finish}</td>

<td onClick={onResultsClick}>Results</td>

</tr>

)

}

ContestInList.propTypes = {

name: PropTypes.string.isRequired,

start: PropTypes.string.isRequired,

finish: PropTypes.string.isRequired,

onContestClick: PropTypes.func.isRequired,

onResultsClick: PropTypes.func.isRequired

}

export default ContestInList

Page 37: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

30

6.3. Akcije i tok podataka

U teorijskom dijelu završnog rada opisane su Redux akcije i kreatori akcija te sinkroni tok

podataka – svaki put kada se akcija odašalje, stanje se odmah ažurira.

Django Online Judge aplikacija treba podržavati asinkrone akcije, budući da podatke

dohvaća s vanjskog API-ja. Međutim, Redux sam po sebi ne podržava asinkrone akcije pa je

potrebno uključiti posrednika (engl. middleware) – softver koji definira kako će aplikacija

komunicirati s vanjskim poslužiteljem. Django Online Judge koristi posrednik redux-thunk koji

upravlja dispatch() metodom spremišta na način da omogućuje odašiljanje ne samo akcija, već

i funkcija ili Promisea. Takav kreator akcije naziva se thunk. Funkcije koje thunk odašilje ne

moraju biti čiste (čista akcija svaki put za isti ulaz mora vratiti isti izlaz), što omogućuje izvođenje

asinkronih poziva API-ju. Ako se koristi više posrednika, drugi posrednik može preuzeti što je

odaslano i proslijediti odgovarajuću akciju dalje. Zadnji posrednik u nizu mora odaslati akciju kao

običan objekt i zatim Redux nastavlja sinkroni tok podataka.

Posrednik se uključuje u aplikaciju pri kreiranju spremišta, korištenjem funkcije

applyMiddleware(), kao što je prikazano u kodu:

//configureStore.prod.js

//...

export default function configureStore(preloadedState) {

return createStore(

rootReducer,

preloadedState,

applyMiddleware(thunk, api)

)

}

Uz Thunk posrednik, Django Online Judge koristi i vlastitog posrednika koji služi za

komunikaciju s API-jem. Definira 4 funkcije, za 4 različite metode HTTP zahtjeva:

callApiToGet() - dohvaća podatke, koristi GET metodu,

callApiToPost() - šalje podatke unesene od strane korisnika, koristi POST metodu,

callApiToPut() - šalje podatke unesene od strane korisnika, koristi PUT metodu,

callApiToDelete() - briše podatke, koristi DELETE metodu.

Page 38: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

31

Funkcije vraćaju podatke u JSON formatu koje posrednik prosljeđuje Redux aplikaciji.

Pritom koristi alat normalizr koji normalizira podatke prema definiranim shemama kako bi ih

aplikacija mogla koristiti. Naime, Reduxu je jako teško iščitati podatke iz ugniježđenih odgovora

API-ja. Normalizr pomoću dobivenih JSON podataka i definiranih shema zapisuje sve Contests,

Challenges i Problems u objekt entities, pri čemu sve ugniježđene podatke zamjenjuje njihovim

identifikacijskim atributima. Iz ovakvih "plošnih" podataka jednostavno je kreirati normalizirano

stablo i ažurirati ga kad se dohvate novi podaci.

//iz api.js – shema za normalizaciju elemenata contests

const contestSchema = new Schema('contests', {

idAttribute: contest => contest.name

})

//iz api.js – funkcija callApiToGet()

function callApiToGet(endpoint, schema) {

const fullUrl = (endpoint.indexOf(API_ROOT) === -1) ? API_ROOT + endpoint :

endpoint

return fetch(fullUrl, { headers: {'Authorization': 'Token ' +

localStorage.token }})

.then(response =>

response.json().then(json => ({ json, response }))

).then(({ json, response }) => {

if (!response.ok) {

return Promise.reject(json)

}

const camelizedJson = camelizeKeys(json)

return Object.assign({},

normalize(camelizedJson, schema)//,

//{ nextPageUrl }

)

})

}

Page 39: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

32

export default store => next => action => {

// …

switch (method){

case 'GET':

return callApiToGet(endpoint, schema).then(

response => next(actionWith({

response,

type: successType

})),

error => next(actionWith({

type: failureType,

error: error.message || 'Something bad happened'

}))

)

//…

Page 40: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

33

6.4. Autentikacija korisnika

U produkcijskoj verziji Django Online Judge aplikacije koristit će se prijava i autentikacija

pomoću AAI@EduHr elektroničkog identiteta. Za potrebe razvoja aplikacije, implementirana je

jednostavna autentikacija pomoću tokena. Na slici 6.1. prikazan je dijagram interakcija pri

autentikaciji korisnika pomoću tokena.

Tok događaja vezanih uz autentikaciju je:

1. Ako korisnik pokuša pristupiti aplikaciji bez autenticiranja, preusmjerava se na stranicu za

prijavu (engl. login).

2. Uneseni korisnički podaci se prosljeđuju DRF-u. Ako su važeći, korisniku se dodjeljuje

autentikacijski token.

3. Token se sprema u lokalni spremnik u pregledniku kako bi pri daljnjim HTTP zahtjevima

mogao automatski biti proslijeđen u zaglavlju zahtjeva.

4. Prijavljeni korisnik se preusmjerava na aplikaciju, a token mu omogućava pristup

podacima.

5. Kada se korisnik odjavi, token se briše iz lokalnog spremnika, a aplikacija se preusmjerava

na stranicu za prijavu.

Page 41: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

34

Slika 6.1. Dijagram interakcija pri autentikaciji korisnika

Prilikom generacije komponente, react-router opcija onEnter poziva funkciju

requireAuth() koja, ako korisnik nije prijavljen, preusmjerava na stranicu za prijavu. Usto, pamti

trenutnu lokaciju, pa nakon prijave vraća korisnika točno na stranicu kojoj je htio pristupiti.

// iz index.js

function requireAuth(nextState, replace) {

if (!auth.loggedIn()) {

replace({

pathname:'/app/login/',

state: {nextPathname: '/app/'}

})

}

}

Page 42: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

35

Autentikacijska logika nalazi se u datoteci auth.js, a definira funkcije za prijavu (login),

odjavu (logout), provjeru je li korisnik trenutno ulogiran (loggedIn) i dobivanje tokena

(getToken).

//auth.js

module.exports = {

login: function(username, pass, cb) {

if (localStorage.token) {

if (cb) cb(true)

return

}

this.getToken(username, pass, (res) => {

if (res.authenticated) {

localStorage.token = res.token

if (cb) cb(true)

} else {

if (cb) cb(false)

}

})

},

logout: function() {

delete localStorage.token

},

loggedIn: function() {

return !!localStorage.token

},

getToken: function(username, pass, cb) {

$.ajax({

type: 'POST',

url: 'http://localhost:8000/api/obtain-auth-token/',

data: {

username: username,

password: pass

},

success: function(res){

cb({

authenticated: true,

token: res.token

Page 43: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

36

})

}

})

},

}

Komponenta za prijavu (Login) traži unos korisničkog imena i lozinke te poziva funkciju

login() definiranu u auth.js koja, ako su korisnički podaci ispravni, od API-ja dohvaća

odgovarajući token i preusmjerava sada prijavljenog korisnika na stranicu kojoj je nastojao

pristupiti.

Nakon što se u poslužiteljskom dijelu aplikacije postave potrebni uvjeti, autentikacija je

implementirana i korisnik ima pristup podacima API-ja, samo je potrebno u svaki zahtjev API-ju

uključiti zaglavlje Authorization header koji prosljeđuje autentikacijski token.

// iz middleware/api.js

function callApiToGet(endpoint, schema) {

const fullUrl = (endpoint.indexOf(API_ROOT) === -1) ? API_ROOT +

endpoint : endpoint

return fetch(fullUrl, { headers: {'Authorization': 'Token ' +

localStorage.token }})

Page 44: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

37

7. PREDNOSTI I NEDOSTACI PREBACIVANJA APLIKACIJSKE

LOGIKE NA KLIJENTA

Pri razvoju jednostraničnih web aplikacija, uobičajeno je prenijeti aplikacijsku logiku s

poslužiteljskog na klijentski dio aplikacije. U ovom se poglavlju navode prednosti i nedostaci

takvog pristupa.

7.1. Prednosti

Prva, očita prednost je rasterećenje poslužitelja. Poslužitelj ne treba sam kreirati web stranicu,

već prosljeđuje statičke dokumente klijentu, a zatim samo odgovara na zahtjeve slanjem JSON

podataka. Takvo rasterećenje omogućuje posluživanje više klijenata nego kod tradicionalnih

aplikacija.

Umjesto dohvaćanja i učitavanja brojnih stranica dok je korisnik na nekom web sjedištu,

jednostranične aplikacije dohvaćaju sav potreban kod pri inicijalnom učitavanju stranice te se

kreira virtualni DOM, a zatim po potrebi osvježava i učitava samo dijelove korisničkog sučelja i

DOM-a. Time je korisničko iskustvo puno ugodnije, jer nema nepotrebnog čekanja da se stranica

dohvati ili ponovnog učitavanja cijele stranice, već korisnik ima osjećaj korištenja desktop

aplikacije, bez dohvaćanja resursa s vanjskog poslužitelja.

Budući da se većina resursa (HTML, CSS, skripte) učitava samo jednom, između klijenta

i poslužitelja se razmjenjuju samo podatci (engl. data), što uvelike ubrzava rad aplikacije te i

zahtijeva manju propusnost mreže (engl. bandwith). Podatci koje razmjenjuju su u JSON formatu,

što znači da je vrlo lako provesti testiranje aplikacije - dovoljno je napisati testne JSON podatke i

poslati ih aplikaciji.

Kada se sva interakcija s korisničkim sučeljem odvija isključivo na klijentu, korištenjem

JavaScripta, HTML-a i CSS-a, poslužitelj služi isključivo kao uslužni sloj za dobavljanje

podataka. Klijent treba znati samo koje HTTP zahtjeve treba slati, bez ikakvog znanja o

implementaciji poslužiteljskog dijela. Ovakvo razdvajanje (engl. decoupling) klijentskog i

poslužiteljskog dijela aplikacije osigurava iskoristivost koda i olakšava održavanje aplikacije.

Samostalnost svakog dijela znači da je moguće zamijeniti cijeli klijentski dio bez ikakvog utjecaja

na poslužiteljski, i obrnuto. Također, otvara mogućnost proširenja aplikacije; za izradu mobilne

verzije iste aplikacije dovoljno je projektirati klijentsku mobilnu aplikaciju, a poslužiteljski je dio

Page 45: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

38

iskoristiv ovakav kakav je. S obzirom na raznolikost uređaja koji se danas koriste, ovo je velika

prednost.

7.2. Nedostaci

Jedan od nedostataka ovakvog pristupa je nedostatak kontrole na klijentskoj strani. Naime,

brzina aplikacije ovisi o pregledniku i samom računalu koji se koristi, na što se ne može utjecati.

S druge strane, kada se generiranje odrađuje na poslužiteljskoj strani i performanse su loše,

moguće ih je poboljšati npr. povećanjem broja poslužiteljskih uređaja. Iako su mogućnosti klijenta

posebno bitne za aplikacije s logikom na klijentskoj strani, zapravo utječu na svaku aplikaciju pa

se ovaj problem može javiti i s logikom na poslužiteljskoj strani.

Općenito, kompatibilnost s različitim preglednicima je upitna pa je potrebno ili razviti

aplikaciju sa što manjim zahtjevima ili osigurati više verzija, prilagođenih pojedinom pregledniku.

Neki stariji preglednici uopće ne podržavaju aplikacije pisane JavaScriptom, a neki korisnici

odluče onemogućiti JavaScript. Međutim, problemi kompatibilnosti s preglednicima postoje i kod

aplikacija s logikom na poslužiteljskoj strani, iako u manjoj količini, a gotovo sve moderne

aplikacije koriste JavaScript pa se preglednici koji ga ne podržavaju sve manje koriste.

Kod aplikacija koje se generiraju na poslužiteljskoj strani, kada klijent dohvaća stranicu,

odmah dobije učitanu stranicu. Generiranje na klijentskoj stranici znači da preglednik prvo

dohvaća kod, a zatim ga pokreće kako bi učitao stranicu. To znači da, ovisno o kompleksnosti

aplikacije i mogućnostima preglednika, prvo učitavanje stranice traje duže nego pri generiranju na

poslužiteljskoj strani (dok se kod ne pokrene, korisniku je prikazana prazna stranica). Međutim,

suvremena računala i preglednici su sposobni odraditi dodatan posao dovoljno brzo te korisnik

uglavnom i ne primjećuje dodatno vrijeme učitavanja.

Kada se aplikacija generira na poslužitelju, sve konstantne podatke (HTML, slike, CSS...),

kao i konačnu generiranu verziju aplikacije moguće je spremiti u predmemoriju (engl. cache)

preglednika, što rasterećuje poslužitelja i ubrzava učitavanje aplikacije. Generiranje na klijentu

znači da se aplikacija mora uvijek iznova graditi.

Ako se dogodi greška na aplikaciji s logikom na poslužitelju, automatski je zapisana na

poslužitelju. Kod aplikacija s logikom na klijentu, potrebno je dodatno specificirati zapisivanje

grešaka i slanje na poslužitelj kako bi se mogle zabilježiti i obraditi. Osim što je problematično,

ovakvo bilježenje često je i nepouzdano.

Generiranje aplikacije na klijentu može predstavljati problem za web tražilice. Naime,

budući da web stranica zapravo nastaje i dobiva sav svoj sadržaj u pregledniku, pretraživač web

Page 46: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

39

stranica će vidjeti drukčiju verziju nego stranice nego krajnji korisnik, jer pretraživači ne

prepoznaju URL-ove i stranice učitane pomoću JavaScripta. Iako se sami pretraživači

nadograđuju, i dalje je pri izgradnji aplikacije potrebno imati na umu dodatnu optimizaciju za web

tražilice, koja kod aplikacija s logikom na poslužitelju nije potrebna.

7.3. Zaključak analize

Može se zaključiti da je zadržavanje aplikacijske logike na poslužiteljskoj strani aplikacije

nužno samo u slučaju kada početno učitavanje stranice mora biti veoma brzo. Za sve druge potrebe,

prebacivanje logike na klijenta je bolji izbor jer pridonosi responzivnosti aplikacije te rasterećenju

mreže i poslužitelja.

Postoji i treća opcija, u kojoj je aplikacijska raspodijeljena između klijenta i poslužitelja

tako da poslužitelj učita početnu stranicu sa svim podacima, a sve daljnje akcije preuzima klijent.

Time je osigurana brzina i responzivnost u svakom trenutku. Ovakve se aplikacije nazivaju

univerzalnim (engl. universal) ili izomorfnim (engl. isomorphic) aplikacijama, a izrađuju se

koristeći React i Node.js, pri čemu Node.js služi kao poslužitelj.

Page 47: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

40

ZAKLJUČAK

U ranijim danima interneta, sadržaj web stranica bio je isključivo statičan i služio kao izvor

informacija. Moderne web aplikacije su interaktivne i mogu pružiti bogato korisničko iskustvo,

slično mobilnim ili desktop aplikacijama. Sadržaj stranice se učitava i mijenja dinamički, umjesto

da se odjednom dohvaća sve.

Tradicionalno se korisnička sučelja web aplikacija grade većinom pomoću HTML

predložaka. Pri razvoju modernih aplikacija se koriste moderne metode i alati, primarno HTML5,

AJAX i JavaScript. U zadnjih nekoliko godina postao je trend graditi klijentsku stranu web

aplikacije najvećim dijelom u JavaScriptu te se razvilo nekoliko radnih okvira, poput ReactJS,

AngularJS, EmberJS, MeteorJS… Tim se radnim okvirima uglavnom grade jednostranične web

aplikacije, pri čemu se aplikacijska logika u velikom dijelu prebacuje s poslužiteljske na klijentsku

stranu aplikacije.

Držanje aplikacijske logike na klijentskoj strani znači da se pri početnom učitavanju

aplikacije preuzimaju svi potrebni resursi s poslužitelja i zatim se aplikacija generira na klijentskoj

strani, unutar web preglednika. Stoga početno učitavanje stranice traje duže nego kod aplikacija s

logikom na poslužiteljskoj strani. Međutim, sva daljnja interakcija s aplikacijom je brža, jer se

ponovno ne učitava cijela stranica, nego samo dijelovi koji se izmijene. Pritom je uloga poslužitelja

svedena na jednostavno sučelje za dohvat podataka, koje prosljeđuje u JSON formatu, što je brzo

i ne opterećuje mrežu.

Pri razvoju jednostraničnih web aplikacija koristeći ReactJS radni okvir, aplikacija se dijeli

na komponente koje predstavljaju dijelove korisničkog sučelja, njihov izgled i poslovnu logiku.

Pritom je uobičajeno koristiti JSX sintaksu, „proširenje“ JavaScripta koje uključuje XML sintaksu.

Redux je knjižnica za upravljanje stanjem aplikacije koja posebno dobro radi uz React (za razliku

od ostalih JS radnih okvira) jer React omogućuje definiranje korisničkog sučelja kao funkcije

stanja, a Redux ažurira stanje kao odgovor na akcije.

Page 48: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

41

LITERATURA I IZVORI

[1] Wasson, M.: „ASP.NET - Single-Page Applications: Build Modern, Responsive Web Apps

with ASP.NET“, s Interneta, https://msdn.microsoft.com/en-us/magazine/dn463786.aspx, 7.

rujna 2016.

[2] Single-page applications, s Interneta, https://en.wikipedia.org/wiki/Single-page_application,

7. rujna 2016.

[3] Hunt, P.: „Why did we build React?“, s Interneta,

https://facebook.github.io/react/blog/2013/06/05/why-react.html, 8. rujna 2016.

[4] Krajka, B.: „The difference between Virtual DOM and DOM“, s Interneta,

http://reactkungfu.com/2015/10/the-difference-between-virtual-dom-and-dom/, 10. rujna 2016.

[5] Hunt, P.: „Thinking in React“, s Interneta, https://facebook.github.io/react/docs/thinking-in-

react.html, 9. rujna 2016.

[6] Abramov, D: „Presentational and Container Components“, s Interneta,

https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0#.rjdlmnpsr, 9.

rujna 2016.

[7] Abramov, D.: „Usage with React“, s Interneta,

http://redux.js.org/docs/basics/UsageWithReact.html, 9. rujna 2016.

Page 49: SVEUČILIŠTE U RIJECI TEHNIČKI FAKULTET · 2016-09-28 · Online Judge koristeći React.js radni okvir te analiza prednosti i nedostataka prebacivanja aplikacijske logike na klijenta

42

SAŽETAK

U radu je ukratko objašnjen način izrade modernih jednostraničnih web aplikacija koristeći

ReactJS radni okvir i Redux knjižnicu za upravljanje stanjem. Jednostranične web aplikacije

nastoje pružiti korisničko iskustvo slično onome desktop aplikacija, a to postižu prebacivanjem

aplikacijske logike s poslužiteljske na klijentsku stranu aplikacije. Nakon početnog učitavanja web

stranice, sve se daljnje promjene izvršavaju samo na dijelovima aplikacije, bez ponovnog

učitavanja cijele stranice. Komunikacija s poslužiteljem svedena je na dohvaćanje podataka, koje

poslužitelj dostavlja u JSON formatu. U radu se analiziraju prednosti i nedostaci ovakvog pristupa

razvoju web aplikacije te se dolazi do zaključka da prebacivanje aplikacijske logike na klijenta

uvelike pridonosi responzivnosti stranice i korisničkom iskustvu te rasterećenju poslužitelja, a nije

preporučljivo jedino u slučaju kada početno učitavanje aplikacije mora biti jako brzo.

Kao praktični dio završnog rada izrađen je klijentski dio jednostranične aplikacije Django

Online Judge koristeći ReactJS i Redux te je aplikacija opisana u radu.

Ključne riječi: jednostranične web aplikacije, klijentski dio web aplikacije, ReactJS, Redux.

ABSTRACT

The thesis paper contains a brief introduction to development of modern single-page web

applications (SPA) using ReactJS framework and Redux state management library. Single-page

applications strive to provide customer experience similar to that found in desktop apps, which is

achieved by moving the application logic from the server to the client side of the application. After

the initial loading of the webpage, all the following changes are rendered on parts of the page,

without the need for a full reload. All the server does is provide needed dana in JSON format. The

paper analyses the advantages and disadvantages of this approach to web application development

and comes to the conclusion that keeping the application logic on the client-side greatly contributes

to the application's responsiveness and user experience as well as server unloading, and is not

recommended only for applications that need the initial loading to be very fast.

The practical part of the thesis consisted of building the frontend for a single-page

application Django Online Judge using ReactJS and Redux, which is described in the paper.

Key words: single-page application, frontend, React.js, Redux.