Class komponente i funkcijske komponente u Reactu
Tags: webdev, javascript, react
Published: 2024-02-26 21:08:46

#### Komponente su osnovni element React biblioteke. Međutim, kada je  u pitanju kreiranje komponenti u Reactu, postoje dva pristupa: class komponente i funkcijske kompontente.

#### U ovom tekstu ću objasniti osnovne razlike između ova dva načina kreiranja komponenti.

**Napomena**: _Kada je React u pitanju često će se istovremeno koriste termini biblioteka i 'framework'. React-ova dokumentacija ga navodi kao biblioteka, tako da ću ja u ovom tekstu koristiti taj termin. Međutim, često se može naći da React nazivaju 'framework'._

---

### Osnovna sintaksa

Prva razlika između class i funkcijskih komponenti je način na koji se kreiraju.
Class komponenta je obična klasa iz JavaScripta koja ima `render()` metodu koja vraća `jsx` u `return` dijelu.


![base class component in react](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mvwtb4udt0or89dpn27b.png)

Treba obratiti pažnju na to da class komponenta koristi osnovnu komponentu `Component` koja se uvozi iz 'reacta'. U funkcijskim komponentama ovo nije potrebno.

Funkcijska komponenta je obična JavaScript funkcija koja vraća `jsx`. Treba obratiti pažnju da u funkcijskim komponentama **nema** `render()` metode.


![Ibasic example of functional component in react](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9r3acqzwazmpm419gotu.png)

---

### State

Druga značajna razlika je način na koji se postavlja i koristi `state`.

U class komponentama state mora biti definisan unutar konstruktor metode.

Da bi se koristio state u class komponentama potrebno mu je pristupiti kao i svakom drugom objektu uz korištenje ključne riječi `this`.


![example of state in react class components](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e5dah0ctnz7po03wubwu.png)

Promjena 'state-a' u class komponentama donosi nove 'probleme'.

![change state in react class components example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/or15bvptk2drg7h3v7h7.png)

Kao što može da se vidi potrebno je prvo kreirati funkciju koja mijenja godine sa 33 na 34. Ali ono šta je neophodno uraditi nakon toga je vezati tu funkciju za tu instancu klase. To se radi pomoću `.bind()` metode unutar konstruktora.

