简体   繁体   English

Mobx:将新的(数组)属性添加到可观察对象

[英]Mobx: add new (array) property to observable object

I have an observable object, where I want to store some data. 我有一个可观察的对象,我想存储一些数据。 Keys are unique IDs for my customer entity, and values are arrays of customers' orders (which are objects themselves). 密钥是我的客户实体的唯一ID,值是客户订单的数组(对象本身)。

I initialize an object with: 我初始化一个对象:

@observable data =  {};

Then, when I get data from network, I want to store them, using: 然后,当我从网络获取数据时,我想存储它们,使用:

@action
saveData(customerId, ordersForCustomer) {
  this.data = extendObservable(this.data, {
    [customerId]: observable(ordersForCustomer);
  }
}

Unfortunately, it seems my object (or its properties) are not being watched. 不幸的是,似乎我的对象(或其属性)没有被监视。

Why is this? 为什么是这样? And how can I fix this? 我该如何解决这个问题? Is there something special I need to know about how observable objects work with arrays as its values? 对于可观察对象如何使用数组作为其值,我需要了解一些特殊内容吗?

This problem is brought up in the Common pitfalls & best practices section of the documentation: 此问题在文档的常见陷阱和最佳实践部分中提出:

MobX observable objects do not detect or react to property assignments that weren't declared observable before. MobX可观察对象不会检测或响应之前未声明可观察的属性分配。 So MobX observable objects act as records with predefined keys. 因此,MobX可观察对象充当具有预定义键的记录。 You can use extendObservable(target, props) to introduce new observable properties to an object. 您可以使用extendObservable(target, props)向对象引入新的可观察属性。 However object iterators like for .. in or Object.keys() won't react to this automatically. 但是像for .. inObject.keys()这样的对象迭代器不会自动响应。 If you need a dynamically keyed object, for example to store users by id, create observable _map_s using observable.map . 如果需要动态键控对象,例如按id存储用户,请使用observable.map创建observable _map_s。

So instead of using extendObservable on an observable object, you could just add a new key to a map : 因此,您可以在地图上添加新密钥,而不是在可观察对象上使用extendObservable

@observer
class App extends Component {
  @observable data = asMap({});
  constructor() {
    super();
    setInterval(() => {
      this.data.set(Math.random().toString(36).slice(-5), Math.random());
    }, 1000);
  }
  render() {
    return (
      <div> 
        { this.data.entries().map(e => <div> {e[1]} </div>) }
      </div>
    );
  }
}

ReactDOM.render(
  <App />,
  document.getElementById('app')
);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM