search
HomeWeb Front-endJS TutorialExploring the internal mechanisms of React

Exploring the internal mechanisms of React

Oct 25, 2017 pm 03:06 PM
reactinternalExplore

Exploring the internal mechanisms of React - React Component and Element

This article is relatively basic, but it is crucial for getting started with the internal mechanisms and implementation principles of React. It can be regarded as an introduction for in-depth explanation in the future, if you already know it very well:

React Component Render => JSX => React.createElement => Virtual Dom

process, you can skip this article directly.

A coquettish question from Google engineers

A few months ago, Google's front-end development expert Tyler McGinnis posted such a tweet on his personal twitter account, triggering a discussion on React components. discuss.

Exploring the internal mechanisms of React

The question he raised is: As in the above code, React component Icon appears directly in the code, what does it count?

The options provided are:

  • A. Component Declaration

  • B. Component Invocation

  • C. Component Instantiation

  • D. Using a Component Simply using a component

Interestingly, among the developers who responded:

  • 15% chose option A;

  • 8% chose Item B;

  • 45% chose item C;

  • 32% chose item D;

For front-end engineers experienced in React development, this problem is actually easy to understand. The key is: Really understand how React Element and React Components, and the JSX abstraction layer are connected to React. Of course, you also need to understand some simple internal working mechanisms of React.

This article will lead you to study the mystery of this JSX abstraction layer and the React Reconciliation process.

What exactly are React and React Element?

Let us go back to the beginning and think about the most original question, what exactly is React?

In short,

React is a library for building user interfaces.

React is a class library (framework. ..whatever...). No matter how complex React itself is, no matter how huge its ecosystem is, Building Views is always its core. With this information in mind, we are about to move into today’s first concept — React Element.

Simply put, React Element describes what "you want" to see on the screen.

Abstractly speaking, the React Element element is an object that describes a Dom Node.

Please note my wording - "describe" because React Element is not the actual thing you see on the screen. Rather, it is a collection of descriptions of real things. What exists is reasonable. Let’s take a look at the meaning of React Element’s existence and why there is such a concept:

  • JavaScript objects are very lightweight. Using objects as React Elements, React can easily create or destroy these elements without worrying too much about the operation cost;

  • #React has the ability to analyze these objects, and further, it also has The ability to analyze virtual Dom. The performance benefits of updating a virtual Dom (compared to a real Dom) when changes occur are significant.

In order to create the object (or React Element) we describe the Dom Node, we can use the React.createElement method:

const element = React.createElement( 
  'p', 
  {id: 'login-btn'}, 
  'Login'
)

Here the React.createElement method accepts three parameters :

  • A string describing the tag name (p, span, etc.);

  • Attributes that the current React Element needs to have;

  • The content to be expressed by the current React Element, or a child element.

After the React.createElement method is called above, a javascript object will be returned:

{ 
  type: 'p', 
  props: { 
    children: 'Login', 
    id: 'login-btn' 
  } 
}

Then when we use the ReactDOM.render method, it will be rendered to the real DOM. When, you will get:

<p id=&#39;login-btn&#39;>Login</p>

And this is the real Dom node.

So far, there are no concepts that are difficult to understand.

React Element and React Component

We introduced React Element at the beginning of this article, instead of introducing React Component like the official website or learning materials. I believe you understand React Element. , understanding React Component is natural.

In actual development, we do not use React.createElement directly. It is simply too boring. If every component is written like this, it will definitely go crazy. At this time, React Component appeared, that is, React component.

A component is a function or a Class which optionally accepts input and returns a React element.

Yes, a component is a function or a Class (of course Class is also function), which takes input parameters and finally returns a React Element, without requiring us to write boring React Elements directly.

So, we actually use React Component to generate React Element, which will undoubtedly greatly improve the development experience.

这里剖出一个思考题:所有 React Component 都需要返回  React Element 吗?显然是不需要的,那么 return null; 的 React 组件有存在的意义吗,它能完成并实现哪些巧妙的设计和思想?(请关注作者,下篇文章将会专门进行分析、讲解)

从场景实例来看问题

接下来,请看这样一段代码:

