Kaikki React.js-peruskonseptit ovat juuttuneet tähän yhdeksi Medium-artikkeliksi

Johdanto oppia Reaktin miksi, mitä ja miten

Tämä artikkeli on mukautus interaktiiviseen oppaaseen osoitteessa jsComplete.com/react-intro. JsComplete-versiossa on upotettu koodiesimerkkejä ja linkkejä sisällössä liikkumiseen.
Ennen kuin aloitat, huomaa, että tämä on aloittelijoille sopiva opas, joka kattaa käsitteet, jotka luokittelen Reaktin kanssa työskentelyn perusteiksi. Se ei ole täydellinen opas reagoimaan, vaan täydellinen johdanto.
Tämän oppaan lopussa luetteloin sinulle muutamia seuraavan tason resursseja. Tämä opas auttaa sinua ymmärtämään niitä.

React on määritelty JavaScript-kirjastoksi käyttöliittymien rakentamiseksi. Aloitetaan puhumalla tämän määritelmän kahdesta eri osasta.

React on JavaScript “kirjasto”. Se ei ole tarkalleen "kehys". Se ei ole täydellinen ratkaisu, ja joudut usein käyttämään enemmän kirjastoja Reaktin kanssa minkä tahansa ratkaisun muodostamiseksi. React ei oleta mitään ratkaisun muista osista.

Kehykset palvelevat suurta tarkoitusta, etenkin nuorille joukkueille ja startup-yrityksille. Kun työskentelet kehyksen kanssa, monet älykkäät suunnittelupäätökset tehdään jo sinulle, mikä antaa sinulle selkeän tien keskittyä hyvien sovellustason logiikoiden kirjoittamiseen. Kehyksillä on kuitenkin joitain haittoja. Kokeneille kehittäjille, jotka työskentelevät suurten tietokantojen kanssa, nämä haitat ovat toisinaan rikkovia.

Kehykset eivät ole joustavia, vaikka jotkut väittävät olevansa. Kehys yleensä haluaa sinun koodaavan kaiken tietyllä tavalla. Jos yrität poiketa siitä, kehykset päätyvät yleensä taistelemaan sinusta siitä. Kehykset ovat myös yleensä suuria ja täynnä ominaisuuksia. Jos joudut käyttämään vain pientä kappaletta niistä, koko asia on joka tapauksessa mukana. Tosin tämä kohta on muuttumassa tänään, mutta se ei ole vieläkään ihanteellinen. Jotkut kehykset menevät modulaarisesti, mikä on mielestäni hienoa, mutta olen suuri fani puhtaasta Unix-filosofiasta:

Kirjoita ohjelmia, jotka tekevät yhden asian ja tekevät sen hyvin. Kirjoita ohjelmia työskentelemään yhdessä.
- Doug McIlroy

React noudattaa Unix-filosofiaa, koska se on pieni kirjasto, joka keskittyy vain yhteen asiaan ja sen tekemiseen erittäin hyvin. Tuo "yksi asia" on toinen osa Reaktin määritelmää: Käyttöliittymien rakentaminen.

Käyttöliittymä (UI) on mikä tahansa, jonka laitamme käyttäjien eteen saadaksemme heidät toimimaan koneen kanssa. Käyttöliittymiä on kaikkialla, mikroaaltouunin yksinkertaisista painikkeista avaruussukkulan kojelautaan. Jos laite, jota yritämme rajata, ymmärtää JavaScriptin, voimme käyttää Reaktia kuvaamaan sen käyttöliittymän. Koska selaimet ymmärtävät JavaScriptiä, voimme käyttää Reaktia kuvaamaan verkkoon liittyviä käyttöliittymiä.

Haluan käyttää täällä sanaa kuvaile, koska juuri sitä teemme Reaktin kanssa. Me vain kerromme sille mitä haluamme! React rakentaa sitten todellisen käyttöliittymän meidän puolestamme verkkoselaimeen. Ilman React tai vastaavia kirjastoja meidän olisi rakennettava manuaalisesti käyttöliittymiä natiivien Web-sovellusliittymien ja JavaScriptin kanssa, mikä ei ole niin helppoa.

Kun kuulet lausunnon siitä, että "reagointi on deklaratiivista", juuri sitä se tarkoittaa. Kuvailemme käyttöliittymiä Reaktin kanssa ja kerromme sille mitä haluamme (emme kuinka tehdä). React huolehtii "miten" ja kääntää deklaratiiviset kuvauksemme (jotka kirjoitamme React-kielellä) todellisiin käyttöliittymiin selaimessa. React jakaa tämän yksinkertaisen deklaratiivisen vallan itse HTML: n kanssa, mutta Reaktin kanssa meidän on oltava deklaratiivisia HTML-käyttöliittymissä, jotka edustavat dynaamista tietoa, ei vain staattista tietoa.

Kun React julkaistiin, sen suorituksesta oli paljon hätää, koska se esitteli älyllisen idean virtuaalisesta DOM: sta, jota voidaan käyttää todellisen DOM: n sovittamiseen (ja siitä puhutaan seuraavassa osiossa).

DOM on ”Document Object Model”. Selainten ohjelmointirajapinta HTML (ja XML) -asiakirjoille käsittelee niitä puurakenteina. DOM-sovellusliittymää voidaan käyttää muuttamaan asiakirjan rakennetta, tyyliä ja sisältöä.

Vaikka Reaktin esitys on edelleen yksi tärkeimmistä syistä, miksi se on tänään erittäin suosittu, en luokittele sitä "parhaaksi" asiaksi. Mielestäni React oli pelinvaihtaja, koska se loi kehittäjien ja selainten välillä yhteisen kielen, jonka avulla kehittäjät voivat kuvata deklaratiivisesti käyttöliittymiä ja hallita niiden tilan toimintoja DOM-elementteihin kohdistuvien toimintojen sijaan. Se on yksinkertaisesti käyttöliittymän "tulosten" kieli. Sen sijaan, että esittäisivät vaiheita kuvaamaan rajapintojen toimia, kehittäjät kuvaavat rajapintoja vain "lopullisessa" tilassa (kuten funktiossa). Kun toimenpiteitä tapahtuu kyseiseen tilaan, React huolehtii DOM: n käyttöliittymien päivittämisestä tämän perusteella (ja se tekee niin tehokkaasti kuin näemme seuraavaksi).

Jos joku pyysi sinua antamaan yhden syyn, miksi React on oppimisen arvoinen, tämä on tulospohjainen käyttöliittymäkieli. Kutsun tätä kieltä ”React-kieleksi”.

Reaktin kieli

Sano, että meillä on luettelo tämän tyyppisistä TODO-operaatioista:

const todos: [
  {body: 'Opi reagoimaan perusteet', valmis: tosi},
  {body: 'Luo TODOs-sovellus', tehty: false},
  {body: 'Rakenna peli', valmis: väärä},
];

Tämä todos-taulukko on käyttöliittymäsi aloitustila. Sinun on rakennettava käyttöliittymä niiden näyttämistä ja hallintaa varten. Käyttöliittymällä on lomake lisätäksesi uusia TODOja, tapa merkitä TODO täydelliseksi ja tapa poistaa kaikki valmiit TODOt.

Jokainen näistä toimista vaatii sovelluksen suorittamaan DOM-operaation luoda, lisätä, päivittää tai poistaa DOM-solmuja. Reaktin kanssa et ole huolissasi kaikista näistä DOM-toiminnoista. Sinun ei tarvitse huolehtia siitä, milloin niiden on tapahduttava, tai siitä, kuinka ne suoritetaan tehokkaasti. Sijoita vain todos-taulukko sovelluksesi "tilaan" ja käytä sitten Reakt-kieltä "komentaa" React näyttääksesi tämän tilan tietyllä tavalla käyttöliittymässä:

TODO-luettelo
      {todos.map (todo =>     
  • {todo.body}   )}
// Muut lomakeelementit ...

Älä ole vielä huolissasi syntaksista, mutta jos ihmettelet mitä tapahtuu, me vain kartoitimme joukon JavaScript-objekteja reaktoriosien joukkoon. Lisää siitä pian.

Sen jälkeen voit keskittyä vain dataoperaatioiden tekemiseen kyseiseen todos-taulukkoon! Voit lisätä, poistaa ja päivittää kyseisen taulukon kohteita, ja React heijastaa muutoksia, jotka olet tehnyt tähän objektiin selaimen käyttöliittymässä.

Tämä mielentila, joka koskee käyttöliittymän mallintaa lopputilaan perustuen, on helpompi ymmärtää ja työskennellä, etenkin kun näkymissä on paljon tiedonsiirtoja. Harkitse esimerkiksi näkymää, joka kertoo kuinka moni ystävistäsi on online-tilassa. Tämän näkymän tila on vain yksi luku kuinka monta kaveria on tällä hetkellä verkossa. Ei välitä siitä, että hetki sitten kolme ystävää liittyi verkkoon, sitten yksi heistä katkesi ja sitten kaksi muuta liittyi. Se vain tietää, että tällä hetkellä neljä ystävää on online-tilassa.

Reaktin puun yhteensovittaminen

Ennen reagointia, kun piti työskennellä selaimen DOM-sovellusliittymänä, joka tunnetaan nimellä DOM API, vältimme DOM-puun kuljettamisen mahdollisimman paljon, ja siihen on syy. Kaikki DOM: n toiminnot tehdään samassa ketjussa, joka vastaa kaikesta muusta selaimessa tapahtuvasta, mukaan lukien reaktiot käyttäjän tapahtumiin, kuten kirjoittaminen, vieritys, koon muuttaminen jne.

Kaikki kalliit operaatiot DOM: lla tarkoittavat käyttäjän hidasta ja janky-kokemusta. On erittäin tärkeää, että sovelluksesi tekevät ehdottomat minimitoiminnot ja panostavat ne mahdollisuuksien mukaan. React keksi ainutlaatuisen konseptin, joka auttoi meitä tekemään juuri sen!

Kun käskemme Reaktia tarjoamaan elementtipuun selaimessa, se luo ensin puun virtuaalisen esityksen ja pitää sen muistissa myöhemmin. Sitten suoritetaan DOM-toiminnot, jotka saavat puun näkymään selaimessa.

Kun sanomme Reaktin päivittävän aiemmin renderoitujen elementtien puun, se luo uuden virtuaalisen esityksen päivitetystä puusta. Nyt Reaktyella on 2 puun versiota muistissa!

Jotta päivitetty puu saataisiin selaimeen, React ei hylkää sitä, mikä on jo hahmonnettu. Sen sijaan se vertaa muistissa olevan puun kahta virtuaalista versiota, laskee niiden väliset erot, selvittää, mitkä pääpuun alapuut on päivitettävä, ja päivittää vain nämä alapuut selaimessa.

Tämä prosessi tunnetaan puun täsmäytysalgoritmina, ja se tekee Reaktista erittäin tehokkaan tavan työskennellä selaimen DOM-puun kanssa. Näemme pian sen esimerkki.

Deklaratiivisen tulokseen perustuvan kielen ja tehokkaan puiden täsmäytyksen lisäksi tässä on muutamia muita syitä, joiden vuoksi Reaktin mielestäni on saatu valtava suosio:

  • DOM-sovellusliittymän kanssa työskenteleminen on vaikeaa. React antaa kehittäjille mahdollisuuden työskennellä “virtuaalisen” selaimen kanssa, joka on ystävällisempi kuin todellinen selain. Reaktio toimii periaatteessa kuin edustajasi, joka kommunikoi DOM: n kanssa puolestasi.
  • Reaktylle annetaan usein ”Just JavaScript” -merkki. Tämä tarkoittaa, että sillä on hyvin pieni sovellusliittymä oppia, ja sen jälkeen JavaScript-taitosi tekevät sinusta paremman React-kehittäjän. Tämä on etu verrattuna kirjastoihin, joissa on suurempia sovellusliittymiä. Myös React API on enimmäkseen toimintoja (ja valinnaisesti luokkia, jos tarvitset niitä). Kun kuulet, että käyttöliittymänäkymä on tietosi funktio, Reaktissa niin tapahtuu kirjaimellisesti.
  • React-oppiminen kannattaa myös iOS- ja Android-mobiilisovelluksia. React Native antaa sinun käyttää React-taitojasi natiivien mobiilisovellusten luomiseen. Voit jopa jakaa jonkin verran logiikkaa verkko-, iOS- ja Android-sovellusten välillä.
  • Facebookissa oleva Reakt-tiimi testaa kaikki parannukset ja uudet ominaisuudet, jotka ovat tutustuneet Reaketiin heti facebook.com-sivustossa, mikä lisää luottamusta kirjastoon yhteisössä. On harvinaista nähdä suuria ja vakavia virheitä Reaktin julkaisuissa, koska ne julkaistaan ​​vasta perusteellisen tuotantotestin jälkeen Facebookissa. Reaktin avulla voidaan käyttää myös muita voimakkaasti käytettyjä verkkosovelluksia, kuten Netflix, Twitter, Airbnb ja monet muut.

Ensimmäinen reagointisi esimerkki

Työskentelemme yksinkertaisen esimerkin avulla, joka keskittyy juuri kyseiseen käsitteeseen, jotta näet puun täsmäytysprosessin käytännön edut ja sen tekemän suuren eron. Luodaan ja päivitetään HTML-elementtien puu kahdesti, kun käytetään ensin natiivia Web-sovellusliittymää ja sitten React-sovellusliittymää (ja sen täsmäytystyötä). Jotta tämä esimerkki olisi yksinkertainen, en käytä komponentteja tai JSX: ää (JavaScriptin laajennus, jota suositaan Reaktin kanssa). Aion päivittää myös JavaScript-aikavälin ajastimen. Tällä tavalla ei kirjoiteta React-sovelluksia, mutta keskitytään yhteen konseptiin kerrallaan.

Aloita tällä jsComplete-leikkikenttäistunnolla: jsdrops.com/react-dom1.

Tässä istunnossa yksinkertainen HTML-elementti renderoidaan näytölle kahdella menetelmällä:

Tapa # 1: Web DOM -sovellusliittymän käyttäminen suoraan

document.getElementById ('mountNode'). innerHTML = `
  
    Hei HTML    `;

Tapa 2: Reaktan sovellusliittymän käyttäminen

ReactDOM.render (
  React.createElement (
    'Div'
    tyhjä,
    "Hei reagoi",
  ),
  document.getElementById ( 'mountNode2'),
);

ReactDOM.render-menetelmä ja React.createElement-menetelmä ovat React-sovelluksen keskeiset API-menetelmät. Itse asiassa React-verkkosovellus ei voi olla olemassa käyttämättä näitä molempia menetelmiä. Selitän heille lyhyesti:

ReactDOM.render

Tämä on pohjimmiltaan React-sovelluksen lähtökohta selaimen DOM: iin. Sillä on 2 perustetta:

  1. Ensimmäinen argumentti on se, mitä selaimelle annetaan. Tämä on aina ”reagoi elementti”.
  2. Toinen argumentti on MITEN tehdä siitä React-elementti selaimessa. Tämän on oltava kelvollinen DOM-solmu, joka esiintyy staattisesti esitetyssä HTML-muodossa. Yllä olevassa esimerkissä käytetään erityistä mountNode2 -elementtiä, joka on leikkikentän näyttöalueella (ensimmäistä mountNodea käytetään alkuperäisessä versiossa).

Mikä tarkalleen on React-elementti? Se on VIRTUAL-elementti, joka kuvaa DOM-elementtiä. Se on mitä React.createElement API-menetelmä palaa.

React.createElement

Sen sijaan, että toimisimme merkkijonoja edustamaan DOM-elementtejä (kuten yllä olevassa DOM-esimerkissä), edustamme DOM-elementtejä objekteilla käyttämällä kutsuja React.createElement-menetelmään. Näitä esineitä kutsutaan reagoiviksi elementeiksi.

React.createElement-funktiolla on monia argumentteja:

  1. Ensimmäinen argumentti on HTML-tunniste edustatavalle DOM-elementille, joka on div tässä esimerkissä.
  2. Toinen argumentti on kaikille määritteille (kuten id, href, otsikko jne.), Jotka haluamme DOM-elementin olevan. Käytetyllä yksinkertaisella div-yksiköllä ei ole määritteitä, joten käytimme siellä tyhjää.
  3. Kolmas argumentti on DOM-elementin sisältö. Olemme ottaneet "Hello React" -merkkijonon sinne. Valinnainen kolmas argumentti ja kaikki sen jälkeen valinnaiset argumentit muodostavat lasketun elementin lastenluettelon. Elementillä voi olla 0 tai enemmän lapsia.
React.createElement voidaan myös luoda elementtejä React-komponenteista.

Reagoivat elementit luodaan muistiin. Jotta React-elementti näkyy DOM: ssa, käytämme ReactDOM.render-menetelmää, joka tekee monta asiaa selvittääkseen parhaimman tavan reagoida elementin tila heijastamaan selaimen todellista DOM-puuta.

Kun suoritat 2 menetelmää tässä koodistunnossa, näet "Hello HTML" -ruudun ja "Hello React" -ruudun:

Pesivät reagoivat elementit

Meillä on kaksi solmua: yhtä ohjataan suoraan DOM API: lla ja toista ohjataan React API: lla (joka puolestaan ​​käyttää DOM API: ta). Ainoa merkittävä ero näiden kahden solmun rakentamisessa selaimessa on se, että HTML-versiossa käytimme merkkijonoa edustamaan DOM-puuta, kun taas React-versiossa käytimme puhtaita JavaScript-kutsuja ja edustaimme DOM-puuta objektilla. merkkijonon sijasta.

Ei ole väliä kuinka monimutkaista HTML-käyttöliittymä tulee, Reaktia käytettäessä jokainen HTML-elementti esitetään React-elementin kanssa.

Lisäämme lisää HTML-elementtejä tähän yksinkertaiseen käyttöliittymään. Lisäämme tekstikenttään käyttäjän syöttämiä tietoja. HTML-versiossa voit pistää uuden elementin tunnisteen suoraan mallin sisään:

document.getElementById ('mountNode'). innerHTML = `
  
    Hei HTML         `;

Voit tehdä samoin Reaktin kanssa lisäämällä lisäargumentteja yllä olevan React.createElementin kolmannen argumentin jälkeen. Vastatakseen toistaiseksi alkuperäisessä DOM-esimerkissä, voimme lisätä neljännen argumentin, joka on toinen React.createElement-puhelu, joka tuottaa käyttöönoton:

ReactDOM.render (
  React.createElement (
    "Div"
    tyhjä,
    "Hei reagoi",
    React.createElement ( "input")
  ),
  document.getElementById ( 'mountNode2'),
);

Tarkastellaan myös nykyinen aika molemmissa versioissa. Laitetaan se esielementtiin (vain, että sille annetaan monospace fontti leikkikentällä). Voit käyttää uutta Date () .toLocaleTimeString () -näkymää yksinkertaisen aikamerkkijonon näyttämiseen. Tässä on mitä sinun on tehtävä natiivi-DOM-versiolle:

document.getElementById ('mountNode1'). innerHTML = `
  
    Hei HTML          
 $ {uusi päivämäärä (). toLocaleTimeString ()} 

   `;

Jos haluat tehdä saman Reakt-toiminnossa, lisäämme viidennen argumentin ylimmän tason div-elementtiin. Tämä uusi viides argumentti on toinen React.createElement-kutsu, tällä kertaa käyttämällä esitunnistetta uudella Date () .toLocaleTimeString () -merkkijonolla sisällölle:

ReactDOM.render (
  React.createElement (
    'Div'
    tyhjä,
    "Hei reagoi",
    React.createElement (input),
    React.createElement (
      'Pre',
      tyhjä,
      uusi päivämäärä (). toLocaleTimeString ()
    )
  ),
  document.getElementById ( 'mountNode2')
);

Molemmat versiot tuottavat edelleen täsmälleen saman HTML-koodin selaimessa.

Koska olet todennäköisesti jo ajatellut, Reaktin käyttäminen on paljon vaikeampaa kuin yksinkertainen ja tuttu alkuperäinen tapa. Mikä on se, että Reakty tekee niin hyvin, että kannattaa luopua tutusta HTML: stä ja joutua oppimaan uusi sovellusliittymä kirjoittaaksesi HTML-kirjoitettavat asiat?

Vastaus ei koske ensimmäisen HTML-näkymän tekemistä. Kyse on siitä, mitä meidän on tehtävä päivittääksemme DOM: n nykyisen kuvan.

Päivitetään React-elementtejä

Tehdään päivitys operaatioille DOM-puissa, joita meillä on toistaiseksi. Tehdään yksinkertaisesti aikamerkkivalikko joka sekunnissa.

Voimme helposti toistaa JavaScript-toiminnon puhelun selaimessa setInterval Web timer API: n avulla. Laitaan kaikki molempien versioiden DOM-manipulaatiot funktioon, nimeä se renderoitavaksi ja käytä sitä setInterval-puhelussa saadaksesi se toistumaan joka toinen.

Tässä on täydellinen lopullinen koodi tälle esimerkille:

// jsdrops.com/react-dom2
const render = () => {
  document.getElementById ('mountNode'). innerHTML = `
    
      Hei HTML              
 $ {uusi päivämäärä (). toLocaleTimeString ()} 
       `;
  ReactDOM.render (
    React.createElement (
      'Div'
      tyhjä,
      "Hei reagoi",
      React.createElement ('input', nolla),
      React.createElement (
        'Pre',
        tyhjä,
        uusi päivämäärä (). toLocaleTimeString ()
      )
    ),
    document.getElementById ( 'mountNode2')
  );
};
setInterval (render, 1000);

Tutustu tämän koodin suorittamisen tulokseen osoitteessa jsdrops.com/react-dom2 ja huomaa, kuinka aikamerkkipaikka tikkaa joka toinen sekunnissa molemmissa versioissa. Päivitämme nyt käyttöliittymämme DOM: ssa.

Tämä on hetki, jolloin React potentiaalisesti puhaltaa mieltäsi. Jos yrität kirjoittaa jotain alkuperäisen DOM-version tekstikenttään, et voi. Tämä on erittäin odotettua, koska heitämme pohjimmiltaan koko DOM-solmun jokaisen ruudun kohdalle ja uudistamme sen. Jos kuitenkin yrität kirjoittaa jotain Reaktin tarjoamaan tekstikenttään, voit varmasti tehdä niin!

Vaikka koko Reaktorin renderointikoodi on tikkausajastimessa, React muuttaa vain pre-elementin sisältöä eikä koko DOM-puuta. Siksi tekstinsyöttöruutua ei uudistettu, ja pystyimme kirjoittamaan sen.

Voit nähdä erilaisia ​​tapoja päivittää DOM visuaalisesti, jos tarkastat kaksi DOM-solmua Chrome DevTools -elementtipaneelissa. Chrome DevTools -elementtipaneeli korostaa kaikki DOM-elementit, jotka päivitetään. Näet kuinka natiivi HTML-versio uudistaa koko div # mountNode -säiliönsä jokaisella rastillä, kun taas React uudistaa älykkäästi vain div # mountNode2 -säiliössä olevan esitunnisteen.

Tämä on Reaktyn älykäs diffuusioalgoritmi toiminnassa. Se päivittää vain DOM-pääpuussa sen, mitä todella pitää päivittää, kun taas kaikki muu pysyy samana. Tämä hajautusprosessi on mahdollista Reaktin virtuaalisen DOM-esityksen takia, että se pysyy muistissa. Riippumatta siitä, kuinka monta kertaa käyttöliittymänäkymät on uusittava, React vie selaimeen vain tarvittavat “osittaiset” päivitykset.

Paitsi että tämä menetelmä on paljon tehokkaampi, se myös poistaa suuren monimutkaisuuskerran tavasta, jolla ajattelemme käyttöliittymien päivittämistä. Kun reagoimme, tee kaikki laskelmat siitä, pitäisikö meidän päivittää DOM-tietokantaa, jotta voimme keskittyä ajattelemaan tietojamme (tilaa) ja tapaa kuvata sen käyttöliittymä. Hallitsemme sitten datatilan päivitykset tarpeen mukaan huolehtimatta vaiheista, joita tarvitaan näiden päivitysten heijastamiseksi selaimen todellisessa käyttöliittymässä (koska tiedämme, että React tekee juuri sen ja se tekee sen tehokkaalla tavalla!)

Reaktorissa on kyse komponenteista

Reaktiossa kuvailemme käyttöliittymiä, joissa käytetään komponentteja, jotka ovat uudelleenkäytettäviä, komposiittioitavia ja tilallisia.

Määrittelemme pienet komponentit ja kootame ne sitten suurempien muodostamiseksi. Kaikki pienet tai suuret komponentit ovat uudelleenkäytettäviä jopa erilaisissa projekteissa.

Voit ajatella komponentteja yksinkertaisina toimintoina (millä tahansa ohjelmointikielellä). Kutsumme funktioita jollain syötöllä ja ne antavat meille jonkin tulon. Voimme käyttää toimintoja uudelleen tarpeen mukaan ja säveltää suurempia toimintoja pienemmistä.

Reaktiiviset komponentit ovat täsmälleen samat; heidän sisääntulonsa on joukko rekvisiitta ja niiden lähtö on kuvaus käyttöliittymästä. Voimme käyttää yhtä komponenttia uudelleen useissa käyttöliittymissä ja komponentit voivat sisältää muita komponentteja. React-komponentin perusmuoto on itse asiassa tavallinen JavaScript-toiminto.

Jotkut React-komponentit ovat puhtaita, mutta voit myös tuoda komponenttiin sivuvaikutuksia. Komponentti voi esimerkiksi muuttaa verkkosivun HTML-otsikkoa, kun se kiinnitetään selaimeen tai se voi selata selainnäkymää tiettyyn sijaintiin.

Tärkeintä on, että React-komponentilla voi olla yksityinen tila tietojen säilyttämiseksi, joka voi muuttua komponentin elinkaaren aikana. Tämä yksityinen tila on implisiittinen osa syötteestä, joka ohjaa komponentin lähtöä, ja juuri se antaa Reaktylle sen nimen!

Miksi React on joka tapauksessa nimeltään “React”?
Kun React-komponentin (joka on osa sen tuloa) tila muuttuu, myös sen edustama käyttöliittymä (sen lähtö) muuttuu. Tämän käyttöliittymän kuvauksen muutoksen on heijastettava sitä laitetta, jonka kanssa työskentelemme. Selaimessa meidän on päivitettävä DOM-puu. React-sovelluksessa emme tee sitä manuaalisesti. Reagoi reagoi vain tilan muutoksiin ja päivittää DOM: n automaattisesti (ja tehokkaasti) tarvittaessa.

Komponenttien luominen toimintojen avulla

React-komponentti - yksinkertaisimmassa muodossaan - on tavallinen JavaScript-toiminto:

// jsdrops.com/bx1
toimintopainike (rekvisiitta) {
  // Palauttaa DOM / reagoi -elementin täältä. Esimerkiksi:
  return ;
}
// Painikeelementin esittäminen selaimessa
ReactDOM.render (

Huomaa, kuinka kirjoitin HTML: n näyttävän yllä olevan Button-toiminnon palautetussa tulostuksessa. Tämä ei ole HTML eikä JavaScript, eikä se edes reagoi. Tämä on JSX. Se on JavaScriptin laajennus, jonka avulla voimme kirjoittaa toimintopuhelut HTML-kaltaisessa syntaksissa.

Yritä palauttaa kaikki muut HTML-elementit Button-toiminnon sisällä ja katso kuinka niitä kaikkia tuetaan (esimerkiksi palauta syöttöelementti tai textarea-elementti).

JSX ei ole HTML

Selaimet eivät ymmärrä JSX: tä. Jos yrität suorittaa Button-toiminto tavallisessa selainkonsolissa, se valittaa JSX-osan ensimmäisestä merkistä:

Selaimet ymmärtävät (ottaen huomioon, että React-kirjasto sisältyy), ovat React.createElementAPI-puhelut. Sama Button-esimerkki voidaan kirjoittaa ilman JSX: tä seuraavasti:

// jsdrops.com/bx2
toimintopainike (rekvisiitta) {
  palauta React.createElement (
    "-Painiketta",
    {tyyppi: "lähetä"},
    props.label
  );
}
ReactDOM.render (
  React.createElement (painike, {tunniste: "Tallenna"}),
  mountNode
);

Voit käyttää Reagoida näin (ilman JSX: tä). Voit suorittaa Button-toiminnon selaimessa suoraan (React-kirjaston lataamisen jälkeen) ja asiat toimivat hyvin. Haluamme kuitenkin nähdä ja työskennellä HTML: n kanssa funktion puheluiden käsittelemisen sijaan. Milloin viimeksi rakensit verkkosivun, jossa oli vain JavaScripti ja et käyttänyt HTML: ää? Voit, jos haluat, mutta kukaan ei tee sitä. Siksi JSX on olemassa.

JSX on pohjimmiltaan kompromissi. Sen sijaan, että kirjoittaisimme React-komponentteja käyttämällä React.createElement-syntaksia, käytämme HTML: n kaltaista syntaksia ja käännämme sitten kääntäjän avulla React.createElement-kutsuihin.

Kääntäjä, joka kääntää syntaksin yhden muodon toiseen, tunnetaan nimellä "siirräjä". JSX: n kääntämiseen voidaan käyttää siirtäjiä, kuten Babel tai TypeScript. Esimerkiksi jsComplete-leikkikenttä käyttää TypeScriptiä siirtämään minkä tahansa siihen laittamasi JSX: n. Kun käytät luo-reagoi -sovellusta, luotu sovellus käyttää sisäisesti Babelia JSX: n siirtämiseen.

Voit käyttää babeljs.io/repl/ -sovellusta nähdäksesi mitä JSX-syntaksit muunnetaan Reaktiksi, mutta JSX: ää voidaan käyttää myös yksinään. Se ei ole vain reagoiva asia.

Joten React-komponentti on JavaScript-funktio, joka palauttaa React-elementin (yleensä JSX: n kanssa). Kun käytetään JSX: tä,

Nimen on alkaa isoilla kirjaimilla

Huomaa, kuinka nimitin komponentin “Button”. Ensimmäinen kirjain, joka on iso, on oikeastaan ​​vaatimus, koska käsittelemme HTML-elementtien ja React-elementtien sekoitusta. JSX-kääntäjä (kuten Babel) pitää kaikkia nimikkeitä, jotka alkavat pienillä kirjaimilla, HTML-elementtien nimiä. Tämä on tärkeää, koska HTML-elementit välitetään merkkijonoina React.createElement-kutsuihin, kun taas React-elementit on välitettävä muuttujina:

Mene eteenpäin ja kokeile nimetä React-komponentti “painike” painikkeen sijaan ja katso kuinka ReactDOM jättää toiminnon kokonaan huomioimatta ja tuottaa säännöllisen tyhjän HTML-painikeelementin.

// jsdrops.com/bx3
// Väärä:
toimintopainike () {
  palauta 
My Fancy Button
; };
// Seuraava tekee HTML-painikkeen
// (ja ohita hieno painiketoiminto)
ReactDOM.render (, mountNode);

Ensimmäinen argumentti on "rekvisiitta" -objekti

Aivan kuten HTML-elementeille voidaan määrittää määritteitä, kuten tunnus tai otsikko, React-elementti voi myös saada luettelon määritteistä, kun se renderoidaan. Yllä oleva Button-elementti (jsdrops.com/bx2) sai tunnistemääritteen. Reakt-elementissä React-elementin vastaanottamien määritteiden luetteloa kutsutaan rekvisiittaksi. React-funktion komponentti vastaanottaa tämän luettelon ensimmäisenä argumenttinsa. Lista välitetään objektina avaimilla, jotka edustavat määritteiden nimiä ja arvoja, jotka edustavat niille annettuja arvoja.

Kun käytät funktiokomponenttia, sinun ei tarvitse nimetä määriteluetteloa pitävää objektia rekvisiitta, mutta se on vakiokäytäntö. Käytettäessä luokkakomponentteja, jotka teemme alla, sama attribuuttiluettelo esitetään aina erityisen esiintymän ominaisuuden, nimeltään rekvisiitta, avulla.

Huomaa, että rekvisiittien vastaanottaminen on valinnaista. Joissakin komponenteissa ei ole rekvisiitta. Komponentin palautusarvo ei ole kuitenkaan valinnainen. React-komponentti ei voi palauttaa ”määrittelemätöntä” (joko suoraan tai epäsuorasti). Sen on palautettava arvo. Se voi palauttaa arvon "nolla", jotta renderoija jättää huomioimatta tuotoksensa.

Tykkään käyttää esineiden tuhoamista aina, kun käytän komponentti rekvisiitta (tai tila, todella). Esimerkiksi Button-komponentti-funktio voidaan kirjoittaa tällä tavoin rekvisiittien tuhoamalla:

const-painike = ({label}) => (
   {label} 
);

Tällä lähestymistavalla on monia etuja, mutta tärkein on tarkistaa visuaalisesti, mitä komponentteja komponentissa käytetään, ja varmistaa, että komponentti ei saa ylimääräisiä rekvisiitta, joita ei tarvita.

Huomaa, kuinka käytin nuolitoimintoa tavallisen sijasta. Tämä on vain tyylipaino henkilökohtaisesti minulle. Jotkut ihmiset pitävät tavallista toimintotyyliä, eikä siinä ole mitään vikaa. Mielestäni on tärkeää olla johdonmukainen valitsemasi tyylin kanssa. Käytän tässä nuolitoimintoja, mutta en tulkitse sitä vaatimukseksi.

Lausekkeet JSX: ssä

Voit sisällyttää JavaScripti-lausekkeen käyttämällä paria kiharasulkeja missä tahansa JSX: n sisällä:

// jsdrops.com/bx4
const RandomValue = () => (
  
    {Math.floor (Math.random () * 100)}    );
ReactDOM.render (, mountNode);

Huomaa, että näihin kiharoihin voidaan sisällyttää vain lausekkeita. Et voi esimerkiksi sisällyttää säännöllistä if-lauseketta, mutta kolmiosainen lauseke on kunnossa. Kaikki mikä palauttaa arvon, on kunnossa. Voit aina laittaa minkä tahansa koodin funktioon, saada sen palauttamaan jotain ja soittamaan kyseiselle toiminnolle kiharassa. Pidä kuitenkin näiden kiharaan kiinnitettyjen logiikka minimissään.

Javascript-muuttujat ovat myös lausekkeita, joten kun komponentti vastaanottaa luettelon rekvisiitta, voit käyttää näitä rekvisiittaja kiharassa. Näin käytimme painiketta {label} Button-esimerkissä.

JavaScript-objektin kirjaimet ovat myös lausekkeita. Joskus käytämme JavaScript-objektia kiharasilmien sisällä, mikä tekee siitä näyttävän kaksinkertaisena kiharasulkeena: {{a: 42}}. Tämä ei ole erilainen syntaksi; se on vain kohde, joka on määritelty tavallisten JSX-kiharakiinnikkeiden sisällä.

Esimerkiksi yksi käyttötapa objektin käyttämiseen kirjaimellisesti näissä kiharaissa on CSS-tyyliobjektin siirtäminen erityiseen tyylimääritteeseen Reaktissa:

// jsdrops.com/bx5
const ErrorDisplay = ({viesti}) => (
  
    {viesti}    );
ReactDOM.render (
  ,
  mountNode
);

Yllä oleva tyylitunnus on erityinen. Käytämme objektina sen arvoa ja tämä objekti määrittelee tyylit ikään kuin asetamme ne JavaScript DOM API: n kautta (kamelilaatikon ominaisuuksien nimet, merkkijonoarvot). React kääntää nämä tyyliobjektit CSS-tyylimääritteisiin. Tämä ei ole paras tapa muotoilla React-komponentti, mutta minusta on erittäin kätevä käyttää sitä sovellettaessa ehdollisia tyylejä elementteihin. Esimerkiksi tässä on komponentti, joka tuottaa sen tekstin joko vihreänä tai punaisena satunnaisesti noin puolet ajasta:

// jsdrops.com/bx6
luokan ConditionalStyle laajentaa React.Component {
  tehdä () {
    palata (
      
        Kuinka pidät tästä?            );   } }
ReactDOM.render (
  ,
  mountNode,
);

Tämän muotoilun logiikka on siinä komponentissa. Pidän siitä! Tämän kanssa on helpompaa työskennellä kuin ehdollisesti käyttämällä luokan nimeä ja seuraamalla sitten mitä luokan nimi tekee globaalissa CSS-tyylitaulukossa.

JSX ei ole mallikieli

Jotkut HTML-kirjastot tarjoavat sille mallikielen. Voit kirjoittaa dynaamiset näkymät "parannetulla" HTML-syntaksilla, jossa on silmukat ja ehdolliset ehdot. Nämä kirjastot käyttävät sitten JavaScriptiä mallien muuntamiseksi DOM-toimintoiksi. DOM-toimintoja voidaan sitten käyttää selaimessa parannetun HTML: n kuvaaman DOM-puun näyttämiseen.

React eliminoi tämän vaiheen. Emme lähetä selaimeen mallia, jossa on React-sovellus. Lähetimme sille React API: lla kuvatun objektipuun. React käyttää näitä objekteja luodaan DOM-toiminnot, joita tarvitaan halutun DOM-puun näyttämiseen.

Kun HTML-mallia käytetään, kirjasto jäsentää sovelluksesi merkkijonona. React-sovellus jäsentää objektipuuna.

Vaikka JSX saattaa näyttää malli kieleltä, se ei oikeastaan ​​ole. Se on vain JavaScript-laajennus, jonka avulla voimme edustaa Reaktan objektipuuta syntaksilla, joka näyttää HTML-mallilta. Selainten ei tarvitse lainkaan käsitellä JSX: ää, eikä Reaktin tarvitse myöskään käsitellä sitä! Vain kääntäjä tekee. Selaimeen lähettämämme mallivapaa ja JSX-vapaa koodi.

Esimerkiksi edellä esitetyn todos-taulukon tapauksessa, jos meidän on tarkoitus näyttää kyseinen taulukko käyttöliittymässä mallin kielellä, meidän on tehtävä jotain:

      <% Jokaisesta tehtäväluettelosta tehtäväluettelosta%>     
  • <% = todo.body%>
  •   <% END FOR%>
<%%> On yksi syntaksi edustamaan dynaamisesti parannettuja osia. Saatat nähdä myös {{}} syntaksin. Jotkut mallikielet käyttävät parannettuun logiikkaansa erityisiä määritteitä. Jotkut mallikielet käyttävät välilyönnin sisennystä (ulkopuolinen sääntö).

Kun todos-taulukkoon tapahtuu muutoksia (ja meidän on päivitettävä DOM-muodossa tuotetut mallineen kielellä), meidän on joko tehtävä kyseinen malli uudelleen tai laskettava, missä DOM-puussa meidän on heijastettava todos-taulukon muutosta. .

React-sovelluksessa malli kieltä ei ole ollenkaan. Sen sijaan käytämme JSX: tä:

      {todos.map (todo =>     
  • {todo.body}   )}

Joka käännetään ennen selaimessa käyttöä:

React.createElement (
  "UL",
  tyhjä,
  todos.map (todo =>
    React.createElement ("li", nolla, todo.body)
  ),
);

React ottaa tämän esineiden puun ja muuntaa sen DOM-elementtien puuksi. Näkemyksemme mukaan olemme valmiita tämän puun kanssa. Emme hallitse mitään siihen liittyviä toimia. Hallitsemme vain toimia itse todos-ryhmässä.

Komponenttien luominen luokkien avulla

React tukee komponenttien luomista myös JavaScript-luokan syntaksin kautta. Tässä on sama Button-komponentti esimerkki, joka on kirjoitettu luokan syntaksilla:

// jsdrops.com/bx7
luokan painike laajentaa React.Component {
  tehdä () {
    palata (
      Painiketta <> {this.props.label} 
    );
  }
}
// Käytä sitä (sama syntaksi)
ReactDOM.render (

Tässä syntaksissa määrität luokan, joka laajentaa React.Componentia, joka on yksi React-ylimmän tason sovellusliittymän pääluokista. Luokkaperusteisen React-komponentin on ainakin määritettävä renderöinti nimeltään ilmentymän menetelmällä. Tämä renderöintimenetelmä palauttaa elementin, joka edustaa komponentista välitetyn objektin lähtöä. Aina kun käytämme Button-luokkaperusteista komponenttia (tekemällä ), React pilkkoo objektin tästä luokkapohjaisesta komponentista ja käyttää kyseisen objektin esitystä DOM-elementin luomiseen. Se yhdistää myös DOM-hahmonnetun elementin luokkaan luomaan ilmentymään.

Huomaa, kuinka käytimme tätä.props.label-sulaketta sulatetun JSX: n sisällä. Jokainen komponentti saa erityisen ilmentymän ominaisuuden nimeltä rekvisiitta, joka sisältää kaikki arvot, jotka välitetään komponentin elementille, kun se toteutettiin. Toisin kuin funktiokomponentit, luokkaperusteisissa komponenteissa renderofunktio ei saa argumentteja.

Toiminnot vs. luokat

Komponentit, jotka on luotu funktioilla, joita on aiemmin rajoitettu Reaktorissa. Ainoa tapa tehdä komponentista “tilallinen” oli käyttää luokkasyntaksia. Tämä on muuttunut julkaisemalla ”React Hooks”, joka alkaa Reactin versiosta 16.8, joka julkaistiin vuoden 2019 alussa. React-koukutiedotteet esittelivät uuden sovellusliittymän, jonka avulla funktiokomponentti on tilallinen (ja antaa sille monia muita ominaisuuksia).

Tämän uuden sovellusliittymän avulla suurin osa siitä, mitä Reaktin kanssa tehdään, voidaan suorittaa toiminnoilla. Luokkapohjaista syntaksia tarvitaan vain edistyneissä ja erittäin harvinaisissa tapauksissa.

Uskon, että uusi sovellusliittymä korvaa hitaasti vanhan, mutta se ei ole ainoa syy, jonka haluan kannustaa käyttämään sitä (yksinomaan jos mahdollista).

Olen käyttänyt molempia sovellusliittymiä suurissa sovelluksissa ja voin kertoa teille, että uusi sovellusliittymä on paljon parempi kuin vanha monista syistä, mutta tässä on ne, jotka olen henkilökohtaisesti mielestäni tärkeimmät:

  • Sinun ei tarvitse työskennellä luokan ”esiintymien” ja niiden implisiittisen tilan kanssa. Työskentelet yksinkertaisilla toiminnoilla, jotka päivitetään jokaisessa renderissä. Valtio julistetaan nimenomaisesti eikä mitään ole piilotettu. Kaikki tämä tarkoittaa pohjimmiltaan sitä, että koodissasi on vähemmän yllätyksiä.
  • Voit ryhmitellä liittyvän tilallisen logiikan ja jakaa sen itsenäisiksi kompostoitaviksi ja jaettaviksi yksiköiksi. Tämä helpottaa monimutkaisten komponenttien jakamista pienemmiksi osiksi. Se myös helpottaa komponenttien testaamista.
  • Voit kuluttaa mitä tahansa tilallista logiikkaa deklaratiivisella tavalla ja joutumatta käyttämään hierarkkista "pesimistä" komponenttipuissa.

Vaikka luokkaperusteiset komponentit ovat edelleen osa Reaktoria lähitulevaisuudessa, ekosysteemin uutuutena mielestäni on mielestäni järkevää aloittaa pelkästään toiminnoista (ja koukkuista) ja keskittyä uuden sovellusliittymän oppimiseen (ellet täytyy työskennellä kooditietokannan kanssa, joka käyttää jo luokkia).

Komponentit vs. elementit
Saatat löytää sanat ”komponentti” ja “elementti” sekoitettuna siellä oleviin React-oppaisiin ja oppaisiin. Mielestäni reagoivan oppijan on ymmärrettävä tärkeät erot.
React-komponentti on malli. Suunnitelma. Globaali määritelmä. Tämä voi olla joko funktio tai luokka (renderöintimenetelmällä).
React-elementti on se, mikä palautetaan komponenteista. Se on esine, joka kuvaa käytännössä komponentin edustamia DOM-solmuja. Funktion komponentin kanssa tämä elementti on objekti, jonka funktio palauttaa, ja luokkakomponentin kanssa elementti, jonka komponentin renderöintimenetelmä palauttaa. Reagoivat elementit eivät ole mitä selaimessa näet. Ne ovat vain muistissa olevia esineitä, etkä voi muuttaa niistä mitään.
Reaktio luo sisäisesti, päivittää ja tuhoaa esineitä selvittääkseen selaimeen annettavan DOM-elementtipuun. Kun työskentelet luokkakomponenttien kanssa, on yleistä viitata niiden selaimen tarjoamiin DOM-elementteihin komponentti-ilmentyminä. Voit tehdä useita komponentteja samasta komponentista. Esimerkki on "tämä" avainsana, jota käytät luokkaperusteisten komponenttien sisällä. Sinun ei tarvitse luoda ilmentymää luokasta manuaalisesti. Sinun on vain muistettava, että se on jossain Reaktin muistissa. Funktion komponenteille React käyttää vain funktion kutsumista määrittääkseen mitä DOM-elementti renderöidään.

Komponenttien edut

Termiä ”komponentti” käytetään monissa muissa puitteissa ja kirjastoissa. Voimme jopa kirjoittaa web-komponentteja natiivisti HTML5-ominaisuuksilla, kuten mukautetuilla elementeillä ja HTML-tuonnilla.

Komponenteilla on paljon etuja riippumatta siitä, työskentelemmekö heidän kanssaan natiivisti tai Reaktorin kaltaisen kirjaston kautta.

Ensinnäkin komponentit tekevät koodistasi helpommin luettavan ja helpomman työskennellä. Harkitse tätä käyttöliittymää:


 

Mitä tämä käyttöliittymä edustaa? Jos puhut HTML: ää, voit jäsentää sen nopeasti täältä ja sanoa, että "se on napsautettava kuva". Jos me muunnamme tämän käyttöliittymän komponentiksi, voimme nimetä sen vain ClickableImage!

Kun asiat muuttuvat monimutkaisemmiksi, tämä HTML: n jäsentäminen vaikeutuu, joten komponenttien avulla voimme nopeasti ymmärtää, mitä käyttöliittymä edustaa meille sopivalla kielellä. Tässä on suurempi esimerkki:


  
  
  

Tarkastelematta todellista HTML-koodia tiedämme tarkalleen, mitä tämä käyttöliittymä edustaa. Lisäksi, jos meidän on muokattava jäljellä olevien merkkien osiota, tiedämme tarkalleen mihin mennä.

Reaktiiviset komponentit voidaan myös käyttää uudelleen samassa sovelluksessa ja useiden sovellusten välillä. Esimerkiksi, tässä on mahdollinen ClickableImage-komponentin toteutus:

const ClickableImage = ({href, src}) => {
  palata (
    
      
    
  );
};

Sekä href- että src-rekvisiittien muuttujat tekevät tästä komponentista uudelleenkäytettävän. Esimerkiksi, jotta voimme käyttää tätä komponenttia, voimme hahmottaa sen joukolla rekvisiitta:

Ja voimme käyttää sitä uudelleen käyttämällä erilaista rekvisiitta:

Toiminnallisessa ohjelmoinnissa meillä on käsite puhtaista toiminnoista. Ne ovat periaatteessa suojattuja kaikkia ulkopuolisia valtioita vastaan; jos annamme heille saman tulon, saamme aina saman tuotoksen.
Jos React-komponentti ei ole riippuvainen (tai muokkaa) mitään määritelmän ulkopuolella olevaa (tai esimerkiksi, jos se ei käytä globaalia muuttujaa), voimme merkitä kyseisen komponentin myös puhtaana. Puhtailla komponenteilla on paremmat mahdollisuudet käyttää niitä uudelleen ilman mitään ongelmia.

Luomme komponentteja näkymien esittämiseen. ReactDOM: n määrittelemät React-komponentit edustavat HTML DOM -solmuja. Yllä oleva ClickableImage-komponentti koostui kahdesta sisäkkäisestä HTML-elementistä.

Voimme ajatella HTML-elementtejä selaimen sisäänrakennetuina komponenteina. Voimme myös käyttää omia räätälöityjä komponentteja säveltääksemme suurempia. Kirjoita esimerkiksi komponentti, joka näyttää luettelon hakukoneista.

const SearchEngines = () => {
  palata (
    
                     ); };

Huomaa, kuinka olen käyttänyt ClickableImage-komponenttia SearchEngines-komponentin säveltämiseen!

Voimme myös tehdä SearchEngines-komponentista uudelleenkäytettävän purkamalla sen tiedot muuttujaan ja suunnittelemalla sen toimimaan kyseisen muuttujan kanssa.

Voimme esimerkiksi ottaa käyttöön tietojoukon muodossa kuten:

const data = [
  {href: "http://google.com", src: "google.png"},
  {href: "http://bing.com", src: "bing.png"},
  {href: "http://yahoo.com", src: "yahoo.png"}
];

Sitten, jotta toimisi, me vain kartoitamme tietojoukon objektiluettelosta ClickableImage-komponenttien luetteloon:

const SearchEngines = ({moottorit}) => {
  palata (
    
      {moottorit.kartta (moottori => )}
    
  );
};
ReactDOM.render (
 ,
 document.getElementById ( "mountNode")
);

Tämä SearchEngines voi toimia minkä tahansa luettelon hakukoneista, jotka me sille annamme.

Mitä tarkalleen ovat koukut?

Koukku React-komponentissa on kutsu erikoistoimintoon. Kaikki koukutoiminnot alkavat sanalla ”käyttö”. Joitakin niistä voidaan käyttää toimintokomponentin aikaansaamiseksi tilallisilla elementeillä (kuten useState), toisia voidaan käyttää hallittujen sivuvaikutusten (kuten useEffect) tai toimintojen ja objektien välimuistiin tallentamiseen / muistamiseen (kuten useCallback). Koukut ovat erittäin voimakkaita ja taivas on raja, kun kyse on asioista, joita voit tehdä niiden kanssa.

Reaktiokoukutoimintoja voidaan käyttää vain toimintokomponentteihin. Et voi käyttää niitä luokan komponenteissa.

Jos haluat nähdä esimerkin perustana olevasta useState-koukusta, saakaamme yllä oleva Button-komponentti vastaamaan napsautustapahtumaan. Pidämme yllä, kuinka monta kertaa sitä napsautetaan "muuttuja" -muuttujassa, ja näytä kyseisen muuttujan arvo sen antaman painikkeen etikettinä.

const-painike = () => {
  lasketaan = 0;
  palata (
    Painiketta <> {count} 
  );
};
ReactDOM.render (

Tämä laskentamuuttuja on tilaelementti, joka meidän on esitettävä esimerkille. Se on tieto, josta käyttöliittymä riippuu (koska näytämme sitä), ja se on tilaelementti, koska se aikoo muuttua ajan myötä.

Aina kun määrität muuttujan koodissasi, otat käyttöön tilan ja joka kerta, kun muutat kyseisen muuttujan arvoa, mutaat kyseisen tilan. Pidä se mielessä.

Ennen kuin voimme muuttaa laskentatilan arvoa, meidän on opittava tapahtumista.

Vastaaminen käyttäjän tapahtumiin

Voit lisätä tapahtumakäsittelijän, jolla on “onEvent” -ominaisuus (tässä tapauksessa painikeelementtiin). Tämä voi olla onClick, onMouseOver, onScroll, onSubmit jne.

Tarvitsemme täällä onClick-tapahtuman, ja määrittelemme sen vain kohdeelementin määritteeksi. Esimerkiksi, jotta ohjelmalokista saataisiin viesti konsoliin aina, kun painiketta napsautetaan, voimme tehdä jotain:

const-painike = () => {
  lasketaan = 0;
  palata (
    <-painike onClick = {() => console.log ('Nappia napsautettu')}>
      {Kreivi}
    
  );
};
ReactDOM.render (

Toisin kuin onClick-määritteen DOM-versio (joka käyttää merkkijonoa), Reaktin onClick-määrite käyttää toimintoviittausta. Määrität kyseisen kiharasilman sisällä.

toiminto func () {}
<-painike onClick = {func} />

Huomaa, kuinka välitimme func-viitteen (nimen) onClick-käsittelijänä. Emme vedonneet funciin siellä. Reakti kutsuu funktiota, kun painiketta napsautetaan.

Yllä olevan Button-komponentin onClick-tapahtumaa varten "viivattiin" funktion määritelmä, joka kutsuessaan lähettää viestin konsoliin. Joka kerta kun napsautamme painiketta, onClick-käsittelijä (inline arrow -toiminto) käynnistetään ja näemme kyseisen viestin.

Huomaa, kuinka tapahtuman nimi on kamelikotelo. Kaikkien DOM-liittyvien määritteiden (joita React käsittelee) on oltava kameli-tapaus (ja React näyttää virheen, ellei näin ole). React tukee myös mukautettujen HTML-määritteiden käyttöä, ja niiden on oltava pienimuotoisia.
Jotkut Reaktin DOM-määritteet eroavat hiukan siitä, mitä ne tekevät tavallisessa DOM-sovellusliittymässä. Esimerkki siitä on onChange-tapahtuma. Tavallisessa selaimessa se yleensä laukaistaan, kun napsautat lomakekentän ulkopuolella (tai välilehteä siitä). Reaktorissa onChange välähtää aina, kun lomakekentän arvoa muutetaan (jokaisessa lisätyn / poistetun merkin kohdalla).
Jotkut Reaktin attribuutit on nimetty eri tavalla kuin niiden HTML-vastaavuus. Esimerkki tästä on Reaktin className -attribuutti, joka vastaa luokka-määritteen käyttöä HTML-muodossa. Katso täydellinen luettelo React-määritteiden ja DOM-määritteiden välisistä eroista osoitteessa jscomplete.com/react-attributes.

Lukemisen ja päivittämisen tila

Tilapäivitysten seuraamiseksi ja virtuaalisen DOM-hajautuksen ja todellisen DOM-täsmäytyksen käynnistämiseksi Reaktin on oltava tietoinen kaikista komponenteissa käytettyjen tilaelementtien muutoksista. Jotta tämä toimisi tehokkaasti, React vaatii erityisten getterien ja setterien käytön jokaiselle komponentissa käyttöön otettavalle tilaelementille. UseState-koukku tulee tässä peliin. Se määrittelee tilaelementin ja antaa meille sen takaisin!

Tässä on mitä tarvitsemme count state -elementtiin, jota yritämme toteuttaa:

const [count, setCount] = React.useState (0);

UseState-funktio palauttaa taulukon, jossa on tarkalleen 2 kohdetta. Ensimmäinen kohta on arvo (getter) ja toinen kohde on funktio (setter). Käytin taulukon hajotusta antamaan näille nimikkeille. Voit antaa heille haluamasi nimet, mutta [nimi, setName] on yleinen tapa.

Ensimmäinen alkion arvo voi olla merkkijono, numero, taulukko tai muu tyyppi. Tässä tapauksessa tarvitsimme lukua ja meidän oli alustettava se nollalla. React.useStateis -argumenttia käytettiin tilaelementin alkuarvona.

Toinen kohta ”funktio” muuttaa tilaelementin arvoa, kun sitä kutsutaan (ja se käynnistää DOM-prosessoinnin tarvittaessa). Aina kun setCount-toiminto käynnistetään, React tekee Button-komponentin uudelleen, joka päivittää kaikki komponentissa määritellyt muuttujat (mukaan lukien laskenta-arvot). Argumentista, jonka välitämme setCountille, tulee laskennan uusi arvo.

Se, mitä meidän on tehtävä, jotta painikkeen lisäys sen merkinnässä on, on käynnistää setCount-toiminto onClick-tapahtumassa ja siirtää siihen nykyinen laskenta-arvo, joka on lisätty yhdellä. Tässä on tarran lisäyspainikkeen täydellinen koodi:

const-painike = () => {
  const [count, setCount] = useState (0);
  palata (
    <-painike onClick = {() => setCount (count + 1)}>
      {Kreivi}
    
  );
};
ReactDOM.render (

Mene eteenpäin ja testaa sitä. Painike lisää nyt tarraa jokaiseen napsautukseen.

Huomaa, kuinka emme ole toteuttaneet mitään toimia itse käyttöliittymän muuttamiseksi. Sen sijaan toteutimme toimenpiteen JavaScript-objektin muuttamiseksi (muistissa)! Käyttöliittymämme toteutus käytännössä kertoi Reaktille, että haluamme painikkeen etiketin heijastavan aina vastaelementin arvoa. Koodimme ei tehnyt mitään DOM-päivityksiä. Reaktio teki.

Huomaa myös, kuinka käytin const-avainsanaa laskennan määrittämiseen, vaikka se muuttuisi arvoksi! Koodimme ei muuta sitä arvoa. Reagoi, kun se käyttää uutta Button-toiminnon kutsua esittämään uuden tilan käyttöliittymä. Tässä uudessa puhelussa useState-funktiopuhelu antaa meille uuden tuoreen laskenta-arvon.

UseState-toiminto on saatavana maailmanlaajuisesti leikkipaikalla. Tämä on vain aliava React.useState-sovellukselle. Koodissasi voit käyttää nimettyjä tuontia, jotta useState on saatavana suoraan moduulin laajuudessa:
Tuo React, {useState} kohdasta 'react';

Tarvitset muutama esimerkki arvostaaksesi tätä voimaa. Lisäämme vielä joitain ominaisuuksia tähän perusesimerkkiin. Meillä on monia painikkeita ja tee niistä kaikista yksi jaettu laskenta-arvo.

Useiden komponenttien käsittely

Jaetaan Button-komponentti, joka meillä on toistaiseksi, kahteen osaan:

  • Pidä painikekomponentti painikeelementin edustajana, mutta siinä on staattinen tarra.
  • Lisää uusi näyttökomponentti laskurin arvon näyttämiseksi.

Uusi näyttökomponentti on puhtaasti esitysmuotoinen ilman erillistä tilaa tai vuorovaikutusta. Se on normaalia. Kaikilla React-komponenteilla ei tarvitse olla tilavia koukkuja tai olla vuorovaikutteisia.

const Näyttö = (rekvisiitta) => (
  
 LUE ARVO TÄTÄ ... 
);

Näyttökomponentin vastuulla on yksinkertaisesti näyttää arvo, jonka se saa potkurina. Esimerkiksi se, että pre-elementtiä käytettiin arvon ylläpitämiseen, on osa tätä vastuuta. Tämän sovelluksen muilla komponenteilla ei ole sanottavaa siitä!

Sisarkomponenttien renderointi

Meillä on nyt kaksi elementtiä, jotka voidaan antaa: painike ja näyttö. Emme voi tehdä niitä suoraan vierekkäin seuraavasti:

// Tämä ei toimi
ReactDOM.render (

Vierekkäisiä elementtejä ei voida hajottaa tällä tavalla Reaktissa, koska jokainen niistä käännetään funktion puheluksi, kun JSX muunnetaan. Sinulla on muutama vaihtoehto käsitellä tätä asiaa.

Ensinnäkin, voit välittää joukon elementtejä ReactDOM.renderille ja lisätä siihen taulukon niin monta React-elementtiä kuin haluat.

Vaihtoehto 1

ReactDOM.render ([

Tämä on yleensä hyvä ratkaisu, kun kaikki tarjoamasi elementit ovat peräisin dynaamisesta lähteestä. Se ei kuitenkaan ole ihanteellinen tapaukselle, jota teemme täällä.

Toinen vaihtoehto on saada sisaruksen React-elementit toisen React-elementin lapsiksi. Voimme esimerkiksi sulkea ne vain div-elementtiin.

Vaihtoehto 2

ReactDOM.render (
  
            ,   mountNode );

React API tukee tätä pesää. Itse asiassa Reaktylla on erityinen objekti, jos joudut sulkemaan useita vierekkäisiä elementtejä, kuten tämä, ottamatta käyttöön uutta DOM-emo-solmua. Voit käyttää React.Fragment:

Vaihtoehto 3

ReactDOM.render (
  
    
    
  ,
  mountNode
);

Tämä tapaus on niin yleinen Reaktissa, että JSX-laajennuksella on siihen pikakuvake. React.Fragmentin kirjoittamisen sijasta voit käyttää tyhjää tunnistetta <> .

Vaihtoehto 3 +

ReactDOM.render (
  <>
    
    
  ,
  mountNode
);

Tyhjä tunniste siirretään React.Fragment-syntaksiin. Käytän tätä syntaksia jatkaaksesi esimerkissä.

Sinun tulisi kuitenkin aina yrittää tehdä ensimmäinen argumentti ReactDOM.renderille yhden komponenttikutsun tekemämme sisäkkäisen puun sijasta. Tämä on lähinnä koodin laatuominaisuus. Se pakottaa sinut pohtimaan komponenttien hierarkiaa, nimiä ja suhteita. Tehdään se seuraavaksi.

Ylimmän tason komponentti

Otetaan käyttöön ylätason komponentti sekä Button- että Display-komponenttien ylläpitämiseksi. Kysymys on nyt: mitä meidän pitäisi nimetä tämä uusi vanhempi komponentti?

Usko tai älä, komponenttien ja niiden tila / rekvisiittielementtien nimeäminen on erittäin vaikea tehtävä, joka vaikuttaa tapaan, jolla nämä komponentit toimivat ja suorittavat. Oikeat nimet pakottavat sinut tekemään oikeita suunnittelupäätöksiä. Ota hetki ja mieti jokaista uutta nimeä, jonka esität React-sovelluksillesi.

Koska tämä uusi emokomponentti isännöi näyttöä painikkeella, joka kasvattaa näytettyä määrää, voimme ajatella sitä laskenta-arvonhallinnana. Nimeämme sen CountManageriksi.

const CountManager = () => {
  palata (
    <>
      
      
    
  );
};
ReactDOM.render (, mountNode);

Koska aiomme näyttää laskun arvon uudessa näyttökomponentissa, meidän ei enää tarvitse näyttää laskun arvoa painikkeen etiketissä. Sen sijaan voimme muuttaa tunnisteen jotain "+1".

const-painike = () => {
  palata (
    <-painike onClick = {() => console.log ('TODO: Kasvulaskuri')}>
      +1
    
  );
};

Huomaa, että olen myös poistanut tilaelementin Button-komponentista, koska meillä ei ole sitä enää siellä. Uuden vaatimuksen myötä sekä painike- että näyttökomponentit tarvitsevat pääsyn laskentatilaelementtiin. Näyttökomponentti näyttää sen ja Button-komponentti päivittää sen. Kun komponentin on päästävä sisarkomponentin omistamaan tilaelementtiin, eräs ratkaisu on "nostaa" kyseinen tilaelementti yhden tason ylöspäin ja määritellä se vanhemman komponentinsa sisällä. Tässä tapauksessa vanhempi on juuri käyttöön ottamamme CountManager-komponentti.

Siirtämällä tilan CountManager-sovellukseen, voimme nyt "kuljettaa" tietoja vanhemmilta lapsille komponenttiviestien avulla. Tämän meidän pitäisi tehdä näyttääksesi laskenta-arvon Näyttö-komponentissa:

const Näyttö = ({content}) => (
  
 {pitoisuus} 
);
const CountManager = () => {
  const [count, setCount] = useState (0);
  palata (
    <>
      
      
    
  );
};
ReactDOM.render (, mountNode);

Huomaa, kuinka CountManagerissa käytin täsmälleen samaa useState-riviä, joka oli Button-komponentissa. Nostamme samaa valtion elementtiä. Huomaa myös, kuinka kun virrasin laskenta-arvon alas näyttökomponenttiin potkurin kautta, käytin sille eri nimeä (sisältö). Se on normaalia. Sinun ei tarvitse käyttää täsmälleen samaa nimeä. Itse asiassa joissain tapauksissa uusien yleisnimien käyttöönotto on parempi lapsille, koska ne tekevät niistä uudelleenkäytettäviä. Näyttökomponenttia voitaisiin käyttää uudelleen muiden lukuarvojen näyttämiseen lukuarvon lisäksi.

Vanhemmat komponentit voivat myös heikentää käyttäytymistä lapsilleen, mikä meidän on tehtävä seuraavaksi.

Koska count state -elementti on nyt CountManager-komponentissa, tarvitsemme kyseisen tason toiminnon sen päivittämiseksi. Nimeämme tämän funktion lisäyslaskuri. Tämän toiminnon logiikka on oikeastaan ​​sama logiikka, joka meillä oli aiemmin Button-komponentin handleClick-toiminnossa. Uusi IncrementCounter-toiminto aikoo päivittää CountManager-komponenttilaskurin tilan arvon kasvattamiseksi käyttämällä edellistä arvoa:

const CountManager = () => {
  // ....
  const IncrementCounter = () => {
    setCount (määrä + 1);
  }
  // ...
};

Button-komponentin onClick-käsittelijän on nyt muututtava. Haluamme sen suorittavan CountManager-komponentissa olevan lisäyksenCounter-toiminnon, mutta komponentti voi käyttää vain omia toimintojaan. Joten, jotta Button-komponentti kykenee käyttämään CountManager-komponentin IncrementCounter-toimintoa, voimme välittää viittauksen IncrementCounter Button-komponenttiin prop. Kyllä, rekvisiitta voi pitää myös toimintoja, ei vain dataa. Toiminnot ovat vain JavaScriptin kohteita ja aivan kuten esineitä, voit siirtää niitä ympäri.

Voimme nimetä tämän uuden potkurin mille tahansa. Nimenin sen clickAction-arvoksi ja välitän sille lisäysnopeuden arvo, joka on viittaus CountManager-komponentissa määriteltyyn toimintoon. Voimme käyttää tätä uutta ohitettua käyttäytymistä suoraan onClick-käsittelijän arvona. Se on Button-komponentin rekrytointi:

const-painike = ({clickAction}) => {
  palata (
    <-painike onClick = {clickAction}>
      +1
    
  );
};
// ...
const CountManager = () => {
  // ...
  palata (
    
                     ); };

Jotain erittäin voimakasta tapahtuu täällä. Tämä clickAction-ominaisuus antoi Button-komponentille mahdollisuuden käynnistää CountManager-komponentin lisäyskeskuksen toiminto. Kuten napsautamme tätä painiketta, Button-komponentti tavoittaa CountManager-komponentin ja sanoo: "Hei vanhempi, mene eteenpäin ja vedota siihen lisäyslaskurin käyttäytymiseen nyt".

Todellisuudessa CountManager-komponentti on tässä hallinnassa ja Button-komponentti noudattaa vain yleisiä sääntöjä. Jos analysoit koodia sellaisena kuin se on nyt, huomaat, kuinka Button-komponentilla ei ole aavistustakaan siitä, mitä tapahtuu, kun sitä napsautetaan. Se noudattaa vain vanhemman määrittelemiä sääntöjä ja vetoaa yleiseen clickAction-toimintaan. Vanhempi hallitsee, mikä menee siihen yleiseen käyttäytymiseen. Tämä seuraa vastuullisuuden eristämisen käsitettä. Jokaisella komponentilla on tietyt vastuut ja he saavat keskittyä siihen.

Katso näyttökomponentista toinen esimerkki. Sen mielestä laskenta-arvo ei ole tila. Se on vain rekvisiitti, jonka CountManager-komponentti siirtyy siihen. Näyttökomponentti näyttää aina kyseisen tuen. Tämä on myös vastuunjako.

Näiden komponenttien suunnittelijana sinun on valittava heidän vastuutaso. Voisimme esimerkiksi olla vastuussa itse CountManager-komponentin laskenta-arvon osan näyttämisestä eikä käyttää siihen uutta näyttökomponenttia.

CountManager-komponentti on vastuussa laskentatilan hallinnasta. Tämä on tärkeä suunnittelupäätös, jonka teimme, ja se sinun on tehtävä paljon Reakt-sovelluksessa. Missä valtio määritellään?

Seuraamani käytäntö on määritellä tilaelementti jaetussa vanhemman solmussa, joka on mahdollisimman lähellä kaikkia lapsia, jotka tarvitsevat käyttää kyseistä tilaelementtiä. Pienessä tämänkaltaisessa sovelluksessa se tarkoittaa yleensä itse ylimmän tason komponenttia. Suuremmissa sovelluksissa osapuu voi hallita omaa tilahaaraaan sen sijaan, että luottaisi ylimmän tason juurikomponentissa määriteltyihin globaalitilaelementteihin.

Ylimmän tason komponenttia käytetään yleisesti jaetun sovelluksen tilan ja toimintojen hallintaan, koska se on emo kaikille muille komponenteille. Ole varovainen suunnittelussa, koska ylemmän tason komponentin tilaelementin päivittäminen tarkoittaa, että koko komponenttipuu renderoidaan uudelleen (muistiin).

Tässä on täydellinen koodi tähän esimerkkiin toistaiseksi:

// jsdrops.com/bx8
const-painike = ({clickAction}) => {
  palata (
    <-painike onClick = {clickAction}>
      +1
    
  );
};
const Näyttö = ({content}) => (
  
 {pitoisuus} 
);
const CountManager = () => {
  const [count, setCount] = useState (0);
  const IncrementCounter = () => {
    setCount (määrä + 1);
  };
  palata (
    
                     ); };

Komponenttien uudelleenkäyttö

Komponentit koskevat uudelleenkäyttöä. Tehdään Button-komponentti uudelleenkäytettäväksi muuttamalla sitä niin, että se voi kasvattaa globaalia määrää millä tahansa arvolla, ei vain yhdellä.

Aloitetaan lisäämällä lisää painikeelementtejä CountManager-komponenttiin, jotta voimme testata tätä uutta ominaisuutta:

const CountManager = () => {
  // ..
  palata (
    <>
       {/ * +1 * /}
       {/ * +5 * /}
       {/ * +10 * /}
      
    
  );
};

Kaikilla yllä esitetyillä nappielementeillä on tällä hetkellä +1-tarra ja ne kasvavat lukumäärällä yhdellä. Haluamme saada heidät näyttämään erilaisen tunnisteen, joka on erityinen kullekin painikkeelle, ja saada heidät suorittamaan erilainen toiminta tietyn arvon perusteella. jokaiselle heistä. Muista, että voit välittää minkä tahansa arvon React-elementille potkurina.

Tässä on mielessäni käyttöliittymä, kun olen napsauttanut kutakin painiketta kerran:

Yllä olevassa kuvakaappauksessa laskenta alkaa nollasta. Lisäsin yhden, sitten 5 ja sitten 10 päästäkseni 16: een

Ennen kuin suoritamme tämän harjoituksen, harkitse jonkin aikaa ja mieti sitä ja yritä toteuttaa se itse. Se on enimmäkseen suoraviivaista. Vihje: sinun on otettava käyttöön yksi uusi painike painikkeelle. Yritä. Palaa takaisin, kun olet valmis vertaamaan ratkaisuasi omaan.

Uusien rekvisiittien lisääminen

Ensimmäinen asia, joka meidän on tehtävä, on tehdä Button-komponentin +1-etiketistä muokattava.

Jotta jotain muokattavissa olevaa React-komponentissa, esittelemme uuden potentiaalin (jota vanhempi komponentti voi hallita) ja saamme komponentin käyttämään arvoaan. Esimerkkinämme voimme saada Button-komponentin vastaanottamaan määrän asteikolla (1, 5, 10) uutena potkurina. Nimeni sen clickValue. Voimme muuttaa renderöintimenetelmää CountManagerissa siirtääksemme haluamamme arvot tälle uudelle prop.

palata (
  <>
    
    
    
    
  
);

Huomaa muutama asia tästä koodista toistaiseksi:

  • En nimennyt uutta omaisuutta mistään laskentaan liittyvästä. Button-komponentin ei tarvitse olla tietoinen napsautustapahtumansa merkityksestä. Sen on vain läpäistävä tämä clickValue pitkin, kun sen napsautustapahtuma laukaistaan. Esimerkiksi tämän uuden ominaisuuden countValue-nimeäminen ei olisi paras valinta, koska nyt Button-komponentissa luemme koodin ymmärtääksemme, että Button-elementti liittyy määrään. Tämä tekee Button-komponentista vähemmän käyttökelpoista. Esimerkiksi, jos haluan käyttää samaa Button-komponenttia kirjeen lisäämiseen merkkijonoon, sen koodi olisi hämmentävä.
  • Käytin kiharasulkeita uuden clickValue-ominaisuuden (clickValue = {5}) arvojen välittämiseksi. En käyttänyt merkkijonoja siellä (clickValue = "5"). Koska minulla on matemaattinen toiminto näiden arvojen suhteen (joka kerta kun nappia napsautetaan), tarvitsen näiden arvojen olevan numeroita. Jos välitän ne merkkijonona, joudun suorittamaan jonkin verran merkkijono-numero-muuntamista, kun lisäysoperaatio on tarkoitus suorittaa.
Numeron siirtäminen merkkijonona on yleinen virhe Reaktissa. Tässä artikkelissa on lisää Reakt-aiheisiin liittyviä yleisiä virheitä.

Käyttäytymisen mukauttaminen

Toinen asia, joka meidän on tehtävä yleiseksi CountManager-komponentissa, on IncrementCounter-toiminto. Sillä ei voi olla koodattua laskenta + 1-operaatiota kuten nyt. Samanlainen kuin mitä teimme Button-komponentille, jotta funktiosta tehdään geneerinen, saamme sen vastaanottamaan argumentin ja käyttämään argumentin arvoa. Esimerkiksi:

IncrementCounter = (IncrementValue) => {
  setCount (määrä + lisäysarvo);
};

Nyt kaikki, mitä meidän on tehtävä, on saada Button-komponentti käyttämään clickValue-prop-merkintäänsä ja saada se käynnistämään onClick-toimintansa argumenttina clickValue-arvon kanssa.

const Button = ({clickValue, clickAction}) => {
  palata (
    <-painike onClick = {() => clickAction (clickValue)}>
      + {ClickValue}
    
  );
};

Huomaa, kuinka minun piti kääriä onClick-prop-linkki inline-nuolitoiminnolla, jotta se sidottu Buttonin clickValue-arvoon. Tämän uuden nuolitoiminnon JavaScript-sulkeminen hoitaa asian.

Kolmen painikkeen pitäisi nyt kasvaa kolmella eri napsautusarvolla. Voit nähdä tämän esimerkin koodin osoitteessa jsdrops.com/bx9.

Hyväksytään käyttäjän syötteet

Kuvittele, että meidän on laskettava käyttäjän kirjoittamat merkit tekstialueelle, kuten Twitterin twiittimuoto. Jokaisen käyttäjän kirjoittaman merkin kanssa meidän on päivitettävä käyttöliittymä uudella merkkimäärällä.

Tässä on komponentti, joka näyttää tekstialueen syöttöelementin ja merkkimäärän paikkamerkinnän div:

// jsdrops.com/bx10
const CharacterCounter = () => {
  palata (