前端之React实战-交互与动态UI
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对于事件的支持非常完善,可以查看这里。React 实现了一个“合成事件”层(synthetic event system),这个事件模型保证了和 W3C 标准保持一致,所以不用担心有什么诡异的用法,并且这个事件层消除了 IE 与 W3C 标准实现之间的兼容问题。“合成事件”额外提供了两个好处:自动绑定上下文和事件委托
当然,在React中,也可以使用原生事件,比如你在 Event Bind最基本的绑定方式就是依靠类似于 onClick={()=>{alert(1);}} Event Params给事件处理函数传递额外参数的方式: 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中进行。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |