let Comment = React.createClass({ rawMarkup: function () { let rawMarkup = marked(this.props.children.toString(), { sanitize: true }); return { __html: rawMarkup }; }, render: function () { return (

{this.props.author}

); } }); let CommentList = React.createClass({ render: function () { let commentNodes = this.props.data.map(function (comment) { return ( {comment.text} ); }); return (
{commentNodes}
); } }); let CommentForm = React.createClass({ getInitialState: function () { return { author: "", text: "" }; }, handleAuthorChange: function (e) { this.setState({ author: e.target.value }); }, handleSubmit: function (e) { e.preventDefault(); let author = this.state.author.trim(); let text = this.state.text.trim(); if (!text || !author) { return; } // TODO send request to the server. this.setState({ author: '', text: '' }); }, handleTextChange: function (e) { this.setState({ text: e.target.value }); }, render: function () { return (
); } }); let CommentBox = React.createClass({ componentDidMount: function () { this.loadCommentsFromServer(); setInterval(this.loadCommentsFromServer, this.props.pollInterval); }, getInitialState: function () { return { data: [] }; }, loadCommentsFromServer: function () { $.ajax({ url: this.props.url, dataType: "json", cache: false, success: function (result) { this.setState({ data: result }); }.bind(this), error: function (xhr, status, err) { console.error(this.props.url, status, err.toString()); }.bind(this) }); }, render: function () { return (

Comments

); } }); ReactDOM.render( , document.getElementById("content") );