组件,实例和元素之间的不同点困扰了很多 React 初学者。为什么会有三个不同的术语指向屏幕的绘图。 管理实例如果你是 React 新手,也许你以前只使用过组件类和实例。例如你也许会通过创建一个类的方式声明一个 Button 组件。当 App 运行的时候,你也许会在屏幕上创建几个 Button 组件的引用,每个引用都有自己的属性和本地状态。这是传统的面向对象 UI 程序。那为什么会有元素呢? 在这个传统的 UI 模块里,由你来管理子组件实例的创建和销毁。如果一个 Form 组件想渲染一个 Button 组件,它需要创建它的实例,并手动的保持信息的更新。 class Form extends TraditionalObjectOrientedView {
render() {
// Read some data passed to the view
const { isSubmitted, buttonText } = this.attrs;
if (!isSubmitted && !this.button) {
// Form is not yet submitted. Create the button!
this.button = new Button({
children: buttonText,
color: 'blue'
});
this.el.appendChild(this.button.el);
}
if (this.button) {
// The button is visible. Update its text!
this.button.attrs.children = buttonText;
this.button.render();
}
if (isSubmitted && this.button) {
// Form was submitted. Destroy the button!
this.el.removeChild(this.button.el);
this.button.destroy();
}
if (isSubmitted && !this.message) {
// Form was submitted. Show the success message!
this.message = new Message({ text: 'Success!' });
this.el.appendChild(this.message.el);
}
}
}
这虽然是伪代码,但是通过一个面向对象的方式使用像 BackBone 这样库时,你最终还是或多或少的像通常那样写一个复合 UI 代码。 |
每一个组件都得保留到其DOM节点还有其子组件实例的引用,并且在正确时间对它们进行创建、更新和销毁操作。代码行数量的增长是潜在的组件语句数量的平方,而父组件得直接访问它们的子组件实例,使得将来要对它们进行解耦会很困难。 React 如何不同了呢? 元素来描述树在React中,由元素来解决问题。元素就是一个单纯的对象,它描述了一个组件实例或者DOM节点机器需要的属性。 它只包含有关于组件类型(例如:一个Button),组件的属性(例如:它的颜色),以及它里面的子元素这些信息。 元素并不是一个实在的实例,而是一种告诉React你想要在屏幕上看到什么东西的方式。你不能在元素上面调用方法。它只是一个不可修改的描述性对象,带有两个属性域:type:string|ReactClass)和props:Object1 。 |
DOM 元素
|
组件元素
|
组件封装了元素树
|
组件可以是类或者函数
|
自上而下的整合
|
只有声明为类的组件拥有实例,而你从来不会去直接创建它们: React 会为你做这些事儿。而存在的父组件访问子组件实例的机制, 只被用于必要的操作(比如设置一个输入域的焦点),并且一般应该避免这样做。 React 会为每个类组件负责创建一个实例,因此你可以用一种面向对象的方法使用方法和本地状态编写组件,但除此之外,实例在 React 的编程模型中并不是特别重要,并且它是有 React 自身去管理的。 总结元素时一个纯对象,描述了你想要在屏幕上显示的 DOM 节点或者其它组件。元素可以在他们的 props 中包含其它元素。创建一个 React 组件是廉价的。元素一旦被创建,就从不会被改变。 组件可以用几种不同的方式进行声明。它可以是一个带有 render() 方法的类。也可在简单的情况下被定义成一个函数。两种情况中它都是以 props 作为输入,以返回的元素树作为输出。 当组件会接收一些 props 作为输入,这是因为一个特定的父组件会返回一个带有其类型和 props 的元素。这就是为什么人们会说在 React 中 props 会单项流转: 从父元素到子元素。 |
实例是你在你写的组件类中使用 this 表示的东西,这在存储本地状态和对生命周期内的事件做出反应中是有用的。 函数式组件根本没有实例。类组件有实例,但是你不必自己创建一个组件实例 —— React 自己处理。 最终,使用 React.createElement(), JSX, 或者 element factory helper 创建元素。不必通过在代码中写元素的简单类 —— 只要知到它们是隐藏的类就可以了。 深入阅读 |
1.所有的 React 元素由于安全原因都需要一个额外的 $$typeof: Symbol.for('react.element')字段声明。在上面的例子中遗漏了这段。这个博客的入口为元素使用内联对象,是为了让你知道下面会发生什么,但是代码不能运行,除非对元素你添加了 $$typeof,或者修改代码去使用 React.createElement() 或 JSX。 |
本文转自:开源中国社区 [http://www.oschina.net]
本文标题:React 组件,元素和实例
本文地址:http://www.oschina.net/translate/react-components-elements-and-instances
参与翻译:祝青, leoxu, gracesyuan
英文原文:React Components, Elements, and Instances