Az első React.js komponens megírása

A React funkció- és osztálykomponensei, kellékei, állapota és eseménykezelői

Frissítés: Ez a cikk most a „React.js Beyond The Basics” című könyvem része. Olvassa el a tartalom frissített verzióját és többet a React-ról a jscomplete.com/react-beyond-basics címen .

A React.js-ben a legfontosabb megértendő fogalom az összetevő. A React komponens kétféle lehet. Ez lehet egy függvénykomponens vagy egy osztálykomponens . Néha különböző kifejezéseket fog hallani e két típus leírására, például hontalan és állam nélküli . A funkciókomponensek gyakran társulnak a prezentációs koncepcióval is. Ebben a cikkben funkciókomponensként és osztálykomponensként fogom őket hivatkozni.

A függvénykomponens a React komponens legegyszerűbb formája. Ez egy egyszerű funkció, egyszerű szerződéssel:

A függvénykomponens olyan tulajdonságú objektumot kap, amelyet általában kellékeknek neveznek . Visszaadja azt, ami HTML-nek tűnik, de valójában egy speciális JavaScript-szintaxis, amelyet JSX-nek hívnak.

Az osztálykomponens a React komponens definiálásának egyik kiemelt módja. Úgy is működik, mint egy függvény, amely fogadja a kellékeket, de ez a funkció egy privát belső állapotot is további bemenetnek tekint, amely vezérli a visszaküldött JSX-t.

Ez a belső belső állapot adja a React-nak reaktív jellegét. Amikor egy osztályösszetevő állapota megváltozik, a React újra megjeleníti az összetevőt a böngészőben.

Az State és a Prop objektumoknak egyetlen fontos különbségük van. Egy osztálykomponensen belül az State objektum megváltoztatható, míg a Props objektum fix értékeket képvisel. Az osztálykomponensek csak a belső állapotukat változtathatják meg, a tulajdonságait nem. Ez egy alapvető gondolat, amelyet meg kell érteni a React-ben, és ebben a cikkben lesz erre példa.

Nézzünk meg egy komponens tényleges példáját. Egy nagyon egyszerű, anélkül, hogy bemeneti és egy egyszerű h1, egy divkimenettel.

A bal oldalon az összetevő be van írva a speciális JSX szintaxisba.

A JSX lehetővé teszi számunkra a felhasználói interfészek (UI) leírását olyan szintaxisban, amely nagyon közel van a megszokott HTML-hez. Ez azonban nem kötelező. A React JSX nélkül is használható, amint az a jobb oldalon látható. Valójában a React csak a bal oldalon látható JSX-et fordítja le a jobb oldali JavaScript-hez. Ezután lefordított JavaScript-sel működik a böngészőben.

A React.createElementjobb oldali hívás a Document Object Model (DOM) JavaScript ábrázolása. A React hatékonyan lefordítja a böngészőben végrehajtott DOM-műveletekké.

Írjunk egy React komponenst.

A cikk példáihoz a jsComplete React Playground-ját fogom használni. Ez egy olyan eszköz, ahol közvetlenül a böngészőben tesztelheti a JavaScript-et és a React kódot. Semmit sem kell telepíteni vagy konfigurálni.

Az eszköznek egyszerű kétpaneles felülete van. A bal oldali panel a szerkesztő, ahová beírja a JavaScript és a React kódot. A React és a ReactDOM legújabb verziója már előre van feltöltve. A szerkesztő megérti a JSX kiterjesztést és a JavaScript összes modern funkcióját is. Ez lehetővé teszi számunkra, hogy magára a React API-ra koncentráljunk, ahelyett, hogy konfigurálnánk és összeállítanánk a React alkalmazást.

A jobb oldali panel az előnézeti panel. Van egy előre definiált mountNodeeleme a szerkesztőben. Amikor végrehajtja a JavaScript-kódját, az mountNodeelembe helyezett bármi megjelenik az előnézeti panelen. Az előnézeti panel megjeleníti azokat a hibákat is, amelyekkel találkozik, amikor végrehajtja a kódot. A játszótér egyben egy egyszerű JavaScript REPL (Run, Eval, Print, Loop) is, ahol tesztelheted a gyors JavaScript funkciókat és kifejezéseket. A kód bármikor végrehajtásához nyomja meg a gombot CTRL+Enter.

