This article is excerpted from React Technology Debunked

JSX, as a data structure that describes component content, gives JS more visual expression. We use it a lot in React. Before diving into the source code, there are a few questions we need to address:

  • JSXIs it the same thing as the virtual DOM?
  • React Component,React ElementIs it the same thing? They’re the same thingJSXWhat does it matter?

With these questions in mind, let’s begin this section.

JSX profile

As a React user, you’ve already worked with JSX. If you don’t know him, check out his description on the official website.

JSX is compiled by Babel as a react. createElement method.

JSX Compiles Demo for the Internet

JSX Compiles Demo Intranet

Is that why you have to declare it explicitly in every JS file that uses JSX

import React from 'react';
Copy the code

Otherwise, the module will fail to define the React variable at runtime.

JSX is not only compiled as a react. createElement method, You can use the @babel/plugin-transform-react-jsx plugin to explicitly tell Babel why JSX needs to be compiled (default: react.createElement).

For example, in the Preact class React library, JSX is compiled into a function call called h.

/ / before compilation
<p>KaSong</p>
// compiledh("p", null, "KaSong");
Copy the code

React.createElement

Since JSX will compile to react. createElement, let’s see what it does:

export function createElement(type, config, children) {
  let propName;

  const props = {};

 let key = null;  let ref = null;  let self = null;  let source = null;   if(config ! =null) {  // assign the config to props  / /... omit  }   const childrenLength = arguments.length - 2;  // Handle children, which is assigned to props. Children  / /... omit   / / defaultProps processing  / /... omit   return ReactElement(  type,  key,  ref,  self,  source,  ReactCurrentOwner.current,  props,  ); }  const ReactElement = function(type, key, ref, self, source, owner, props) {  const element = {  // mark this as a React Element  $typeof: REACT_ELEMENT_TYPE,   type: type,  key: key,  ref: ref,  props: props,  _owner: owner,  };   return element; }; Copy the code

As you can see, the react. createElement method will eventually call the ReactElement method and return an object containing the component’s data that takes one argument. Okay? Typeof: REACT_ELEMENT_TYPE marks the object as a React Element.

So does the React Element call return the React Element?

React provides a global API to validate valid React elements. React. IsValidElement.

export function isValidElement(object) {
  return (
    typeof object === 'object' &&
object ! = =null &&
    object.$typeof === REACT_ELEMENT_TYPE
 ); } Copy the code

You can see,? A non-null object of typeof === REACT_ELEMENT_TYPE is a valid React Element. In other words, in React, all JSX returns at runtime (i.e., the return value of react.createElement ()) are React Elements.

How about the React Component and JSX?

React Component

In React, we use ClassComponent and FunctionComponent to build components.

class AppClass extends React.Component {
  render() {
    return <p>KaSong</p>
  }
}
console.log('Here's ClassComponent:', AppClass); console.log('This is Element:', <AppClass/>);   function AppFunc() {  return <p>KaSong</p>; } console.log('Here's FunctionComponent:', AppFunc); console.log('This is Element:', <AppFunc/>); Copy the code

Details React Component Category Demo

As we can see from the object printed by the Demo console, the Type field of the Element corresponding to the ClassComponent is AppClass itself.

The type field of the Element corresponding to the FunctionComponent is AppFunc itself, as shown below:

{
  $typeof: Symbol(react.element),
  key: null.  props: {},
  ref: null. type: ƒ AppFunc (), _owner: null. _store: {validated: false},  _self: null. _source: null } Copy the code

One thing worth noting is that

AppClass instanceof Function= = =true;
AppFunc instanceof Function= = =true;
Copy the code

So you can’t distinguish ClassComponent from FunctionComponent by reference type. React uses the isReactComponent variable on the ClassComponent prototype to determine if it is a ClassComponent.

ClassComponent.prototype.isReactComponent = {};
Copy the code

JSX and the virtual DOM

As we can see from the above, JSX is a data structure that describes the content of current components. It does not reconcile, reconcile, and render information related to components. For example, the following information is not included in JSX:

  • Priority of the component in the update
  • The component’sstate
  • The markup that the component is tagged with for the Renderer

All of this is contained in the virtual DOM.

So, when the components are mounted, the Reconciler generates the corresponding virtual DOM for the components based on the contents of the components described by the JSX. When the Reconciler is updated, the JSX is compared with the data stored in the virtual DOM, marking the virtual DOM with changes in state after the comparison.

The resources

Use this article to modify React. CreateElement at run time to eliminate all div elements on the page

How to kill all divs of Zhihu