Say I have an object with two MobX @observable fields:
class Address {
@observable country
@observable city
}
When one of them changes, I want to call a function that changes the other one. For example, when country changes, I might want to clear city if its value isn't valid for the new country.
Is there a good pattern for this?
I don't think I can use autorun. Since I'm trying to change an observable value, and I have enforceActions turned on, I need to change it in an action. But this throws an error "Autorun does not accept actions since actions are untrackable":
autorun(action(() => {
if (this.country === 'US' && this.city === 'Paris') this.city = '';
}));
I know I can add a @computed function that returns either city or a new value. But then the original value of city is still there, and will get returned when country changes back. I don't want this; I want to permanently change city.
@computed get realCity() {
if (this.country === 'US' && this.city === 'Paris') return '';
return this.city;
}
You could use observe to observe the object in the constructor, and reset the city if the country changed.
Example (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}`);
I think you should look at your problem with a different angle.
The thing I am asking myself is: isn't there something you could do to avoid the problem you face altogether?
Why allow the situation to happen in the first place?
Regarding mobx specific patterns this bit of docs is useful:
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With