JSX conversion

<div id="app"></div>
<div id="app1"></div>

<script type="text/babel">
    const msg1 = <h2>Hello React</h2>
    {/* The JSX syntax is not directly recognized by the browser. Instead, use Babel to convert JSX to React. CreateElement for the browser to parse and call */}
    const msg2 = React.createElement('h2'.null.'Hello React')

    ReactDOM.render(msg1, document.getElementById('app'))
    ReactDOM.render(msg2, document.getElementById('app1'))
</script>
Copy the code
/* @param1: type: specifies the current ReactElement type. If it is a tag element, use the string "div". If it is a component element, use the component name app@param2: Config All properties in JSX are stored in config as properties and values of objects @param3: children The contents of the tag (child components) are stored as an array of children; * /
React.createElement(type, config, children)
Copy the code

useBabel’s official websiteconvert

Before conversion -- JSX

<main>
    <header className="header">I am a head</header>
    <section className="section">
        <div>I am content</div>
        <button>I am a button</button>
    </section>
    <footer className="footer">I am a footer</footer>
</main>
Copy the code

After conversion -- react. createElement

"use strict";

/*#__PURE__*/
React.createElement("main".null./*#__PURE__*/React.createElement("header", {
  className: "header"
}, "\u6211\u662F\u5934\u90E8"), /*#__PURE__*/React.createElement("section", {
  className: "section"
}, /*#__PURE__*/React.createElement("div".null."\u6211\u662Fcontent"), /*#__PURE__*/React.createElement("button".null."\u6211\u662F\u6309\u94AE")), /*#__PURE__*/React.createElement("footer", {
  className: "footer"
}, "\u6211\u662Ffooter"));
Copy the code

The following points can be seen from the above transformation:

  1. When JSX code is transformed using Babel, strict mode is turned on

  2. The above code is eventually converted to something like react. createElement(type, config, child1, child2, child3….) In the form of

    Each child will continue to be converted following the React. CreateElement form

    1. In each oneReact.createElementEach function is preceded by one/*__PURE__*/; Represents the start of a transformed component

CreateElement (type, config, child1, child2, child3….)

React createElement(type, config, children)

It does not use extension parameters, so how does it get all the child components?

React uses arguments internally. React defines and uses arguments as follows

1.1 ReactElement

When we call the react. createElement method to create the object, it returns an object of type ReactElement

It contains information about the type, properties, and subcomponents of the current component

So objects of type ReactElement are what we call virtual DOM

React uses ReactElement objects to form a JavaScript object tree

All DOM operations will be performed on the VDOM tree, and the tree will be rendered as a real DOM

1.2 Dom rendering process in React

  1. Use the react. createElement method to create a ReactElement object.

  2. Map the VDOM to the real DOM

    A VDOM is just a DOM tree that exists in memory, so every node on it is mapped to the real DOM

1.3 Why use VDOM

Before VDOM

  1. You need to manipulate the DOM manually, you need to consider browser compatibility, and so on, and Jquery comes along

  2. Libraries like JQuery simplify DOM manipulation and don’t have to worry about browser compatibility,

  3. As front-end projects became more complex, dom manipulation became more complex, and we had to think about manipulating data as well as dom, which is where the template engine came in

    But the template engine did not solve the problem of tracking state changes, is when the data changes, unable to get the previous state, had to put on the interface elements to delete, and then recreated, jquery wrote a list, when new delete order, add a transition effect, operation list will be deleted first, and then rebuilding, cost performance. The template engine didn’t solve the problem of tracking state changes, so there was an MVVM framework based on the virtual DOM

  4. The VDOM-based MVVM framework helps us solve the synchronization problem of viewable and state. So you update the view automatically when the data changes, you update the view automatically when the data changes.

    For example, in React, we just need to use JSX to tell React what the interface should look like and what the data is. React will automatically render for us. We don’t need to do any DOM manipulation

    If the data changes, we only need to use setState to tell the React interface that it needs to be modified. It will automatically modify the interface without DOM manipulation

Reasons to use VDOM:

  1. It is difficult to keep track of state changes:With the old development model, it's hard to track state changes, it is not convenient to debug our application;
  2. Low performance for manipulating the real DOM: Traditional development models tend to do a lot of DOM manipulation, which is very low performance;
    1. document.createElementIt creates a verycomplextheobject
    2. Frequent DOM manipulation results in pages that need to be paged frequentlyredrawandbackflowoperation
    3. VDOM is inmemoryIn theThe batch operationThe running time and efficiency are relatively high
    4. Updates in VDOM are usedThe diff algorithmTo update the DOM in the most efficient way possible
    5. The virtual DOM helps us move from imperative programming to declarative programming

For example:

For example, we have an array to render: [1, 2, 3, 4,5]

Now change to [1, 2, 3, 4, 5, 6, 7, 8, 9,10]

Method 1: Iterate through the entire array (not recommended)

Method 2: Add another 5 Li to ul

What about the performance of the above code? Very inefficient.

  • Because we create the element through document.createElement and render it to the DOM through ul.appendChild(li), we do a lot of DOM manipulation;

  • For batch operations, the best approach is not to modify the DOM again and again, but to merge the batch operations; (for example, merge with A DocumentFragment);

