Differences

This shows you the differences between two versions of the page.

Link to this comparison view

pw:laboratoare:09 [2020/04/16 10:14]
alexandru.hogea [Exercitii]
pw:laboratoare:09 [2021/05/09 19:53] (current)
alexandru.hogea [Exercitii]
Line 1: Line 1:
-===== Laboratorul 09: SASS & React Hooks =====+===== Laboratorul 09: React Router & Request-uri HTTP =====
  
-==== 1. Syntactically Awesome Style Sheets ​====+===== Premisa ​===== 
 +<note important>​In cadrul acestui laborator, vom accesa backend-ul creat la [[https://​gitlab.com/​tehnologiiweb/​lab5| Laboratorul 5]]. Cel mai recomandat este sa il clonati din nou si sa dati docker-compose up. Atat serverul cat si baza de date ruleaza amandoua in Docker.</​note>​
  
-SASS este un preprocesor de stil compilat in CSSVa permite sa utilizati variabilenested rules, mixins, functii si multe altele, toate cu o sintaxa complet compatibila CSS. SASS ajuta la mentinerea bine organizata a fisierelor mari de stil si faciliteaza partajarea designului in cadrul proiectelor.+===== 1. React Router ===== 
 +React Router DOM este un API creat pentru React pentru a "​simula"​ un browser history pentru aplicatia noastraDeoarece aplicatia noastra este un Single Page Application (SPA)browser-ul nostru nu navigheaza prin fisiere html.
  
-=== 1.1 Variabile ​===+==== 1.1. Instalare React Router ==== 
 +Pentru a instala react-router-dom trebuie sa executam urmatoarea comanda: 
 +<​code>​npm install react-router-dom</​code>​
  
-Ganditi-va la variabile ca la o modalitate de a stoca informatiile pe care doriti sa le reutilizati ​in intreaga aplicatie ​(stiluri). Puteti stoca lucruri precum culoristive de fonturi sau orice valoare CSS pe care considerati ca veti dori sa o reutilizati. SASS foloseste simbolul ​**$** pentru a face ceva variabil. Mai jos puteti vedea un exemplu:+==== 1.2. Utilizarea React Router ==== 
 +Utilizarea React Router-ului se realizeaza ​in 3 pasi: 
 +   * Adaugarea dependintelor din react-router-dom ​(**HashRouter**, **Switch** si **Route**)
  
-{{ :​pw:​laboratoare:​sass_1.png?nolink |}}+{{ :​pw:​laboratoare:​router-1.png?nolink&​500 ​|}}
  
-=== 1.2 Nested rules (Ierarhizare) ===+  * Inglobarea tuturor componentelor din cadrul aplicatiei in **<​HashRouter>​** si **<​Switch>​**  
 +  * Definirea rutelor folosind **<​Route>​** ​
  
-Cand scrieti HTML, ati observat probabil ca are o ierarhizare clara si vizuala. CSS, in schimb, nu. +{{ :​pw:​laboratoare:​router-2.png?​nolink&​500 |}}
-SASS va permite sa va ierarhizati selectoarele CSS intr-un mod care sa urmeze aceeasi ierarhie vizuala a HTML-ului. Fiti constienti de facptul ca regulile exagerat de imbibate vor duce la CSS supra-calificate,​ care s-ar putea dovedi greu de intretinut si nu este, in general, considerata o practica buna.+
  
-{{ :​pw:​laboratoare:​sass_2.png?​nolink |}}+Schimbarea continutului dinamic se realizeaza prin folosirea componentei **<​Link>​** din react-router-dom
  
-=== 1.Mixins ===+{{ :​pw:​laboratoare:​router-3.png?​nolink&​400 |}}
  
-Unele lucruri ​din CSS sunt destul de complicate de scrisin special ​cu CSS3 si cu numeroasele prefixuri ale furnizorilor care exista. Un mixin va permite sa faceti grupuri de declaratii CSS pe care doriti sa le reutilizati pe site-ul vostru.+===== 2. Axios si Request-uri HTTP ===== 
 +Axios este o biblioteca JavaScript folosita pentru a face **Request-uri HTTP** ​din **Node.Js** sau **XMLHttpRequest** din browsercerinta principala fiind compatibilitatea ​cu **ES6 Promise API**.
  
-{{ :pw:laboratoare:sass_3.png?​nolink ​|}}+=== 2.1. Caracteristici principale === 
 +  * **[[https://​developer.mozilla.org/​en-US/​docs/​Web/​API/​XMLHttpRequest|XMLHttpRequests]]** din browser 
 +  * Request-uri **[[https://​nodejs.org/​api/​http.html|HTTP]]** din **Node.JS** 
 +  * Suporta **[[https://​developer.mozilla.org/​en-US/​docs/​Web/​JavaScript/​Reference/​Global_Objects/​Promise|Promise API]]** 
 +  * Interceptare request-uri si responses
  
 +=== 2.2. Instalare axios ===
  
-===== 2. React Hooks ===== +<​code>​npm install axios</code>
-**[[https://​reactjs.org/​docs/​hooks-overview.html|Hooks]]** sunt o noua adaugare in **React 16.8**. Va permit sa utilizati functiile de stare si alte functii React, fara a scrie o clasa. Avantajul este mai putin cod scris pentru a obtine aceeasi functionalitate.+
  
-=== 2.1 useState() === 
-[[https://​reactjs.org/​docs/​hooks-state.html|useState]] este un hook de React care va permite sa interactionati cu starea unei componente. Acesta va intoarce un vector format din 2 elemente: 
-  * Variabila de stare 
-  * Functia care va modifica variabila de stare 
  
-Functia **useState** primeste ca parametru valoarea initiala a starii +=== 2.3. HTTP Get === 
-<code javascript>​ +{{ :​pw:​laboratoare:​axios_get.png?​nolink&​500 |}}
-const [myState, myFunctionToChangeState] ​useState(initialValue);​ +
-</​code>​+
  
-<note tip>​Atentie,​ valoarea initiala trebuie sa reflecte tipul de stare pe care vreti sa il retineti (string, numar, obiect, etc...)</​note>​ +=== 2.4HTTP Post === 
-<note tip>O componenta poate apela **useState** de mai multe ori, pentru a retine stari diferite</​note>​+{{ :​pw:​laboratoare:​axios_post.png?​nolink&​500 |}}
  
-{{:​pw:​laboratoare:​mai_multe_stari.png?800|}}+=== 2.5. HTTP Put === 
 +{{ :​pw:​laboratoare:​axios_put.png?nolink&​500 ​|}}
  
-Acest exemplu reda un contorCand faceti clic pe buton, creste valoarea:+=== 2.6. HTTP Delete === 
 +{{ :pw:​laboratoare:​axios_delete.png?​nolink&​500 |}}
  
-{{ :​pw:​laboratoare:​usestate_1.png?nolink |}}+=== 2.7. HTTP Request cu Headers === 
 +{{ :​pw:​laboratoare:​axios_headers.png?nolink&​500 ​|}}
  
-<note tip>​Observati cum valoarea initiala a starii este 0</​note>​ 
  
-=== 2.2 useEffect() ===+<note important>​Pe langa HOST (localhost in cazurile de mai sus), trebuie mentionat si portul si protocolul. Pentru acest laborator o sa fie http://​localhost:​3000</​note>​
  
-[[https://​reactjs.org/​docs/​hooks-effect.html|useEffect]] este al doilea hook important din React si va permite propagarea **efectelor colaterale** din React - sau pe scurt, **efecte** - (de exemplu, modificarea DOM-ului, afisarea unor alerte, preluarea unor date, etc...).+===== Exercitii =====
  
-Orice actiune care nu se poate efectua in timpul randarii (render), pentru ca poate modifica structura componentei,​ este considerat efect+{{ :​pw:​laboratoare:​brief.png?​nolink&​700 |}}
  
-Pe vremuri, cand componentele functionale nu erau atat de folosite si inca se foloseau foarte mult componentele clasa, aceste efecte erau tratate in **ciclurile de viata** ale componentelor. Aceste cicluri de viata nu sunt nimic mai mult decat metode ale claselor de React. Amintim cateva: +{{ :pw:​laboratoare:​lab_4_-_register.png?​nolink&​700 |}}
-  * **componentDidMount** ​metoda care se executa dupa redarea initiala a componentei +
-  * **componentDidUpdate** - metoda care se executa dupa ce state sau props au fost modificate +
-  * **componentWillUnmount** - metoda care se executa inainte de stergerea componentei - adica este scoasa din DOM+
  
-In principal, **efectele** declarate folosind **useEffect** se realizeaza, prin analogie, in **componentDidMount**,​ **componentDidUpdate** si, daca este declarat un comportament specific si in **componentWillUnmount**.+{{ :​pw:​laboratoare:​lab_4_-_login.png?​nolink&​700 |}}
  
-Mai jos aveti un exemplu de efect care schimba titlul paginii:+{{ :pw:​laboratoare:​lab_4_-_books.png?​nolink&​700 |}}
  
-{{ :​pw:​laboratoare:​useeffect_1.png?nolink |}}+{{ :​pw:​laboratoare:​lab_4_-_authors.png?nolink&​700 ​|}}
  
-Prin analogieasa s-ar fi scris folosind clase:+<note tip>​Pentru vizualizarea detaliilorputeti intra pe acest [[https://​xd.adobe.com/​view/​7ba0a1d7-2e62-45d7-b27b-f74a16e55876-2ef3/​screen/​47f00dd6-0679-4cbb-b4ae-abe03f8445fc/​specs/​|link]] si alegand optiunea **</>​** din meniul vertical aflat in dreapta.</​note>​
  
-{{:pw:​laboratoare:​react_hook_clasa.png|}}+<note tip>​Pentru ilustratie puteti folosi [[https://undraw.co|Undraw]]. Ilustratia folosita in design poate fi gasita cautand 'Tree swing'​.</​note>​
  
-<note tip> Observati cum logica este duplicata in **componentDidMount** si **componentDidUpdate**useEffect elimina aceasta duplicare</​note>​ +1Creati o componenta **Autentificare** care sa contina un formular cu **doua ​campuri text si un buton de Submit** respectiv ​**Register**.  
- +<note important>​Componenta ​Autentificare ​va fi responsabila ​de a trimite un request ​de tip POST catre APIavand in body datele necesare autentificarii respectiv inregistrarii utilizatorului.
-Exista cazuri cand doriti sa anulati un efect in momentul in care nu mai aveti nevoie de componenta ​sau cand proprietatile componentei se schimba. Acest proces se numeste ​**curatare**. In Reactul clasic, acest lucru era scris in metoda **componentWillUnmount**,​ sau in metoda **componentDidUpdate**. Pentru a face acest lucru in useEffect, este nevoie ​sa **returnati o functie**.  +
- +
-Asadar, ce se intampla in corpul functiei useEffect se intampla **de fiecare data** cand componenta se randeaza (render) si ce se returneaza se executa **de fiecare data** cand componenta a terminat de executat render. +
- +
-De exemplu, sa presupunem ca avem un API de Chat care are doua metode: subscribe ​si unsubscribe. Aceste doua metode au doi parametri, ​un id si o functie ​de callback care seteaza statusul pe online sau offline. Ne dorim sa dam subscribe la inceputul componentei si sa dam unsubscribe,​ atunci cand parasim componenenta. +
- +
-Folosind useEffect, acest lucru se poate realiza foarte usor: +
- +
-{{ :​pw:​laboratoare:​useeffect_2.png?​nolink |}} +
- +
-Pe de alta parte, folosind clasa, codul ar fi aratat astfel: +
- +
-{{:​pw:​laboratoare:​react_hook_clasa_2.png|}} +
- +
-<note tip>​Observati cum ce este returnat in **useEffect** este scris in **componentWillUnmount** si ce este scris in corpul **useEffect** este scris in **componentDidMount**,​ asa cum am explicat anterior.</​note>​ +
- +
-<note important>​Codul din ultima coza este un cod ce are bug. Ganditi-va la urmatorul caz: cand **props** este modificat (adica atunci cand parintele ii trimite alta valoare pentru props), componenta **NU** va efectua unsubscribe,​ chiar daca id-ul s-a modificat. Acest lucru trebuie tratat tot in **componentDidMount**. useEffect elimina aceasta problema, executand codul la fiecare render.</​note>​ +
- +
-Asa ar fi trebuit sa arate codul corect, folosind clase: +
- +
-{{:​pw:​laboratoare:​react_hook_clasa_3.png|}} +
-==== Exercitii ==== +
- +
-Vom extinde aplicatia creata la laboratorul precedent. +
- +
-1. Folosind componentele App si Count, trimiteti valoarea counter-ului si functiile (incrementare,​ decrementare,​ reset) folosind props. Cand counter-ul ajunge 0, afisati o alerta+
-<note important>​Componenta ​**Count** si **App** trebuie sa fie componente functionale. Pentru afisarea alertei va trebui sa folositi **useEffect()**. Valoarea lui count va fi definita drept state in App, la fel si functiile ​de incrementare,​ decrementare si reset.</​note>​ +
- +
-2. Instalati biblioteca **node-sass**. hint: **npm** +
- +
-3. Modificati fisierele ​de css din extensia **.css** in **.scss**. +
-<note important>​ +
-De asemeneaReact permite modularizarea fisierelor SCSS prin denumirea acestora ​in **numeFisier.module.scss**. +
-In acest caz, importarea si referentierea claselor css, se face in felul urmator:+
  
 <​code>​ <​code>​
-numeFisier.module.scss +
- +   username"​admin",​ 
-.container ​+   password"​admin"​
-  ​displayflex; +
-  ​justify-contentspace-between;​ +
-  align-items:​ center; +
-  flex-direction:​ row; +
-  padding: 1rem 0; +
-  font-size: 1em; +
-  font-weight:​ 700; +
-  [...]+
 } }
 +</​code>​
  
-import styles from './numeFisier.module.scss';​+Raspunsul primit de la server, in cazul login, va contine token-ul JWTStocarea token-ului se face in browser, folosind **localStorage**
  
-<div className={styles.container}+Stocare token in **localStorage** 
-[...] +<code
-</​div>​+localStorage.setItem("​token",​ jwt_token);
 </​code>​ </​code>​
  
-In cazul in care doriti import-ul standard, fara module, acesta va arata in felul urmator: +Citirea token-ului din **localStorage**
- +
-numeFisier.scss +
 <​code>​ <​code>​
-.container { +localStorage.getItem("​token"​) 
-  ​display:​ flex; +</​code>​ 
-  ​justify-content:​ space-between;​ +</​note>​
-  align-items:​ center; +
-  flex-direction:​ row; +
-  padding: 1rem 0; +
-  font-size: 1em; +
-  font-weight:​ 700; +
-  [...] +
-}+
  
-import './numeFisier.scss';+2Creati doua componente, **Book** si **Author**, care sa afiseze detaliile despre fiecare carte, respectiv autor. Stilizarea poate sa urmeze design-ul de mai sus. Nu este obligatorie copierea exacta a design-ului,​ importanta este afisarea datelor.
  
-<div className="​container">​ +3Creati o componenta **BooksList** care sa contina o lista cu toate cartile existente, respectiv **AuthorsList** care sa contina o lista cu toti autorii existenti in baza de datePentru afisarea tuturor cartilor, respectiv autorilor, se vor folosi componentele create anterior, **Book** si **Author**. Aceste componente pot fi reprezentate de paginile Books si Authors din design. Din nou, nu este obligatorie respectarea design-ului.
-[...+
-</​div>​ +
-</​code>​+
  
-</​note>​+4. Componentele **BooksList** si **AuthorsList** trebuie sa trimita cate un request de HTTP Get pentru a aduce toate intrarile din baza de date.
  
-4. Stilizarea **Header****Nav** si **Footer**.+<note important>​Cererile catre server pot fi date fie la apasarea pe un butonfie atunci cand se incarca componenta (hint, useEffect)</​note>​
  
-  * Nav: va prezenta in partea din stanga un logo si 3 meniuri (**Home, Books, Authors**) iar in partea din dreapta, un meniu de tip Dropdown cu un buton de **Logout** 
-  * Header: va afisa ca background o imagine (la libera alegere) 
-  * Footer: poate avea orice culoare, iar in Footer se va afisa Prenumle si Numele studentului,​ facultatea si anul absolvirii. 
-5. Componenta Layout va trebui sa alcatuiasca toata interfata utilizator, folosind **Header**, **Nav** si **Footer**. 
-        ​ 
pw/laboratoare/09.1587021264.txt.gz · Last modified: 2020/04/16 10:14 by alexandru.hogea
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0