Michel Weststrate, author of the reactive state management library MobX, recently released MobX 6. MobX 6 now supports Internet Explorer and React Native and updates its decorator-based API to reflect the new JavaScript decorators proposal (currently in Stage 2). Important pieces of the MobX ecosystem are also updated to support the latest version of MobX (e.g. mobx-react-lite, mobx-react, mobx-utils).
MobX 6 removes support for the current implementation of decorators and supports instead the new JavaScript decorators proposal. The new proposal is in the Draft stage (stage 2) of the standardization track managed by the JavaScript TC39 committee. The TC39 committee is responsible for evolving the JavaScript programming language and authoring its specification. Stage 2 proposals are considered experimental. Proposals are moved from Stage 1 to Stage 2 when the committee has reasonable expectations that the proposal will be developed and eventually included in the standard.
The new decorators proposal comes after two previous decorators proposals that did not proceed further in the standardization process. Those two proposals — the legacy (Babel) and experimental (TypeScript) decorators proposals, are incompatible with the Stage 3 class fields proposal.
Weststrate cites adoption as another reason for the change:
Using decorators has always been a serious hurdle in adopting and advocating MobX. […] As one MobX fan puts it:
I am guessing this choice [to drop decorators] was probably a good call. Maybe now without decorators I am hopeful I will be able to convey to people how amazing Mobx is, and at least I won’t hear the decorators excuse anymore. I have never seen an “@” sign scare so many people.
Developers using MobX 6 thus have two options. The first consists of using decorator-free JavaScript and MobX 6’s new APIs:
import {observable, computed, action, makeObservable} from "mobx"
// Before:
class TodoStore {
@observable
todos: Todo[] = []
@computed
get unfinishedTodoCount() {
return this.todos.filter(todo => !todo.done).length
}
@action
addTodo(todo: Todo) {
this.todos.push(todo)
}
}
// After:
class TodoStore {
todos: Todo[] = []
constructor() {
makeObservable(this, {
todos: observable,
unfinishedTodoCount: computed,
addTodo: action
})
}
get unfinishedTodoCount() {
return this.todos.filter(todo => !todo.done).length
}
addTodo(todo: Todo) {
this.todos.push(todo)
}
}
(Source: release note)
Developers may also use the revamped version of decorators together with the new APIs:
class TodoStore {
@observable
todos: Todo[] = []
constructor() {
makeObservable(this)
}
@computed
get unfinishedTodoCount() {
return this.todos.filter(todo => !todo.done).length
}
@action
addTodo(todo: Todo) {
this.todos.push(todo)
}
}
(Source: release note)
When and if the new decorator proposal is eventually adopted as a new JavaScript standard, developers will no longer have to resort to making makeObservable(this)
calls when using decorators.
Developers can migrate a MobX 4 and MobX 5 codebase to MobX 6 thanks to the mobx-undecorate codemod.
While MobX 6 requires JavaScript proxies, a feature that is not supported in some legacy browsers, developers may opt-out from proxy usage to support older engines.
mobx-react (React bindings for MobX), mobx-react-lite, (Lightweight React bindings based on React 16.8, and React hooks) and mobx-utils are additionally updated to use MobX 6.
Developers are invited to review the full release note which contains additional details about the release.
MobX is an unopinionated state management library that can be used standalone or with any UI framework. MobX APIs allow defining entities to be observed for changes, and the reactions to those changes (updating dependent pieces of states or running effects). MobX shares some similarities with Redux and Recoil while striving to eliminate the boilerplate associated to tracking and propagating state changes.
MobX is open-source software available under the MIT license. Contributions and feedback are encouraged via the MobX GitHub project.