原文 How Does React Tell a Class from a Function?

译注:

一分钟概览——

React最后采用了在React.Component上加入isReactComponent标识作为区分。

1.在这之前,考虑了ES6的区分方法,但是由于Babel的存在,这个方法不可用。

2.总是调用new,对于一些纯函数组件不适用。而且对箭头函数使用new会出错。

3.把问题约束到React组件下,通过判定原型链来做,但是可能有多个React实例导致判定出错,所以在原型上添加了标识位,标识位是一个对象,因为早期Jest会忽略普通类型如Boolean型。

4.API检测也是可行的,但是API的发展无法预测,每个检测都会带来额外的损耗,所以不是主要做法,但是在现在版本里已经加入了render检测,用来检测prototype.render存在,但是prototype.isReactComponent不存在的场景,这样会抛出一个warning。

以下正文。

思考一下下面这个使用function定义的Greeting组件:

  1. function Greeting() {
  2. return Hello;
  3. }

React也支持class定义:

  1. class Greeting extends React.Component {
  2. render() {
  3. return Hello;
  4. }
  5. }

(直到最近,这是唯一可以使用类似state这种功能的方法。)

当你在使用<Greeting />组件时,其实并不关心它是怎么定义的。

  1. // Class or function — whatever.

但是React自己是关心这些不同的!

如果Greeting是一个函数,React需要去调用它:

  1. // Your code
  2. function Greeting() {
  3. return Hello;
  4. }
  5. // Inside React
  6. const result = Greeting(props); // Hello

但是如果Greeting是类,React就需要用new关键字去实例化一个对象,然后立刻调用它的render方法。

  1. // Your code
  2. class Greeting extends React.Component {
  3. render() {
  4. return Hello;
  5. }
  6. }
  7. // Inside React
  8. const instance = new Greeting(props); // Greeting {}
  9. const result = instance.render(); // Hello

React有一个相同的目的——得到一个渲染完毕的node(在这个例子里,<p>Hello</p>)。但是如果定义Greeting决定了剩下的步骤。

所以React是如何知道一个组件是类还是函数?

就像我之前的博客,你不需要知道这个东西对于React而言的效果。我同样好几点不了解这些。请不要把这个问题变成一个面试题。事实上,比起React,这篇博客更关注于JavaScript。

这篇博客写给那些富有好奇心的读者,他们想知道为什么React能以一种确定的方式工作。你是这样的人吗?一起深入探讨吧!

这是一段漫长的旅程。这篇博客不会写很多关于React的东西,但是会一掠JavaScript本身的风采,诸如:new,this,class,箭头函数,prototype,__proto__,instanceof,以及这些东西如何在JavaScript中合作。幸运的是,在你使用React的时候,你不必想太多这些事。


首先,我们需要明白为什么区分函数和类如此重要。注意我们怎么使用new操作符去调用一个类:

  1. // If Greeting is a function
  2. const result = Greeting(props); // Hello
  3. // If Greeting is a class
  4. const instance = new Greeting(props); // Greeting {}
  5. const result = instance.render(); // Hello

先来对new操作符做了什么给出一个粗浅的定义。


