MobX:如何改变一个可观察值以响应另一个值的变化?

MobX: how to change an observable value in response to another value's change?

假设我有一个包含两个 MobX @observable 字段的对象:

class Address {
  @observable country
  @observable city
}

当其中一个改变时,我想调用一个函数来改变另一个。例如,当 country 更改时,如果 city 的值对新国家/地区无效,我可能想清除它。

有好的模式吗?

我不认为我可以使用 autorun。由于我正在尝试更改可观察值,并且我已打开 enforceActions,因此我需要在 action 中更改它。但这会引发错误 "Autorun does not accept actions since actions are untrackable":

autorun(action(() => {
    if (this.country === 'US' && this.city === 'Paris') this.city = '';
}));

我知道我可以添加 @computed 函数 returns city 或新值。但是 city 的原始值仍然存在,并且会在 country 变回时返回。我不想要这个;我想永久更改 city.

@computed get realCity() {
    if (this.country === 'US' && this.city === 'Paris') return '';
    return this.city;
}

此任务可以通过在商店构造函数中初始化的 "when" 进程完成:

class store(){
    constructor(){
     when (){
      ()=>{(this.country === 'US' && this.city === 'Paris')}
      ()=>{ this.city = ''}
    } 
  }
} 

可以在此处找到完整且有据可查的解释: https://mobx.js.org/refguide/when.html

我觉得你应该换个角度看你的问题。

我问自己的是:难道你没有办法完全避免你面临的问题吗?

为什么一开始就允许这种情况发生?

  • 如果设置了一个国家:为该国家创建一个城市子集。
  • 如果设置了城市,国家发生变化,请同时取消设置城市。

关于 mobx 特定模式,这段文档很有用:

As a rule of thumb: use autorun if you have a function that should run automatically but that doesn't result in a new value. Use computed for everything else. Autoruns are about initiating effects, not about producing new values. Mobx docs

您可以使用observe观察构造函数中的对象,如果国家/地区发生变化,则重新设置城市。

示例 (JSBin)

class Address {
  @observable country = 'Sweden';
  @observable city = 'Stockholm';

  constructor() {
    observe(this, (change) => {
      if (change.name === 'country') {
        // Put your logic for changing the city here
        this.city = '';
      }
    });
  }
}

const address = new Address();

console.log(`${address.country}, ${address.city}`);
address.country = 'Spain';
console.log(`${address.country}, ${address.city}`);
observe(state, "country", ({ oldValue, newValue }) => this.handleCountryChange(oldValue, newValue));


handleCountryChange = (oldValue, newValue) => {}