前言前言React是Facebook推出的一个用来构建用户界面的JavaScript库。具备以下特性:•不是一个MVC框架•不使用模板•响应式更新非常简单•HTML5仅仅是个开始仅仅是UI仅仅是UI许多人使用React作为MVC架构的V层。尽管React并没有假设过你的其余技术栈,但它仍可以作为一个小特征轻易地在已有项目中使用虚拟DOM虚拟DOMReact为了更高超的性能而使用虚拟DOM作为其不同的实现。它同时也可以由服务端Node.js渲染-而不需要过重的浏览器DOM支持数据流数据流React实现了单向响应的数据流,从而减少了重复代码,这也是它为什么比传统数据绑定更简单。一个简单的组件一个简单的组件React组件通过一个render()方法,接受输入的参数并返回展示的对象。以下这个例子使用了JSX,它类似于XML的语法输入的参数通过render()传入组件后,将存储在this.propsJSX是可选的,并不强制要求使用。JSX是可选的,并不强制要求使用。点击CompiledJS可以看到JSX编译之后的JavaScript代码LiveJSXEditorvarHelloMessage=React.createClass({render:function(){returndivHello{this.props.name}/div;}});React.render(HelloMessagename=John/,mountNode)HelloJohnCompiledJSvarHelloMessage=React.createClass({displayName:HelloMessage,render:function(){returnReact.createElement(div,null,Hello,this.props.name);}});React.render(React.createElement(HelloMessage,{name:John}),mountNode);一个有状态的组件一个有状态的组件除了接受输入数据(通过this.props),组件还可以保持内部状态数据(通过this.state)。当一个组件的状态数据的变化,展现的标记将被重新调用render()更新。LiveJSXEditorvarTimer=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(divSecondsElapsed:{this.state.secondsElapsed}/div);}});React.render(Timer/,mountNode);CompiledJSvarTimer=React.createClass({displayName:Timer,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(React.createElement(div,null,SecondsElapsed:,this.state.secondsElapsed));}});React.render(React.createElement(Timer,null),mountNode);一个应用程序一个应用程序通过使用props和state,我们可以组合构建一个小型的Todo程序。下面例子使用state去监测当前列表的项以及用户已经输入的文本。尽管事件绑定似乎是以内联的方式,但他们将被收集起来并以事件代理的方式实现。LiveJSXEditorCompiledJSvarTodoList=React.createClass({render:function(){varcreateItem=function(itemText){returnli{itemText}/li;};returnul{this.props.items.map(createItem)}/ul;}});varTodoApp=React.createClass({getInitialState:function(){return{items:[],text:''};},onChange:function(e){this.setState({text:e.target.value});},handleSubmit:function(e){e.preventDefault();varnextItems=this.state.items.concat([this.state.text]);varnextText='';this.setState({items:nextItems,text:nextText});},render:function(){return(divh3TODO/h3TodoListitems={this.state.items}/formonSubmit={this.handleSubmit}inputonChange={this.onChange}value={this.state.text}/button{'Add#'+(this.state.items.length+1)}/button/form/div);}});React.render(TodoApp/,mountNode);CompiledJSvarTodoList=React.createClass({displayName:TodoList,render:function(){varcreateItem=function(itemText){returnReact.createElement(li,null,itemText);};returnReact.createElement(ul,null,this.props.items.map(createItem));}});varTodoApp=React.createClass({displayName:TodoApp,getInitialState:function(){return{items:[],text:''};},onChange:function(e){this.setState({text:e.target.value});},handleSubmit:function(e){e.preventDefault();varnextItems=this.state.items.concat([this.state.text]);varnextText='';this.setState({items:nextItems,text:nextText});},render:function(){return(React.createElement(div,null,React.createElement(h3,null,TODO),React.createElement(TodoList,{items:this.state.items}),React.createElement(form,{onSubmit:this.handleSubmit},React.createElement(input,{onChange:this.onChange,value:this.state.text}),React.createElement(button,null,'Add#'+(this.state.items.length+1)))));}});React.render(React.createElement(TodoApp,null),mountNode);一个使用外部插件的组件一个使用外部插件的组件React是灵活的,并且提供方法允许你跟其他库和框架对接。下面例子展现了一个案例,使用外部库Markdown实时转化textarea的值。LiveJSXEditorvarconverter=newShowdown.converter();varMarkdownEditor=React.createClass({getInitialState:function(){return{value:'Typesome*markdown*here!'};},handleChange:function(){this.setState({value:this.refs.textarea.getDOMNode().value});},render:function(){return(divclassName=MarkdownEditorh3Input/h3textareaonChange={this.handleChange}ref=textareadefaultValue={this.state.value}/h3Output/h3divclassName=contentdangerouslySetInnerHTML={{__html:converter.makeHtml(this.state.value)}}//div);}});React.render(MarkdownEditor/,mountNode);CompiledJSvarconverter=newShowdown.converter();varMarkdownEditor=React.createClass({displayName:MarkdownEditor,getInitialState:function(){return{value:'Typesome*markdown*here!'};},handleChange:function(){this.setState({value:this.refs.textarea.getDOMNode().value});},render:function(){return(React.createElement(div,{className:MarkdownEditor},React.createElement(h3,null,Input),React.createElement(textarea,{onChange:this.handleChange,ref:textarea,defaultValue:this.state.value}),React.createElement(h3,null,Output),React.createElement(div,{className:content,dangerouslySetInnerHTML:{__html:converter.makeHtml(this.state.value)}})));}})