React 深刻系列1:React 中的元素、组件、实例和节点

React 深刻系列,深刻讲解了React中的重点概念、特性和模式等,旨在帮助你们加深对React的理解,以及在项目中更加灵活地使用React。

React 中的元素、组件、实例和节点,是React中关系密切的4个概念,也是很容易让React 初学者迷惑的4个概念。如今,老干部就来详细地介绍这4个概念,以及它们之间的联系和区别,知足喜欢咬文嚼字、刨根问底的同窗(老干部就是其中一员)的好奇心。html

元素 (Element)

React 元素其实就是一个简单JavaScript对象,一个React 元素和界面上的一部分DOM对应,描述了这部分DOM的结构及渲染效果。通常咱们经过JSX语法建立React 元素,例如:node

const element = <h1 className='greeting'>Hello, world</h1>;

element是一个React 元素。在编译环节,JSX 语法会被编译成对React.createElement()的调用,从这个函数名上也能够看出,JSX语法返回的是一个React 元素。上面的例子编译后的结果为:数组

const element = React.createElement(
  'h1',
  {className: 'greeting'},
  'Hello, world!'
);

最终,element的值是相似下面的一个简单JavaScript对象:函数

const element = {
  type: 'h1',
  props: {
    className: 'greeting',
    children: 'Hello, world'
  }
}

React 元素能够分为两类:DOM类型的元素和组件类型的元素。DOM类型的元素使用像h一、div、p等DOM节点建立React 元素,前面的例子就是一个DOM类型的元素;组件类型的元素使用React 组件建立React 元素,例如:this

const buttonElement = <Button color='red'>OK</Button>;

buttonElement就是一个组件类型的元素,它的值是:spa

const buttonElement = {
  type: 'Button',
  props: {
    color: 'red',
    children: 'OK'
  }
}

对于DOM类型的元素,由于和页面的DOM节点直接对应,因此React知道如何进行渲染。可是对于组件类型的元素,如buttonElement,React是没法直接知道应该把buttonElement渲染成哪一种结构的页面DOM,这时就须要组件自身提供React可以识别的DOM节点信息,具体实现方式在介绍组件时会详细介绍。3d

有了React 元素,咱们应该如何使用它呢?其实,绝大多数状况下,咱们都不会直接使用React 元素,React 内部会自动根据React 元素,渲染出最终的页面DOM。更确切地说,React元素描述的是React虚拟DOM的结构,React会根据虚拟DOM渲染出页面的真实DOM。code

组件 (Component)

React 组件,应该是你们最熟悉的React中的概念。React经过组件的思想,将界面拆分红一个个能够复用的模块,每个模块就是一个React 组件。一个React 应用由若干组件组合而成,一个复杂组件也能够由若干简单组件组合而成。htm

React组件和React元素关系密切,React组件最核心的做用是返回React元素。这里你也许会有疑问:React元素不该该是由React.createElement() 返回的吗?但React.createElement()的调用自己也是须要有“人”负责的,React组件正是这个“责任人”。React组件负责调用React.createElement(),返回React元素,供React内部将其渲染成最终的页面DOM。对象

既然组件的核心做用是返回React元素,那么最简单的组件就是一个返回React元素的函数:

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

Welcome是一个用函数定义的组件。若是使用类(class)定义组件,返回React元素的工做具体就由组件的render方法承担,例如:

class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

其实,使用类定义的组件,render方法是惟一必需的方法,其余组件的生命周期方法都只不过是为render服务而已,都不是必需的。

如今来考虑下面这个例子:

class Home extends React.Component {
  render() {
    return (
      <div>
        <Welcome name='老干部' />
        <p>Anything you like</p>
      </div>
    )
  }
}

Home 组件使用了Welcome组件,返回的React元素为:

{
  type: 'div',
  props: {
    children: [
      {
        type: 'Welcome',
        props: {
          name: '老干部'
        }
      },
      {
        type: 'p',
        props: {
          children: 'Anything you like'
        }
      },
    ]
  }
}

对于这个结构,React 知道如何渲染type = 'div' 和 type = 'p' 的节点,但不知道如何渲染type='Welcome'的节点,当React 发现Welcome 是一个React 组件时(判断依据是Welcome首字母为大写),会根据Welcome组件返回的React 元素决定如何渲染Welcome节点。Welcome组件返回的React 元素为:

{
  type: 'h1',
  props: {
      children: 'Hello, 老干部'
  }
}

这个结构中只包含DOM节点,React是知道如何渲染的。若是这个结构中还包含其余组件节点,React 会重复上面的过程,继续解析对应组件返回的React 元素,直到返回的React 元素中只包含DOM节点为止。这样的递归过程,让React 获取到页面的完整DOM结构信息,渲染的工做天然就水到渠成了。

另外,若是仔细思考的话,能够发现,React 组件的复用,本质上是为了复用这个组件返回的React 元素,React 元素是React 应用的最基础组成单位

实例 (Instance)

这里的实例特指React组件的实例。React 组件是一个函数或类,实际工做时,发挥做用的是React 组件的实例对象。只有组件实例化后,每个组件实例才有了本身的props和state,才持有对它的DOM节点和子组件实例的引用。在传统的面向对象的开发方式中,实例化的工做是由开发者本身手动完成的,但在React中,组件的实例化工做是由React自动完成的,组件实例也是直接由React管理的。换句话说,开发者彻底没必要关心组件实例的建立、更新和销毁。

节点 (Node)

在使用PropTypes校验组件属性时,有这样一种类型:

MyComponent.propTypes = { 
  optionalNode: PropTypes.node,
}

PropTypes.node又是什么类型呢?这代表optionalNode是一个React 节点。React 节点是指能够被React渲染的数据类型,包括数字、字符串、React 元素,或者是一个包含这些类型数据的数组。例如:

// 数字类型的节点
function MyComponent(props) {
  return 1;
}

// 字符串类型的节点
function MyComponent(props) {
  return 'MyComponent';
}

// React元素类型的节点
function MyComponent(props) {
  return <div>React Element</div>;
}

// 数组类型的节点,数组的元素只能是其余合法的React节点
function MyComponent(props) {
  const element = <div>React Element</div>;
  const arr = [1, 'MyComponent', element];
  return arr;
}

// 错误,不是合法的React节点
function MyComponent(props) {
  const obj = { a : 1}
  return obj;
}

最后总结一下,React 元素和组件的概念最重要,也最容易混淆;React 组件实例的概念你们了解便可,几乎使用不到;React 节点有必定使用场景,但看过本文后应该也就不存在理解问题了。

下篇预告:

React 深刻系列2:组件分类


个人新书《React进阶之路》已上市,请你们多多支持!
连接:京东 当当

图片描述

相关文章
相关标签/搜索