React是怎么搞的?
React中,把一切东西都看成组件,而且所有组件有其状态。
什么是状态?简单来说,一个组件有多种有限的状态,但同时只能是一种状态,不过条件处罚就会变成另一种状态。学术上叫有限状态机。
具体可以参考阮老师的这篇http://www.ruanyifeng.com/blog/2013/09/finite-state_machine_for_javascript.html
从评论这个组件说起,评论组件整体叫做CommentBox,这个父组件有两个子组件:CommentList和CommentForm,CommentList中又包含Comment这个小组件。
从CommentBox开始
先来看看最大的CommentBox,创建一个叫CommentBox组件,然后可以用这个名字作为标签名实例化。里面包含两个子组件。数据我们可以从属性上传进去。
jsvar data = [ {author: "Pete Hunt",text: "This is one comment"},{author: "Jordan Walke",text: "This is *another* comment"} ]; var CommentBox = React.createClass({ render: function() { return ( <div className="commentBox"> <CommentList data="this.props.data"/> </div> ); } }); var CommentList = React.createClass({ render: function() { var commentNodes = this.props.data.map(function (comment) { return ( <Comment author={comment.author}> {comment.text} </Comment> ); }); return ( <div className="commentList"> {commentNodes} </div> ); } }); React.render( <CommentBox data={data}/>,document.getElementById('content') );
在React中,最重要的两个点之一就是这个props,可以通过组件的属性来传递数据。上面的代码就可以展现出评论的列表。
获取服务器的数据
那么如何获取服务器数据?这个时候就需要引入一开始说的状态state。
jsvar data = [ {author: "Pete Hunt",text: "This is *another* comment"} ]; var CommentBox = React.createClass({ getInitialState: function() { return {data: []}; },loadCommentsFromServer: function() { $.ajax({ url: this.props.url,dataType: 'json',success: function(data) { this.setState({data: data}); }.bind(this),error: function(xhr,status,err) { console.error(this.props.url,err.toString()); }.bind(this) }); },componentDidMount: function() { this.loadCommentsFromServer(); setInterval(this.loadCommentsFromServer,this.props.pollInterval); },render: function() { return ( <div className="commentBox"> <CommentList data={this.state.data} /> </div> ); } }); var CommentList = React.createClass({ render: function() { var commentNodes = this.props.data.map(function (comment) { return ( <Comment author={comment.author}> {comment.text} </Comment> ); }); return ( <div className="commentList"> {commentNodes} </div> ); } }); React.render( <CommentBox url="comments.json" pollInterval={2000}/>,document.getElementById('content') );
通过getInitialState设置初始化的状态,然后通过React提供的用来渲染的componentDidMount来轮询数据,这样就可以获取服务端的数据。
怎么提交数据呢?
也是通过设置props和state来设置组件状态和数据。
jsvar CommentForm = React.createClass({ handleSubmit: function(e) { e.preventDefault(); var author = this.refs.author.getDOMNode().value.trim(); var text = this.refs.text.getDOMNode().value.trim(); if (!text || !author) { return; } this.refs.author.getDOMNode().value = ''; this.refs.text.getDOMNode().value = ''; this.props.onCommentSubmit({author: author,text: text}); return; },render: function() { return ( <form className="commentForm"> <input type="text" placeholder="Your name" /> <input type="text" placeholder="Say something..." /> <input type="submit" value="Post" /> </form> ); } }); var CommentBox = React.createClass({ handleCommentSubmit: function(comment) { $.ajax({ url: this.props.url,type: 'POST',data: comment,render: function() { return ( <div className="commentBox"> <h1>Comments</h1> <CommentList data={this.state.data} /> <CommentForm onCommentSubmit={this.handleCommentSubmit} /> </div> ); } });