React JS  

Pagrindai

Parengė: Martynas Kašelionis

From zero to hero

React - deklaratyvi, efektyvi ir lanksti JavaScript biblioteka, skirta kurti naudotojo sąsajoms (UI).

React

  • Sukurta Facebook
  • Populiari biblioteka rimtose aplikacijose
  • UI kuriamas naudojant komponentus

React

Ką turiu mokėti:

  • HTML5
  • SASS
  • Vanilla JS + ES6

Virtual DOM

JSX

JavaScript praplėtimas inicijuotas React. Kuris leidžia lanksčiau ir patogiau aprašyti UI komponentus naudojant pažangesnį būdą su  HTML, JavaScript ir CSS.

JS nėra privalomas, bet labai patogus ir rekomenduotinas.

JSX

JSX vs JS

JSX vs JS

JSX skirtumai

JS string

const element = <h1>Sveikas pasauli!</h1>
const myId = 'kodas123'
const element = <h1 id={myId}>Labas pasauli!</h1>

JSX skirtumai su HTML

  • class tampa className
  • for tampa htmlFor
  • CSS ypatybės naudoja camel stilių, kaip ir Vanilla JS

Komponentai

Komponentas yra vartotojo sąsajos dalis.

Vartotojo sąsąją sudaro komponentai, kurie pagal nustatytą tvarką ir sąlygas yra apjungiami į visumą dinamiškai.

Tai pat viena i gerų praktikų komponentus apjungti konteineriais, jeigu UI yra sudėtinga ir turi daugiau layout variacijų.

Komponentai

Komponentai

React egzistuoja dviejų tipų komponentai:

  • Komponentas sukurtas funkcijos pagrindu
  • Komponentas sukurtas klasės pagrindu

Komponentas funkcija

function Welcome() {
return <h1>Hello</h1>;
}
const BlogPostExcerpt = () => {
  return (
    <div>
      <h1>Title</h1>
      <p>Description</p>
    </div>
  )
}

Komponentas klasė

import React, { Component } from 'react'
class BlogPostExcerpt extends Component {
  render() {
    return (
      <div>
        <h1>Title</h1>
        <p>Description</p>
      </div>
    )
  }
}

Komponentai

  • Klasės komponentas buvo privalomas tada, kai norime naudoti state ir gyvavimo ciklo metodus, kurie apibrėžia veiksmus su komponentu, kai pirmą kartą inicijuojamas, atnaujinamas, pašalinamas.
  • Tačiau dabartinėje React versijoje, tą patį galime padaryti su function pagrindu sukurtais komponentais. Dėka React hooks.
import React from 'react'
React.createClass({
  render() {
    return (
      <div>
        <h1>Title</h1>
        <p>Description</p>
      </div>
    )
  }
})

Komponentai

import React from "react"

import Header from "./Header"
import MainContent from "./MainContent"
import Footer from "./Footer"

function App() {
    return (
        <div>
            <Header />
            <MainContent />
            <Footer />
        </div>
    )
}

export default App

Props ir State

  • Props  (ypatybė) yra būdas  perduoti duomenis iš vieno komponento į kitą. Props yra read-only (negali būti keičiami). Panašiai, kaip su funkcijų parametrais. 
  • State (būsena) saugo duomenis apie komponentą, kurie gali būti keičiami visą laiką. Dėl aplikacijoje vykstančių įvykių, vartotojo interakcijos.

      Inicijuotas komponentas turi numatytąją būseną, kuri yra keičiama aukščiau paminėtais atvejais.

Props ir State

Props ir State

Props

Props

import React from "react"

function ContactCard() {
    return (
        <div className="contact-card">
            <img src="http://placekitten.com/300/200"/>
            <h3>Mr. Whiskerson</h3>
            <p>Phone: (212) 555-1234</p>
            <p>Email: mr.whiskaz@catnap.meow</p>
        </div>
    )
}

export default ContactCard

Props

Komponentu struktūrą aprašo statinis HTML su statinėmis ypatybėmis.

Props leidžia tas ypatybes pakeisti, perduoti ir išnaudoti komponento pernaudojamumą.

Props

Props

import React from "react"
import ContactCard from "./ContactCard"

function App() {
    return (
        <div className="contacts">
            <ContactCard 
                name="Mr. Whiskerson" 
                imgUrl="http://placekitten.com/300/200" 
                phone="(212) 555-1234" 
                email="mr.whiskaz@catnap.meow"
            />
            
            <ContactCard 
                name="Fluffykins" 
                imgUrl="http://placekitten.com/400/200" 
                phone="(212) 555-2345" 
                email="fluff@me.com"
            />
        </div>
    )
}

export default App

Props

import React from "react"

function ContactCard(props) {
    return (
        <div className="contact-card">
            <img src={props.imgUrl}/>
            <h3>{props.name}</h3>
            <p>Phone: {props.phone}</p>
            <p>Email: {props.email}</p>
        </div>
    )
}

export default ContactCard

Props

function App() {
    return (
        <div className="contacts">
            <ContactCard 
                contact={{name: "Mr. Whiskerson", imgUrl: "http://placekitten.com/300/200", 
phone: "(212) 555-1234", email: "mr.whiskaz@catnap.meow"}}
            />
            
            <ContactCard 
                contact={{name: "Fluffykins", imgUrl: "http://placekitten.com/400/200", 
phone: "(212) 555-2345", email: "fluff@me.com"}}
            />
            />
            
        </div>
    )
}

Props

import React from "react"

function ContactCard(props) {
    console.log(props)
    return (
        <div className="contact-card">
            <img src={props.contact.imgUrl}/>
            <h3>{props.contact.name}</h3>
            <p>Phone: {props.contact.phone}</p>
            <p>Email: {props.contact.email}</p>
        </div>
    )
}

export default ContactCard}

Props ir map

const postai = [
    {
        id: 1,
        pavadinimas: "Labai geras postas",
        tekstas: "Labai daug teksto, apie labai idomu posta"
    },
    {
        id: 2,
        pavadinimas: "Labai geras postas",
        tekstas: "Labai daug teksto, apie labai idomu posta"
    },
    {
        id: 3,
        pavadinimas: "Labai geras postas",
        tekstas: "Labai daug teksto, apie labai idomu posta"
    },
    {
        id: 4,
        pavadinimas: "Labai geras postas",
        tekstas: "Labai daug teksto, apie labai idomu posta"
    },
    {
        id: 5,
        pavadinimas: "Labai geras postas",
        tekstas: "Labai daug teksto, apie labai idomu posta"
    },
    {
        id: 6,
        pavadinimas: "Labai geras postas",
        tekstas: "Labai daug teksto, apie labai idomu posta"
    }
]

export default postai

Props ir map

import React from "react"

function Post(props) {
    return (
        <div>
            <h3>{props.pavadinimas}</h3>
            <p>{props.tekstas}</p>
            <hr/>
        </div>
    )
}

export default Post

State

Valdo komponento veikimą, keičiant reikšmes, bei atliekant kitus veiksmus po įvykusio įvykio aplikacijoje.

State

Jeigu norime naudoti state komponente yra būtina naudoti construct() metodą, kuris naudodamas super() paveldi reikiamus metodus ir ypatybes iš React.Component.

Konstruktoriuje state apibrėžiamas naudojant this.state

Dažniausiai sate keičiamas naudojant setState metodą.

State

import React from "react"


class App extends React.Component {
    constructor() {
        super()
        this.state = {
            
        online: false
}
    }
    
    render() {
        return (
            <div>
                <h1>Ar vartotojas prisijunges? {this.state.online}</h1>
            </div>
        )
    }
}

export default App

State

Kai norime state reikšmę perduoti child komponentui, tai darome per props.

<Elementas kietasPropsas = {this.state.kietareiskme} />

 

Pasikeitus state React automatiškai atnaujina props visuose komponentuose.

Įvykiai

Daugeliu atveju state keitimas naudojant setState() metodą nenaudojant įvykių yra gana komplikuotas.

Įvykiai įrašomi JSX'e elmento viduje naudojant "camel" sintaksę

import React from "react"

function App() {
    return (
        <div>
            <p>Labai geras patarimas </p> 
            
            <button onClick={() => console.log("I was clicked!")}>Paspausk</button>

         //arba

             <button onClick={handleClick}>Paspausk</button>
        </div>
    )
}

export default App

Įvykiai

setState

Svarbu:

setState() nekeičia esančio state, bet suteikia naują state versiją.

 

Jeigu aprašome metodą komponento klasėje jį turi bind'inti konstruktoriuje.

setState

  handleClick(){
        this.setState(prevState => {
            return {
                counter: prevState.counter + 1
            }
        })
    }

setState

 <div className="todo-item">
            <input 
                type="checkbox" 
                checked={props.item.completed} 
                onChange={(event) => props.handleChange(props.item.id)}
            />
            <p>{props.item.text}</p>
        </div>

Kartais reikia perduoti įvykį su props.

Gera praktika naudoti arow function perduodant įvykį, kaip parametrą

Komponento gyvavimo ciklai

Gyvavimo ciklai

Kiekvienas React komponentas atsineša rinkinį metodų, kurie leidžia programuotojui atnaujinti aplikacijos būseną pagal pasikeitimus UI.

 

Pagrindinės komponento gyvavimo fazės:

  • mounting
  • updating
  • unmounting

Gyvavimo ciklai

Kiekvienas React komponentas atsineša rinkinį metodų, kurie leidžia programuotojui atnaujinti aplikacijos būseną pagal pasikeitimus UI.

 

Pagrindinės komponento gyvavimo fazės:

  • mounting
  • updating
  • unmounting

Gyvavimo ciklai

class Posts extends Component {
    constructor() {
        super()
        this.state = {}
    }
    
    componentDidMount() {
        //gaunami duomenys iš API
    }

    shouldComponentUpdate(nextProps, nextState) {
        if (nextProps.title !== this.props.title) {
            // return true atnaujiname false neatnaujinam
        }
    }

     componentWillUnmount() {
        // kodo valymas prieš komponentui išnykstant
        // (pvz. pašalinami event listeneriai)
    }
    
    
    }
}

export default App

Salyginis renderinimas

componentDidMount() {
        setTimeout(() => {
            this.setState({
                isLoading: false
            })
        }, 1500)
    }
    
    render() {
        return (
            <div>
                <Conditional isLoading={this.state.isLoading}/>
            </div>
        )
    }

Salyginis renderinimas

import React from "react"

function Conditional(props) {
    if(props.isLoading === true) {
        return (
            <h1>Kraunama...</h1>
        )
    } else {
        return (
            <h1>Postai</h1>
        )
    }
    
}

export default Conditional

Darbass su API

Pagrindinės komponento gyvavimo fazės:

  • Naudojama JS promises
  • API call turi būti componentDidMount viduje

Duomenų gavimas iš API

componentDidMount() {
        fetch("https://lrytas.lt/api/lietuva")
            .then(response => response.json())
            .then(data => {
                this.setState({
                    character: data
                })
            })
    }

Duomenų gavimas iš API

 constructor() {
        super()
        this.state = {
            loading: false,
            character: {}
        }
    }
    
  
    componentDidMount() {
        this.setState({loading: true})
        fetch("https://lrytas.lt/api/lietuva")
            .then(response => response.json())
            .then(data => {
                this.setState({
                    loading: false,
                    character: data
                })
            })
    }

Duomenų siuntimas į API

fetch(API_BASE_URL + '/post/' + this.state.id + '/comment', {
            method: 'POST',
            headers: {
                'Content-Type':'application/json',
                Accept: 'application/json'
            },
            body: JSON.stringify({
                "correct": true
            })
        });

Formos

class NameForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: ''};

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
    this.setState({value: event.target.value});
  }

  handleSubmit(event) {
    alert('A name was submitted: ' + this.state.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input type="text" value={this.state.value} onChange={this.handleChange} />
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

REACT JS

By Martynas Kašelionis