发布于 2015-07-12 10:08:32 | 1073 次阅读 | 评论: 0 | 来源: 网络整理
React提供了强大的抽象,让你在大多数应用场景中不再直接操作DOM,但是有时你需要简单地调用底层的API,或者借助于第三方库或已有的代码。
React是很快的,因为它从不直接操作DOM。React在内存中维护一个快速响应的DOM描述。render()
方法返回一个DOM的描述,React能够利用内存中的描述来快速地计算出差异,然后更新浏览器中的DOM。
另 外,React实现了一个完备的虚拟事件系统,尽管各个浏览器都有自己的怪异行为,React确保所有事件对象都符合W3C规范,并且持续冒泡,用一种高 性能的方式跨浏览器(and everything bubbles consistently and in a performant way cross-browser)。你甚至可以在IE8中使用一些HTML5的事件!
大多数时候你应该呆在React的“虚拟浏览器”世界里面,因为它性能更加好,并且容易思考。但是,有时你简单地需要调用底层的API,或许借助于第三方的类似于jQuery插件这种库。React为你提供了直接使用底层DOM API的途径。
为了和浏览器交互,你将需要对DOM节点的引用。每一个挂载的React组件有一个getDOMNode()
方法,你可以调用这个方法来获取对该节点的引用。
注意:
getDOMNode()
仅在挂载的组件上有效(也就是说,组件已经被放进了DOM中)。如果你尝试在一个未被挂载的组件上调用这个函数(例如在创建组件的render()
函数中调用getDOMNode()
),将会抛出异常。
为了获取一个到React组件的引用,你可以使用this
来得到当前的React组件,或者你可以使用refs来指向一个你拥有的组件。它们像这样工作:
var MyComponent = React.createClass({
handleClick: function() {
// Explicitly focus the text input using the raw DOM API.
this.refs.myTextInput.getDOMNode().focus();
},
render: function() {
// The ref attribute adds a reference to the component to
// this.refs when the component is mounted.
return (
<div>
<input type="text" ref="myTextInput" />
<input
type="button"
value="Focus the text input"
onClick={this.handleClick}
/>
</div>
);
}
});
React.render(
<MyComponent />,
document.getElementById('example')
);
为了学习更多有关Refs的内容,包括如何有效地使用它们,参考我们的更多关于Refs文档。
组件的生命周期包含三个主要部分:
React提供生命周期方法,你可以在这些方法中放入自己的代码。我们提供will方法,会在某些行为发生之前调用,和did方法,会在某些行为发生之后调用。
getInitialState(): object
在组件被挂载之前调用。状态化的组件应该实现这个方法,返回初始的state数据。componentWillMount()
在挂载发生之前立即被调用。componentDidMount()
在挂载结束之后马上被调用。需要DOM节点的初始化操作应该放在这里。componentWillReceiveProps(object nextProps)
当一个挂载的组件接收到新的props的时候被调用。该方法应该用于比较this.props
和nextProps
,然后使用this.setState()
来改变state。shouldComponentUpdate(object nextProps, object nextState): boolean
当组件做出是否要更新DOM的决定的时候被调用。实现该函数,优化this.props
和nextProps
,以及this.state
和nextState
的比较,如果不需要React更新DOM,则返回false。componentWillUpdate(object nextProps, object nextState)
在更新发生之前被调用。你可以在这里调用this.setState()
。componentDidUpdate(object prevProps, object prevState)
在更新发生之后调用。componentWillUnmount()
在组件移除和销毁之前被调用。清理工作应该放在这里。挂载的复合组件也支持如下方法:
getDOMNode(): DOMElement
可以在任何挂载的组件上面调用,用于获取一个指向它的渲染DOM节点的引用。forceUpdate()
当你知道一些很深的组件state已经改变了的时候,可以在该组件上面调用,而不是使用this.setState()
。在Facebook,我们支持低版本的浏览器,包括IE8。我们已经写好兼容代码很长时间了,这能让我们写有远见的JS。这意味着我们没有零散的骇客代码充斥在我们的代码库里面,并且我们依然能够预计我们的代码“正常工作起来”。例如,不使用+new Date()
,我们能够写Date.now()
。 At Facebook, we support older browsers, including IE8. We've had polyfills in place for a long time to allow us to write forward-thinking JS. This means we don't have a bunch of hacks scattered throughout our codebase and we can still expect our code to "just work". For example, instead of seeing +new Date()
, we can just write Date.now()
. Since the open source React is the same as what we use internally, we've carried over this philosophy of using forward thinking JS.
In addition to that philosophy, we've also taken the stance that we, as authors of a JS library, should not be shipping polyfills as a part of our library. If every library did this, there's a good chance you'd be sending down the same polyfill multiple times, which could be a sizable chunk of dead code. If your product needs to support older browsers, chances are you're already using something like es5-shim.
kriskowal的es5-shim es5-shim.js
提供了以下react需要的api:
Array.isArray
Array.prototype.every
Array.prototype.forEach
Array.prototype.indexOf
Array.prototype.map
Date.now
Function.prototype.bind
Object.keys
String.prototype.split
String.prototype.trim
kriskowal的es5-shim es5-sham.js
同样提供了以下react需要的api:
Object.create
Object.freeze
The unminified build of React needs the following from paulmillr's console-polyfill.
console.*
When using HTML5 elements in IE8 including <section>
, <article>
, <nav>
, <header>
, and <footer>
, it's also necessary to include html5shiv or a similar script.
Although React is pretty good at abstracting browser differences, some browsers are limited or present quirky behaviors that we couldn't find a workaround for.
On IE8 the onScroll
event doesn't bubble and IE8 doesn't have an API to define handlers to the capturing phase of an event, meaning there is no way for React to listen to these events. Currently a handler to this event is ignored on IE8.
See the onScroll doesn't work in IE8 GitHub issue for more information. ve carried over this philosophy of using forward thinking JS.
In addition to that philosophy, we've also taken the stance that we, as authors of a JS library, should not be shipping polyfills as a part of our library. If every library did this, there's a good chance you'd be sending down the same polyfill multiple times, which could be a sizable chunk of dead code. If your product needs to support older browsers, chances are you're already using something like es5-shim.
es5-shim.js
from kriskowal's es5-shim provides the following that React needs:
Array.isArray
Array.prototype.every
Array.prototype.forEach
Array.prototype.indexOf
Array.prototype.map
Date.now
Function.prototype.bind
Object.keys
String.prototype.split
String.prototype.trim
es5-sham.js
, also from kriskowal's es5-shim, provides the following that React needs:
Object.create
Object.freeze
The unminified build of React needs the following from paulmillr's console-polyfill.
console.*
When using HTML5 elements in IE8 including <section>
, <article>
, <nav>
, <header>
, and <footer>
, it's also necessary to include html5shiv or a similar script.
Although React is pretty good at abstracting browser differences, some browsers are limited or present quirky behaviors that we couldn't find a workaround for.
On IE8 the onScroll
event doesn't bubble and IE8 doesn't have an API to define handlers to the capturing phase of an event, meaning there is no way for React to listen to these events. Currently a handler to this event is ignored on IE8.
See the onScroll doesn't work in IE8 GitHub issue for more information.