Why MobX?

Removing the burden of state management

photo of Eugen Kiss
Eugen Kiss

Software Engineer

Posted on Mar 15, 2018

Removing the burden of state management

State management and change propagation are arguably some of the hardest challenges in GUI programming. Many tools promised to save us from their burden. Only a few remained. Among them is MobX and its flavor of Transparent Reactive Programming.

To understand the appeal of MobX, it is helpful to first understand how React revolutionized GUI programming. Traditional approaches allow description of the initial state of the GUI. Further GUI state transitions must be accomplished with references to GUI elements and piece-wise mutations. This is error-prone as edge cases are easily missed. With React you describe the GUI at any given point in time. Put differently, taking care of GUI state transitions, e.g. manipulating the DOM, is a thing of the past: Your GUI code has become declarative.

React’s crucial advantage is making the “how” of updating the GUI transparent. That idea is reapplied by MobX. Not for GUI manipulation code, but instead for state management and change propagation. In fact, combining both React and MobX is synergistic since even though React nicely takes care of how to update the GUI, when to update the GUI remains cumbersome without MobX. Cross communication between components is the biggest pain point.

Let us explore an example in React and JavaScript illustrating MobX’s advantages:

import { observable } from mobx
import { observer } from mobx-react
const store = observable({
 itemCount: 0,
 lastItem: null
})
const handleBuy = (name) => () => {
 store.itemCount += 1
 store.lastItem = name
}

const handleClearCart = () => {
 store.itemCount = 0
 store.lastItem = null
}
const Cart = observer(() =>

    Items in cart: {store.itemCount}
    Clear cart

)
const Header = observer(({children}) =>

    Header
    {children}

)
const LastBought = observer(() =>
  Last bought item: {store.lastItem}.
)

const Main = observer(() =>


    Buy shoes
    Buy shirt


)

The example represents a very simplified e-commerce page. Any resemblance to Zalando’s fashion store is, of course, coincidental. Here is a demo and its live-editable source code. The behavior is as follows: Initially, your cart is empty. When you click on “Buy shoe” your cart item count increases by one and the recently bought component shows “shoe”. A click on “Buy shirt” does the same for “shirt”. You can also clear your cart. In the live example you will see that only the cart in the header is re-rendered but not the header itself. You will also see that the recently bought component does not rerender when you buy the same product in succession.

Notice that the dependency between the observable variables itemCount and lastItem, and the components is not explicitly specified. Yet, the components correctly and efficiently rerender on changes. You may wonder how this is accomplished. The answer is that MobX implicitly builds up a dependency graph during execution of the components’ render functions that tracks which components to rerender when an observable variable changes. A way to think of MobX is in terms of a spreadsheet where your components are formulas of observable variables. Regardless of how the “magic” works underneath, and which analogy to use, the result is clear: You are freed from the burden of explicitly managing change propagation!

To sum up, MobX is a pragmatic, non-ceremonial, and efficient solution to the challenge of state management and change propagation. It works by building up a run-time dependency graph between observable variables and components. Using both React and MobX together is synergistic. Currently, MobX is used in just a few projects inside Zalando. Seeing as MobX offers a great deal to anyone writing GUI programs, I am confident that its adoption will rise in the future.

Keep in touch with fresh Zalando Tech news. Follow us on Twitter.