Brzi Uvod
Dobro došli u React dokumentaciju! Ova stranica pružiće vam uvod u 80% React koncepata koje ćete koristiti u svakodnevnom radu.
Naučićete:
- Kako kreirati i umetati komponente
- Kako dodavati markup i style-ove
- Kako prikazivati podatke
- Kako renderovati kondicione izraze i liste
- Kako odgovarati na event-e i ažurirati prikaz na ekranu
- Kako prosleđivati podatke među komponentama
Kreiranje i umetanje komponenti
React aplikacije su sačinjene od komponenti. Komponenta je deo UI-a (korisničkog interfejsa) koji ima svoju logiku i izgled. Komponenta može biti mala kao dugme ili velika kao cela stranica.
React komponente su JavaScript funkcije koje vraćaju markup:
function MyButton() {
return (
<button>Ja sam dugme</button>
);
}
Sada kada ste deklarisali MyButton
, možete ga umetnuti unutar druge komponente:
export default function MyApp() {
return (
<div>
<h1>Dobrodošli u moj app</h1>
<MyButton />
</div>
);
}
Primetite da <MyButton />
počinje velikim slovom. Tako znate da je to React komponenta. Nazivi React komponenti uvek moraju počinjati velikim slovom, dok HTML tagovi moraju biti pisani malim slovima.
Pogledajte rezultat:
function MyButton() { return ( <button> Ja sam dugme </button> ); } export default function MyApp() { return ( <div> <h1>Dobrodošli u moj app</h1> <MyButton /> </div> ); }
Ključne reči export default
određuju glavnu komponentu u fajlu. Ukoliko niste upoznati sa nekim delom JavaScript sintakse, MDN i javascript.info imaju odlične reference.
Pisanje markup-a sa JSX
Sintaksa markup-a koju ste videli iznad se zove JSX. Ona nije obavezna, ali većina React projekata koristi JSX zbog njegove praktičnosti. Svi alati koje preporučujemo za lokalni razvoj podržavaju JSX odmah po instalaciji.
JSX je striktniji od HTML-a. Morate zatvoriti tagove poput <br />
. Vaša komponenta takođe ne može vraćati više JSX tagova. Morate ih obuhvatiti zajedničkim parent-om, poput <div>...</div>
ili praznog <>...</>
omotača:
function AboutPage() {
return (
<>
<h1>O nama</h1>
<p>Zdravo<br />Kako se ste?</p>
</>
);
}
Ukoliko imate mnogo HTML-a koje treba preneti u JSX, možete koristiti online konventor.
Dodavanje style-ova
U React-u, CSS klasu specificirate sa className
. To funkcioniše na isti način kao HTML class
atribut:
<img className="avatar" />
Potom CSS pravila za zadatu klasu pišete u odvojenom CSS fajlu:
/* U vašem CSS-u */
.avatar {
border-radius: 50%;
}
React ne propisuje kako dodajete CSS fajlove. U najjednostavnijem slučaju, dodajete <link>
tag u vaš HTML. Ako koristite build alat ili framework, konsultujte dokumentaciju istog, da biste saznali kako da dodate CSS fajl u vaš projekat.
Prikazivanje podataka
JSX vam omogućava da ubacite markup u JavaScript. Vitičaste zagrade vam omogućavaju da se “prebacite nazad” u JavaScript tako da možete ugraditi neku varijablu iz vašeg koda i prikazati je korisniku. Na primer, ovo će prikazati user.name
:
return (
<h1>
{user.name}
</h1>
);
Takođe možete se “prebaciti u JavaScript” iz JSX atributa, ali morate koristiti vitičaste zagrade umesto navodnika. Na primer, className="avatar"
prosleđuje "avatar"
string kao CSS klasu, ali src={user.imageUrl}
čita vrednost JavaScript user.imageUrl
varijable, a zatim tu vrednost prosleđuje kao src
atribut:
return (
<img
className="avatar"
src={user.imageUrl}
/>
);
Možete staviti i složenije izraze unutar JSX vitičastih zagrada, na primer, konkatenaciju stringova:
const user = { name: 'Hedy Lamarr', imageUrl: 'https://i.imgur.com/yXOvdOSs.jpg', imageSize: 90, }; export default function Profile() { return ( <> <h1>{user.name}</h1> <img className="avatar" src={user.imageUrl} alt={'Fotografija od ' + user.name} style={{ width: user.imageSize, height: user.imageSize }} /> </> ); }
U gore navedenom primeru, style={{}}
nije posebna sintaksa, već običan {}
objekat unutar style={ }
JSX vitičastih zagrada. Možete koristiti style
atribut kada se vaši style-ovi oslanjaju na JavaScript varijable.
Kondicionalno renderovanje
U React-u nema posebne sintakse za pisanje kondicionih izraza. Umesto toga, koristićete iste tehnike kao kada pišete običan JavaScript kod. Na primer, možete koristiti if
izraz za kondicionalno uključivanje JSX-a:
let content;
if (isLoggedIn) {
content = <AdminPanel />;
} else {
content = <LoginForm />;
}
return (
<div>
{content}
</div>
);
Ako preferirate kompaktniji kod, možete koristiti kondicionalni ?
operator. Za razliku od if
, on radi unutar JSX-a:
<div>
{isLoggedIn ? (
<AdminPanel />
) : (
<LoginForm />
)}
</div>
Kada vam nije potrebna else
grana, možete koristiti i kraću logičku &&
sintaksu:
<div>
{isLoggedIn && <AdminPanel />}
</div>
Svi ovi pristupi takođe rade i za kondicionalno specificiranje atributa. Ako niste upoznati sa ovim delovima JavaScript sintakse, možete početi tako što ćete uvek koristiti if...else
.
Renderovanje listi
Oslanjaćete se na JavaScript funkcionalnosti poput for
loop-a i array map()
funkcije za renderovanje listi komponenata.
Na primer, pretpostavimo da imate niz proizvoda:
const products = [
{ title: 'Kupus', id: 1 },
{ title: 'Luk', id: 2 },
{ title: 'Jabuka', id: 3 },
];
Unutar vaše komponente, koristite map()
funkciju da transformišete niz proizvoda u niz <li>
stavki:
const listItems = products.map(product =>
<li key={product.id}>
{product.title}
</li>
);
return (
<ul>{listItems}</ul>
);
Primetite kako <li>
poseduje key
atribut. Za svaku stavku u listi, trebalo bi da prosledite string ili broj koji jedinstveno identifikuje tu stavku među njenim susedima. Obično, ključ (key) bi trebalo da dolazi iz vaših podataka, kao što je ID iz baze podataka. React koristi vaše ključeve (keys) da bi znao šta se dogodilo ako kasnije ubacite, izbrišete ili preuredite stavke.
const products = [ { title: 'Kupus', isFruit: false, id: 1 }, { title: 'Luk', isFruit: false, id: 2 }, { title: 'Jabuka', isFruit: true, id: 3 }, ]; export default function ShoppingList() { const listItems = products.map(product => <li key={product.id} style={{ color: product.isFruit ? 'magenta' : 'darkgreen' }} > {product.title} </li> ); return ( <ul>{listItems}</ul> ); }
Odgovaranje na event-e
Možete odgovarati na event-e deklarisanjem event handler funkcija za obradu event-a unutar vaših komponenti:
function MyButton() {
function handleClick() {
alert('Kliknuli ste me!');
}
return (
<button onClick={handleClick}>
Kliknite me
</button>
);
}
Obratite pažnju na to kako onClick={handleClick}
nema zagrade na kraju! Ne treba da pozivate event handler funkciju: samo je treba proslediti. React će pozvati vaš event handler kada korisnik klikne na dugme.
Ažuriranje ekrana
Često ćete želeti da vaša komponenta “zapamti” neke informacije i prikaže ih. Na primer, možda želite da prebrojite koliko puta je dugme kliknuto. Da biste to uradili, dodajte stanje (state) u svoju komponentu.
Prvo, uvezite useState
iz React-a:
import { useState } from 'react';
Sada možete deklarisati state varijablu unutar vaše komponente:
function MyButton() {
const [count, setCount] = useState(0);
// ...
Od useState
dobićete dve stvari: trenutni state (count
), i funkciju koja vam omogućava da ga ažurirate (setCount
). Možete im dati bilo koja imena, ali je konvencija da pišete [something, setSomething]
.
Prvi put kada se dugme prikaže, count
će biti 0
jer ste 0
prosledili u useState()
. Kada želite da promenite state, pozovite setCount()
i prosledite joj novu vrednost. Klikom na ovo dugme inkrementujte brojač:
function MyButton() {
const [count, setCount] = useState(0);
function handleClick() {
setCount(count + 1);
}
return (
<button onClick={handleClick}>
Kliknuto je {count} puta
</button>
);
}
React će ponovo pozvati funkciju vaše komponente. Ovaj put, count
će biti 1
. Zatim će biti 2
. I tako dalje.
Ako renderujete istu komponentu više puta, svaka će dobiti svoje sopstveni state. Kliknite svako dugme posebno:
import { useState } from 'react'; export default function MyApp() { return ( <div> <h1>Brojači koji se ažuriraju nezavisno</h1> <MyButton /> <MyButton /> </div> ); } function MyButton() { const [count, setCount] = useState(0); function handleClick() { setCount(count + 1); } return ( <button onClick={handleClick}> Kliknuto je {count} puta </button> ); }
Primetite kako svako dugme “pamti” svoj sopstveni state brojača count
i ne utiče na drugu dugmad.
Korišćenje Hook-ova
Funkcije koje počinju sa use
nazivaju se Hook-ovi. useState
je ugrađeni Hook koji pruža React. Možete pronaći i druge ugrađene Hook-ove u API referenci. Takođe, možete pisati svoje sopstvene Hook-ove kombinovanjem postojećih.
Hook-ovi su restriktivniji od ostalih funkcija. Hook-ove možete pozivati samo na vrhu svojih komponenata (ili drugih Hook-ova). Ukoliko nameravate koristiti useState
u nekom condition-u ili loop-u, izdvojite novu komponentu i stavite ga tamo.
Prosleđivanje podataka među komponentama
U prethodnom primeru, svaki MyButton
je imao nezavisni count
, i kada je svako pojedinačno dugme bilo pritisnuto, count
se menjao samo za trenutno pritisnuto dugme:
Međutim, često će vam biti potrebno da komponente prosleđuju podatke međusobno i uvek se zajedno ažuriraju.
Da biste obe MyButton
komponente prikazali sa istim count
i ažurirali zajedno, morate premestiti state iz pojedinačnih dugmadi “nagore” do najbliže komponente koja sadrži sve njih.
U ovom primeru, to je MyApp
:
Sada, kada kliknete na bilo koje dugme, count
u MyApp
će se promeniti, što će promeniti oba brojača u MyButton
. Evo kako to možete izraziti u kodu.
Prvo, podignite state nagore iz MyButton
u MyApp
:
export default function MyApp() {
const [count, setCount] = useState(0);
function handleClick() {
setCount(count + 1);
}
return (
<div>
<h1>Brojači koji se ažuriraju odvojeno</h1>
<MyButton />
<MyButton />
</div>
);
}
function MyButton() {
// ... premeštamo kod odavde ...
}
Zatim, prosleđujemo state nadole iz MyApp
u oba MyButton
, zajedno sa zajedničkim handler-om za klik. Informacije možete proslediti u MyButton
koristeći vitičaste zagrade u JSX-u, baš kao što ste to ranije radili sa ugrađenim tagovima poput <img>
:
export default function MyApp() {
const [count, setCount] = useState(0);
function handleClick() {
setCount(count + 1);
}
return (
<div>
<h1>Brojači koji se ažuriraju zajedno</h1>
<MyButton count={count} onClick={handleClick} />
<MyButton count={count} onClick={handleClick} />
</div>
);
}
Informacije koje na ovaj način prosleđujete nazivaju se props. Sada MyApp
komponenta sadrži count
state i handleClick
event handler i prosleđuje obe nadole kao props svakom dugmetu.
Konačno, promenite MyButton
da čita props koje ste prosledili iz njegove parent komponente:
function MyButton({ count, onClick }) {
return (
<button onClick={onClick}>
Kliknuto {count} puta
</button>
);
}
Kada kliknete na dugme, onClick
handler se aktivira. onClick
prop svakog dugmeta postavljen je na funkciju handleClick
unutar MyApp
pa se kod unutar nje izvršava. Taj kod poziva setCount(count + 1)
, inkrementirajući count
state varijablu. Nova count
vrednost se prosleđuje kao prop svakom dugmetu, pa svi prikazuju novu vrednost. Ovo se naziva “podizanje state-a nagore”. Pomeranjem state-a nagore, podelili ste ga između komponenata.
import { useState } from 'react'; export default function MyApp() { const [count, setCount] = useState(0); function handleClick() { setCount(count + 1); } return ( <div> <h1>Brojači koji se ažuriraju zajedno</h1> <MyButton count={count} onClick={handleClick} /> <MyButton count={count} onClick={handleClick} /> </div> ); } function MyButton({ count, onClick }) { return ( <button onClick={onClick}> Kliknuto {count} puta </button> ); }
Sledeći koraci
Sada već znate osnove pisanja React koda!
Pogledajte Tutorijal biste primenili naučeno i izgradili svoj prvi mini-app sa React-om.