Όλες οι βασικές έννοιες του React.js, μπλοκαρίστηκαν σε αυτό το άρθρο

Ενημέρωση: Αυτό το άρθρο είναι πλέον μέρος του βιβλίου μου "React.js Beyond The Basics". Διαβάστε την ενημερωμένη έκδοση αυτού του περιεχομένου και περισσότερα σχετικά με το React στη διεύθυνση jscomplete.com/react-beyond-basics .

Αυτό το άρθρο δεν πρόκειται να καλύψει τι είναι το React ή γιατί πρέπει να το μάθετε. Αντ 'αυτού, αυτή είναι μια πρακτική εισαγωγή στις βασικές αρχές του React.js για όσους είναι ήδη εξοικειωμένοι με το JavaScript και γνωρίζουν τα βασικά στοιχεία του API DOM.

Όλα τα παραδείγματα κώδικα παρακάτω επισημαίνονται για αναφορά. Προορίζονται αποκλειστικά για την παροχή παραδειγμάτων εννοιών. Τα περισσότερα από αυτά μπορούν να γραφτούν με πολύ καλύτερο τρόπο.

Θεμελιώδες # 1: Το React αφορά όλα τα συστατικά

Το React έχει σχεδιαστεί γύρω από την έννοια των επαναχρησιμοποιήσιμων εξαρτημάτων. Ορίζετε μικρά συστατικά και τα συνδυάζετε για να σχηματίσετε μεγαλύτερα συστατικά.

Όλα τα εξαρτήματα μικρά ή μεγάλα μπορούν να επαναχρησιμοποιηθούν, ακόμη και σε διαφορετικά έργα.

Ένα στοιχείο React - στην απλούστερη μορφή του - είναι μια απλή παλιά λειτουργία JavaScript:

// Example 1 // //jscomplete.com/repl?j=Sy3QAdKHW function Button (props) { // Returns a DOM element here. For example: return {props.label}; } // To render the Button component to the browser ReactDOM.render(, mountNode)

Τα σγουρά τιράντες που χρησιμοποιούνται για την ετικέτα κουμπιού εξηγούνται παρακάτω. Μην ανησυχείτε για αυτά τώρα. ReactDOMθα εξηγηθεί επίσης αργότερα, αλλά αν θέλετε να δοκιμάσετε αυτό το παράδειγμα και όλα τα επερχόμενα παραδείγματα κώδικα, η παραπάνω renderσυνάρτηση είναι αυτό που χρειάζεστε.

Το δεύτερο όρισμα ReactDOM.renderείναι το στοιχείο DOM προορισμού στο οποίο το React πρόκειται να αναλάβει και να ελέγξει. Στην παιδική χαρά jsComplete React, μπορείτε απλώς να χρησιμοποιήσετε την ειδική μεταβλητή mountNode.

REPL JavaScript και παιδική χαρά για React.js

Δοκιμάστε σύγχρονο κώδικα JavaScript και React.js στο πρόγραμμα περιήγησης χωρίς διαμορφώσεις jscomplete.com/react

Σημειώστε τα παρακάτω σχετικά με το Παράδειγμα 1:

  • Το όνομα του στοιχείου ξεκινά με κεφαλαίο γράμμα. Αυτό απαιτείται επειδή θα ασχολούμαστε με ένα συνδυασμό στοιχείων HTML και στοιχείων React. Τα πεζά ονόματα προορίζονται για στοιχεία HTML. Στην πραγματικότητα, προχωρήστε και προσπαθήστε να ονομάσετε το στοιχείο React απλώς "κουμπί" και δείτε πώς το ReactDOM θα αγνοήσει τη λειτουργία και αποδίδει ένα κανονικό κενό κουμπί HTML.
  • Κάθε στοιχείο λαμβάνει μια λίστα χαρακτηριστικών, όπως τα στοιχεία HTML. Στο React, αυτή η λίστα ονομάζεται στηρίγματα . Με ένα στοιχείο λειτουργίας, μπορείτε να το ονομάσετε οτιδήποτε.
  • Περιγράψαμε περίεργα πώς μοιάζει με HTML στην επιστρεφόμενη έξοδο του Buttonπαραπάνω στοιχείου συνάρτησης. Αυτό δεν είναι ούτε JavaScript ούτε HTML και δεν είναι καν React.js. Όμως, είναι τόσο δημοφιλές που έγινε η προεπιλογή στις εφαρμογές React. Ονομάζεται JSX και είναι μια επέκταση JavaScript. Το JSX είναι επίσης συμβιβασμός ! Προχωρήστε και δοκιμάστε να επιστρέψετε οποιοδήποτε άλλο στοιχείο HTML μέσα στην παραπάνω λειτουργία και δείτε πώς υποστηρίζονται όλα (για παράδειγμα, επιστρέψτε ένα στοιχείο εισαγωγής κειμένου).

Θεμελιώδες # 2: Ποια είναι η ροή JSX;

Το παραπάνω παράδειγμα 1 μπορεί να γραφτεί σε καθαρό React.js χωρίς JSX ως εξής:

// Example 2 - React component without JSX // //jscomplete.com/repl?j=HyiEwoYB- function Button (props) { return React.createElement( "button", { type: "submit" }, props.label ); } // To use Button, you would do something like ReactDOM.render( React.createElement(Button, { label: "Save" }), mountNode );

Η createElementσυνάρτηση είναι η κύρια συνάρτηση του React top-level API. Είναι 1 από τα 8 πράγματα σε αυτό το επίπεδο που πρέπει να μάθετε. Είναι τόσο μικρό το React API.

Όπως το ίδιο το DOM που έχει μια document.createElementσυνάρτηση για τη δημιουργία ενός στοιχείου που καθορίζεται από ένα όνομα ετικέτας, η createElementσυνάρτηση React είναι μια λειτουργία υψηλότερου επιπέδου που μπορεί να κάνει ό document.createElement, τι μπορεί, αλλά μπορεί επίσης να χρησιμοποιηθεί για τη δημιουργία ενός στοιχείου για την αναπαράσταση ενός στοιχείου React. Κάναμε το τελευταίο όταν χρησιμοποιήσαμε το Buttonστοιχείο στο Παράδειγμα 2 παραπάνω.

Αντίθετα document.createElement, το React createElementδέχεται έναν δυναμικό αριθμό επιχειρημάτων μετά το δεύτερο για να αντιπροσωπεύσει τα παιδιά του δημιουργημένου στοιχείου. createElementΔημιουργεί λοιπόν ένα δέντρο .

Ακολουθεί ένα παράδειγμα:

// Example 3 - React’s createElement API // //jscomplete.com/repl?j=r1GNoiFBb const InputForm = React.createElement( "form", { target: "_blank", action: "//google.com/search" }, React.createElement("div", null, "Enter input and click Search"), React.createElement("input", { name: "q", className: "input" }), React.createElement(Button, { label: "Search" }) ); // InputForm uses the Button component, so we need that too: function Button (props) { return React.createElement( "button", { type: "submit" }, props.label ); } // Then we can use InputForm directly with .render ReactDOM.render(InputForm, mountNode);

Σημειώστε μερικά πράγματα για το παραπάνω παράδειγμα:

  • InputFormδεν είναι ένα στοιχείο React? είναι απλώς ένα στοιχείο React . Γι 'αυτό το χρησιμοποιήσαμε απευθείας στην ReactDOM.renderκλήση και όχι με />.
  • The React.createElement function accepted multiple arguments after the first two. Its list of arguments starting from the 3rd one comprises the list of children for the created element.
  • We were able to nest React.createElement calls because it’s all JavaScript.
  • The second argument to React.createElement can be null or an empty object when no attributes or props are needed for the element.
  • We can mix HTML element with React elements.
  • React’s API tries to be as close to the DOM API as possible, that’s why we use className instead of class for the input element. Secretly, we all wish the React’s API would become part of the DOM API itself. Because, you know, it’s much much better.

The code above is what the browser understands when you include the React library. The browser does not deal with any JSX business. However, we humans like to see and work with HTML instead of these createElement calls (imagine building a website with just document.createElement, which you can!). This is why the JSX compromise exists. Instead of writing the form above with React.createElement calls, we can write it with a syntax very similar to HTML:

// Example 4 - JSX (compare with Example 3) // //jscomplete.com/repl?j=SJWy3otHW const InputForm = Enter input and click Search ; // InputForm "still" uses the Button component, so we need that too. // Either JSX or normal form would do function Button (props) { // Returns a DOM element here. For example: return {props.label}; } // Then we can use InputForm directly with .render ReactDOM.render(InputForm, mountNode);

Note a few things about the above:

  • It’s not HTML. For example, we’re still doing className instead of class.
  • We’re still considering what looks like HTML above as JavaScript. See how I added a semicolon at the end.

What we wrote above (Example 4) is JSX. Yet, what we took to the browser is the compiled version of it (Example 3). To make that happen, we need to use a pre-processor to convert the JSX version into the React.createElement version.

That is JSX. It’s a compromise that allows us to write our React components in a syntax similar to HTML, which is a pretty good deal.

The word “Flux” in the header above was chosen to rhyme, but it’s also the name of a very popular application architecture popularized by Facebook. The most famous implementation of which is Redux. Flux fits the React reactive pattern perfectly.

JSX, by the way, can be used on its own. It’s not a React-only thing.

Fundamental #3: You can use JavaScript expressions anywhere in JSX

Inside a JSX section, you can use any JavaScript expression within a pair of curly braces.

// To use it:ReactDOM.render(, mountNode);// Example 5 - Using JavaScript expressions in JSX // //jscomplete.com/repl?j=SkNN3oYSW const RandomValue = () => { Math.floor(Math.random() * 100) } ; // To use it: ReactDOM.render(, mountNode);

Any JavaScript expression can go inside those curly braces. This is equivalent to the ${} interpolation syntax in JavaScript template literals.

This is the only constraint inside JSX: only expressions. So, for example, you can’t use a regular if statement, but a ternary expression is ok.

JavaScript variables are also expressions, so when the component receives a list of props (the RandomValue component didn’t, props are optional), you can use these props inside curly braces. We did this in the Button component above (Example 1).

JavaScript objects are also expressions. Sometimes we use a JavaScript object inside curly braces, which makes it look like double curly braces, but it’s really just an object inside curly braces. One use case of that is to pass a CSS style object to the special style attribute in React:

// Example 6 - An object passed to the special React style prop // //jscomplete.com/repl?j=S1Kw2sFHb const ErrorDisplay = ({message}) => {message} ; // Use it: ReactDOM.render( , mountNode );

Note how I destructured only the message out of the props argument. Also note how the style attribute above is a special one (again, it’s not HTML, it’s closer to the DOM API). We use an object as the value of the style attribute. That object defines the styles as if we’re doing so with JavaScript (because we are).

You can even use a React element inside JSX, because that too is an expression. Remember, a React element is essentially a function call:

// Example 7 - Using a React element within {} // //jscomplete.com/repl?j=SkTLpjYr- const MaybeError = ({errorMessage}) => {errorMessage && } ; // The MaybeError component uses the ErrorDisplay component: const ErrorDisplay = ({message}) => {message} ; // Now we can use the MaybeError component: ReactDOM.render(  0.5 ? 'Not good' : ''} />, mountNode );

The MaybeError component above would only display the ErrorDisplay component if there is an errorMessage string passed to it and an empty div. React considers {true}, {false}, {undefined}, and {null} to be valid element children, which do not render anything.

You can also use all of JavaScript functional methods on collections (map, reduce, filter, concat, and so on) inside JSX. Again, because they return expressions:

// Example 8 - Using an array map inside {} // //jscomplete.com/repl?j=SJ29aiYH- const Doubler = ({value=[1, 2, 3]}) => {value.map(e => e * 2)} ; // Use it ReactDOM.render(, mountNode);

Note how I gave the value prop a default value above, because it’s all just Javascript. Note also that I outputted an array expression inside the div. React is okay with that; It will place every doubled value in a text node.

Fundamental #4: You can write React components with JavaScript classes

Simple function components are great for simple needs, but sometimes we need more. React supports creating components through the JavaScript class syntax as well. Here’s the Button component (in Example 1) written with the class syntax:

// Example 9 - Creating components using JavaScript classes // //jscomplete.com/repl?j=ryjk0iKHb class Button extends React.Component { render() { return {this.props.label}; } } // Use it (same syntax) ReactDOM.render(, mountNode);

The class syntax is simple. Define a class that extends React.Component (another top-level React API thing that you need to learn). The class defines a single instance function render(), and that render function returns the virtual DOM element. Every time we use the Button class-based component above (for example, by doing