We know that React actually generates the real DOM from the virtual DOM. React extends JavaScript so that React has the ability to attribute HTML code in JavaScript to make developers feel more connected. However, here, The thing to do here is to look at the nature of this closeness – JavaScript DOM descriptions.

Create a React element

  • API: React.createElement(component, props, … children)
import React from 'react'
// A React component
function App(props) {
  return (
    <div>{props.name}</div>
 ) }  // Render this component to the specified DOM ReactDOM.render(<App />, document.getElementById('app')) Copy the code

Compiled by Babel

import React from 'react'; // A React component

function App(props) {
  return /*#__PURE__*/React.createElement("div".null, props.name);
} // Render this component to the specified DOM
  ReactDOM.render( /*#__PURE__*/React.createElement(App, null), document.getElementById('app')); Copy the code

The realization of the React. The createElement method

The React. The createElement method/ReactEleme… It processes props and then calls ReactElement to generate a React element

export function createElement(type, config, children) {
  let propName;
  const props = {};

  // other codes
  if(config ! =null) {  // other codes   for (propName in config) {  if (  hasOwnProperty.call(config, propName) && ! RESERVED_PROPS.hasOwnProperty(propName) ) {  props[propName] = config[propName];  }  }  }   const childrenLength = arguments.length - 2;  if (childrenLength === 1) {  props.children = children;  } else if (childrenLength > 1) {  const childArray = Array(childrenLength);  for (let i = 0; i < childrenLength; i++) {  childArray[i] = arguments[i + 2];  }  // __DEV__ codes  props.children = childArray;  }   if (type && type.defaultProps) {  const defaultProps = type.defaultProps;  for (propName in defaultProps) {  if (props[propName] === undefined) {  props[propName] = defaultProps[propName];  }  }  }  // __DEV__ codes  return ReactElement(  type,  key,  ref,  self,  source,  ReactCurrentOwner.current,  props,  ); } Copy the code

The sample

  • Example 1: Nested delivery props
import React from 'react'
import ReactDOM from 'react-dom'

const h = React.createElement

const Comp2 = function Hello (props) {  const { name } = props  return h('div'.null.`my name is ${name}`) }  let Comp1 = h(Comp2, {name: 'tom'}, null)  ReactDOM.render(Comp1, document.getElementById('app')) Copy the code
  • Example 2: Implicit function component with no declared function, children contains variables
const name = 'Josh Perez';
const h = React.createElement

const element = /*#__PURE__*/h("h1".null."Hello, ", name);
ReactDOM.render(element, document.getElementById('root'));
Copy the code
  • Example 3: Children contains functions
function formatName(user) {
  return user.firstName + ' ' + user.lastName;
}

const user = {
 firstName: 'Harper'. lastName: 'Perez' }; const h = React.createElement  const element = /*#__PURE__*/h("h1".null."Hello, ", formatName(user), "!"); ReactDOM.render(element, document.getElementById('root')); Copy the code
  • Example 4: A function component with conditional statements
const h = React.createElement

function getGreeting(user) {
  if (user) {
    return /*#__PURE__*/h("h1".null."Hello, ", formatName(user), "!");
 }   return /*#__PURE__*/h("h1".null."Hello, Stranger."); } Copy the code
  • Example 5: Properties in an implicit function component
const h = React.createElement

const element1 = /*#__PURE__*/h("div", {
  tabIndex: "0"
});
const element2 = /*#__PURE__*/h("img", {  src: user.avatarUrl }); Copy the code
  • Example 6: Multiple child elements
const h = React.createElement

const element = /*#__PURE__*/React.createElement("div".null./*#__PURE__*/React.createElement("h1".null."Hello!"), /*#__PURE__*/React.createElement("h2".null."Good to see you here."));
Copy the code
  • Example 7: Compilation of a class component
class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}
 / / the compiled const h = React.createElement  class Welcome extends React.Component {  render() {  return /*#__PURE__*/h("h1".null."Hello, ".this.props.name);  } } Copy the code
  • Example 8: A relatively complex functional component
function Comment(props) {
  return (
    <div className="Comment">
      <div className="UserInfo">
 <img className="Avatar"  src={props.author.avatarUrl}  alt={props.author.name}  />  <div className="UserInfo-name">  {props.author.name}  </div>  </div>  <div className="Comment-text">  {props.text}  </div>  <div className="Comment-date">  {formatDate(props.date)}  </div>  </div>  ); }  / / the compiledconst h = React.createElement  function Comment(props) {  return /*#__PURE__*/h("div", {  className: "Comment"  }, /*#__PURE__*/h("div", {  className: "UserInfo"  }, /*#__PURE__*/h("img", {  className: "Avatar",  src: props.author.avatarUrl,  alt: props.author.name  }), /*#__PURE__*/h("div", {  className: "UserInfo-name"  }, props.author.name)), /*#__PURE__*/h("div", {  className: "Comment-text"  }, props.text), /*#__PURE__*/h("div", {  className: "Comment-date"  }, formatDate(props.date))); } Copy the code

When writing a complex component that looks nested and difficult to understand, it is best to separate the contents of the child components to keep the logic simple.

At this point, the advantages of templates appear, but there are solutions to this problem. Here are two solutions provided by the community, so that we can be more comfortable in the h function.

Solution for the React community

  • React-hyperscript Hyperscript syntax for the react. js tag
  • Helpers Hyperscript – Brief syntax for helpers Hyperscript

Compare Vue$createElment

$createElement ($createElement); $createElement ($createElement); $createElement ($createElement); Then use the virtual DOM to compare DOM, to the real DOM process.

Not Using Templates in Vue This article explains how to use not using Vue templates

reference

  • React without using JSX
  • Babel’s React playground makes it easier to play React

This article is formatted using MDNICE