react.js 从零开始(七)React (虚拟)DOM

React 元素

React 中最主要的类型就是 ReactElement。它有四个属性:typepropskey 和ref。它没有方法,并且原型上什么都没有。

可以通过 React.createElement 创建该类型的一个实例。

var root = React.createElement(‘div‘);

为了渲染一个新的树形结构到 DOM 中,你创建若干个 ReactElement,然后传给React.render 作为第一个参数,同时将第二个参数设为一个正规的 DOM 元素HTMLElement 或者 SVGElement)。不要混淆 ReactElement 实例和 DOM 元素 实例。一个 ReactElement 实例是一个轻量的,无状态的,不可变的,虚拟的 DOM 元素 的表示。是一个虚拟 DOM。

React.render(root, document.body);

要添加属性到 DOM 元素,把属性对象作为第二个参数传入 React.render,把子级作为第三个参数传给 React.render

var child = React.createElement(‘li‘, null, ‘Text Content‘);
var root = React.createElement(‘ul‘, { className: ‘my-list‘ }, child);
React.render(root, document.body);

如果使用 React JSX 语法,这些 ReactElement 实例自动创建。所以,如下代码是等价的:

var root = <ul className="my-list">
             <li>Text Content</li>
           </ul>;
React.render(root, document.body);

工厂

一个 ReactElement 工厂就是一个简单的函数,该函数生成一个带有特殊 type 属性的ReactElement。React 有一个内置的辅助方法用于创建工厂函数。事实上该方法就是这样的:

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

该函数能创建一个方便的短函数,而不是总调用 React.createElement(‘div‘)

var div = React.createFactory(‘div‘);
var root = div({ className: ‘my-div‘ });
React.render(root, document.body);

React 已经内置了常用 HTML 标签的工厂函数:

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

如果使用 JSX 语法,就不需要工厂函数了。JSX 已经提供了一种方便的短函数来创建ReactElement 实例。

React 节点

一个 ReactNode 可以是:

  • ReactElement
  • string (又名 ReactText
  • number (又名 ReactText
  • ReactNode 实例数组 (又名 ReactFragment

这些被用作其它 ReactElement 实例的属性,用于表示子级。实际上它们创建了一个ReactElement 实例树。 (These are used as properties of other ReactElements to represent children. Effectively they create a tree of ReactElements.)

React 组件

在使用 React 开发中,可以仅使用 ReactElement 实例,但是,要充分利用 React,就要使用 ReactComponent 来封装状态化的组件。

一个 ReactComponent 类就是一个简单的 JavaScript 类(或者说是“构造函数”)。

var MyComponent = React.createClass({
  render: function() {
    ...
  }
});

当该构造函数调用的时候,应该会返回一个对象,该对象至少带有一个 render 方法。该对象指向一个 ReactComponent 实例。

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

除非为了测试,正常情况下不要自己调用该构造函数。React 帮你调用这个函数。

相反,把 ReactComponent 类传给 createElement,就会得到一个 ReactElement 实例。

var element = React.createElement(MyComponent);

或者使用 JSX:

var element = <MyComponent />;

当该实例传给 React.render 的时候,React 将会调用构造函数,然后创建并返回一个ReactComponent

var component = React.render(element, document.body);

如果一直用相同的 ReactElement 类型和相同的 DOM 元素容器调用 React.render,将会总是返回相同的实例。该实例是状态化的。

var componentA = React.render(<MyComponent />, document.body);
var componentB = React.render(<MyComponent />, document.body);
componentA === componentB; // true

这就是为什么不应该创建你自己的实例。相反,在创建之前,ReactElement 是一个虚拟的ReactComponent。新旧 ReactElement 可以比对,从而决定是创建一个新的ReactComponent 实例还是重用已有的实例。

ReactComponent 的 render 方法应该返回另一个 ReactElement,这就允许组件被组装。 (The render method of a ReactComponent is expected to return another ReactElement. This allows these components to be composed. Ultimately the render resolves intoReactElement with a string tag which instantiates a DOM Element instance and inserts it into the document.)

正式的类型定义

入口点(Entry Point)

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

节点和元素(Nodes and Elements)

type ReactNode = ReactElement | ReactFragment | ReactText;

type ReactElement = ReactComponentElement | ReactDOMElement;

type ReactDOMElement = {
  type : string,
  props : {
    children : ReactNodeList,
    className : string,
    etc.
  },
  key : string | boolean | number | null,
  ref : string | null
};

type ReactComponentElement<TProps> = {
  type : ReactClass<TProps>,
  props : TProps,
  key : string | boolean | number | null,
  ref : string | null
};

type ReactFragment = Array<ReactNode | ReactEmpty>;

type ReactNodeList = ReactNode | ReactEmpty;

type ReactText = string | number;

type ReactEmpty = null | undefined | boolean;

类和组件(Classes and Components)

type ReactClass<TProps> = (TProps) => ReactComponent<TProps>;

type ReactComponent<TProps> = {
  props : TProps,
  render : () => ReactElement
};
时间: 2024-08-24 16:08:57

react.js 从零开始(七)React (虚拟)DOM的相关文章

react学习(四)Element和虚拟DOM

参考:https://facebook.github.io/react/docs/rendering-elements.html (一)Element 1.Element是react中最小的构建单元,是一个对象不是DOM,创建的代价比较低. (1)通常我们在代码中使用JSX定义一个Element: const element = <h1>Hello, world</h1>; (2)使用ReactDOM.render来渲染 ReactDOM.render( element, docu

react.js 从零开始(一)

React 是什么? 网络上的解释很多...我这里把他定义为 通过javascript 的形式组件化 html的框架... React 仅仅是 VIEW 层. React 提供了模板语法以及一些函数钩子用于基本的 HTML 渲染.这就是 React 全部的输出——HTML.你把 HTML / JavaScript 合到一起,被称为“组件”,允许把它们自己内部的状态存到内存中(比如在一个选项卡中哪个被选中),不过最后你只是吐出 HTML. React 的安装? 首先是下载 reactjs的文件包.

學習 React.js:用 React.js 和 Flux 創建一個簡單的購物車

Creating A Simple Shopping Cart with React.js and Flux Ken Wheeler (@ken_wheeler) 簡介 歡迎來到學習 React 的第四章這也是最後一章!到現在,我們已經學習了怎樣利用 React 的 API 來創建狀態型組件,如何應用它們,以及如何運用臉書的 Flux 架構來工作的 今天我們將把所有的這一切放到一塊,來創建一個簡單的購物車應用.在現在的電商網站上,產品的詳細頁面相互依賴,而 React 有助於簡化並有效的組織它們

react.js 从零开始(四)React 属性和状态详解

属性的含义和用法: 1.属性的含义. props=properties 属性:一个事物的性质和关系. 属性往往与生俱来,不可以修改. 2. 属性的用法. <Helloworld name=??? /> 这个name 可以是 变量 ,对象,数组,函数表达式的值. var props={ a:1, b:2 } <Helloworld {...props} /> 这样react就会自动遍历props对象并添加到属性中去. 状态的含义和用法: 1.状态的含义. state 状态:事物所处的

react.js 从零开始(三)JSX 语法及特点介绍

什么是jsx? jsx = JavaScript + xml jsx 是一种 Ecmascript 的一种新标准. jsx 是一种 带有结构性的语法. jsx 的特点: 1.类xml语法易于理解. 2.增强js语意. 3.结构清晰. 4.抽象程度高,易于跨平台. 5.代码模块化. 如何使用jsx? var style={color:"red"}; var HolleWorld = React.createClass({ render: function() { return <p

react.js 从零开始(二)组件的生命周期

什么是生命周期? 组件本质上是一个状态机,输入确定,输出一定确定. 当状态改变的时候 会触发不同的钩子函数,可以让开发者做出响应.. 一个组件的生命周期可以概括为 初始化:状态下 可以自定义的函数 getDefaultProps object getDefaultProps() 在组件类创建的时候调用一次,然后返回值被缓存下来.如果父组件没有指定 props 中的某个键,则此处返回的对象中的相应属性将会合并到 this.props (使用 in 检测属性). 该方法在任何实例创建之前调用,因此不

Angular、React.js 和Node.js到底选谁?

为了工作,程序员选择正确的框架和库来构建应用程序是至关重要的,这也就是为什么Angular和React之间有着太多的争议.Node.js的出现,让这场战争变得更加复杂,虽然有选择权通常是一件很棒的事情,但在这种情况下,对于到底应该选择哪种框架,程序员之间并没有一致的意见,每个人都有不同的想法,并且听起来都相当合理. 为了让一切归于和谐,本文就来探究一下这三大框架各自的优缺点. 基础知识部分: 在我们深入研究这三种框架的具体细节之前,先来了解一些前情提要.yigouyul22.com xucaiz

React JS 基础知识17条

1. 基础实例 <!DOCTYPE html> <html> <head> <script src="../build/react.js"></script> <script src="../build/react-dom.js"></script> <script src="../build/browser.min.js"></script&g

React.js 新手教程

正如你能从标题猜到的,这篇文章的目标是给那些有很少编程经验的读者的.比如,像我这样的人:因为迄今为止,我才探索了编程世界6个月.所以,这将是一篇新手村教程! 你只需要拥有对 HTML 和 CSS 的理解,以及基本的 JavaScript(JS)知识就能看懂本文. 注意:在接下来的例子中,我们将会利用 ES6 提供的新能力,来简化写 JS 代码的过程.然而,你也能完全使用 ES5 来写 React. 预计阅读时间9分钟 什么是 React ? React 是一个 JS 库,由 Facebook 和