React Component 和 React Element 有什么区别?文档提到了两者但没有详细说明,一些方法需要组件,其他元素......
React 组件和 React 元素的区别
这里涉及三种相关的事物,它们都有自己的名字:
- 组件
- 组件实例
- 元素
这有点令人惊讶,因为如果您习惯于其他 UI 框架,您可能会认为只有两种东西,大致对应于类(如Widget)和实例(如new Widget())。在 React 中不是这样。组件实例与元素不是一回事,它们之间也没有一一对应的关系。为了说明这一点,请考虑以下代码:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
class MyComponent extends React.Component {
constructor(props) {
super(props);
console.log('This is a component instance:', this);
}
render() {
const another_element = <div>Hello, World!</div>;
console.log('This is also an element:', another_element);
return another_element;
}
}
console.log('This is a component:', MyComponent)
const element = <MyComponent/>;
console.log('This is an element:', element);
ReactDOM.render(
element,
document.getElementById('root')
);
在上面的代码中:
MyComponent(类本身)是一个组件element是一个元素。这不是一个实例MyComponent; 相反,它只是对要创建的组件实例的描述。这是一个对象key,props,ref和type属性。在这里,key并且ref有null,props是一个空的对象,type是MyComponent。- 一个实例的
MyComponent被创建(并且,在上述例子中,从它的构造记录本身)时element被呈现。 another_element也是一个元素,并有key,ref,props和type刚才一样的属性element那样-但这次的值type是字符串"div"。
React 团队的博客文章React Components、Elements 和 Instances中详细探讨了 React 具有这三个不同概念的设计原因,我推荐阅读。
最后,应该注意的是,虽然官方文档严格使用术语“组件”来指代函数或类,使用“组件实例”来指代实例,但其他来源不一定遵循此术语;在 GitHub 上阅读 Stack Overflow 答案或讨论时,您应该会看到“组件”使用(错误地)表示“组件实例”。
为了进一步详细说明答案,React Element 没有任何方法,原型上也没有任何内容。这也使他们快速。
“ReactElement 是 DOM 元素的轻量级、无状态、不可变的虚拟表示”——React术语表
react组件render()函数在幕后返回react元素的 DOM 树(顺便说一下,这是虚拟 DOM)。涉及到一些复杂的映射和差异逻辑,但基本上这些 React 元素映射到 DOM 元素。
你也可以直接创建一个 Element ,React.createElement(arg)其中 arg 可以是一个 html 标签名称,或者一个 React Component 类。
react元素
React Element 只是一个Object没有自己方法的普通 JavaScript 。它基本上有四个属性:
type,String表示 HTML 标签或引用 React 组件的引用key, aString唯一标识一个 React 元素ref,访问底层 DOM 节点或 React 组件实例的引用)props(属性Object)
React Element 不是 React 组件的实例。它只是type对要创建的 React 组件实例(或取决于HTML 标签)应该是什么样子的简化“描述” 。
描述 React 组件的 React Element 不知道它最终被渲染到哪个 DOM 节点——这个关联是抽象的,将在渲染时解析。
React Elements 可能包含子元素,因此能够形成代表虚拟 DOM 树的元素树。
React 组件和 React 组件实例
自定义 React 组件要么是React.createClass通过扩展React.Component(ES2015)创建的,要么是通过扩展创建的。如果一个 React 组件被实例化,它需要一个props Object并返回一个实例,它被称为一个 React 组件实例。
React 组件可以包含状态并可以访问 React Lifecycle 方法。它必须至少有一个render方法,该方法在调用时返回一个 React Element(-tree)。请注意,您永远不会自己构建 React 组件实例,而是让 React 为您创建它。
React 元素与 React 组件
react元素
- React Element 是从组件返回的内容。它是一个虚拟地描述组件所代表的 DOM 节点的对象。
- 对于函数组件,此元素是函数返回的对象。
- 对于类组件,元素是组件的渲染函数返回的对象。电阻
- React 元素不是我们在浏览器中看到的。它们只是内存中的对象,我们无法更改它们的任何内容。
- React 元素可以具有
type除原生 HTML 元素之外的其他属性。
- react 元素描述了我们希望在屏幕上看到的内容。
- React 元素是 DOM 节点的对象表示。
_在这里进行区分很重要,因为元素不是我们在屏幕上看到的实际事物,而是对象表示是呈现的内容。
React 在这些方面做得很好:
- React 可以在没有太多开销的情况下创建和销毁这些元素。JS 对象是轻量级和低成本的。
- React 可以将一个对象与之前的对象表示进行比较,以查看发生了什么变化。
- React 可以更新实际的 DOM,特别是它检测到的变化发生的地方。这有一些性能优势。
createElement方法创建 DOM 节点(又名 React 元素)的对象表示。
const element = React.createElement(
'div',
{id: 'login-btn'},
'Login'
)
这里createElement接受三个参数
- 标签名称(例如 div、span 等)
- 我们希望元素具有的任何属性
- 元素的子元素的内容(例如读取的文本
Login)
createElement调用返回一个对象
{
type: 'div',
props: {
children: 'Login',
id: 'login-btn'
}
}
当它被渲染到 DOM(使用ReactDOM.render)时,我们将有一个新的 DOM 节点,如下所示:
<div id='login-btn'>Login</div>
哈扎!

