score:4

it's usually not a very good idea to have jquery mucking with react components (though jquery + react can play nice with each other for certain tasks); we are running a large scale react application and have spent many hours removing instances of this from our early days.

in terms of saving the comments, you need a new endpoint to handle that functionality, it should look almost exactly like app.post('/api/comments') except instead of getting data from reading the file, it should get data from req.body, which is the data posted to it. to keep the same url this.props.url you could set it up as a patch endpoint: app.patch('/api/comments' ...). i'll leave that implementation up to you. the react save functionality should happen like this: the comment component should use state to manage it's...state. clicking "edit" should switch that state to have the contenteditable set to true, "edit" become "save", etc. the actual saving part should be defined in the parent component commentbox and should be passed down to the comment component. here is a basic idea of the changes you should make to allow editing, it's 100% untested but hopefully helps out some.

// changes to comment component
var comment = react.createclass({
  getinitialstate: function() {
    return {
      contenteditable: false,
      buttontext: 'edit',
      text: this.props.text
    };
  },
  handlebutton: function() {   
    var commenttag = this.refs.comment;
    // if the component is currently editable and the text is different from the original, save it
    if (this.state.contenteditable && commenttag.textcontent != this.state.text) {
      this.props.onupdatecomment(this.props.id, commenttag.textcontent);
    }
    // invert current contenteditable state save => edit or edit => save
    var editable = !this.state.contenteditable;
    this.setstate({
      contenteditable: editable,
      // update the state to reflect the edited text
      text: commenttag.textcontent,
      // change button text based on editable state
      buttontext: editable ? 'save' : 'edit'
    });
 },
 render: function() {
   return (
     <div classname="comment">
       <h2 classname="commentauthor">{this.props.author}</h2>
       <p ref="comment" contenteditable={this.state.contenteditable}>{this.state.text}</p>
       <button onclick={this.handlebutton}>{this.state.buttontext}</button>
     </div>
   );
 }
});

// changes to commentlist
var commentlist = react.createclass({ 
   render: function() { 
     var commentnodes = this.props.data.map(function(comment) { 
       return <comment onupdatecomment={this.props.onupdatecomment} {...comment} />  
     }); 
     return ( 
       <div classname="commentlist"> 
         {commentnodes} 
       </div> 
     ); 
   } 
 });

 // changes to commentbox
 var commentbox = react.createclass({
   loadcommentsfromserver: function() {
     $.getjson(this.props.url)
      .then(function(newcomments) {
        this.setstate({ data: newcomments });
      }.bind(this))
      .fail(function(xhr, status, err) {
        console.error(this.props.url, status, err.tostring());
      });
   }, 
   handlecommentsubmit: function(comment) { 
     var comments = this.state.data; 
     comment.id = date.now(); 
     var newcomments = comments.concat([comment]); 
     this.setstate({data: newcomments}); 

     $.post(this.props.url, comments)
      .then(function(data) {
        this.setstate({ data: data });
      }.bind(this))
      .fail(function(xhr, status, err) {
        this.setstate({ data: comments });
        console.error(this.props.url, status, err.tostring());
      }.bind(this));
   },
   onupdatecomment: function(id, comment) {
     // clone state, we don't want to alter this directly
     var newdata = this.state.data.slice(0);
     newdata.foreach(function(item) {
       if(item.id === id) {
         item.text = comment;
       }
     });
     $.ajax({
       url: this.props.url,
       datatype: 'json',
       method: 'patch',
       data: newdata
     }).then(function(data) {
       this.setstate({ data: data });
     }.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> 
     ); 
   } 
 }); 

Related Query

More Query from same tag