以前,JavaScript没有类的概念。然而,你也可以用纯函数去描述一种近似于类的模式。具体而言,你可以在调用函数之前,添加new,就可以使用任何类似于类构造器的函数了。

  1. // Just a function
  2. function Person(name) {
  3. this.name = name;
  4. }
  5. var fred = new Person('Fred'); // ✅ Person {name: 'Fred'}
  6. var george = Person('George'); //
  7. [译]React如何区别classfunction的更多相关文章

      1. vuejsangularjs以及react的区别?
      1. 1.AngularJS的区别 相同点: 都支持指令:内置指令和自定义指令. 都支持过滤器:内置过滤器和自定义过滤器. 都支持双向数据绑定. 都不支持低端浏览器. 不同点: 1.AngularJS的学 ...

      1. 为什么React事件处理函数必须使用Function.bind()绑定this
      1. 最近在React官网学习Handling Events这一章时,有一处不是很明白.代码如下: class Toggle extends React.Component { constructor(pr ...

      1. [译] React 16.3(.0-alpha) 新特性
      1. 原文地址:What's new in React 16.3(.0-alpha) 原文作者:Bartosz Szczeciński 译文出自:掘金翻译计划 本文永久链接:github.com/xitu/ ...

      1. [译]React Context
      1. 欢迎各位指导与讨论 : ) 前言 由于笔者英语和技术水平有限,有不足的地方恳请各位指出.我会及时修正的 O(∩_∩)O 当前React版本 15.0.1 时间 2016/4/25 正文 React一个 ...

      1. [译]React 在服务端渲染的实现
      1. 原文地址:Server-Side React Rendering 原文作者:Roger Jin React 在服务端渲染的实现 React是最受欢迎的客户端 JavaScript 框架,但你知道吗(可 ...

      1. 前端框架 vue 和 react 的区别
      1. 前言:最近需要使用 react,以前用过 vue,故来总结两者的区别. 首先React与vue有几点相同之处 1.都使用了Virtual DOM 2.提供了响应式(Reactive)和组件化(Comp ...

      1. [React] Preventing extra re-rendering with function component by using React.memo and useCallback
      1. Got the idea form this lesson. Not sure whether it is the ncessary, no othere better way to handle i ...

      1. JS中的函数声明和函数表达式的区别,即function(){}和var function(){},以及变量提升、作用域和作用域链
      1. 一.前言 Uncaught TypeError: ... is not a function function max(){}表示函数声明,可以放在代码的任何位置,也可以在任何地方成功调用: var ...

      1. Vue和React的区别,以及如何选择?
      1. 简介 React:React是一个用于创建可重用且有吸引力的UI组件的库.它非常适合代表经常变化的数据的组件. Vue:Vue.js是一个开源JavaScript框架,能够开发单页面应用程序.它还可以 ...

    1. 随机推荐

        1. Python OOP面向对象
        1. 一.什么是面向对象的程序设计 1.面向过程 程序设计:核心是过程二字,过程指的是解决问题的步骤,即先干什么再干什么......面向过程的设计就好比精心设计好一条流水线,是一种机械式的思维方式. 优点是 ...

        1. c#开源项目收集
        1. 1百度云高速下载c#开源: https://github.com/ResourceHunter/BaiduPanDownloadWinform 2.IdaCsharp http://idacsharp ...

        1. 《一马当先 O2O创业真人秀》阿里云创客+项目提交报名中
        1. 传统行业与互联网的相互融合,线上与线下的互通,正在掀起一股“互联网+”新风潮和创业热潮.支付宝钱包.快的打车.淘点点……这些耳熟能详的应用早已成为人们生活的一部分.而越来越多的“互联网+”创新项目,将 ...

        1. 《Visual C++ 2010入门教程》系列一:关于Visual Studio、VC和C++的那些事
        1. 原文:http://www.cnblogs.com/Mrt-02/archive/2011/07/24/2115606.html 作者:董波 日期:2010.6.15 写在前面 在我还在上学的时候,我 ...

        1. Oracle归档模式和非归档模式的区别
        1. 一.查看oracle数据库是否为归档模式: Sql代码1.select name,log_mode from v$database; NAME LOG_MODE ------------------ ...

        1. SQL Server ->> SQL Server 2016重要功能改进之 -- INSERT SELECT时并发插入数据
        1. SQL Server 2016对INSERT INTO XXXX SELECT语句进行了优化,在某些情况下可以触发数据的并行插入,但是要求兼容模式是130(SQL Server 2016)以及在插入的 ...

        1. UnicodeDecodeError: 'utf8' codec can't decode byte in position invalid start byte
        1. scrapy项目中,由于编码问题,下载的网页中中文都是utf-8编码,在Pipeline.py中方法process_item将结果保存到数据库中时,提示UnicodeDecodeError: 'ut ...

        1. M-PalindromeP-DP
        1. Palindrome Partitioning 动态规划+深度优先搜索 https://leetcode.com/discuss/23480/c-solution-with-dp-and-dfs-12 ...

        1. hearbeat
        1. heartbeat介绍: 作用: 通过heartbeat,可以将资源(IP及程序服务等资源)从一台已经故障的计算机快速转移到另一台正常运转的机器上继续提供服务,一般称之为高可用服务.在升级生产应用场景 ...

        1. D3——绘制SVG图形-直方图
        1. 1.创建SVG元素 var svg = d3.select("body").append("svg"); 2.为SVG元素设置属性 svg.attr() .at ...