Próbálja ki például a következőt a REPL-ben:

mountNode.innerHTML = 'Hello!!';

Vagy az egyszerű REPL mód

3 == '3'

React komponens létrehozásához adjon meg egy új függvényt. Tegyük vissza, hogy a függvény egy HTML gomb elemet adjon vissza:

function Button() { return ( Go );}

Amit itt visszaadtunk, úgy néz ki, mint a HTML, de ne feledje, hogy nem az. JavaScript-be fogják fordítani. A tényleges JavaScript, amelyet a böngésző lát, amikor ezt a gombelemet használjuk a JSX-ben, a React.createElement függvény hívása :

function Button() { return ( React.createElement("button", null, "Go") );}

Bár a React-ot így is használhatja JSX nélkül, sokkal nehezebb kódolni és karbantartani. Tehát maradjunk a JSX-nél.

A fenti funkció egy teljes és nagyon egyszerű React komponens. Használjuk!

Egy komponenst úgy használunk, hogy a böngészőbe illesztjük. Az erre tervezett funkció ReactDOM.renderkét argumentumot tartalmaz:

  • Az első a megjelenítendő komponens, esetünkben az Button.
  • A második érv az az elem, amelyben ezt az összetevőt meg kell jeleníteni. A REPL környezetében használhatjuk a speciális mountNodeváltozót.
ReactDOM.render(, mountNode);

A cikkben található összes kódpéldányhoz tartozik egy link a képernyőkép feliratában, ahol a példát szerkesztheti a jsComplete REPL oldalon.

A React függvénykomponens első argumentumként megkapja az propsobjektumot. Ez az érv lehetővé teszi számunkra, hogy az alkatrészt újrafelhasználhatóvá tegyük. Például a fenti gomb „Go” címkéjének kemény kódolása helyett átadhatjuk az Buttonösszetevőnek egy labelattribútumot, mint a szokásos HTML elemeknél:

ReactDOM.render(, mountNode);

Ezután egy göndör zárójel segítségével elérhetjük ezt az attribútumot az összetevő belsejében props.label.

function Button(props) { return ( {props.label} );}

Az propsargumentum egy olyan objektum, amely tartalmazza az összes értéket, amelyet a komponensnek továbbítottak annak megjelenítésekor.

Az alkatrész interaktívvá tétele

Van egy gombelemünk, és a React komponensen keresztül jelenik meg.

Adjunk most némi interaktivitást ehhez az eddig unalmas példához. Tegyük meg, hogy ez a gombelem minden kattintásnál számláló értéket növeljen, és ezt az értéket jelenítsük meg a gomb címkéjeként. Tehát ennek a gombnak a címkéje az 1-es számmal kezdődik, és amikor a felhasználó rákattint a gombra, a címkéje 2, 3, 4 és így tovább változik.

Mivel ezt tükröznie kell a komponens renderelt kimenetében, ez a komponens állapotához tartozik. Szükségünk van arra, hogy az összetevő minden alkalommal újra megjelenjen, amikor a számláló megváltozik. Itt nem használhatunk tulajdonságot, mert az alkatrész kellékei nem módosíthatók. Segítségével speciális reagál objektum, mi lesz felhasználva reagálnak a reaktív jellegű, és akkor nem kell aggódnia , hogy hogyan , hogy a változások a böngészőt. React ezt megteszi helyettünk.

De a Gomb komponensünk jelenleg egy funkciókomponens. A funkciókomponenseknek nem lehet állapotuk, ezért először ezt az összetevőt osztálykomponensre kell frissítenünk.

Ez nagyon egyszerű. Először meghatározunk egy kiterjedő osztálytReact.Component

class Button extends React.Component { }

Ebben az osztályban meghatározunk egy renderfüggvényt, amely visszaadja az összetevő JSX-jét; a HTML gomb esetünkben.

render() { return ( 1 );}

Ez egy kicsit több kód, de most már használhatunk privát állapotot a Button komponensen!

Egy állapotobjektum használatához először inicializálnunk kell. Az állapotobjektum egy egyszerű példánytulajdonság, ezért inicializálhatjuk az Buttonosztály konstruktor funkciójában . Csak meghatározzuk a normál konstruktor függvényt (amely propsobjektumot fogad a React-ben), és meghívjuk a supermetódust az összetevő öröklődésének tiszteletben tartására.

