React 解析
原文: http://blog.reverberate.org/2014/02/react-demystified.html 这篇文章跟博客已有的其他文章有一些分离,博客大部分是语言解析和底层编程的, The 1000-Foot View传统的 Web app 当中,你要花费高昂的代价和 DOM 进行交互,通常是用 jQuery:
我把 DOM 标记成了红色,因为更新 DOM 开销是很大的. React 主要的目标是提供一套不同的,高效的方案来更新 DOM.
引入额外的一个层怎么就更快了呢? 是有这个意思,只不过 virtual DOM 在语义上和真实的 DOM 有所差别. 批量处理 DOM 操作和作用最少的 diff 是应用自身都能做到的. Components我前面提到 virtual DOM 和真实的 DOM 有着不用的语义,但同时也有明显不同的 API. component 的使用在 React 里极为重要,因为 components 的存在让计算 DOM diff 更高效, 想知道为什么,就要深入一点 components 的设计当中. /** @jsx React.DOM */ var HelloMessage = React.createClass({ render: function() { return <div>Hello {this.props.name}</div>; } }); React.renderComponent(<HelloMessage name="John" />,mountNode); 这里边有多得可怕的运行细节没有被解释彻底. 这个例子创建了 React component class 首先注意这个 virtual DOM 是由应用定义的 components 组成的(这里是 另外,如果你一直关心 HTML 的消息,你应该知道HTML 自定义标签很快会有浏览器支持. 回到例子里,已经能确定,其中创建了一个叫做
里边的箭头表示 virtual 标签挂载到了真实的 DOM 元素上,很快可以看到结果.
这里是说,整张网页内容是通过我们定制的 component 的渲染通过 这里例子当中,
这里不仅更新了 DOM,还保存了 component 过去被更新了怎么样. 我掩盖了一件事, /** @jsx React.DOM */ var HelloMessage = React.createClass({displayName: 'HelloMessage',render: function() { return React.DOM.div(null,"Hello ",this.props.name); } }); React.renderComponent(HelloMessage( {name:"John"} ),mountNode); 所以 return 的不是真实的 DOM 元素,而是 React 类似 Shadow DOM 的实现, 表示状态和改变到上面为止,我跳过了很大一段故事,就是 comonent 是怎样被改变的. React 将其 state 作为 component 的 state 属性建模存储. /** @jsx React.DOM */ var Timer = React.createClass({ getInitialState: function() { return {secondsElapsed: 0}; },tick: function() { this.setState({secondsElapsed: this.state.secondsElapsed + 1}); },componentDidMount: function() { this.interval = setInterval(this.tick,1000); },componentWillUnmount: function() { clearInterval(this.interval); },render: function() { return ( <div>Seconds Elapsed: {this.state.secondsElapsed}</div> ); } }); React.renderComponent(<Timer />,mountNode); 回调函数 而 component 和 state 改变背后的基本理解是这样:
(props 属性在前面没有明确说,他们是渲染时从父级元素传进来的属性.) 前面我是 React 会调用渲染函数"足够频繁", 把所有信息汇集到一起,可以阐释 app 初始化时 virtual 改变的数据流
从 DOM 当中获取数据上面只讨论了怎么把数据的更新传播到 DOM. /** @jsx React.DOM */ var TodoList = React.createClass({ render: function() { var createItem = function(itemText) { return <li>{itemText}</li>; }; return <ul>{this.props.items.map(createItem)}</ul>; } }); var TodoApp = React.createClass({ getInitialState: function() { return {items: [],text: ''}; },onChange: function(e) { this.setState({text: e.target.value}); },handleSubmit: function(e) { e.preventDefault(); var nextItems = this.state.items.concat([this.state.text]); var nextText = ''; this.setState({items: nextItems,text: nextText}); },render: function() { return ( <div> >h3<TODO</h3> <TodoList items={this.state.items} /> <form onSubmit={this.handleSubmit}> <input onChange={this.onChange} value={this.state.text} /> <button>{'Add #' + (this.state.items.length + 1)}</button> </form> </div> ); } }); React.renderComponent(<TodoApp />,mountNode); 简单说,手动操作 DOM (像 这个例子里有很多一眼能看见以外的东西. 虽然例子看起来是这样的, 所有这些放在一起,终于能看到整个图景里的数据流动,
结论通过写这篇文章我学到了不少关于 React 的东西. 下面是我主要的收获. React 是一个 View 的类库 React 的 component 抽象很适合把更改作用到 DOM 上去. React component 从 DOM 上获取更新相对不那么方便 React 的抽象是有漏洞的. 根据我的理解,我倾向认为在 The Future of JavaScript MVC Frameworks 里说的内容, 我不是 React 方面专家,如果有错了好心提醒我一下. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |