Skip welcome & menu and move to editor
Welcome to JS Bin
Load cached copy from
 
<!DOCTYPE html>
<html>
<head>
<meta name="description" content="React with List of Comments">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/react.js"></script>
<script src="https://rawgit.com/spoike/refluxjs/master/dist/reflux.js"></script>  
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  <div id="example"></div>
  
</body>
</html>
 
const commentActions = Reflux.createActions({
  addComment: {}
});
const commentStore = Reflux.createStore({
  data: {
    comments: [{
      id: 1,
      author: 'Bob Dobson',
      text: 'I had a great time'
    },{
      id: 2,
      author: 'John Thompson',
      text: 'It was the worst day of my life'
    },{
      id: 3,
      author: 'Stan Simpson',
      text: 'Meh'
    }]
  },
  getInitialState() {
    this.data.newComment = this.getDefaultComment();
    return this.data;
  },
  init() {
     this.listenTo(commentActions.addComment, this.addComment);
  },
  getDefaultComment() {
    return {
      text: '',
      author: ''
    };
  },
  addComment(newComment) {
    newComment.id = this.data.comments.length + 1;
    this.data.comments = this.data.comments.concat([newComment]);
    this.data.newComment = this.getDefaultComment();
    this.trigger(this.data);
  }
});
class Comment extends React.Component {
  render() {
    return (
      <div className="comment">
        <p>{this.props.comment.text}</p>
        <p>by <strong>{this.props.comment.author}</strong></p>
      </div>
    )
  }
}
Comment.propTypes = {
  comment: React.PropTypes.shape({
    text: React.PropTypes.string.isRequired,
    author: React.PropTypes.string.isRequired
  })
};
class CommentList extends React.Component {
  render() {
    return (
      <div className="comment-list">
        {this.props.comments.map(comment => <Comment comment={comment} key={comment.id} />)}
      </div>
    )
  }
}
CommentList.propTypes = {
  comments: React.PropTypes.array.isRequired
};
class CommentForm extends React.Component {
  handleSubmit(e) {
    e.preventDefault();
    this.props.onSubmit(this.props.comment);
  }
  render() {
    return (
      <form onSubmit={this.handleSubmit.bind(this)}>
         <div>
          <textarea placeholder="Your Comment" rows="4" cols="40" value={this.props.comment.text} name="text" onChange={this.props.onChange} />
         </div>
         <div>
          <input type="text" placeholder="Your Name" value={this.props.comment.author} name="author" onChange={this.props.onChange} />
         </div>
         <button type="submit">Add Comment</button>
      </form>
    )
  }
}
CommentForm.propTypes = {
  onSubmit: React.PropTypes.func.isRequired,
  onChange: React.PropTypes.func.isRequired,
  comment: React.PropTypes.shape({
    text: React.PropTypes.string.isRequired,
    author: React.PropTypes.string.isRequired
  }).isRequired
};
class CommentsContainer extends React.Component {
  constructor(props) {
    super(props);
    this.state = commentStore.getInitialState();
  }
  
  componentDidMount() {
    commentStore.listen(this.onCommentsChange.bind(this));
  }
  
  onCommentsChange(data) {
    this.setState(data);
  }
  
  handleChange(name, value) {
    let newComment = { ...this.state.newComment };
    newComment[name] = value;
    this.setState({
      newComment: newComment
    });
  }
  
  handleSubmit(newComment) {
    commentActions.addComment(newComment);
  }
  
  render() {
    return (
      <div className="comments-container">
        <CommentList comments={this.state.comments} />
        <CommentForm 
          comment={this.state.newComment} 
          onSubmit={newComment => this.handleSubmit(newComment)} 
          onChange={e => this.handleChange(e.target.name, e.target.value)} />
      </div>
    )
  }
}
  
React.render(
  <CommentsContainer />,
  document.getElementById('example')
);
Output

You can jump to the latest bin by adding /latest to your URL

Dismiss x
public
Bin info
benglasspro
0viewers