constructor(props) { super(props); this.state = { counter: 1 };}

After that, we initialize this.state to whatever we want. The keys of this state object are the various elements of the state. For our case, we need a counter state, which starts from 1.

Inside the render function, since we can write any JavaScript expression within curly brackets, we can read the value of the new counter state element that we initialized on the state using this.state.counter.

render() { return ( {this.state.counter} );}

The “this” keyword refers to the component instance we are handing off to ReactDOM.

You can try and change that counter state to see how the button will render the values you put on the state.

There is another shorter syntax to define the initial state, which is to simply use a class property without a constructor call:

class Button extends React.Component { state = { counter: 1 }; render() { return ( {this.state.counter} ); }}

This is not yet part of the official JavaScript language but it will be soon. The syntax works at the jsComplele REPL playground because that tool is using Babel to transpile it to the supported JavaScript that the browser will understand.

When you configure your own React application you’ll have to use something like Babel anyway to compile JSX into JavaScript. It is an easy win to also include and use the JavaScript features that are well on their way to becoming an official part of the language.

In the Button example so far, we have a state object and an HTML button element that displays a counter value that we initialized on the state. Now we need to change that value when we click the button. We need to define a click handler on that button.

React comes with normalized events that are easy to use. For this case, we need the onClick event, which we define on the HTML button element itself:

function F() {}

Unlike DOM event handlers, which use a string, React event handlers use an actual JavaScript function. This function can be a global one (like F above), or an inline function:

 {}} />

However, the standard practice is to define a function on the class component itself. Let’s call it handleClick and we can define it on the component as an instance property:

class Button extends React.Component { state = { counter: 1 }; handleClick = () => { console.log('Button is clicked!!'); }; render() { return (  {this.state.counter}  ); }}

We are using the modern class field syntax, which allows us to use arrow functions that are bound to the component instance. handleClick will now act as a prototype function on this class. Inside handleClick the keyword “this” refers to the component instance that we are mounting in the DOM.

handleClick ’s job is easy: read the current counter value from the state object using this.state.counter. Then increment this value and update the component state with the new incremented value.

We can use React’s built-in setState method, which is available on every class component instance, to update a component state.

The button will now increment its label on every click.

This was simple and powerful! We defined an event handler for the onClick method. Every time the user clicks the button the handleClick function will be executed. The function reads the current state of the counter value, increments it, and then sets the state to the new incremented value. React takes care of all the rendering needed after these changes so you do not have to worry about that.

Note that we did not update the state object directly. We have to use React’s setState method when we want to update any element on the state. You can’t for example do this:

// WRONG:this.state.counter = this.state.counter + 1;

React’s setState method is an asynchronous one which schedules an update. Multiple setState calls might potentially be batched for performance. Since we are both reading and writing to the state object inside the handleClick function, we could hit a race condition. The general rule of thumb is whenever you need to update the state using a value from the current state, use the other contract of the setState method. This receives a function reference instead of an object as its first argument:

this.setState((prevState) => {});

Ez a funkció olyan prevStateobjektumot kap , amelyet magabiztosan használhatunk, anélkül, hogy aggódnánk a versenykörülmények miatt. A függvény visszaadja azt az objektumot, amelyet a React használatával szeretnénk használni az állapot beállításához. A counterfenti értékpélda:

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

Csak akkor kell ezt a második szintaxist használni, setStateha a frissítés az aktuális állapottól függ. Jó ötlet lehet azonban megszokni, hogy mindig a második függvény-argumentum szintaxist használja.

Itt van a végső kód:

class Button extends React.Component { state = { counter: 1 }; handleClick = () => { this.setState((prevState) => ({ counter: prevState.counter + 1 })); }; render() { return (  {this.state.counter}  ); }}
ReactDOM.render(, mountNode);

Próbáld ki, és ha kérdésed van, tudasd velem az alábbi megjegyzéseket.

Ez a cikk a Pluralsight tanfolyamom - React.js: Kezdő lépések - egy része. Én hasonló tartalmat fedek le videó formátumban ott.

A React vagy a Node tanulása? Pénztárak:

  • Ismerje meg a React.js-t az Épület játékok segítségével
  • Node.js Az alapokon túl