Reputation: 23
I am doing React.js tutorial and here is my code:
//Comment box
var CommentBox = React.createClass({
loadCommentsFromServer: function() {
$.ajax({
url: this.props.url,
dataType: 'json',
success: function(data) {
this.setState({data: data});
console.log('Data has obtained... Refresh state')
}.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;
var newComments = comments.concat([comment]);
this.setState({data: newComments});
$.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)
})
},
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>
);
}
});
//Comment list
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>
);
}
});
//Comment form
var CommentForm = React.createClass({
handleSubmit: function(e) {
e.preventDefault();
var author = React.findDOMNode(this.refs.author).value.trim();
var text = React.findDOMNode(this.refs.text).value.trim();
if (!text || !author) {
return;
}
this.props.onCommentSubmit({author: author, text: text});
//TODO: send request to the server
React.findDOMNode(this.refs.author).value = '';
React.findDOMNode(this.refs.text).value = '';
},
render: function() {
return (
<form className="commentForm" onSubmit={this.handleSubmit}>
<input type="text" placeholder="Your name" ref="author" />
<input type="text" placeholder="Say something..." ref="text" />
<input type="submit" value="Post" />
</form>
);
}
});
//Comment
var converter = new Showdown.converter();
var Comment = React.createClass({
render: function() {
var rawMarkup = converter.makeHtml(this.props.children.toString());
return (
<div className="comment panel">
<h3 className="commentAuthor">
{this.props.author}
</h3>
<span dangerouslySetInnerHTML={{__html: rawMarkup}} />
</div>
);
}
});
React.render(
<CommentBox url="comments.json" pollInterval={2000} />,
document.getElementById('example')
);
HTML file looks like this:
<!DOCTYPE html>
<html>
<head>
<title>8R</title>
<meta charset="utf-8">
<script src="react.js"></script>
<script src="JSXTransformer.js"></script>
<script src="jquery-2.1.3.min.js"></script>
<script src="showdown.min.js"></script>
</head>
<body>
<div id="example"></div>
<script type="text/jsx" src="app.js"></script>
</body>
</html>
And i have comments.json file with comments:
[
{"author": "Pete Hunt", "text": "This is one comment"},
{"author": "Jordan Walker", "text": "This is *another* comment"},
{"author": "Mary Jane", "text": "My comment is the best comment"},
{"author": "Peter Parker", "text": "Have you called spider-man?"}
]
Those comments appear in the list, but when i type my own comment in the comment form and submit it, it does not appear in the list. In Chrome it just blinks for a part of a second and disappears and that's all. I have tried to do it on Webstorm's localhost and on MAMP server and i've gotten the same result. What is the problem?
Upvotes: 0
Views: 1739
Reputation: 5082
If anyone else gets here and wants to use their own PHP server which they've already setup (instead of using the react server scripts) you can do like this:
// in your commentsBox class declaration
handleCommentSubmit: function(comment) {
console.log(comment);
//console.log(this.props.url);
var comments = this.state.data;
var newComments = comments.concat([comment]);
this.setState({data: newComments});
$.ajax({
url: '../update_json_manager.php', // declare your own file to post to
dataType: 'json',
type: 'POST',
data: comment,
success: function(data) {
this.setState({data: data});
console.log(data);
}.bind(this),
error: function(xhr, status, err) {
console.error(xhr, status, err.toString());
}.bind(this)
});
},
Then you can receive the post and update your json file like this (in a file called update_json_manager.php
in the same directory as comments.json
:
<?php
$comments = file_get_contents('comments.json');
$commentsDecoded = json_decode($comments, true);
$commentsDecoded[] = ['author' => $_POST['author'],
'text' => $_POST['text']];
$comments = json_encode($commentsDecoded, JSON_PRETTY_PRINT);
file_put_contents('comments.json', $comments);
?>
Upvotes: 2
Reputation: 387
I think what you can do is to comment out the setInterval function in your componentDidMount.
componentDidMount: function() {
this.loadCommentsFromServer();
//setInterval(this.loadCommentsFromServer, this.props.pollInterval);
},
If you check your comments.json, you will find your comments are not appended there. So every time you fetch, your list will go back to original state.
Upvotes: 1
Reputation: 26
The zip you can download from Github for the React example you mention includes server scripts for a variety of languages, which will handle the JSON data update in the example.
So, if you download and use one of those server scripts to run the examples locally, you will see your code will work. The ajax call will send your comment data to the url specified and the server script will take care of updating the JSON comments file.
HTH
Upvotes: 1