When it comes to JSX, almost everyone knows that React plays an important role in describing the UI and associated rendering logic. Less well known is how JSX is compiled and turned into individual elements. This article will analyze the JSX compilation results to deepen the understanding of how JSX works in React

Prepare the JSX compilation environment

Three packages need to be installed (development dependencies)

  • @babel/cli
  • @babel/core
  • @babel/preset-react

After the installation, add the configuration file babelrc to the root directory.

{
  "presets": ["@babel/preset-react"]}Copy the code

JSX -w -o.\index. Js to compile index.jsx to index.js and enable the listening mode

Basic example

const h1 = <h1>this is a H1 Tag</h1>
Copy the code

Compiled by Babel:

const h1 = React.createElement("h1", null, "this is a H1 Tag");
Copy the code

As you can see, Babel parses the JSX and passes the DOM node associated data slice to the React. CreateElement method call.

The React. The createElement method were linked to a function called createElementWithValidation, there are three types of parameters:

  • Type: indicates the node type
  • Props: indicates the properties of a node
  • Children – Represents the children of a node (there may be multiple)
function createElementWithValidation(type, props, children) {
  / /...
  var element = createElement.apply(this.arguments);
  / /...
  return element;
}
Copy the code

The result is easy to understand: h1 is the type of the node, the attribute is null, and the child element is a text node :” This is an h1 Tag”.

So JSX will end up as an Element, which is essentially a javascript object.

JSX various embedded scenarios

We can pass the normal expression, JSX itself as a whole, to the Children or props property of the React.createElement

  • Expression as attribute value
var className = "div_class"
const div = <div class={'prefix_'+className} ></div>
Copy the code

Compile as follows:

var className = "div_class";
const div = React.createElement("div", {
  class: 'prefix_' + className
});
Copy the code
  • JSX nested JSX(as a child of another JSX)
const childJsx = <span>child span</span>
const parentJsx = <div>{childJsx}</div>
Copy the code

Compile as follows:

const childJsx = React.createElement("span".null."child span");
const parentJsx = React.createElement("div".null, childJsx);
Copy the code
  • The JSX outermost layer can contain only one node
JSX expressions must have one parent element
const multipleWrapper = <p>first p</p><p>second p</p>
Copy the code

Each JSX represents a tree node that can be used as a carrier or mounted to other tree nodes, and a tree node can have only one root.

  • Collocative logical operators
let condition = true;
const jsxExamp = <div>{condition && [1, 2, 3]. Join (" - ")}</div>
Copy the code

Compile as follows:

let condition = true;
const jsxExamp = React.createElement("div".null, condition && [1.2.3].join("-"));
Copy the code

Function, class component compilation

JSX literals can also be compiled inside a Class component, a function component, etc.

function FnComp(){
  return <div>A Function Component</div>
}
class ClassComp extends React.Component{
  render(){
    return <div>
      <h1>A Class Component</h1>
      <FnComp/>
    </div>}}Copy the code

Compiled as:

function FnComp() {
  return React.createElement("div".null."A Function Component");
}
class ClassComp extends React.Component {
  render() {
    return React.createElement("div".null, React.createElement("h1".null."A Class Component"), React.createElement(FnComp, null)); }}Copy the code

The last

JSX compilation errors are no longer a problem because Babel allows you to view the compilation results and analyze the cause of the errors.

To sum up:

JSX is precompiled and parsed by Babel, and then replaced with react. createElement, which creates reactElement sequences. These reactElement are essentially JavaScript objects that contain all of the node’s information and are subsequently rendered to a web page through a series of manipulations and scheduling.