官术网_书友最值得收藏!

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 a DOMElement.
  • 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:

  1. Add the following code to your ~/snapterest/source/app.js file:
    const reactElement = React.createElement('h1');
    ReactDOM.render(reactElement, document.getElementById('react-application'));
  2. 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')
    );
  3. 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
    
  4. Navigate to the ~/snapterest/build/ directory, and open index.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 the React.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.

主站蜘蛛池模板: 榆中县| 武穴市| 达拉特旗| 滨海县| 萨嘎县| 静乐县| 抚远县| 遂平县| 梁河县| 石门县| 萨嘎县| 嘉义县| 宝清县| 即墨市| 石首市| 宿州市| 海伦市| 朝阳市| 台安县| 来安县| 天峨县| 隆德县| 镇坪县| 鄂伦春自治旗| 北辰区| 综艺| 灵寿县| 峨边| 新乡市| 盈江县| 涟源市| 泸水县| 离岛区| 府谷县| 綦江县| 桂阳县| 黎城县| 含山县| 新营市| 东丽区| 青浦区|