facebookarchive / react-meteor

React rendering for Meteor apps
948 stars 114 forks source link

strange update behaviour #23

Open jhartma opened 9 years ago

jhartma commented 9 years ago

Hi there, I am seeing some strange behaviour when reactive data changes. This is what I have

AnnotationListComponent = ReactMeteor.createClass({
  getMeteorState: function() { return {
    annotations: Annotation.documents.find({},{sort: {rank: 1}}).fetch() };
  },
  handleDrop: function(e, ui) {
    ...
    Meteor.call('annotation-update-publication-rank', Meteor.userId(), el.id , newRank);
  },
  componentDidUpdate: function(){
    console.log( _.pluck(this.state.annotations,'content') )
    console.log( _.pluck(this.state.annotations,'rank') )
  },
  renderAnnotation: function(annotation){ return <AnnotationListItemComponent key={annotation._id} rank={annotation.rank} content={annotation.content} id={annotation._id} /> },
  componentDidMount: function(){
    jQuery(this.getDOMNode()).sortable({
      handle: ".handle",
      stop: this.handleDrop
    })
  },
  render: function(){
    return (
      <div className='uk-list'>
        {this.state.annotations..map(this.renderAnnotation)}
      </div>
    )
  }
});

It is basically a sortable list which updates the rank after a list item is dropped and shows the items in the new order. Everything works fine. When an item is dropped, the Meteor.call method is triggered and the rank is changed. However, the view does not rerender the items in the correct order. Instead, it rerenders them in the old order. I had a look a the new data: the output in the componentDidUpdate shows the correct order. In addition, when having a second browser window open, the items are displayed in their correct order.

Any ideas?

mrozbarry commented 9 years ago

Because you re-use keys in renderAnnotation, react will attempt to reorder.

I think it will work if you do:

renderAnnotation: function(annotation, index){ return <AnnotationListItemComponent key={index} rank={annotation.rank} content={annotation.content} id={annotation._id} /> },
jhartma commented 9 years ago

yep, thx :+1: