- React 16 Essentials(Second Edition)
- Artemij Fedosejev Adam Boduch
- 1463字
- 2021-07-02 22:25:21
Creating React elements with JavaScript
We'll start by familiarizing ourselves with fundamental React terminology. It will help us build a clear picture of what the React library is made of. This terminology will most likely update over time, so keep an eye on the official documentation at https://facebook.github.io/react/docs/react-api.html.
Just like the DOM is a tree of nodes, React's virtual DOM is a tree of React nodes. One of the core types in React is called ReactNode
. It's a building block for a virtual DOM and it can be any one of these core types:
ReactElement
: This is the primary type in React. It's a light, stateless, immutable, virtual representation of aDOMElement
.ReactText
: This is a string or a number. It represents textual content and it's a virtual representation of a text node in the DOM.
ReactElement
and ReactText
are ReactNode
. An array of ReactNode
is called a ReactFragment
. You will see examples of all of these in this chapter.
Let's start with an example of ReactElement
:
- Add the following code to your
~/snapterest/source/app.js
file:const reactElement = React.createElement('h1'); ReactDOM.render(reactElement, document.getElementById('react-application'));
- Now your
app.js
file should look exactly like this:import React from 'react'; import ReactDOM from 'react-dom'; const reactElement = React.createElement('h1'); ReactDOM.render( reactElement, document.getElementById('react-application') );
- Navigate to the
~/snapterest/
directory and run this command:npm start
You will see the following output:
Hash: 826f512cf95a44d01d39 Version: webpack 3.8.1 Time: 1851ms
- Navigate to the
~/snapterest/build/
directory, and openindex.html
in a web browser. You will see a blank web page. Open Developer tools in your web browser and inspect the HTML markup for your blank web page. You should see this line, among others:<h1 data-reactroot></h1>
Well done! We've just rendered your first React element. Let's see exactly how we did it.
The entry point to the React library is the React
object. This object has a method called createElement()
that takes three parameters: type
, props
, and children
:
React.createElement(type, props, children);
Let's take a look at each parameter in more detail.
The type parameter
The type
parameter can be either a string or ReactClass
:
- A string could be an HTML tag name, such as
'p'
,'p'
, and'h1'
. React supports all the common HTML tags and attributes. For a complete list of HTML tags and attributes supported by React, you can refer to https://facebook.github.io/react/docs/dom-elements.html. - A
ReactClass
class is created via theReact.createClass()
method. I'll introduce this in more detail in Chapter 4, Creating Your First React Component.
The type
argument describes how an HTML tag or a ReactClass
class is going to be rendered. In our example, we're rendering the h1
HTML tag.
The props parameter
The props
parameter is a JavaScript object passed from a parent element to a child element (and not the other way around) with some properties that are considered immutable, that is, those that should not be changed.
While creating DOM elements with React, we can pass the props
object with properties that represent the HTML attributes such as class
and style
. For example, run the following code:
import React from 'react'; import ReactDOM from 'react-dom'; const reactElement = React.createElement( 'h1', { className: 'header' } ); ReactDOM.render( reactElement, document.getElementById('react-application') );
The preceding code will create an h1
HTML element with a class
attribute set to header
:
<h1 data-reactroot class="header"></h1>
Notice that we name our property className
rather than class
. The reason for this is that the class
keyword is reserved in JavaScript. If you use class
as a property name, it will be ignored by React, and a helpful warning message will be printed on the web browser's console:
Warning: Unknown DOM property class. Did you mean className?
Use className instead.
You might be wondering what this data-reactroot
attribute is doing in our h1
tag? We didn't pass it to our props
object, so where did it come from? It is added and used by React to track the DOM nodes.
The children parameter
The children
parameter describes what child elements this html element should have, if any. A child element can be any type of ReactNode
: a virtual DOM element represented by ReactElement
, a string or a number represented by ReactText
, or an array of other ReactNode
nodes, which is also called ReactFragment
.
Let's take a look at this example:
import React from 'react'; import ReactDOM from 'react-dom'; const reactElement = React.createElement( 'h1', { className: 'header' }, 'This is React' ); ReactDOM.render( reactElement, document.getElementById('react-application') );
The preceding code will create an h1
HTML element with a class
attribute and a text node, This is React
:
<h1 data-reactroot class="header">This is React</h1>
The h1
tag is represented by ReactElement
, while the This is React
string is represented by ReactText
.
Next, let's create a React element with a number of other React elements as its children:
import React from 'react'; import ReactDOM from 'react-dom'; const h1 = React.createElement( 'h1', { className: 'header', key: 'header' }, 'This is React' ); const p = React.createElement( 'p', { className: 'content', key: 'content' }, 'And that is how it works.' ); const reactFragment = [ h1, p ]; const section = React.createElement( 'section', { className: 'container' }, reactFragment ); ReactDOM.render( section, document.getElementById('react-application') );
We've created three React elements: h1
, p
, and section
. The h1
and p
both have child text nodes, 'This is React'
and 'And that is how it works.'
, respectively. The section
tag has a child that is an array of two ReactElement
types, h1
and p
, called reactFragment
. This is also an array of ReactNode
. Each ReactElement
type in the reactFragment
array must have a key
property that helps React to identify that ReactElement
type. As a result, we get the following HTML markup:
<section data-reactroot class="container"> <h1 class="header">This is React</h1> <p class="content">And that is how it works.</p> </section>
Now we understand how to create React elements. What if we want to create a number of React elements of the same type? Does it mean that we need to call React.createElement('type')
over and over again for each element of the same type? We can, but we don't need to because React provides us with a factory function called React.createFactory()
. A factory function is a function that creates other functions. This is exactly what React.createFactory(type)
does: it creates a function that produces ReactElement
of a given type.
Consider the following example:
import React from 'react'; import ReactDOM from 'react-dom'; const listItemElement1 = React.createElement( 'li', { className: 'item-1', key: 'item-1' }, 'Item 1' ); const listItemElement2 = React.createElement( 'li', { className: 'item-2', key: 'item-2' }, 'Item 2' ); const listItemElement3 = React.createElement( 'li', { className: 'item-3', key: 'item-3' }, 'Item 3' ); const reactFragment = [ listItemElement1, listItemElement2, listItemElement3 ]; const listOfItems = React.createElement( 'ul', { className: 'list-of-items' }, reactFragment ); ReactDOM.render( listOfItems, document.getElementById('react-application') );
The preceding example produces this HTML:
<ul data-reactroot class="list-of-items"> <li class="item-1">Item 1</li> <li class="item-2">Item 2</li> <li class="item-3">Item 3</li> </ul>
We can simplify it by first creating a factory function:
import React from 'react'; import ReactDOM from 'react-dom'; const createListItemElement = React.createFactory('li'); const listItemElement1 = createListItemElement( { className: 'item-1', key: 'item-1' }, 'Item 1' ); const listItemElement2 = createListItemElement( { className: 'item-2', key: 'item-2' }, 'Item 2' ); const listItemElement3 = createListItemElement( { className: 'item-3', key: 'item-3' }, 'Item 3' ); const reactFragment = [ listItemElement1, listItemElement2, listItemElement3 ]; const listOfItems = React.createElement( 'ul', { className: 'list-of-items' }, reactFragment ); ReactDOM.render( listOfItems, document.getElementById('react-application') );
In the preceding example, we're first calling the React.createFactory()
function and passing a li
HTML tag name as a type parameter. Then, the React.createFactory()
function returns a new function that we can use as a convenient shorthand to create elements of the li
type. We store a reference to this function in a variable called createListItemElement
. Then, we call this function three times, and each time we only pass the props
and children
parameters, which are unique for each element. Notice that React.createElement()
and React.createFactory()
both expect an HTML tag name string (such as li
) or the ReactClass
object as a type parameter.
React provides us with a number of built-in factory functions to create common HTML tags. You can call them from the React.DOM
object; for example, React.DOM.ul()
, React.DOM.li()
, and React.DOM.p()
. Using them, we can simplify our previous example even further:
import React from 'react'; import ReactDOM from 'react-dom'; const listItemElement1 = React.DOM.li( { className: 'item-1', key: 'item-1' }, 'Item 1' ); const listItemElement2 = React.DOM.li( { className: 'item-2', key: 'item-2' }, 'Item 2' ); const listItemElement3 = React.DOM.li( { className: 'item-3', key: 'item-3' }, 'Item 3' ); const reactFragment = [ listItemElement1, listItemElement2, listItemElement3 ]; const listOfItems = React.DOM.ul( { className: 'list-of-items' }, reactFragment ); ReactDOM.render( listOfItems, document.getElementById('react-application') );
Now, we know how to create a tree of ReactNode
. However, there is one important line of code that we need to discuss before we can progress further:
ReactDOM.render( listOfItems, document.getElementById('react-application') );
As you might have already guessed, it renders our ReactNode
tree to the DOM. Let's take a closer look at how it works.
- 案例式C語言程序設計
- 圖解Java數據結構與算法(微課視頻版)
- Windows系統管理與服務配置
- HTML5 Mobile Development Cookbook
- Cassandra Data Modeling and Analysis
- Visual C#.NET程序設計
- Jenkins Continuous Integration Cookbook(Second Edition)
- Windows內核編程
- NoSQL數據庫原理
- 一步一步學Spring Boot:微服務項目實戰(第2版)
- React and React Native
- 高質量程序設計指南:C++/C語言
- Eclipse開發(學習筆記)
- 現代JavaScript編程:經典范例與實踐技巧
- Mastering PostgreSQL 11(Second Edition)