We can use Virtual DOM to help us solve the above problems.

1.4 VDOM helps us move from imperative to declarative programming

React: The Virtual DOM is a programming concept.

  • In this concept, the UI is stored in an idealized or virtual waymemoryIn, and it’s aRelatively simple JavaScript objects
  • We can get throughReactDOM.renderletVirtual DOMReal DOMSyncing up, this process is calledcoordinate(Reconciliation);
  • This way of programming givesReact declarative API:
    • You just tell React what state you want the UI to be;
    • React to ensure that the DOM matches those states; You don’t need to do DOM manipulation directly, freeing yourself from manually changing the DOM, manipulating properties, and handling events;

Ii. React Phase cases

Requirements:

  1. Render some data in the form of a table on the interface
  2. The total price of the table is displayed at the bottom
  3. Click the + or – sign to show the purchase quantity and modify the total price in real time
  4. If the purchase quantity is zero, it cannot be subtracted again, and the interaction of the – button becomes immutable
  5. When you click the Remove button, the row is removed and the total price changes accordingly
  6. If all Data in the list is removed, No Data is displayed on the page
<! DOCTYPEhtml>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
  <title>Document</title>
  <style>
    table {
      border: 1px solid # 333;
      /* This is an array-specific style that folds the borders of the table */
      border-collapse: collapse;
      width: 80%;
    }

    th {
      background-color: #eee;
    }

    th.td {
      border: 1px solid # 333;
      text-align: center;
    }

    .count {
      margin: 0 10px;
    }
  </style>
</head>

<body>
  <div id="app"></div>

  <script src="./dist/react.development.js"></script>
  <script src="./dist/react-dom.development.js"></script>
  <script src="./dist/babel.min.js"></script>

  <script type="text/babel">
    class App extends React.Component{
        constructor() {
          super(a)this.state = {
            books: [{id: 1.title: 'Introduction to Algorithms'.date: 'the 2006-09'.price: 85.count: 1
              },

              {
                id: 2.title: 'UNIX Programming Art'.date: 'the 2006-02'.price: 59.count: 1
              },

              {
                id: 3.title: 'Programming Abas'.date: 'the 2008-10'.price: 39.count: 1
              },

              {
                id: 4.title: 'Complete Code'.date: 'the 2006-03'.price: 128.count: 1}}}]// The render function is written before the render function

        /* Render table */ when data is present
        renderTable() {
          const { books } = this.state

          return (
            <div>
              <table>
                <thead>
                  <tr>
                    <th> </th>
                    <th>The name of the books</th>
                    <th>Date of publication</th>
                    <th>The price</th>
                    <th>Purchase quantity</th>
                    <th>operation</th>
                  </tr>
                </thead>

                <tbody>
                  {
                    books.map((item, index) => (
                        <tr>
                          <td>{ item.id }</td>
                          <td>{ item.title }</td>
                          <td>{ item.date }</td>
                          <td>{ this.formatPrice(item.price) }</td>
                          <td>
                            <button disabled={item.count< =0} onClick={() = > this.changeCount(index, -1) }> - </button>
                            <span className="count">{ item.count }</span>{/* Callback in the event needs to use the arrow function to correct this pointing to */}<button onClick={()= >  this.changeCount(index, 1) }> + </button>
                          </td>
                          <td>
                            <button onClick={() = >This. Remove (item id)} > removed</button>
                          </td>
                        </tr>))}</tbody>
              </table>
              <p>TotalPrice: <strong> { this.formatPrice(this.getTotalPrice()) } </strong></p>
            </div>)}render() {
          return (
            <div>{this.state.books.length > 0? this.renderTable() :<h4>Not Data</h4> }
            </div>)}// The functional function is written after the render function
        remove(id) {
          // Note: One of the most important concepts in React is not to directly modify data in state
          // So instead of using splice to modify the books data, we use the filter function to return a new array
          this.setState({
            books: this.state.books.filter(item= >item.id ! = id) }) }changeCount(index, v) {
          // Based on the immutable nature of data in State
          // There is a shallow copy of the new array. Operations on the new array do not directly modify the original array state
          const newBooks = [... this.state.books]
          newBooks[index].count += v

          // Use the new array address to override the old array address
          this.setState({
            books: newBooks
          })
        }

        formatPrice(price) {
          // parseFloat converts strings that can be converted to numbers (because only numeric values have toFixed methods)
          / / use A | | 0 role is assigned A default value
          // If price cannot be converted to a number (for example, 'aaa') then the return value of the parseFloat call is NaN
          // To avoid this, we need to give it a default value of 0
          return '$' + (parseFloat(price) || 0).toFixed(2)}getTotalPrice() {
          return this.state.books.reduce((preV, item) = > preV + item.price * item.count, 0)
        }
      }

      ReactDOM.render(<App />.document.getElementById('app'))
  </script>
</body>

</html>
Copy the code

React Scaffolding JSX: React scaffolding JSX: React scaffolding