React实践系列笔记-Interactivity and Dynamic UIs
Interactivity and Dynamic UIsReact.findDOMNode()组件并不是真实的 DOM 节点,而是存在于内存之中的一种数据结构,叫做虚拟 DOM (virtual DOM)。只有当它插入文档以后,才会变成真实的 DOM 。根据 React 的设计,所有的 DOM 变动,都先在虚拟 DOM上发生,然后再将实际发生变动的部分,反映在真实 DOM上,这种算法叫做 DOM diff ,它可以极大提高网页的性能表现。但是,有时需要从组件获取真实 DOM 的节点,这时就要用到 React.findDOMNode 方法。 var MyComponent = React.createClass({
handleClick: function() {
React.findDOMNode(this.refs.myTextInput).focus();
},render: function() {
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')
);
需要注意的是,由于 React.findDOMNode 方法获取的是真实 DOM ,所以必须等到虚拟 DOM 插入文档以后,才能使用这个方法,否则会返回 null 。上面代码中,通过为组件指定 Click 事件的回调函数,确保了只有等到真实 DOM 发生 Click 事件之后,才会调用 React.findDOMNode 方法。 getInitialState设置State的初始状态。 var MyComponent = React.createClass({
getInitialState: function(){
return {
count: 5
}
},render: function(){
return (
<h1>{this.state.count}</h1>
)
}
});
Style
Inline-style在React中,如果要使用行内元素,不可以直接使用style="”这种方式,可以有: import React from 'react';
var style = {
backgroundColor: '#EEE'
};
export default React.createClass({
render: function () {
return (
<div style={style}> //或者<div style={{backgroundColor: '#EEE'}}> <h1>Hello world</h1> </div> ) } });
可以看出,React的style属性接收的也是一个JavaScript对象。 Class你可以根据这个策略为每个组件创建 CSS 文件,可以让组件名和 CSS 中的 class 使用一个命名空间,来避免一个组件中的一些 class 干扰到另外一些组件的 class。 app/components/MyComponent.css .MyComponent-wrapper { background-color: #EEE; }
app/components/MyComponent.jsx import './MyComponent.css';
import React from 'react';
export default React.createClass({
render: function () {
return (
<div className="MyComponent-wrapper"> <h1>Hello world</h1> </div> ) } });
Multiple Class上文中提及的利用className方式赋值,如果在存在多个类名的情况下: render: function() {
var cx = React.addons.classSet;
var classes = cx({
'message': true,'message-important': this.props.isImportant,'message-read': this.props.isRead
});
// same final string,but much cleaner
return <div className={classes}>Great,I'll be there.</div>;
}
EventReact对于事件的支持非常完善,可以查看[这里][8]。React 实现了一个“合成事件”层(synthetic event system),这个事件模型保证了和 W3C 标准保持一致,所以不用担心有什么诡异的用法,并且这个事件层消除了 IE 与 W3C 标准实现之间的兼容问题。“合成事件”额外提供了两个好处:**自动绑定上下文和事件委托**
Event Bind最基本的绑定方式就是依靠类似于```onClick={handleClick}```的方式,要注意,这里不同于ng-click,onClick传递的参数只能是一个方法,而不能是一个调用。如果要简单来写的话可以采Lambda表达式的方式: onClick={()=>{alert(1);}}
Event Params给事件处理函数传递额外参数的方式:`bind(this,arg1,arg2,...)` render: function() {
return <p onClick={this.handleClick.bind(this, 'extra param')}>;
},handleClick: function(param,event) {
// handle click
}
由上面可以看出,Event一般都是作为最后一个参数传递到handleClick中,这里的event是SyntheticEvent对象,它的主要属性如下: boolean bubbles
boolean cancelable
DOMEventTarget currentTarget
boolean defaultPrevented
number eventPhase
boolean isTrusted
DOMEvent nativeEvent
void preventDefault()
void isDefaultPrevented()
void stopPropagation()
void isPropagationStopped()
DOMEventTarget target
number timeStamp
string type
List Element在React中,也会经常遇到需要为某个群组绑定事件的情况,可以参考如下代码: var GroceryList = React.createClass({
handleClick: function(i) {
console.log('You clicked: ' + this.props.items[i]);
},render: function() {
return (
<div> {this.props.items.map(function(item,i) { return ( <div onClick={this.handleClick.bind(this, i)} key={i}>{item}</div> ); },this)} </div> ); } }); React.render( <GroceryList items={['Apple', 'Banana','Cranberry']} />,mountNode );
TouchEventIf you’d like to use React on a touch device such as a phone or tablet,simply call 接口暴露譬如在某个子组件中,提供了某个方法: var ButtonComponent = React.createClass({
getDragonKillingSword: function(){
//送宝刀
},render: function(){
return (<button onClick={this.getDragonKillingSword}>屠龙宝刀,点击就送</button>); } });
如果在父组件中想手动调用该方法,则可以利用ref方式: var ImDaddyComponent = React.createClass({
render: function(){
return (
<div> //其他组件 <ButtonComponent /> //其他组件 </div> ); } });
在父组件的功能方程中: this.refs.getSwordButton.getDragonKillingSword();
反之,如果需要在子组件中调用父组件的方法,则可以直接将父组件的方法作为Props参数传入到子组件中: <ButtonComponent clickCallback={this.getSwordButtonClickCallback}/>
Ajax组件的数据来源,通常是通过 Ajax 请求从服务器获取,可以在componentDidMount 方法中设置 Ajax 请求,等到请求成功,再用 this.setState 方法重新渲染 UI。 var UserGist = React.createClass({
getInitialState: function() {
return {
username: '',lastGistUrl: ''
};
},componentDidMount: function() {
$.get(this.props.source,function(result) {
var lastGist = result[0];
if (this.isMounted()) {
this.setState({
username: lastGist.owner.login,lastGistUrl: lastGist.html_url
});
}
}.bind(this));
},render: function() {
return (
<div> {this.state.username}'s last gist is <a href={this.state.lastGistUrl}>here</a>. </div> ); } }); React.render( <UserGist source="https://api.github.com/users/octocat/gists" />,document.body );
不过笔者习惯还是将整个获取数据,处理数据的业务逻辑放在Angular中进行。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |