LEKCJA 01 - REACT (p) - basics, props

LEKCJA 01 - REACT (p) - basics, props
ukryj menu
SPEC
aktualizacja: 2021-09-07 10:01:44

React - biblioteka autorstwa facebook-a, służąca do budowania interfejsów użytkownika przy użyciu JavaScript i (opcjonalnie) XML.
React pracuje nie w rzeczywistym DOM, tylko Virtual DOM, w pamięci, w której zachowuje lustrzane odbicie rzeczywistego DOM.
Ilekroć nastąpi zmiana, React aktualizuje rzeczywiste DOM.
Koncepcja Virtual DOM sprawia, że renderowanie aplikacji jest szybsze i poprawia wydajność.kopiuj


strona

https://reactjs.org/kopiuj

1. trochę terminologii

JSX - pozwala pisać składnię HTML wewnątrz obiektów JavaScript

Virtual DOM - pamięciowa reprezentacja rzeczywistego DOM

ReactDOM.render - podstawowa funkcja - renderuje komponent React-a do węzła DOM na stronie

props - dane przekazywane z nadrzędnego do potomnego komponentu

propTypes - kontrolowanie typów props przekazywanych do komponentu potomnego

state - wewnętrzny zasób danych komponentu React

setState - Metoda do zmiany stanu komponentu



2. dodatek React-a do VS code, będzie potrzebny w przyszłości, można zainstalować

reactjs code snippets

https://marketplace.visualstudio.com/items?itemName=xabikos.ReactSnippetskopiuj


3. biblioteki klienckie, wersja 17

w internecie można odnaleźć wiele przykładów użycia różnych wersji bibliotek Reacta
na zajęciach w tym semestrze pracujemy na wersji Reacta 17

<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
kopiuj
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>kopiuj

istnieją też wersje produkcyjne

https://reactjs.org/docs/cdn-links.htmlkopiuj

poprzednie wersje Reacta mają inny wzorzec tworzenia komponentów (bez javascripta w wersji ES6)
Można ich używać do wersji 15 Reacta, choć wyraźnie są zdeprecjonowane (np React.createClass)


4. cw01 - aplikacja z komponentem React bez klas ES6 i JSX, wszystko dzieje się tylko po stronie klienta

poniższe ćwiczenie służy do zrozumienia faktu że wszystkie działania biblioteki react są oparte
na kilku prostych funkcjach w niej zawartych

Utwórz stronę index01.html

dodaj do head dwa powyższe skrypty React17
dodaj do body diva z id = "react-app" -> do niego będzie renderowany komponent Reacta
dodaj klasę css .klasa {color:red}

PO divie wstaw skrypt, a w nim :


ReactDOM.render(
     React.createElement(
    "h1",
    { className: "klasa" },
    "React component"
      ),
     document.getElementById('react-app')
)kopiuj


objaśnienie:

"h1" // jaki element html się renderuje
{ className: "klasa" }, // parametry dodatkowe, najczęściej klasa css, uwaga na camelCase
"React component" // co się renderuje w elemencie html, może to być tekst, mogą być obiekty o czym później


uruchom stronę html

5. cw02 - tablica

skopiuj poprzednią i utwórz stronę index02.html
komponent React może wyrenderować elementy tablicy w jednym elemencie html


var tab = [1,2,3,4]kopiuj

ReactDOM.render(
   React.createElement("h1", { className: "klasa" }, tab),
   document.getElementById('react-app')
)kopiuj


zwróć uwagę, że powstał jeden h1 a w nim wszystkie elementy tablicy w postaci stringów

5. cw03 - wyrenderowanie dwu elementów

skopiuj poprzednią i utwórz stronę index03.html
w css dodaj dwie klasy: klasa1 i klasa2

w skrypcie


var h1 = React.createElement("h1", { className: "klasa1" }, "React component h1" )
var h2 = React.createElement("h2", { className: "klasa2" }, "React component h2" )kopiuj