Ako želite da saznate više o `bind` metodi, pisao sam o njoj u tekstu koji možete pročidati [ovdje](https://dev.to/bslaven/call-apply-i-bind-metode-u-javascriptu-3pdj).

Kod funkcijskih komponenti definisanje i korištenje state-a je mnogo elegantnije. Prije svega funkcijske komponente nemaju konstruktor jer nisu klasa. State se definiše uz pomoć `useState` hook-a u vidu obične varijable.


![react functional component state in one line](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6nex4d48r7cf6c1o3ju9.png)

Vrijedi naglasiti da se state u funkcijskim komponentama ne mora navoditi pojedinačno kao u vom primjeru, nego sve može da se stavi u jedan npr. objekat. To je čak i preferirani način ako su podaci koji se deklarišu usko povezani.

Kao što se vidi pozivanje `useState` hook-a vraća dvije vrijednosti. Prva vrijednost je varijabla (ili konstanta) koju mogu koristiti u drugim dijelovima komponente, druga vrijendost je funkcija koja mijenja prvu vrijednost. Te dvije vrijednosti sam destrukturisanjem definisao u jednom redu.


![react functional component state example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qqc40hn229p8u5ah1t93.png)

U praktičnim okolnostima pozivanje setGodine metode najčešće neće biti obavljeno direktno u `onClick` 'event-u', nego će biti kreirana posebna funkcija unutar koje će se mijenjati 'state', pa onda tu novokreiranu funkciju dodati na `onClick` event.

---

### Props

Props objekat je skup informacija koje komponente koriste da komuniciraju međusobno, da razmjenjuju podatke. Svaka 'parent' komponenta može proslijediti svojoj 'child' komponenti neke atribute sa vrijednostima, a ti atributi i vrijednosti će biti dostupni 'child' komponenti u objektu 'props'.

Recimo na primjer da imamo ovakvu 'parent' komponentu, koja isto tako može biti class komponenta ili funkcijska komponenta.

![react parent component passing props to children example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cp0yaiqdghbxsitp8skc.png)

Vidimo da ova 'parent' komponenta na identičan način proslijeđuje props svojim 'child' komponentama, bez obzira da li su one class ili funkcijska komponenta.

Korištenje objekta `props` je, međutim, drugačije među ove dvije verzije komponenti u React-u.

Class komponente dobijaju props objekat kao parametar u konstruktor metodi. Kao i kod state-a objekat props se koristi pomoću ključne riječi `this`.


![react class component props example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7j164ul0pujvv8n1hlek.png)

U funkcijskim komponentama `props` objekat je automatski parametar u funkciji. Kao i kod state-a, nema potrebe da se koristi ključna riječ `this`.


![react functional components props example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yl260idc27ke9k653695.png)

Kod funkcijskih komponenti korisno je to što se `props` objekat, kao i u bilo kojoj drugoj funkciji, može odmah destrukturisati direktno.


![destructuring props in react functional component example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/941dzqwxfls5q6dwjcrw.png)

Destrukturisanje objekta `props` nije moguće u klasama u JavaScriptu, pa samim tim nije moguće ni u React-ovim class komponentama.

----

### 'Lifecycle' metode i hooks

U suštini sve komponente, kako class tako i funkcijske komponente, imaju svoj takozvani životni ciklus. To su faze kroz koju komponenta prolazi dok je prikazana u aplikaciji (riječ na Engleskom je 'mount'). Te faze najprostije rečeno su kada se komponenta postavi (_mounted_), kada se komponenta ažurira (_updated_) i kada se komponenta ukloni (_unmounted_).

Class komponente imaju na raspolaganju nešto što se zove 'lifecycle' metode, odnosno metode životnog ciklusa. One se koriste da bi se pratilo u kojoj fazi životnog ciklusa se nalazi. Shodno tome unutar tih metoda se može raditi nešto što želimo da se desi u bilo kojoj od tih faza.
Te metode su, između ostalih: `componentDidMount`, `componentDidUpdate`, `shouldComponentUpdate`, `componentWillUnmount`.


![a few examples of react class component lifecycle methods](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/edr0eh7r96svispwgoh9.png)

Ovo su samo neke od metoda. Ima dosta drugih metoda, od kojih su neke čak i statičke metode. Čak `constructor` i `render` metode koje smo vidili ranije dio su životnog ciklusa komponente.

Funkcijske komponente, s druge strane, nemaju na raspolaganju ove metode za praćenje životnog ciklusa. U ranijim verzijama React-a funkcijske komponente su bile samo prezentacijske komponente, te nije bilo potrebe da se bilo šta radi u njihovom životnom ciklusu. 
Nisu imale svoj 'state', pa nije bilo potrebe da se prati da li je 'state' promijenjen, pa da se poziva nešto šta bi ličilo na npr. `shouldComponentUpdate` ili `componentDidUpdate`. Funkcijske komponente su se mijenjale samo kada se promijenio njihov `props` objekat koji su dobijale od svoje 'parent' komponente.

Međutim, dolaskom hooks-a i ovo se promijenilo. Funkcijske komponente mogu nositi/držati svoj 'state', ali što je još važnije došao je `useEffect` hook.

Ovaj `useEffect` hook, može da se iskoristi da se uradi nešto kada se komponenta postavi ili da se prate neki sporedni efekti koji se prate.


![react functional component useEffect example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x5o2ly2fmb3zg4pykb8z.png)

Hook `useEffect` dobija dva paremetra. Prvi parametar je funkcija koja će bit pozvana minimalno jednom, kada se komponenta prvi put postavi. Drugi parametar je niz koji će pratiti vrijednosti nakon čije promjene će funkcija iz prvog parametra biti ponovo pozvana. Ako niz ostane prazan, funkcija iz prvog parametra će biti pozvana samo jednom, na početku života komponente, kada se postavi.

Važno je naglasiti da `useEffect`, kao ni druge hooks-e, ne treba posmatrati kao zamjenu za metode životnog ciklusa u class komponentama, nego kao jedan drugi način posmatranja životnog ciklusa komponente.

---

### Zaključak

Funkcijske komponente su budućnost React-a. Čak i u [React-ovoj dokumentaciji](https://react.dev/) rijetko ili nikako nećete naići na class komponente. To ne znači da class komponente ne treba naučiti koristiti, jer postoji vjerovatnoća da ćete nekada naići na neki 'legacy' kod na kom treba raditi.

Class komponente su zaostavština iz ranijih verzija React-a kada su samo class komponente mogle nositi `state`, a funkcijske komponente su služile samo za prezentaciju.

Verzija React-a 16.8 je po prvi put uvela pojam/ideju 'hooks'. Hooks-i su, najprostije rečeno, funkcije koje omogućavaju funkcijskim komponentama da koriste neke funkcionalnosti React-a koje su do tog trenutka bile dostupne samo class komponentama. Dva takva 'hooks-a' sam pominjao u ovom tekstu to su `useState` hook koji omogućava funkcijskim komponentama da nose/drže `state`, te `usEffect` koji služi sa praćenje takozvanih sporednih efekata.

Neki drugi hooks-i su `useContext`, `useCallback`, `useMemo`, itd. Međutim, svaki od ovih hooks-a je tema za sebe, pa ću se njima baviti u zasebnim tekstovima.