learn-react
var CommentList = React.createClass({
propTypes: {
data: React.PropTypes.array.isRequired
},
getDefaultProps: function(){
return {
data: []
}
},
renderComment: function(comment){
// the 'key' is required for array items!
// it lets react know when items are removed and added to the list
// should not use array index for the key because the indexes may stay while items are re-ordered/removed
<li key={comment.id}>
<span>{comment.body}</span>
</li>
},
render: function(){
<ul>
{this.props.data.map(this.renderComment)}
</ul>
}
})
var CommentBox = React.createClass({
loadCommentsFromServer: 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)
});
},
handleCommentSubmit: function(comment) {
var comments = this.state.data;
// Optimistically set an id on the new comment. It will be replaced by an
// id generated by the server. In a production application you would likely
// not use Date.now() for this and would have a more robust system in place.
comment.id = Date.now();
var newComments = comments.concat([comment]);
// we set our expected new state
// after the server responds we can reset the state
this.setState({data: newComments});
$.ajax({
url: this.props.url,
dataType: 'json',
type: 'POST',
data: comment,
success: function(data) {
// on success, we set the data from the server because it is the source of truth!
this.setState({data: data, error: false});
}.bind(this),
error: function(xhr, status, err) {
// on error, we put the state back to where it was before.
// can also show an alert because we have an error
this.setState({data: comments, error: status});
console.error(this.props.url, status, err.toString());
}.bind(this)
});
},
getInitialState: function() {
return {data: []};
},
componentDidMount: function() {
this.loadCommentsFromServer();
setInterval(this.loadCommentsFromServer, this.props.pollInterval);
},
render: function() {
return (
<div className="commentBox">
<h1>Comments</h1>
<CommentList data={this.state.data} />
<CommentForm onCommentSubmit={this.handleCommentSubmit} />
</div>
);
}
});