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:
JSX
Is it the same thing as the virtual DOM?React Component
,React Element
Is it the same thing? They’re the same thingJSX
What 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’s
state
- 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