Search code examples
javascriptreactjsreactjs-fluxrefluxjs

Using reactjs, updating an item in a list without updating the whole list?


I'm using React and Reflux. And I'm having a hard time figuring out how to update one comment in a list of comments.

I'm confused on where state should go. I put the state at the top in CommentsList. Thinking it the React way. And then CommentsItem is just props. And then each CommentsItem has a LikeButton, which I made props as well.

The problem is when I call the like action in the LikeButton, it reloads all the comments in CommentsStore. I'm guessing I need a new store that loads one comments instead of all comments? But then does that mean I'm putting state in CommentsItem? I'm kind of confused on the best practice here.

This is what I'm working with:

<ProfilePage />

<div>
    <ProfileBox profile={this.state.profile} />
    <CommentsList query={{profile: this.state.profile._id}} />
</div>

<CommentsList />

var CommentsList = React.createClass({

  mixins: [
    Reflux.connect(CommentsStore, 'comments')
  ],

  componentWillMount: function() {
    CommentsActions.load(this.props.query);
  },

  render: function() {
    var commentNodes = this.state.comments.map(function (comment, i) {
      return (
        <CommentsItem key={i} comment={comment} />
      );
    });
    return (
      <div>
        {commentNodes}
      </div>
    );
  }

});

<CommentsItem />

var CommentsItem = React.createClass({
  render: function() {
    return (
      <div>
        <div>
          {this.props.comment.user.username}:
          {this.props.comment.comment}
        </div>
        <div>
          {this.props.comment.numPoints} people like this
        </div>
        <div>
          OTHER LINKS
          <LikeButton commentId={this.props.comment._id} liked={this.props.comment.liked} />
        </div>
      </div>
    );
  }
});

<LikeButton />

var LikeButton = React.createClass({

  handleLike: function(e) {
    e.preventDefault();
    CommentsActions.like(this.props.commentId);
  },

  render: function() {
    var likeText = this.props.liked ? 'Unlike' : 'Like';
    return(
      <a href="#" onClick={this.handleLike}>{likeText}</a>
    );
  }

});

Solution

  • "I think this is best practice. Because you are looping through the commentlist with map but react only performs the necessary DOM operations. Some JS loops are faster than more DOM operations." – Dustin Hoffner