dwa elementy muszą się zawierać w jednym, jest to wymagane przez render()


var root = React.createElement("div", {}, h1,h2 )

ReactDOM.render(
   root,
   document.getElementById('react-app')
)kopiuj


6. cw04 - wyrenderowanie kilku osobnych elementów Reacta - tablica

skopiuj poprzednią i utwórz stronę index04.html

var h1 = React.createElement("h1", { className: "klasa1" }, "React component h1" )
var h2 = React.createElement("h2", { className: "klasa2" }, "React component h2" )

var tab = [h1,h2,h1,h2,h1,h2]

ReactDOM.render(
   React.createElement("div", {}, tab),
   document.getElementById('react-app')
)kopiuj


7. cw05 - style inline (wewnątrz) obiektu Reacta

skopiuj poprzednią i utwórz stronę index05.html
można pisać style inline, w obiekcie js (nazwy atrybutów w cudzysłowie, bez kreski, koniecznie camelCase)


var square = React.createElement("div", {
            style: {
                width: "100px",
                height: "100px",
                backgroundColor: "red", // nie: background-color
                color:"white",
                fontSize:"20px",
                margin:"2px"
            }
        },
            "React comp"
)kopiuj


    

8. zadanie 06 - style wewnątrz obiektu Reacta

w pliku stronę index06.html wykonaj zadanie jak na skrinie 06
na podstawie poprzednich zadań, z użyciem React.createElement, utwórz elementy:


square
row
table
container


przykład wyrenderowania trzech elementów "element2" w jednym "element"

var element = React.createElement("div",
        {
            style: {
                border: '1px solid blue',
            }
        },
            // elements
            element2,
            element2,
            element2,
)kopiuj


9. Babel w react -> komponenty pisane w JSX

JSX to rozszerzenie składni JavaScript, podobne do XML. Kod JSX wygląda jak HTML,
ale w rzeczywistości jest mieszanką JavaScript i HTML.
Używanie JSX nie jest wymagane podczas pracy z aplikacjami React,
jednak wyraźnie ułatwia konstrukcję komponentów.
Można oczywiście pracować tylko z kodem JavaScript (jak w powyższych punktach).

przykład: porównanie tych samych funkcjonalności w js i jsx


js

ReactDOM.render(
   React.createElement("h1", { className: "klasa1" }, "React component h1" ),
   document.getElementById('react-app')
)kopiuj


JSX

ReactDOM.render(
   <h1 className="klasa1">React component h1</h1>,      
   document.getElementById('react-app')
)kopiuj


kod JSX musi być oczywiście skompilowany do js.
Po stronie klienta, w locie, zajmie się tym biblioteka o nazwie Babel


https://babeljs.io/kopiuj

kiedy używać babla w znaczniku script:

https://babeljs.io/docs/en/babel-standalonekopiuj

10. cw07 - przykład tworzenia komponentu z użyciem JSX i klas ES6:

skopiuj poprzednią i utwórz stronę index07.html

dodaj poniższy skrypt do pliku html


<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>kopiuj

powyższy przykład z punktu 9 używający JSX może służyć tylko do tworzenia najprostszych komponentów.
Właściwe tworzenie komponentów to użycie klas ES6:


w skrypcie wykorzystującym Babel-a, potrzebne jest określenie typu: text/babel

<script type="text/babel">

class Start extends React.Component {
    render() {
        return (
            <h1>React component</h1>
        );
    }
}

ReactDOM.render(
    <Start />,
    document.getElementById('react-app')
);

</script>kopiuj


zasada: nazwa klasy z dużej litery

w powyższym przykładzie cała funkcjonalność, na razie prosta, komponentu Start, została zamknięta w klasie ES6
w kolejnych przykładach będziemy rozbudowywać klasy js, tworząc bardziej złożone komponenty


dokumentacja klas ES6:

https://developer.mozilla.org/pl/docs/Web/JavaScript/Reference/Classeskopiuj

11. cw08 - zmienne w komponencie JSX

skopiuj poprzednią i utwórz stronę index08.html

zmienne wstawiamy
do komponentów w nawiasach {}

class Start extends React.Component {
    render() {
        let place = "city"
        let info = "of angels"
        return (
            <h1>Hello {place} {info}</h1>
        );
    }
}

ReactDOM.render(
    <Start />,
    document.getElementById('react-app')
);kopiuj


wykonaj na stronie trzy takie obiekty klasy Start

uwaga: funkcja return() może zwracać tylko jeden element, a dopiero w nim kolejne zagnieżdzone
np div a wewnątrz kilka h1
diva można zastąpic pustym znacznikiem
<></>

12. cw09 - komponent z listą, użycie props (właściwości)

skopiuj poprzednią i utwórz stronę index09.html
właściwości z komponentu nadrzędnego odczytujemy w podrzędnym przez this.props.nazwawlasciwosci
komponent nadrzędny List ustawia dwie props: quantity i name:


class List extends React.Component {
    render() {
        return (
             div
                <ListItem quantity="1" name="masło" />
                <ListItem quantity="6" name="mleko" />
                <ListItem quantity="2" name="chleb" />
             /div
           
        );
    }
}kopiuj


komponent podrzędny ListItem pobiera i wyświetla obie props

class ListItem extends React.Component {
    render() {
        console.log(this.props)
        return (            
           div
            {this.props.quantity} x {this.props.name}            
           /div
        );
    }
}

ReactDOM.render(
    <List />,
    document.getElementById('react-app')
);
kopiuj

uwaga: moje niepełne div-y należy oczywiście podomykać

13. cw10 - dane zewnętrzne - zadanie

skopiuj poprzednią i utwórz stronę index10.html
dane do komponentu mogą pochodzić z zewnątrz (np tablica obiektów)
utwórz tablicę obiektów z trzema obiektami, np


{
   id: 1,
   quantity: 1,
   name: "masło"            
},kopiuj


a) zmień poprzednie zadanie tak, aby dane pochodziły z tablicy, jak poniżej:

<ListItem quantity={data[0].quantity} name={data[0].name}  />kopiuj

i wyświetlały się w komponencie List1

b) oczywiście nie jest to skalowalne rozwiązanie, a więc:

w tym samym zadaniu skonstruuj komponent List2, w którym komponenty ListItem będą dodawane do dowolnej tablicy w pętli, a sama tablica renderowana

c) jeśli podczas wykonywania tego zadania zobaczysz komunikat: "Warning: Each child in an array or iterator should have a unique "key" prop.", dodaj do powtarzającego się w pętli komponentu właściwość key = {i}
Chodzi o to że React musi mieć możliwość identyfikowania / odróżniania elementów od siebie



14. cw11 - map i filter - funkcje js służące do manipulacji danymi

utwórz stronę index11.html

map i filter - bardzo użyteczne funkcje do obróbki danych, przetestuj je na osobnej stronie, bez użycia jakichkolwiek komponentów Reacta, na poniższych danych, w console.log-ach

var data = [
    { id: 1, quantity: 1, name: "masło" },
    { id: 2, quantity: 6, name: "mleko" },
    { id: 3, quantity: 3, name: "chleb" }
];kopiuj


map - zwraca nową tablicę, której elementy to wynik funkcji podanej jako argument

https://developer.mozilla.org/pl/docs/Web/JavaScript/Referencje/Obiekty/Array/map

po użyciu każdego z poniższych przykładów, sprawdzaj wyniki w konsoli


a)

data.map(function (elem, i) {
    console.log(i + " dowolne działanie dla każdego elementu tablicy data")
})kopiuj


b)

var array = data.map(function (elem) {
    return (elem.quantity)
})
console.log(array)kopiuj


c)

var array = data.map(function (elem) {
    return (elem)
})
console.log(array)kopiuj


d)

var array = data.map(function (elem) {
    return elem.quantity * 2
})
console.log(array)kopiuj


e)

var array = data.map(function (elem) {
    return {
        id: elem.id,
        quantity: elem.quantity * 3,
        name: elem.name
    }
})
console.log(array)kopiuj


filter

https://developer.mozilla.org/pl/docs/Web/JavaScript/Referencje/Obiekty/Array/filterkopiuj

a)

data.filter(function (elem) {
    console.log("dowolne działanie dla każdego elementu tablicy data")
})kopiuj


b)

data.filter(function (elem) {
    console.log(elem > 1)
})kopiuj


c)

data.filter(function (elem) {
    console.log(elem.name == "chleb")
})kopiuj


d)

var array = data.filter(function (elem) {
    return elem.name == "chleb"
})
console.log(array)kopiuj


e)

var array = data.filter(function (elem) {
    return elem.quantity > 1
})
console.log(array)kopiuj




16. zadanie 13 - images list - data from array

na stronie index13.html
wstaw 3 obrazki o nazwach hamlet.jpg, krzyzacy.jpg, lalka.jpg do podkatalogu /gfx
dane (proszę nic w nich nie zmieniać)


var imagesData = [
   {id:1, name:"hamlet" },
   {id:2, name:"krzyzacy" },
   {id:3, name:"lalka" }
] kopiuj


wykonaj dwa komponenty / klasy Image i ImagesList

opis zadania:

- ReactDOM renderuje ImagesList, który dostaje tablicę obiektów w dowolnie nazwanej property
- ImagesList z użyciem map tworzy tablicę uzyskaną z dostarczonych danych
i trzy razy returnuje Image, podając odpowiednie wartości do props
- Image returnuje diva i img w środku z odpowiednimi danymi

aby poprawnie wykonać zadanie do klasy / komponentu Image dodaj dwie funkcje, np:


makeImageName(){
   console.log(this.props)
   //funkcja ma zwracać tytuł z dużej litery

}kopiuj


makeImageUrl(){
   console.log(this.props)
   // funkcja ma zwracać pełny url do obrazka, nie tylko jego nazwę
} kopiuj


użycie ww funkcji w komponencie Image

render() {
    return (      
         <img src={this.makeImageUrl()} />  
    );
}kopiuj



17. zadanie 14 - komponenty i style

na stronie index14.html
wykonaj zadanie jak na skrinie 14, z użyciem 4 komponentów / klas React-a
style umieść w znaczniku style

utwórz komponenty:


Square
Column
Table
Container


//////////////////////

18. zadanie 18 - task list - data from array

na stronie index12.html
z użyciem komponentów / klas Reacta wykonaj zadanie jak poniżej:
utwórz tablicę z trzema obiektami, wg modelu danych:


{
    id: 1,
    quantity: 2,
    name: "masło" ,
    action: "kupić"           
},kopiuj


wykonaj dwa komponenty Task i TaskList

szczegółowy opis zadania:

- ReactDOM renderuje TaskList, który dostaje tablicę obiektów w dowolnie nazwanej property
- TaskList z użyciem map tworzy tablicę uzyskaną z dostarczonych danych
i trzy razy returnuje Task, podając odpowiednie wartości do props
- Task returnuje UL i trzy LI z odpowiednimi danymi (patrz pkt 13)

uwaga: spróbuj rozwiązać to zadanie bez patrzenia na podpowiedź:

podpowiedź - użyj map:


class TaskList extends React.Component {
            render() {
                var lista = this.props.tasksProp.map(function(item)  {
                    return (
                        
                        <Task                           
                            id={item.id}                          
                         />
                     )
                });
                return (
                   
                        div
                           {lista}
                        /div
                   
                );
      }
}

ReactDOM.render(
   <TaskList tasksProp={anyobjectarray} />,
   document.getElementById('react-app')
);kopiuj