MobX Tutorial
MobX tutorial for beginners with code examples from Coding compiler.MobX is Simple, scalable state management. MobX is sponsored by Mendix, Coinbase, Facebook Open Source
MobX Installation
- Installation: npm install mobx –save. React binding library: npm install mobx-react –save. To enable ES Next’s decorator (optional), see below.
- CDN:
MobX Browser Support
- The MobX >=5 version runs on any browser that supports ES6 proxy . If running in a version like IE11, Node.js 6 or below, or React Native with the Android side of the older JavaScriptCore ( click to see how to upgrade ).
- MobX 4 can run on any ES5-capable browser and will continue to be maintained. MobX API 4 and 5 are identical and semantically can achieve the same effect, but MobX 4 there are some limitations .
Tip: The main entry point for the MobX 5 package comes with ES5 code for backward compatibility with all build tools. But because MobX 5 can only run on a modern browser, so you can consider using the fastest, smallest ES6 building: lib/mobx.es6.js. For example, by setting an alias for webpack:resolve: { alias: { mobx: __dirname + “/node_modules/mobx/lib/mobx.es6.js” }}
Getting Started with MobX
MobX is a war-torn library that makes state management simple and extensible through transparently responding functional reactive programming (TFRP). The philosophy behind MobX is simple:
Anything from the application state should be obtained automatically.
These include UI, data serialization, server communication, and more.
React and MobX
React and MobX
Key Concepts of MobX
There are not many core concepts of MobX. The following code snippet can be tried online in the codesandbox example .
Observable state
Egghead.io Lesson 1: observable & observer
MobX adds observable functionality to existing data structures such as objects, arrays, and class instances. You can do this simply by using the @observable decorator (ES.Next) to annotate your class properties.
import { observable } from "mobx";
class Todo {
id = Math.random();
@observable title = "";
@observable finished = false;
}
Use observable like the attribute of the object into the excel cell. But unlike cells, these values are not just raw values, they can also be reference values, such as objects and arrays.
Don’t worry if your environment doesn’t support decorator syntax. Or you can skip setting because MobX can decorate applied in the case do not support the use decorator syntax tool. Still, most MobX users prefer the decorator syntax because it’s more concise.
For example, the ES5 version of the above code should look like this:
import { decorate, observable } from "mobx";
class Todo {
id = Math.random();
title = "";
finished = false;
}
decorate(Todo, {
title: observable,
finished: observable
})
Computed values
Egghead.io Lesson 3: Calculating Values
With MobX, you can define values that are automatically updated when the relevant data changes. By @computed decorator or use (extend)Observable getter / setter function is invoked when to use. (Of course, there can be used again decorate instead of @grammar).
class TodoList {
@observable todos = [];
@computed get unfinishedTodoCount() {
return this.todos.filter(todo => !todo.finished).length;
When a new or a todo todo adds finished when property changes, MobX will ensure unfinishedTodoCount automatic updates. A calculation like this can be similar to a formula in a spreadsheet program like MS Excel. They are automatically updated whenever they are needed.
Reactions
Egghead.io Lesson 9: Customizing the Reaction
Reactions are very similar to calculated values, but instead of generating a new value, they have some side effects, such as printing to the console, network requests, incrementally updating the React component tree to patch the DOM, and so on. In short, reactions in reactive programming and imperative programming building bridges between.
React component
Egghead.io Lesson 1: observable & observer
React If you use, you can put your (stateless function) becomes responsive component assembly, the component is added to the observer function / decorator. Observer By the mobx-react package provided.
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import {observer} from 'mobx-react';
@observer
class TodoListView extends Component {
render() {
return <div>
<ul>
{this.props.todoList.todos.map(todo =>
<TodoView todo={todo} key={todo.id} />
)}
</ul>
Tasks left: {this.props.todoList.unfinishedTodoCount}
</div>
}
}
const TodoView = observer(({todo}) =>
<li>
<input
type="checkbox"
checked={todo.finished}
onClick={() => todo.finished = !todo.finished}
/>{todo.title}
</li>
)
const store = new TodoList();
ReactDOM.render(<TodoListView todoList={store} />, document.getElementById('mount'));
observerThe React (function) component is transformed into a derivative of the data they need to render. There are no so-called smart and brainless components when using MobX.
All components are rendered in a clever way, and only a simple, brainless way to define them is needed. MobX will ensure that components are always re-rendered when needed, but that’s it. So in the example above onClick processing method corresponding to forces TodoView rendering, if the number of uncompleted tasks (unfinished TodoCount) has changed, it will result in TodoListView rendering.
However, if you remove Tasks left this line of code (or to put it another component), click on the checkbox time TodoListView no longer re-rendering. You can verify this yourself in JSFiddle .
Custom reactions
Use autorun, reaction and when functions can easily create custom reactions, in order to meet your specific scenarios.
For example, whenever unfinishedTodoCount the number changes, the following autorun will print log messages:
autorun(() => {
console.log("Tasks left: " + todos.unfinishedTodoCount)
})
What will MobX respond to?
Why every unfinishedTodoCount time changes will print a new message? The answer is the following rule of thumb:
MobX reacts to any existing observable properties that are read during the execution of the trace function.
I want to learn how MobX which is aware of the need to respond to the observable properties, please refer to the understanding of what MobX respond .
Actions
Unlike some frameworks in the Flux system, MobX is completely open to how to handle user events.
- Can be done in a similar way to Flux
- Or use RxJS to handle events
- Or use the most intuitive and simple way to handle events, as shown in the demo above. onClick
Finally, it is summarized as follows: The state should be updated in some way.
When the status is updated, the MobX rest is handled in an efficient and accessible way. A simple statement like the one below is enough to automatically update the user interface.
Technically, there is no need to trigger events, call dispatchers, or the like. In the final analysis, the React component is just a gorgeous representation of the state, and the state is derived from MobX.
store.todos.push(
new Todo("Get Coffee"),
new Todo("Write simpler code")
);
store.todos[0].finished = true;
MobX: Simple and Extensible
MobX is one of the least intrusive in the state management library. This makes MobX the method is not only simple, but also very good scalability:
Use classes and real references
There is no need to standardize data with MobX. This makes the library ideal for domain models that are unusually complex (using Mendix as an example: there are about 500 domain classes in an application).
Guaranteed referential integrity
Because data does not need to be standardized, MobX automatically tracks the relationship between state and derivation, and you can get referential integrity for free. Rendering data accessed through three levels of indirect addressing?
No problem, MobX will track them and re-render once one of the references has changed. In return, the old bugs of old age no longer exist. As a programmer, you may not be able to remember that some of the modified data may affect components that appear to be irrelevant in a corner, but MobX does not.
Simpler actions are easier to maintain
As demonstrated above, using MobX to modify the state is very simple. You simply write your purpose. MobX will handle the rest for you.
Fine-grained observability is efficient
MobX builds all derived graphics in the app to find the minimum number of recalculations needed to stay up-to-date. “Deriving everything” may sound expensive, but MobX builds virtual derived graphs to keep the amount of recalculation needed to keep the state and state synchronized to a minimum.
In fact, when Mendix tested MobX, we found that using this library to track relationships in code is usually more efficient, rather than pushing changes by using handwritten events or “smart” selectors based on container components.
In simple terms, MobX creates a finer-grained “listener” on the data, rather than controlling it through programs.
Second, MobX sees the causal relationship between the derivatives, so it can sort the derivatives so that the derivatives do not run multiple times or introduce defects.
Want to know how this works? See in-depth analysis MobX .
Easy to operate
MobX uses native javascript. Because it is less intrusive, it can be used with most Javascript libraries without the need for a specific MobX style library.
So you can continue to use your routing, data acquisition and tool libraries, such as react-router, director, superagent, lodash, and so on.
For the same reason, you can use it on both the server and client side, or in a homogeneous application like react-native.
The conclusion is: Compared to other state management solutions, when using MobX, you usually only need to learn fewer new concepts.
MobX Inspired by Reactive
MobX is inspired by the reactive programming principles in the excel table. It is also inspired by the MVVM framework like MeteorJS, knockout and Vue.js. But MobX takes transparent Functional Reactive Programming to a better level and provides a standalone implementation. It implements TFRP in an accessible, synchronized, predictable, and efficient manner.
More praise to Mendix , which gives flexibility and support for maintaining MobX and provides the opportunity to prove MobX’s philosophy in real, complex, performance-critical applications.
The ultimate accolade belongs to all those who believe, try, test, and even sponsor MobX.
MobX 4 vs MobX 5
The difference between MobX 4 and MobX 5 is that the latter uses the ES6 proxy to track properties. Therefore, MobX 5 can only run on browsers that support proxy, while MobX 4 can run in any environment that supports ES5.
Important limitations of MobX 4:
- Observable is not really an array of arrays, so they can not pass Array.isArray()inspection. The most common approach is to pass before the third-party libraries, you often need to be .slice()operational, and the true array shallow copy.
- Adding an attribute to an existing observable object is not automatically caught. Either use the observable map instead, or use the methods in the tool function to read/write/itray the objects that you want to dynamically add.
Flow support
MobX comes with Flow typings . Flow automatically includes the corresponding typings when importing the mobx module. Although you absolutely do not need to manually import type, but you can still do so: import type { … } from ‘mobx’.
To use the flow typings that come with MobX , you need to:
- In the .flowconfig middle can not be ignored node_modules.
- In .flowconfig not in the [libs]not explicitly introducing portion.
- No need to define the type library Flow-typed .
MobX used to be called Mobservable
For mobservable changed its name to mobx all the details, see the change log .
MobX Highlights
Using MobX to turn an application into a responsive one can be summarized into the following three steps:
- Define the state and make it observable
- You can store state, such as objects, arrays, and classes, with any data structure you like. It doesn’t matter if you loop data structures or references. Just make sure that all will change over time and the properties marked with
mobx a tag so that they can become observable.
- You can store state, such as objects, arrays, and classes, with any data structure you like. It doesn’t matter if you loop data structures or references. Just make sure that all will change over time and the properties marked with
import {observable} from 'mobx';
var appState = observable({
timer: 0
});
- Create a view to
respond to changes in state- We appStatehave not observed
any thing . You can create a view when appState the view is automatically updated when the data changes. MobX updates the view in a minimal way. In fact, this can save you a lot of boilerplate files, and it is incredibly efficient - In general, any function can be a responsive view of your own data, and MobX can be used in any ES5-compliant JavaScript environment. But the example used here is the ES6 version of the React component view.
- We appStatehave not observed
import {observer} from 'mobx-react';
@observer
class TimerView extends React.Component {
render() {
return (
<button onClick={this.onReset.bind(this)}>
Seconds passed: {this.props.appState.timer}
</button>
);
}
onReset() {
this.props.appState.resetTimer();
}
};
ReactDOM.render(<TimerView appState={appState} />, document.body);
( resetTimerSee the next section for the implementation of the function)
- Change status
- The third thing to do is to change the state. That is what your application is going to do. Unlike some other frameworks, MobX doesn’t tell you how to do it. This is a best practice, but the key thing to keep in mind is that MobX helps you get the job done in a simple and intuitive
way . - The code below will modify your data every second, and the UI will update automatically when needed. There is no explicit relationship definition in either the controller function that changes state or the view that should be
updated . Use observable to decorate your status andview , sufficient to detect all MobX relationship.
- The third thing to do is to change the state. That is what your application is going to do. Unlike some other frameworks, MobX doesn’t tell you how to do it. This is a best practice, but the key thing to keep in mind is that MobX helps you get the job done in a simple and intuitive
appState.resetTimer = action(function reset() {
appState.timer = 0;
});
setInterval(action(function tick() {
appState.timer += 1;
}), 1000);
Only in strict mode when using MobX required under (not enabled by default) action package. It is recommended to use action because it will help you better organize your application and express the intent of a function to modify the state. At the same time, it automatically applies transactions for optimal performance.
Feel free to try this example with JSFiddle or clone MobX boilerplate project
Key Concepts and principles of MobX
MobX Key Concepts
MobX distinguishes between concepts in the following applications. I have seen it in the previous points, and now let us know more about them.
1. State
The status is the data that drives the application. There are usually domain-specific states like to-do lists , as well as view states like currently selected elements . Remember, the state is like an excel table with data.
2. Derivations
Anything that comes from the state and does not have any further interaction is derived. Derivatives exist in many forms:
- User Interface
- Derived data , such as the number of remaining to-do items.
- Back-end integration , such as sending changes to the server.
MobX distinguishes between two types of derivatives:
- Computed values – These are values that can always be derived from the current observable state using a pure function.
- Reactions – Reactions are side effects that need to occur automatically when the state changes. There is a need to have a bridge to connect imperative programming and reactive programming. Or to be more specific, they ultimately need to implement I / O operations.
When you first started using MobX, people tend to use reactions frequently. Golden Rule: Use if you want to create a value based on the current state computed.
Returning to the metaphor of the excel table, the formula is a derivative of the calculated value. But for the user, seeing the response given by the screen requires a partial redrawing of the GUI.
3. Actions
An action is any piece of code that can change state . User events, backend data pushes, scheduled events, and more. The action is similar to the user entering a new value in the excel cell.
Actions can be explicitly defined in MobX, which can help you organize your code more clearly. If you are using MobX in strict mode , MobX will force the state to be modified only during the action.
In principle
MobX supports one-way data flow, which is the action change state , and the state change updates all affected views .
When the state changes, all derivatives are automatically updated at the atomic level . It is therefore never possible to observe intermediate values.
All derived defaults are synchronous updates. This means that, for example, an action can safely check the calculated value directly after changing the state .
The calculated value is delayed . Any calculated value that is not in use will not be updated until it is required for side effect (I/O) operations. If the view is no longer used, it is automatically garbage collected.
All calculated values should be pure . They should not be used to change state .
Instance
The following code listing illustrates the above concepts and principles:
import {observable, autorun} from 'mobx';
var todoStore = observable({
/* Some observed state */
todos: [],
/* Derived value*/
get completedCount() {
return this.todos.filter(todo => todo.completed).length;
}
});
/* Observe the function of state change */
autorun(function() {
console.log("Completed %d of %d items",
todoStore.completedCount,
todoStore.todos.length
);
});
/* .. and some actions that change state */
todoStore.todos[0] = {
title: "Take a walk",
completed: false
};
// -> Synchronous printing 'Completed 0 of 1 items'
todoStore.todos[0].completed = true;
// -> Synchronous printing 'Completed 1 of 1 items'
In 10 minutes to get started with MobX and React you can dive into this example and use React to build user pages around it.
MobX Interview Questions
Which browsers are supported?
MobX can only be run in an ES5 environment. This means supporting Node.js, Rhino and all browsers (except IE8 and below). See caniuse.com
Can MobX be used with RxJS?
Yes, MobX can use RxJS and other TC 39 compatible observables via toStream and fromStream in mobx-utils .
When do you use RxJS instead of MobX?
RxJS is recommended for any concept involving explicit usage time, or when you need to reason about an observable history value/event (not just the latest one), as it provides more low-level primitive types.
When you want to react to state , not events , MobX provides an easier and high-level approach. In fact, combining RxJS with MobX can produce a really powerful architecture. For example, RxJS is used to process and throttle user events and as a result of the update status. If the state has been converted to observable by MobX, it will process the update UI and other derivatives accordingly.
Support React Native?
Of course, mobx and mobx-react can be used in React Native in. The latter is imported “mobx-react/native”. Developer tools do not yet support React Native. Note that if you intend to store in the state of the components you want to be able to reload and use with hot, then do not use the decorator (notes) in the assembly, use the function instead (for example, by action(fn)substitution @action).
How is MobX compatible with other responsive frameworks?
See this issue for some notes.
Is MobX a framework?
MobX is not a framework. It won’t tell you how to organize your code, where to store state or how to handle events. However, it may free you from a framework that imposes various restrictions on your code in the name of performance.
Can MobX be used with Flux?
Assuming that the data in the store is immutable, this is a good fit for MobX, and the implementation of Flux doesn’t work very well. However, when using MobX, the need for Flux is reduced. MobX has optimized rendering, which works with most types of data, including loops and classes. Therefore, other programming paradigms (such as classic MVC) can now be easily applied to applications that use ReactJS + MobX.
Can MobX be used with other frameworks?
maybe. MobX is framework-independent and can be used in any modern JS environment. For convenience, it just uses a small function to convert a ReactJS component into a responsive view function. MobX can also be used on the server side, and it can already be used with jQuery (see this Fiddle ) and Deku .
Can I record the status and add it?
Yes, see createTransformer to see some examples.
Can you tell me how MobX works?
Of course, join the reactivlux channel or check out the code. Or, submit an issue to motivate me to do some better planning :). Also see this Medium article .
Where can I find more MobX resources?
We have official awesome mobx edited numerous types of list of helpful resources in. If you feel that it lacks some resources, please open an issue or pull request to describe the link you are looking for or share: ) .
Related JavaScript Tutorials For Beginners