Using MobX for Data Flow Management in a React Native Mobile Ticketing Application
This article explains how MobX replaces Redux for state management in a React Native flight‑ticket app, detailing its architecture, module breakdown, implementation steps, and the performance and maintenance advantages it brings to complex mobile projects.
Wang Yame joined Qunar's ticketing division in 2015, working on Android clients and React Native‑based flight‑ticket development, gaining experience in complex project architecture, Redux/MobX data‑flow design, and performance optimization.
1. Introduction
(1) The importance of data‑flow management for React Native projects
React Native provides high‑performance, native‑like cross‑platform development, improving development efficiency and mobile web experience while offering simple hot‑update capabilities for iOS and Android. In the ticketing client, the main business flow has gradually switched to React Native. Effective data‑flow management is crucial for project structure, code complexity, and maintainability.
(2) Drawbacks of previous data‑flow solutions
Earlier projects used Redux, which offers a predictable unidirectional flow but suffers from high maintenance cost due to the separation of actions and reducers, cumbersome performance tuning requiring both mapStateToProps and mapDispatchToProps, and the limitation of a single store that makes handling multiple similar pages difficult.
To address these issues, MobX was introduced for data‑flow management.
2. What is MobX
MobX aims to hide the dependency between data and view, providing a simpler management solution. Its core ideas are simplicity and extensibility, delivering predictable and clear data flow with lower learning cost compared to Redux.
MobX’s data flow consists of a Store that holds all data and actions that modify it, the current State, and computed values derived from the original data. UI events or network requests trigger actions, which update the State, automatically causing computed values and the view to refresh.
MobX’s key feature is that it internally maintains the dependency between data state and view, automatically refreshing the view when data changes, thus reducing configuration effort and human‑triggered errors.
3. Project Structure After Introducing MobX
The React Native ticketing project, after adopting MobX, is divided into four main modules, as shown in the diagram below:
(1) View Module
The view module is organized by pages. The top‑level entry page inherits from QView if it needs Ext.router navigation, otherwise from Component. The entry page handles component composition, lifecycle, interaction binding, and store binding, delegating all data‑related logic to the Store to keep the view layer pure.
(2) Store Module
This core module uses MobX concepts such as observable, computed value, and action. Each page has its own PageStore (a separate state tree). Complex state trees can be further divided into sub‑models. The hierarchy includes a GenericPageStore base class, specific XXXPageStore classes, and sub‑models that define observable properties, computed values, and actions (the latter delegate business logic to the Computations module).
(3) Business Logic Module – Computations
Complex business logic (e.g., flight filtering, order creation) is placed in Computations to keep Stores lightweight. Computations follow functional programming principles, contain no state, and return results based on input parameters to the Store.
(4) Data Repository Module
This module provides raw data sources, including network requests and native data, implemented by classes such as HotdogApi and NativeApi.
4. Key Implementation Details
(1) Implementing MobX data flow
Step 1: Create a store instance in each entry page’s constructor and inject it into React’s context so that any child component can access it via @inject.
Step 2: Declare observable properties using @observable.
Step 3: Make components observers with @inject to access store properties and @observer to react to observable changes, enabling automatic view updates.
Step 4: Change store data exclusively via actions, which are called from UI events to update the view.
(2) Relationship between PageStore and sub‑models
When a page’s data is complex, the PageStore is split into sub‑models. The PageStore holds instances of all sub‑models, allowing views to retrieve them via the store. Each sub‑model keeps a reference to the raw data, so business logic changes can be made within the sub‑model without affecting other modules.
(3) Network state machine implementation
A unified NetIndicatorStore manages request parameters, request status, results, and loading indicators, deriving additional view‑related states such as error flags and loading flags.
(4) Serializing asynchronous processes with async/await and Promise
Common asynchronous tasks (network requests, native bridge calls) are handled using Promise chains and async/await syntax, turning asynchronous code into a synchronous‑like flow, reducing callback nesting and improving readability.
5. Advantages of the MobX Data‑Flow Solution
Compared with Redux, MobX solves configuration complexity, high maintenance cost, and single‑store limitations, and offers additional benefits:
Suitable for complex business projects; its object‑oriented approach facilitates clear, layered architecture and rapid iteration.
Simple data‑flow triggering aids debugging and code navigation.
Low performance‑optimization cost; MobX internally handles view updates and overrides ComponentShouldUpdate to avoid unnecessary re‑renders.
Qunar Tech Salon
Qunar Tech Salon is a learning and exchange platform for Qunar engineers and industry peers. We share cutting-edge technology trends and topics, providing a free platform for mid-to-senior technical professionals to exchange and learn.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.