I want to use mobx without using decorators. Usually I use decorate
from mobx package but in this particular case, I could not find a way to make it work.
Original code :
import { observable } from 'mobx'
import { create, persist } from 'mobx-persist'
class Order {
@persist('object')
@observable
currentOrder = null
}
What I tried :
import { observable, decorate } from 'mobx'
import { create, persist } from 'mobx-persist'
import { compose } from 'recompose'
class Order {
currentOrder = null
}
decorate(Order, {
currentOrder: compose(persist('object'), observable),
})
The error comes from persist
telling serializr decorator is not used properly.
Any idea why this is different from above and does not work ?
Property Decorators requires a very specific composition implementation.
Property Decorators are basically a function of the form:
(target, prop, descriptor) => modifiedDescriptor
So, in order to compose two Property Decorators you need to pass the 1st decorator's result as a third argument of the 2nd decorator (along with target
and prop
).
Recompose.compose
(same as lodash.flowRight
) applies functions from right to left and passing the result as a single argument to the next function.
Thus, you can't use Recompose.compose
for composing decorators, but you can easily create a composer for decorators:
/* compose.js */
export default (...decorators) => (target, key, descriptor) =>
decorators.reduce(
(accDescriptor, decorator) => decorator(target, key, accDescriptor),
descriptor
);
Then we use it in order to compose observable
and persist("object")
.
/* Order.js */
import { observable, decorate, action } from "mobx";
import { persist } from "mobx-persist";
import compose from "./compose";
class Order {
currentOrder = null;
}
export default decorate(Order, {
currentOrder: compose(
observable,
persist("object")
)
});
>=4.3.2
& >=5.0.4
:I opened PRs (which have been merged) for MobX5 & MobX4 in order to support multiple decorators OOB within the decorate
utility function.
So, this is available in MobX >=4.3.2
& >= 5.0.4
:
import { decorate, observable } from 'mobx'
import { serializable, primitive } from 'serializr'
import persist from 'mobx-persist';
class Todo {
id = Math.random();
title = "";
finished = false;
}
decorate(Todo, {
title: [serializable(primitive), persist('object'), observable],
finished: observable
})