Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React / Rails : Append dynamically element to DOM

Currently following facebook tutorial on React (react_tuto). I don't understand how 2 components can communicate so that on "submit a comment button" it appends dynamically the "comment list".

currently, comment are created on server but appears on page only when page refreshed

how can the comment appear on submit button?

This i my AddComment component

 var AddComment = React.createClass({
  getInitialState: function(){
    return {
      content: this.props.content,
      adrien: "before"
    }
  },

  handleKeyUp: function(e) {
    this.setState({
      content: this.refs.addComment.getDOMNode().value,
    })
  },

  handleValidation: function() {
    var that = this
    $.ajax({
      type: "POST",
      data: {comment: { content: that.state.content } },
      url: Routes.create_comment_path({format: 'json'}),
      success: function(data) {
       that.setState({
         content: "",
         adrien: "after"
       })
      }
    })
  },

  render: function(){
    return (
      <div>
      <textarea onKeyUp={this.handleKeyUp} value={this.state.value} ref="addComment"></textarea>
      <button onClick={this.handleValidation}>submit</button>
      </div>
    )
  }

})

This is my CommentList component:

var CommentList = React.createClass({
  render: function() {
    return (
      <div>
        {this.props.comments.map(function(comment){
          return <CommentListElement key={comment.id} comment={comment} />;
        })}
      </div>
    );
  }
});
like image 474
Adrien de Villoutreys Avatar asked Dec 01 '25 09:12

Adrien de Villoutreys


1 Answers

You need a common parent component for communication between different components.

I have updated you example a bit to include common parent component CommentSystem

Note: I have removed ajax call to just show the communication between component.

Check below link.

https://jsfiddle.net/j4yk3pzc/15/

Extra Info:

In react we store states on parent component and pass them down to children. Along with state we also pass actions to manipulate data down to the children. When child component want's to update data passed to it from parent, then it fires the action passed from the parent. This is called Data down action up approach. Data is passed from parent to child to grandchild. While actions are propagated from grandchild to child to parent.

If you don't want to create the parent component then you can use some Publish / Subscribe or EventEmitter based system to communicate between children having no common parent.

Reference:

http://ctheu.com/2015/02/12/how-to-communicate-between-react-components/

Code:

var CommentSystem = React.createClass({
    getInitialState: function() {
    return {
       comments: []
    }
  },
  addComments: function(comment) {
    var comments = this.state.comments;
    comments.push(comment);
    this.setState({comments: comments})
  },
  render: function() {
    return (
      <div>
        <AddComment addComments={this.addComments}/>
        <CommentList comments={this.state.comments}/>
      </div>
      )
  }
})

var AddComment = React.createClass({
  getInitialState: function(){
    return {
      content: this.props.content,
      adrien: "before"
    }
  },

  handleKeyUp: function(e) {
    this.setState({
      content: this.refs.addComment.getDOMNode().value,
    })
  },

  handleValidation: function() {
    var that = this;
    this.props.addComments(this.state.content);
  },

  render: function(){
    return (
      <div>
      <textarea onKeyUp={this.handleKeyUp} value={this.state.value} ref="addComment"></textarea>
      <button onClick={this.handleValidation}>submit</button>
      </div>
    )
  }
})

var CommentList = React.createClass({
  render: function() {
    return (
      <div>
        {this.props.comments.map(function(comment){
          return <CommentListElement key={comment.id} comment={comment} />;
        })}
      </div>
    );
  }
});

var CommentListElement = React.createClass({
  render: function() {
    return (
     <div>{this.props.comment}</div>
     )
  }
})

React.render(<CommentSystem/>, document.getElementById('container'));

Hope this helps.

like image 68
Rohan Pujari Avatar answered Dec 03 '25 23:12

Rohan Pujari



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!