React中元素与组件的区分

在初学 React 的时刻,分不清 React 组件和 React 元素,实在踩了一些坑。搞清晰 React 中什么是组件,什么是元素,既能够理清晰观点,也能够让你防止一些不必要的毛病。

React 元素

React 元素(React element),它是 React 中最小基本单位,我们能够运用 JSX 语法轻松地建立一个 React 元素:

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

React 元素不是实在的 DOM 元素,它仅仅是 js 的平常对象(plain objects),所以也没办法直接挪用 DOM 原生的 API。上面的 JSX 转译后的对象大概是如许的:

{
    _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 组件。第二个参数为传入的属性。第三个以及以后的参数,皆作为组件的子组件。

React.createElement(
    type,
    [props],
    [...children]
)

React.cloneElement()

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

React.cloneElement(
  element,
  [props],
  [...children]
)

React 组件

React 中有三种构建组件的体式格局。React.createClass()ES6 class和无状况函数。

React.createClass()

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

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

ES6 class

ES6 class是现在官方引荐的运用体式格局,它运用了ES6规范语法来构建,但它的完成还是挪用React.createClass()来完成了,ES6 class的生命周期和自动绑定体式格局与React.createClass()略有差别。

class Greeting extemds React.Component{
  render: function() {
    return <h1>Hello, {this.props.name}</h1>;
  }
};

无状况函数

无状况函数是运用函数构建的无状况组件,无状况组件传入propscontext两个参数,它没有state,除了render(),没有别的生命周期要领。

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

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

元素与组件的区分

组件是由元素组成的。元素数据结构是平常对象,而组件数据结构是类或纯函数。除此之外,另有几点区分要注意:

this.props.children

在 JSX 中,被元素嵌套的元素会以属性 children 的体式格局传入该元素的组件。当仅嵌套一个元素时,children 是一个 React 元素,当嵌套多个元素时,children 是一个 React 元素的数组。能够直接把 children 写入 JSX 的中,但假如要给它们传入新属性,就要用到React.cloneElement()来构建新的元素。我曾放过以下毛病:

render () {
  var Child = this.props.children
  return <div><Child tip={'error!'}/><div>
}

由于 Child 是一个 React 元素,而不是组件,如许的写法是完整毛病的,准确的体式格局应当是:

render () {
  var child = this.props.children
  return <div>{ React.cloneElement(child, {tip: 'right way!'}) }<div>
}

就如许,原有属性和新增加的属性被一并传入了子元素。运用React.cloneElement()才是操纵元素的准确姿态。

用户组件

有的时刻,组件能够让用户以属性的体式格局传入自定义的组件,来提拔组件的灵活性。这个属性传入的就应当是 React 元素,而非 React 组件。运用 React 元素能够让用户传入自定义组件的同时,为组件增加属性。一样,能够运用React.cloneElement()为自定义组件增加更多属性,或替代子元素。

// 引荐
<MyComponent tick={
  <UserComponent tip="Yes"/>
} />

// 不引荐
<MyComponent tick={ UserComponent } />

末了

末了,打个不适当的比方,React 组件是MyComponent,React 元素就是<MyComponent />

AD

新开博客,更多文章,连续更新中…

    原文作者:notebin
    原文地址: https://segmentfault.com/a/1190000008587988
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