浅谈React实现评论框(三)

来源:互联网 发布:在线客服 java开源 编辑:程序博客网 时间:2024/05/29 16:08

http://blog.csdn.net/zhouziyu2011/article/details/70504651实现了不考虑服务器,直接将 JSON 数据写在代码中的模拟从服务器获取数据。

本文继续进行两方面的改进:

1、给组件引进可变的 state

2、从JSON文件从获取数据

 

1、给组件引进可变的 state

之前的代码中每个组件都是基于自己的props渲染自己,但props 是不可变的,它们从父级传来并被父级拥有。

为实现交互,给组件引进了可变的 state,this.state是组件私有的,可通过调用 this.setState() 改变它,每当state更新,组件就重新渲染自己。

var CommentBox = React.createClass({getInitialState: function() {return {data: [{id: 1, author: "Alice", text: "This is Alice's comment"},{id: 2, author: "Bruce", text: "This is Bruce's comment"}]};},render: function() {return (<div className="commentBox"><h1>CommentBox</h1><CommentList data={this.state.data} /><CommentForm /></div>);}});var CommentList = React.createClass({render: function() {var commentNodes = this.props.data.map(function(comment) {return <Comment author={comment.author} key={comment.id}>{comment.text}</Comment>});return (<div className="commentList">{commentNodes}</div>);}});var Comment = React.createClass({render: function() {return (<div className="comment"><h3>{this.props.author}</h3>{this.props.children}</div>);}});var CommentForm = React.createClass({render: function() {return (<div className="commentForm">CommentForm</div>);}});ReactDOM.render(<CommentBox />,document.getElementById('commentBox'));


2、从JSON文件从获取数据

当组件第一次创建时,从服务器获取JSON并更新状态以反映最新的数据,用jQuery的ajax()方法来发送一个异步请求到服务器以获取需要的数据,这些数据暂时从commentBox.json中获取:

commentBox.json文件:

[{"id": 1, "author": "Cindy", "text": "This is Cindy's comment"},{"id": 2, "author": "David", "text": "This is David's comment"}]

注意:JSON格式的文件的键值对的属性和值都要用双引号括起来。

var CommentBox = React.createClass({getInitialState: function() {return {data: []};},componentDidMount: function() {$.ajax({url: this.props.url,dataType: 'json',cache: false,success: function(data) {this.setState({data: data});}.bind(this),error: function(xhr, status, err) {console.error(this.props.url, status, err.toString());}.bind(this)});},render: function() {return (<div className="commentBox"><h1>CommentBox</h1><CommentList data={this.state.data} /><CommentForm /></div>);}});var CommentList = React.createClass({render: function() {var commentNodes = this.props.data.map(function(comment) {return <Comment author={comment.author} key={comment.id}>{comment.text}</Comment>});return (<div className="commentList">{commentNodes}</div>);}});var Comment = React.createClass({render: function() {return (<div className="comment"><h3>{this.props.author}</h3>{this.props.children}</div>);}});var CommentForm = React.createClass({render: function() {return (<div className="commentForm">CommentForm</div>);}});ReactDOM.render(<CommentBox url="commentBox.json"/>,document.getElementById('commentBox'));

componentDidMount() 是被React自动调用的方法,类似于JavaScript中的window.onload,在render()方法之后,也即组件渲染完毕之后,被React自动调用。

getComments()方法封装从服务器获取数据的Ajax调用。componentDidMount()每隔一定时间调用getComments()方法,实现对服务器的轮询。

var CommentBox = React.createClass({getInitialState: function() {return {data: []};},getComments: function() {$.ajax({url: this.props.url,dataType: 'json',cache: false,success: function(data) {this.setState({data: data});}.bind(this),error: function(xhr, status, err) {console.error(this.props.url, status, err.toString());}.bind(this)});},componentDidMount: function() {this.getComments();setInterval(this.getComments, this.props.inteval);},submitComments: function(comment) {$.ajax({url: this.props.url,dataType: 'json',type: 'POST',data: comment,success: function(data) {this.setState({data: data});}.bind(this),error: function(xhr, status, err) {console.error(this.props.url, status, err.toString());}.bind(this)});},render: function() {return (<div className="commentBox"><h1>CommentBox</h1><CommentForm onCommentSubmit={this.submitComments}/><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} key={comment.id}>{comment.text}</Comment>});return (<div className="commentList">{commentNodes}</div>);}});var Comment = React.createClass({render: function() {return (<div className="comment">{this.props.author}:{this.props.children}</div>);}});var CommentForm = React.createClass({getInitialState: function() {return {author: "", text: ""};},setAuthor: function(e) {this.setState({author: e.target.value});},setText: function(e) {this.setState({text: e.target.value});},submitComments: function(e) {e.preventDefault();var author = this.state.author.trim();var text = this.state.text.trim();if (text == "" || author == "")return;this.props.onCommentSubmit({author: author, text: text});this.setState({author: "", text: ""});},render: function() {return (<form className="commentForm" onSubmit={this.submitComments}><input type="text" placeholder="Please enter your name!" value={this.state.author} onChange={this.setAuthor} /><br/><br/><input type="text" placeholder="Please enter your comment!" value={this.state.text} onChange={this.setText} /><br/><br/><input type="submit" value="submit" /></form>);}});ReactDOM.render(<CommentBox url="commentBox.json" inteval="5000"/>,document.getElementById('commentBox'));

CommentForm 组件渲染一个可以输入作者、评论并提交的表单,state带有 author 和 text 两个属性并初始化为空字符串,给表单的author 文本框字段和text文本框字段绑定一个onChange处理器,在字段更新后更新state的值,并给表单绑定一个onSubmit处理器,在表单提交输入后清空表单字段,并通过调用preventDefault()来阻止提交表单的默认行为。

当用户提交评论时,需要刷新评论列表来包含这条新评论,因此需要从子组件传回数据到它的父组件,在父组件的render()方法中传递一个新的回调函数submitComments到子组件,绑定它到子组件的 onCommentSubmit 事件上。

submitComments通过Ajax请求向服务器POST数据来刷新列表。需要注意的是,由于本实例中是用的是静态的JSON文件模拟服务器数据,因此发GET请求可以成功但POST请求则报错404 Not Found,这个问题在正常的服务器请求中不会出现。

1 0
原创粉丝点击