s-leg3ndz
s-leg3ndz

Reputation: 3538

Mobx don't update observable array

I've store with obersable array :

@observable list = [];

And i've methode for remove an item in my array :

@

@action remove(_id) {
  const presentation = this.list.find(item => _id === item._id);
  this.list.remove(presentation);
  console.log(this.list.slice()); // Don't update, @action log : spliced '[email protected]': index 2, added 0, removed 1
}

@action findUserPresentations(userId) {
  return this.list.filter(item => userId === item.userId);
}

My console.log() work nice (return new array without item), but my container with @observable isn't update :

@observer
@inject('user', 'presentations')
class MyPresentationsContainer extends React.Component {

  get presentations() {
    return this.props.presentations.findUserPresentations(this.props.user.id);
  }

  render() {
    return (
      <MyPresentations
        presentations={this.presentations}
      />
    );
  }
}

Anyone know if i need add other methode in remove(_id) ?

Thank you !

Upvotes: 1

Views: 3758

Answers (2)

Raafay Alam
Raafay Alam

Reputation: 61

the filter method basically returns a new array.

You can do this:

this.list = this.list.filter(item => userId === item.userId);

Upvotes: 0

mweststrate
mweststrate

Reputation: 4978

You can simply define the remove method as:

action remove(_id) { const item = this.list.find(item => _id !== item._id) this.list.remove(item) }

The cause that your update is not working is that you are assigning a new array to this.list. Which is unnecessary, but not a problem it itself.

However, in your component, you store the reference to the list in the state when it is created. Now, after reassigning this.list, the list is updated, but your state is still pointing the old list. Storing references locally is an anti pattern, as you are basically creating redudant information, which causes your bug here.

Instead, you could better write

@observer
@inject('user', 'presentations')
class MyPresentationsContainer extends React.Component {

  get presentations() { 
     return this.props.presentations.findUserPresentations(this.props.user.id)
  }

  render() {
    console.log(this.presentations);
    return (
      <MyPresentations
        presentations={this.presentations}
      />
    );
  }
}

This prevents storing a copy of the old reference to the list.

Upvotes: 2

Related Questions