程序亦非猿

React中元素与组件的区别,和组件有几种类型

2018/01/30 Share

在初学 React 的时候,分不清 React 组件和 React 元素,着实踩了一些坑。搞清楚 React 中什么是组件,什么是元素,既可以理清楚概念,也可以让你避免一些不必要的错误。

React 元素

React 元素(React element),它是 React 中最小基本单位,我们可以使用 JSX 语法轻松地创建一个 React 元素:

1
const element = <div className='element'>I'm element</div>

React 元素不是真实的 DOM 元素,它仅仅是 js 的普通对象(plain objects),所以也没办法直接调用 DOM 原生的 API。上面的 JSX 转译后的对象大概是这样的:

1
2
3
4
5
6
7
8
9
10
11
{
_context: Object,
_owner: null,
key: null,
props: {
className: 'element',
children: 'I‘m element'
},
ref: null,
type: "div"
}

只有在这个元素渲染被完成后,才能通过选择器的方式获取它对应的 DOM 元素。不过,按照 React 有限状态机的设计思想,应该使用状态和属性来表述组件,要尽量避免 DOM 操作,即便要进行 DOM 操作,也应该使用 React 提供的接口refgetDOMNode()。一般使用 React 提供的接口就足以应付需要 DOM 操作的场景了,因此像 jQuery 强大的选择器在 React 中几乎没有用武之地了。

除了使用 JSX 语法,我们还可以使用 React.createElement()React.cloneElement() 来构建 React 元素。

React.createElement()

JSX 语法就是用React.createElement()来构建 React 元素的。它接受三个参数,第一个参数可以是一个标签名。如divspan,或者 React 组件。第二个参数为传入的属性。第三个以及之后的参数,皆作为组件的子组件。

1
2
3
4
5
React.createElement(
type,
[props],
[...children]
)

React.cloneElement()

React.cloneElement()React.createElement()相似,不同的是它传入的第一个参数是一个 React 元素,而不是标签名或组件。新添加的属性会并入原有的属性,传入到返回的新元素中,而就的子元素奖杯替换。

1
2
3
4
5
React.cloneElement(
element,
[props],
[...children]
)

React 组件

React 中有三种构建组件的方式。React.createClass()ES6 class和无状态函数。

React.createClass()

React.createClass()是三种方式中最早,兼容性最好的方法。在0.14版本前官方指定的组件写法。

1
2
3
4
5
var Greeting = React.createClass({
render : function(){
return <h1>Hello,{this.props.name}</h1>
}
});

ES6 class

ES6 class是目前官方推荐的使用方式,它使用了ES6标准语法来构建,但它的实现仍是调用React.createClass()来实现了,ES6 class的生命周期和自动绑定方式与React.createClass()略有不同。

1
2
3
4
5
class Greeting extends React.Component{
render:function(){
return <h1>Hello,{this.props.name}</h1>
}
}

无状态函数

无状态函数是使用函数构建的无状态组件,无状态组件传入propscontext两个参数,它没有state,除了render(),没有其它生命周期方法。

1
2
3
function Greeting (props) {
return <h1>Hello, {props.name}</h1>;
}

React.createClass()ES6 class构建的组件的数据结构是类,无状态组件数据结构是函数,它们在 React 被视为是一样的。

元素与组件的区别

元素是一个纯的JSON对象,用于描述你想通过DOM节点或者其他组件在荧屏上展示的内容。元素可以在他们的参数里面包含其他元素。创建一个React元素代价非常小。一个元素一旦被创建,将不可更改。

一个组件可以用几种不同的方式去声明。可以是一个带有render()方法的类。作为另外一种选择,在简单的情况下,组件可以被定义为一个函数。在两种方式下,组件都是被传入的参数作为输入内容,以返回的元素作为输出内容。

如果有一个组件被调用,传入了一些参数作为输入,那是因为有一某个父组件返回了一个带有这个组件的type以及这些参数(到React上)。这就是为什么大家都认为参数流动方式只有一种:从父组件到子组件。

实例就是你在组件上调用this时候得到的东西,它对本地状态存储以及对响应生命周期事件非常有用。

函数组件根本没有实例,类组件拥有实例,但是你从来都不需要去直接创建一个组件实例——React会帮你管理好它。

最后,想要创建元素,使用React.createElement(),JSX或者一个元素工厂工具。不要在实际代码上把元素写成纯JSON对象——仅需要知道他们在React机制下面以纯JSON对象存在就好。

本文借鉴于https://segmentfault.com/a/1190000008587988

CATALOG
  1. 1. React 元素
  2. 2. React.createElement()
  3. 3. React.cloneElement()
  4. 4. React 组件
    1. 4.1. React.createClass()
    2. 4.2. ES6 class
    3. 4.3. 无状态函数
  5. 5. 元素与组件的区别