本篇会简明扼要的介绍一下React的使用方法。代码会用JSX+ES5和JSX+ES6两种方式实现。 javascript
React来自Facebook,于2013年开源。至今不断修改完善,如今已经到达了版本0.14.2。能够注意到版本尚未到1.0, 广泛应用到大部分产品中还须要必定的时间。2015年3月份,FaceBook发布了React Native,一个用react来构建native app的框架。
步入正题,React是一个javascript的类库,用于构建用户界面。php
JUST THE UI
不一样于Angularjs框架,React不属于MVC框架,它能够算是MVC里面的V层,因此相对来讲入门也简单一下(只指入门,深度研究的话也不简单)。css
DATA FLOW
React是单向响应的数据流。html
一种特殊的js语法,能够在js代码中直接使用html标签。是个语法糖,提升编写代码效率。
要注意不能在标签的中间添加注释,由于最终仍是要翻译成原生js,标签中添加注释至关于在一行代码还没完的时候就添加注释。
在jsx中,变量用花括号包围起来,花括号内的语句将以js代码的方式解析。
例如:java
// 用纯js在react中建立a标签 var newDom=<React.createElement('a', {href: 'https://facebook.github.io/react/'}, 'Hello!');
// 用jsx在react中建立a标签 var newDom=<a href="https://facebook.github.io/react/">Hello!</a>;
要让浏览器认识这种新的语法,就须要下面介绍的babel了。react
是一个javascript代码转换器,在这里咱们能够用于jsx转换为原生js,es6转换为es5(大部分都能转换)。固然它的功能不仅这些,有兴趣的能够去babel官网看看。它还有个线上的转换器,代码比较简单的时候用这个排查问题或练习es6很方便。
介绍两种经常使用的使用方式:webpack
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
//在webpack.config.js文件中配置 module.exports = { module: { loaders: [{ test: /\.jsx?$/, loader: 'babel' }] } }
能够在本地编译好代码后,再将编译后的代码给html引用,提升性能,适合大项目。git
一个模块打包工具,它把不一样的、相互依赖的静态资源都视做模块,而且打包成咱们想要的静态资源。
另外能够方便的配置多种预处理器,如babel。
使用webpack,让代码组织更清晰,一个文件就是一个模块。es6
ES6,也叫ECMAScript2015(如下统称ES6),是ECMAScript标准的最新版本。详细可见ES6的特性简述(译+部分解析)github
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>demo</title> </head> <body> <div id='example'></div> <script src="./build/react.js"></script> <script src="./build/react-dom.js"></script> <script src="./build/browser.min.js"></script> <script type="text/babel"> // react代码写到这里 ReactDOM.render(<h1>hello word!</h1>,document.getElementById('example')); </script> </body> </html>
通常从定义到使用组件的流程是:定义组件creatClass,实现render方法->将组件渲染到页面ReactDOM.render()。
ReactElement对象能够当作是虚拟DOM树。它既是渲染组件ReactDOM.render(root,container)的第一个参数,又是建立组件React.createClass中render方法的返回值。记住ReactElement是惟一父节点的’dom树‘就好。
React.createElement( string/ReactClass type, //type组件类型能够是内置的标签,如div;也能够是由React.createClass(object specification)建立的虚拟组件 [object props], // 标签属性,数组 [children ...],// 标签的innerHtml )//返回类型是ReactElement
var newDom=React.createElement('a', {href: 'https://facebook.github.io/react/'}, 'Hello!');
<a href=''>Hello</a>
react-dom模块中的方法。
ReactDom.render(root, container);
root为ReactElement类型,表示root替换container中的元素。注意是替换不是追加,因此有些状况父元素应该设置为空。
var content=React.createElement('h1',{},'hello'); ReactDOM.render(content,document.getElementById('example'));
ReactDOM.render(<h1>hello word!</h1>,document.getElementById('example'));
组件是一个自定义的js对象,在es5中使用React.createClass();在es6中必须继承React.component。
其中有个特殊的render方法,返回ReactElement对象。该方法会在咱们使用JSX语法的标签
如:ReactDOM.render(<MyElement />,document.getElementById('example'))
var NewDom = React.createClass({//类名必定要大写开头 render: function() { return ( <ol> { React.Children.map(this.props.children, function (child) { //得到元素的子元素 console.info(this); console.info('child:'+child); return <li>{child}</li>;//变量用花括号标识 })//由于有多个子元素,因此返回的是数组。按照JSX变量是数组来解析。 } </ol> ); } }); ReactDOM.render( <NewDom> <span>lala</span> <span>ass</span> </NewDom>, document.getElementById('example') );
class NewDom extends React.Component{ render() {//开头花括号必定要和小括号隔一个空格,不然识别不出来 return <ol>//标签开头必定要和return一行 { React.Children.map(this.props.children, function (child) { return <li>{child}</li>; }) } </ol>; } } ReactDOM.render( <NewDom> <span>lala</span> <span>ass</span> </NewDom>, document.getElementById('example') );
一个js对象,对应于dom的属性。
<a className="center"></a>
<a style={{backgroundImage: 'url(' + imgUrl + ')',font:'12px'}}></a>
<a newProp="propValue"></a>
。这样就能够在this.props['newProp']中读取值var NewDom = React.createClass({//类名必定要大写开头 getDefaultProps: function() {//设置默认属性 return {title:'133'}; }, propTypes: { title:React.PropTypes.string, },//属性校验器,表示必须是string render: function() { return <div>{this.props.title}</div>;//变量用花括号标识 } });
class NewDom extends React.Component{ //不能再组件定义的时候定义一个属性 render() { return <div >1{this.props.title}</div>; }//开头花括号必定要和小括号隔一个空格,不然识别不出来 } //es6 这两个属性不能写在class内。 NewDom.propTypes={//属性校验器,表示改属性必须是bool,不然报错 title: React.PropTypes.bool, } NewDom.defaultProps={title:'133'};//设置默认属性
一个js对象,存储着组件当前的状态以及其值的集合。
我的以为这也是react的创新点之一,能够把组件当作一个“状态机”. 根据不一样的status有不一样的UI展现。只要使用setState改变状态值,根据diff算法算出来有差之后,就会执行ReactDom的render方法,从新渲染页面。
这避免了开发者直接操做dom对象已达到从新渲染页面。开发者只须要关注state这个中间人,控制它就能够控制页面刷新。第二篇中评论框的渲染就是使用的state来控制。
是否是感受和props有些相似?通常区分两个的原则是,可变的放在state中,不可变的放在props中。
class *** extends React.Component{ getInitialState: function() { return {liked: false}; } }
class *** extends React.Component{ constructor(props) { super(props); this.state = {liked: false}; } }
this.setState(新的state对象);
事件名
和属性名相似,到了react中,事件名也成了驼峰命名法,好比onclick变为了onClick.
var NewDom = React.createClass({//类名必定要大写开头 btnClick:function(ele){ console.info(ele); console.info(this.refs.tex); }, render: function() { return <div > <input type="text" ref="tex" /> <input type="button" onClick={this.btnClick} value='click me' /> </div>;//变量用花括号标识 } });
class NewDom extends React.Component{ btnClick(){ console.info(this);//this为该组件类 console.info(this.refs.tex);//this.refs.tex为组件里面索引为tex的 } render() { return <div > <input type="text" ref="tex" /> <input type="button" onClick={this.btnClick.bind(this)} value='click me' /> </div>;//注意bind后面的this } }
handleChange: function(event) { this.setState({value: event.target.value});//event.target.value元素的值 }
每一个控件取值不同,value是指input控件,下拉框为selected,radiobutton为checked。a标签是innerHtml。能够本身经过console.info(e.target) 调试出本身想要的那个字段
render() {//开头花括号必定要和小括号隔一个空格,不然识别不出来 return <ol>//标签前一半必定要和return一行 { React.Children.map(this.props.children, function (child) { return <li>{child}</li>; }) } </ol>; }
onClick={this.func1.bind(this)}
。通过这番简单的练习后,若是还想看看作一个项目中如何使用react参见下章,一个模仿微博展现的demo(编写ing)。 本文没有对react做深刻的研究。经过学习react的使用方法能够看到,react入门的话相对于其余框架仍是比较简单的,代码逻辑也很清晰,好维护也好使用。重要的是,须要使用者把从前直接对dom操做的思惟方式转换过来,相信会爱上它的。 ps: react 还在发展期,学习的话建议英语好的直接看官方文档,能够少走一些弯路。