React

Katso Esimerkki

Katso Esimerkki lomakkeista ja validoinnista

React on Facebookin ja Instagramin Javascript-kirjasto käyttöliittymien tekemiseen. kts. Why React?

Kannattaa katsoa seuraavat videot:

Reactin perusteet käsitellään hyvin ja selkeästi Learning React.js: Getting Started and Concepts-tutoriaalissa.

JSX

Hello world

Yksinkertaisimmassa React-ohjelmassa liitetään html-dokumenttiin react-kirjasto, JSXTransformer-kirjasto ja kirjoitetaan script-elementin sisään oma yksinkertainen komponentti ja renderoidaan se. Huom. script-elementin type-attribuutin arvon on oltava text/jsx.

kts. Getting Started ja tutorial

<!DOCTYPE html>
<html>
  <head>
    <title>Hello World</title>
    <script src="https://code.jquery.com/jquery-2.2.2.min.js"></script>
    <script src="https://fb.me/react-0.14.8.js"></script>
    <script src="https://fb.me/react-dom-0.14.8.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
  </head>
  <body>
    <div id="main"></div>
    <script type="text/jsx">
// yksinkertainen komponentti, joka palauttaa tekstikappaleen jossa lukee haluttu nimi   
// komponentille annetut parametrit löytyvät this.props-objektista
var HelloWorld = React.createClass({
  render: function() {
    return (
      <p>
        Hello {this.props.name}!
      </p>
    );
  }
});
// näytetään main-tunnisteella varustetun lohkon sisällä edellä luotu oma komponentti
// esitettävä nimi annetaan attribuuttina
  ReactDOM.render(
    <HelloWorld name="Tommi" />,
    document.getElementById('main')
  );
    
    </script>
  </body>
</html>
        

React-komponentit

react ja silmukat

Reactin JSX-koodiin ei voi kirjoittaa kuin React-elementteja, html-elementtejä ja {}-sulkujen sisään funktiokutsuja tai laskutoimituksia ja muuttujien nimiä. Jos on tarve käyttää for-looppia tai muita vastaavia rakenteita on nämä suoritettava erikseen. Sisäkkäisten for-looppien tapauksessa on toinen looppi piilotettava erilliseen funktioon tai komponenttiin

Allaolevaa esimerkkiä voi kokeilla pääteohjausmallissa.

var Test = React.createClass({
  render: function(){
    var taulukko = ["foo", "bar", "foobar", "barfoo"];
    var taulukko2 = [1, 2, 3, 4];
    var aputaulukko = [];
    // JSX-koodissa voi olla vain funktiokutsuja tai muuttujia
    // tässä tapauksessa taulukko[i] kelpaa hyvin <li></li>-rakenteen sisään
    // muista antaa jokin uniikki avain jokaiselle riville
    for(var i=0;i<taulukko.length;i++) {
          aputaulukko.push( <li key={i}>{taulukko[i]}</li> );               
    }
    
    aputaulukko = [];
    // entä jos on kaksi for-looppia?
    // tulostetaan sisempään listaan kaikki saman taulukon alkiot    
    // toinen for-looppi on piilotettava toiseen funktioon
//    for(var i=0;i<taulukko2.length;i++) {
//        aputaulukko.push( apufunktio(taulukko2[i], taulukko) );               
//    }
    // sama kuin edellä mutta käyttäen toista react-komponenttia
    for(var i=0;i<taulukko2.length;i++) {
        aputaulukko.push( <Apuluokka key={i} taulukko={taulukko} ulompi={taulukko2[i]} /> );               
    }
    
    return (
      <ul>
      { aputaulukko }
      </ul>
    ) 
    /* tämä ei toimi vaan tulee unexpected token -virheilmoitus
        return (
      <ul> {
        for(var i=0;i<taulukko.length;i++) {
              aputaulukko.push( <li>{taulukko[i]}</li> );               
        }}
      </ul>
    ) 
*/    

  }
});

// tekee saman asian kuin alempana oleva apufunktio
var Apuluokka = React.createClass({
  render: function(){
    var aputaulukko = [];
    for(var i=0;i<this.props.taulukko.length;i++) {
        aputaulukko.push( <li key={i}>{this.props.taulukko[i]}</li> );               
    }
    return (
      <li>
      {this.props.ulompi} 
          <ul>
                { aputaulukko }
          </ul>
      </li>
    )


  }
});


 
// tekee sisemmän for-loopin, parametrina tuodaan ulomman listan teksti ja sisempään
// listaan vaadittava taulukko
function apufunktio(sarake, taulukko) {
    var aputaulukko = [];
    for(var i=0;i<taulukko.length;i++) {
        aputaulukko.push( <li key={i}>{taulukko[i]}</li> );               
    }
    return (
      <li key={sarake}>
      {sarake} 
          <ul>
                { aputaulukko }
          </ul>
      </li>
    )

}


Lomakkeet

Oletuksena Reactissa lomakkeet ovat kontrolloituja komponentteja. Käytä kontrolloitua lomaketta aina kuin vain mahdollista. Jossain tilanteessa voit tehdä lomakkeesta myös kontrolloimattoman komponentin. Kts. esimerkit: kontrolloitu lomake (lähdekoodi) ja kontrolloimaton lomake (lähdekoodi).

Lomakkeissa voi käyttää samoja tarkistuksia ja virheilmoituksia kuin normaalistikin. Kts. validointi-esimerkki

setState

Huomioi Reactista seuraavat seikat:

Asynkroninen setState

Huom!. setState-funktio toimii asynkronisesti. Kts. Why is setState fiving me the wrong value

Asynkronisuus tarkoittaa, että ette voi tietää missä vaiheessa state oikeasti päivittyy. Esim. seuraavanlainen koodi erittäin todennäköisesti tulostaa vielä vanhan tilan eikä sitä mikä on juuri yritetty asettaa:

    uusi.joukkueet.push(joukkue);
    this.setState({ "joukkueet" : uusi });
    console.log(this.state.joukkueet);

kun muutatte tilaa niin tehkää se yhdellä kutsulla eikä usealla. Tämä on siis huono ratkaisu:

    this.setState({teamName: ''});
    this.setState({created: ''});
    this.setState({stampTypes: []});
    this.setState({serie: ''});

pitäisi olla:

    this.setState({teamName: '', created: '', stampTypes: [], serie: ''});

Ensimmäinen versio aiheuttaisi turhaan näytön päivittämistä neljä kertaa, kun vain yksi kerta riittäisi.

Monimutkainen tila

Huom!. Jos tallennat tilaan objekteja tai taulukoita niin ole tarkkana tilaa kopioitaessa. Kts. esimerkki (lähdekoodi). Lisätietoa: How to update nested state properties in React ja Handling State in React: Four Immutable Approaches to Consider.

Jos tarvitset komponentissa muuttujia, jotka eivät vaikuta komponentin renderointiin, niin näitä ei tarvitse käyttää staten kautta vaan voit vapaasti keksiä omia. Esim. this.foobar = "omajuttu"

Lisätietoa

Käyttäjien kommentit

Kommentoi Lisää kommentti
Kurssimateriaalien käyttäminen kaupallisiin tarkoituksiin tai opetusmateriaalina ilman lupaa on ehdottomasti kielletty!
http://appro.mit.jyu.fi/tiea2120/luennot/react/
© Tommi Lahtonen (tommi.j.lahtonen@jyu.fi) <http://hazor.iki.fi/>
2018-11-09 14:40:18
Informaatioteknologia - Jyväskylän yliopiston informaatioteknologian tiedekunta