React (虚拟) DOM 术语

在 React 的术语中,有五个要重点区分的核心类型:

React Elements(React 元素)

React里的首要类型是 ReactElement.它有四个 properties:type, props, keyref.它没有方法,在 prototype 上什么也没有.

你可以通过 React.createElement 来创建这些对象.

  1. var root = React.createElement('div');

要渲染一个新的树到DOM上,你创建 ReactElements 并传递他们到 ReactDOM.render 伴随着一个标准的 DOM Element (HTMLElementSVGElement).ReactElements 不要与 DOM Elements 混淆.ReactElement 是一个轻的,有状态的,不可变的,虚拟的DOM Element 的表达.它是一个虚拟 DOM.

  1. ReactDOM.render(root, document.getElementById('example'));

要给一个DOM元素添加 properties,传递一个properties 对象作为第二个参数,第三个参数传递子级.

  1. var child = React.createElement('li', null, 'Text Content');
  2. var root = React.createElement('ul', { className: 'my-list' }, child);
  3. ReactDOM.render(root, document.getElementById('example'));

如果你使用 React JSX,这些ReactElements 已经为你创建了.所以 这是等价的:

  1. var root = <ul className="my-list">
  2. <li>Text Content</li>
  3. </ul>;
  4. ReactDOM.render(root, document.getElementById('example'));

Factories(工厂)

ReactElement-工厂 是一个产生特定 type property的 ReactElement 的函数.React有一个为你内建的辅助工具来创建工厂.它想这样起作用:

  1. function createFactory(type) {
  2. return React.createElement.bind(null, type);
  3. }

它允许你创建一个方便的速记 来代替每次输入 React.createElement('div') .

  1. var div = React.createFactory('div');
  2. var root = div({ className: 'my-div' });
  3. ReactDOM.render(root, document.getElementById('example'));

React 已经具备用于常用 HTML tags的内建工厂

  1. var root = React.DOM.ul({ className: 'my-list' },
  2. React.DOM.li(null, 'Text Content')
  3. );

如果你使用JSX 你没有必要使用工厂.JSX已经为创建 ReactElements 提供了一个 方便的速记.

React Nodes

一个 ReactNode 可以是:

  • ReactElement
  • string (aka ReactText)
  • number (aka ReactText)
  • Array of ReactNodes (aka ReactFragment)

他们被用作其他ReactElements的properties来表示子级.事实上他们创建了一个 ReactElements 的树.

React Components

你可以使用 React只使用ReactElements 但是要真正利用React,你将要使用 ReactComponents 来创建内嵌 state 的封装.

一个 ReactComponent 类就是一个 JavaScript 类 (或者 “constructor function”).

  1. var MyComponent = React.createClass({
  2. render: function() {
  3. ...
  4. }
  5. });

当这个构造函数被调用,期望返回一个至少有一个 render 方法的对象.这个对象被称为一个 ReactComponent.

  1. var component = new MyComponent(props); // never do this

与测试不同,你可能通常 绝不会 亲自调用这个构造函数.React 为你调用它.

作为替代,你传递 ReactComponent 类到 createElement,你得到一个 ReactElement.

  1. var element = React.createElement(MyComponent);

或者用 JSX:

  1. var element = <MyComponent />;

当这个被传给 ReactDOM.render,React 会为你调用构造函数并创建一个 ReactComponent,返回给你.

  1. var component = ReactDOM.render(element, document.getElementById('example'));

如果你保持用相同类型的 ReactElement 和相同的DOM Element容器调用 ReactDOM.render ,它总是会返回相同的实例.这个实例是状态化的.

  1. var componentA = ReactDOM.render(<MyComponent />, document.getElementById('example'));
  2. var componentB = ReactDOM.render(<MyComponent />, document.getElementById('example'));
  3. componentA === componentB; // true

这就是为什么你不应该构造你自己的实例.作为替代,ReactElement 在它被构造以前 是一个虚拟的 ReactComponent.一个老的和新的ReactElement 可以被比较来判断 一个新的 ReactComponent 实例是否需要被创建或者已经存在的是否应该被重用.

ReactComponentrender 方法被期望返回另一个 ReactElement.这允许这些组件被结构化.最后,渲染分解为 带着一个 string tag的ReactElement,它实例化一个 DOM Element 实例并把它插入document里.

Formal Type Definitions

Entry Point

  1. ReactDOM.render = (ReactElement, HTMLElement | SVGElement) => ReactComponent;

Nodes and Elements

  1. type ReactNode = ReactElement | ReactFragment | ReactText;
  2. type ReactElement = ReactComponentElement | ReactDOMElement;
  3. type ReactDOMElement = {
  4. type : string,
  5. props : {
  6. children : ReactNodeList,
  7. className : string,
  8. etc.
  9. },
  10. key : string | boolean | number | null,
  11. ref : string | null
  12. };
  13. type ReactComponentElement<TProps> = {
  14. type : ReactClass<TProps>,
  15. props : TProps,
  16. key : string | boolean | number | null,
  17. ref : string | null
  18. };
  19. type ReactFragment = Array<ReactNode | ReactEmpty>;
  20. type ReactNodeList = ReactNode | ReactEmpty;
  21. type ReactText = string | number;
  22. type ReactEmpty = null | undefined | boolean;

Classes and Components

  1. type ReactClass<TProps> = (TProps) => ReactComponent<TProps>;
  2. type ReactComponent<TProps> = {
  3. props : TProps,
  4. render : () => ReactElement
  5. };