function Button ({ onLogin }) { 
  return React.createElement( 
    &#39;p&#39;, 
    {id: &#39;login-btn&#39;, onClick: onLogin}, 
    &#39;Login&#39; 
  )
}

我们定义了一个 Button 组件,它接收 onLogin 参数,并返回一个 React Element。注意 onLogin 参数是一个函数,并最终像 id:'login-btn' 一样成为了这个 React Element 的属性。

直到目前,我们见到了一个 React Element type 为 HTML 标签(“span”, “p”, etc)的情况。事实上,我们也可以传递另一个 React Element :

const element = React.createElement(
  User, 
  {name: &#39;Lucas&#39;},
  null 
)

注意此时 React.createElement 第一个参数是另一个 React Element,这与 type 值为 HTML 标签的情况不尽相同,当 React 发现 type 值为一个 class 或者函数时,它就会先看这个 class 或函数会返回什么样的 Element,并为这个 Element 设置正确的属性。

React 会一直不断重复这个过程(有点类似递归),直到没有 “createElement 调用 type 值为 class 或者 function” 的情况。

我们结合代码再来体会一下:

function Button ({ addFriend }) {
  return React.createElement(
    "button", 
    { onClick: addFriend }, 
    "Add Friend" 
  ) 
} 
function User({ name, addFriend }) { 
  return React.createElement(
    "p", 
    null,
    React.createElement( "p", null, name ),
    React.createElement(Button, { addFriend })
  ) 
}

上面有两个组件:Button 和 User,User 描述的 Dom 是一个 p 标签,这个 p 内,又存在一个 p 标签,这个 p 标签展示了用户的 name;还存在一个 Button。

现在我们来看 User 和 Button 中,React.createElement 返回情况:

function Button ({ addFriend }) { 
  return { 
    type: &#39;button&#39;, 
    props: { 
      onClick: addFriend, 
      children: &#39;Add Friend&#39; 
    } 
  } 
} 
function User ({ name, addFriend }) { 
  return { 
    type: &#39;p&#39;, 
    props: { 
      children: [{ 
        type: &#39;p&#39;,
        props: { children: name } 
      }, 
      { 
       type: Button, 
       props: { addFriend } 
      }]
    }
  }
}

你会发现,上面的输出中,我们发现了四种 type 值:

  • "button";

  • "p";

  • "p";

  • Button

当 React 发现 type 是 Button 时,它会查询这个 Button 组件会返回什么样的 React Element,并赋予正确的 props。

直到最终,React 会得到完整的表述 Dom 树的对象。在我们的例子中,就是:

<p style="margin-bottom: 7px;">{<br/>  type: &#39;p&#39;, <br/>  props: {<br/>    children: [{<br/>      type: &#39;p&#39;,<br/>      props: { children: &#39;Tyler McGinnis&#39; }<br/>    }, <br/>    { <br/>      type: &#39;button&#39;, <br/>      props: { <br/>        onClick: addFriend, <br/>        children: &#39;Add Friend&#39;<br/>      }<br/>     }]<br/>   } <br/>}<br/></p>

React 处理这些逻辑的过程就叫做 reconciliation,那么“这个过程(reconciliation)在何时被触发呢?”

答案当然就是每次 setState 或 ReactDOM.render 调用时。以后的分析文章将会更加详细的说明。

好吧,再回到 Tyler McGinnis 那个风骚的问题上。

Exploring the internal mechanisms of React

此时我们具备回答这个问题的一切知识了吗?稍等等,我要引出 JSX 这个老朋友了。

JSX 的角色

在 React Component 编写时,相信大家都在使用 JSX 来描述虚拟 Dom。当然,反过来说,React 其实也可以脱离 JSX 而存在。

文章开头部分,我提到 “不常被我们提起的 JSX 抽象层是如何联通 React 的?” 答案很简单,因为 JSX 总是被编译成为 React.createElement 而被调用。一般 Babel 为我们做了 JSX —> React.createElement 这件事情。

再看来先例:

function Button ({ addFriend }) {
  return React.createElement(
    "button",
    { onClick: addFriend },
    "Add Friend" 
   )
} 
function User({ name, addFriend }) { 
  return React.createElement(
    "p",
    null,
    React.createElement( "p", null, name),
    React.createElement(Button, { addFriend })
  )
}

对应我们总在写的 JSX 用法:

function Button ({ addFriend }) { 
  return ( 
    <button onClick={addFriend}>Add Friend</button> 
  )
}
function User ({ name, addFriend }) {
  return ( 
    <p>
     <p>{name}</p>
     <Button addFriend={addFriend}/>
    </p>
  )
}

就是一个编译产出的差别。

最终答案和文末彩蛋

那么,请你来回答“Icon 组件单独出现代表了什么?”

Icon 在 JSX 被编译之后,就有:

React.createElement(Icon, null)

你问我怎么知道这些编译结果的?

或者

你想知道你编写的 JSX 最终编译成了什么样子?

我写了一个小工具,进行对 JSX 的实时编译,放在 Github仓库中,它使用起来是这样子的:

平台一分为二,左边可以写 JSX,右边实时展现其编译结果:

Exploring the internal mechanisms of React

以及:

Exploring the internal mechanisms of React

这个工具最核心的代码其实就是使用 babel 进行编译:

let code = e.target.value;
try {
    this.setState({
        output: window.Babel.transform(code, {presets: [&#39;es2015&#39;, &#39;react&#39;]})
        .code,
        err: &#39;&#39;
    })
}
catch(err) {
    this.setState({err: err.message})
}

感兴趣的读者可以去 GitHub 仓库参看源码。

总结

其实不管是 JSX 还是 React Element、React Component 这些概念,都是大家在开发中天天接触到的。有的开发者也许能上手做项目,但是并没有深入理解其中的概念,更无法真正掌握 React 核心思想。

这些内容其实比较基础,但同时又很关键,对于后续理解 React/Preact 源码至关重要。在这个基础上,我会更新更多更加深入的类 React 实现原理剖析,感兴趣的读者可以关注。

我的其他几篇关于React技术栈的文章:

  • 通过实例,学习编写 React 组件的“最佳实践”

  • Bind this from React and look at JS language development and framework design

  • It is not enough to create the ultimate performance of Uber mobile web version to see the real story

  • Analyze Twitter front-end architecture and learn complex scene data design

  • React Conf 2017 summary 1: React + ES next = ♥

  • React+Redux creates a "NEWS EARLY" single-page application. A project to understand the essence of the cutting-edge technology stack

  • A react+redux project example


The above is the detailed content of Exploring the internal mechanisms of React. For more information, please follow other related articles on the PHP Chinese website!

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
The Origins of JavaScript: Exploring Its Implementation LanguageThe Origins of JavaScript: Exploring Its Implementation LanguageApr 29, 2025 am 12:51 AM

JavaScript originated in 1995 and was created by Brandon Ike, and realized the language into C. 1.C language provides high performance and system-level programming capabilities for JavaScript. 2. JavaScript's memory management and performance optimization rely on C language. 3. The cross-platform feature of C language helps JavaScript run efficiently on different operating systems.

Behind the Scenes: What Language Powers JavaScript?Behind the Scenes: What Language Powers JavaScript?Apr 28, 2025 am 12:01 AM

JavaScript runs in browsers and Node.js environments and relies on the JavaScript engine to parse and execute code. 1) Generate abstract syntax tree (AST) in the parsing stage; 2) convert AST into bytecode or machine code in the compilation stage; 3) execute the compiled code in the execution stage.

The Future of Python and JavaScript: Trends and PredictionsThe Future of Python and JavaScript: Trends and PredictionsApr 27, 2025 am 12:21 AM

The future trends of Python and JavaScript include: 1. Python will consolidate its position in the fields of scientific computing and AI, 2. JavaScript will promote the development of web technology, 3. Cross-platform development will become a hot topic, and 4. Performance optimization will be the focus. Both will continue to expand application scenarios in their respective fields and make more breakthroughs in performance.

Python vs. JavaScript: Development Environments and ToolsPython vs. JavaScript: Development Environments and ToolsApr 26, 2025 am 12:09 AM

Both Python and JavaScript's choices in development environments are important. 1) Python's development environment includes PyCharm, JupyterNotebook and Anaconda, which are suitable for data science and rapid prototyping. 2) The development environment of JavaScript includes Node.js, VSCode and Webpack, which are suitable for front-end and back-end development. Choosing the right tools according to project needs can improve development efficiency and project success rate.

Is JavaScript Written in C? Examining the EvidenceIs JavaScript Written in C? Examining the EvidenceApr 25, 2025 am 12:15 AM

Yes, the engine core of JavaScript is written in C. 1) The C language provides efficient performance and underlying control, which is suitable for the development of JavaScript engine. 2) Taking the V8 engine as an example, its core is written in C, combining the efficiency and object-oriented characteristics of C. 3) The working principle of the JavaScript engine includes parsing, compiling and execution, and the C language plays a key role in these processes.

JavaScript's Role: Making the Web Interactive and DynamicJavaScript's Role: Making the Web Interactive and DynamicApr 24, 2025 am 12:12 AM

JavaScript is at the heart of modern websites because it enhances the interactivity and dynamicity of web pages. 1) It allows to change content without refreshing the page, 2) manipulate web pages through DOMAPI, 3) support complex interactive effects such as animation and drag-and-drop, 4) optimize performance and best practices to improve user experience.

C   and JavaScript: The Connection ExplainedC and JavaScript: The Connection ExplainedApr 23, 2025 am 12:07 AM

C and JavaScript achieve interoperability through WebAssembly. 1) C code is compiled into WebAssembly module and introduced into JavaScript environment to enhance computing power. 2) In game development, C handles physics engines and graphics rendering, and JavaScript is responsible for game logic and user interface.

From Websites to Apps: The Diverse Applications of JavaScriptFrom Websites to Apps: The Diverse Applications of JavaScriptApr 22, 2025 am 12:02 AM

JavaScript is widely used in websites, mobile applications, desktop applications and server-side programming. 1) In website development, JavaScript operates DOM together with HTML and CSS to achieve dynamic effects and supports frameworks such as jQuery and React. 2) Through ReactNative and Ionic, JavaScript is used to develop cross-platform mobile applications. 3) The Electron framework enables JavaScript to build desktop applications. 4) Node.js allows JavaScript to run on the server side and supports high concurrent requests.

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

MantisBT

MantisBT

Mantis is an easy-to-deploy web-based defect tracking tool designed to aid in product defect tracking. It requires PHP, MySQL and a web server. Check out our demo and hosting services.

EditPlus Chinese cracked version

EditPlus Chinese cracked version

Small size, syntax highlighting, does not support code prompt function

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

Powerful PHP integrated development environment

SecLists

SecLists

SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.