浅谈React实现评论框(三)

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值