通常,React 是从组件优先的方法中教授的,但是理解元素优先可以平滑地过渡到组件。
react组件
组件是一个函数或一个类,它可以选择接受输入并返回一个 React 元素。
React 组件是一个模板。一个蓝图。一个全局定义。这可以是函数或类(带有渲染函数)。
如果 react 将类或函数视为第一个参数,它会检查它渲染的元素,给定相应的 props 并继续这样做,直到不再
createElement有将类或函数作为第一个参数的调用.当 React 看到一个具有函数或类类型的元素时,它会咨询该组件以了解它应该返回哪个元素,给定相应的 props。
在此过程结束时,React 将拥有 DOM 树的完整对象表示。这整个过程在 React 中称为 reconciliation,每次触发
setState或ReactDOM.render调用。
类语法是定义 React 组件的最常见方式之一。虽然比函数式语法更冗长,但它以生命周期钩子的形式提供更多控制。
- 我们可以渲染同一组件的多个实例。
- 实例是在基于类的组件中使用的“this”关键字。
- 不是手动创建的,而是在 React 内存中的某个地方。
创建类组件
// MyComponent.js
import React, { Component } from 'react';
class MyComponent extends Component {
render() {
return (
<div>This is my component.</div>
);
}
}
export default MyComponent;
在任何其他组件中使用它
// MyOtherComponent.js
import React, { Component } from 'react';
import MyComponent from './MyComponent';
class MyOtherComponent extends Component {
render() {
return (
<div>
<div>This is my other component.</div>
<MyComponent />
</div>
);
}
}
export default MyOtherComponent;
使用props
<MyComponent myProp="This is passed as a prop." />
props可以通过 this.props
class MyComponent extends Component {
render() {
const {myProp} = this.props;
return (
<div>{myProp}</div>
);
}
}
使用状态
class MyComponent extends Component {
render() {
const {myState} = this.state || {};
const message = `The current state is ${myState}.`;
return (
<div>{message}</div>
);
}
}
使用生命周期钩子
class MyComponent extends Component {
// Executes after the component is rendered for the first time
componentDidMount() {
this.setState({myState: 'Florida'});
}
render() {
const {myState} = this.state || {};
const message = `The current state is ${myState}.`;
return (
<div>{message}</div>
);
}
}
基于函数的组件
- 没有实例。
- 可以多次渲染,但 React 不会将本地实例与每个渲染相关联。
- React 使用函数的调用来确定要为函数呈现什么 DOM 元素。
和 createElement
function Button ({ addFriend }) {
return React.createElement(
"button",
{ onClick: addFriend },
"Add Friend"
)
}
function User({ name, addFriend }) {
return React.createElement(
"div",
null,
React.createElement(
"p",
null,
name
),
React.createElement(Button, { addFriend })
)
}
用什么createElement回报
function Button ({ addFriend }) {
return {
type: 'button',
props: {
onClick: addFriend,
children: 'Add Friend'
}
}
}
function User ({ name, addFriend }) {
return {
type: 'div',
props: {
children: [
{
type: 'p',
props: {
children: name
}
},
{
type: Button,
props: {
addFriend
}
}
]
}
}
}
这里我们有一个Button组件,它接受一个onLogin输入并返回一个 React 元素。
- 该
Button组件接收一个onLogin方法作为其属性。 - 为了将它传递给我们的 DOM 对象表示,我们将它作为第二个参数传递给 createElement,就像我们对
id属性所做的一样。
React Element- 它是一个简单的对象,它描述了一个 DOM 节点及其属性或属性。它是一个不可变的描述对象,您不能对其应用任何方法。
例如——
<button class="blue"></button>
React Component- 它是一个接受输入并返回 React 元素的函数或类。它必须保持对 DOM 节点和子组件实例的引用。
const SignIn = () => (
<div>
<p>Sign In</p>
<button>Continue</button>
<button color='blue'>Cancel</button>
</div>
);