KEMBAR78
Mobx Internals | PDF
MobX
Performance and Sanity
Adam Klein
ADAM KLEIN
C E O / C O - F O U N D E R
• Persist state to a local storage and then boot up from it, out of
the box.
• Pre-fill state on the server, send it to the client in HTML, and boot
up from it, out of the box.
• Serialize user actions and attach them, together with a state
snapshot, to automated bug reports, so that the product
developers can replay them to reproduce the errors.
• Pass action objects over the network to implement collaborative
environments without dramatic changes to how the code is
written.
• Maintain an undo history or implement optimistic mutations
without dramatic changes to how the code is written.
• Travel between the state history in development, and re-evaluate
the current state from the action history when the code changes,
a la TDD.
• Provide full inspection and control capabilities to the development
tooling so that product developers can build custom tools for their
apps.
• Provide alternative UIs while reusing most of the business logic.
Why Redux
People often use MobX as alternative for Redux.
Please note that MobX is just a library to solve a
technical problem and not an architecture
MICHEL WESTRATE
M O B X C R E A T O R
MobX has no
• Stores
• Data Flow
• Architecture Paradigm
• Persist state to a local storage and then boot up from it, out of
the box.
• Pre-fill state on the server, send it to the client in HTML, and boot
up from it, out of the box.
• Serialize user actions and attach them, together with a state
snapshot, to automated bug reports, so that the product
developers can replay them to reproduce the errors.
• Pass action objects over the network to implement collaborative
environments without dramatic changes to how the code is
written.
• Maintain an undo history or implement optimistic mutations
without dramatic changes to how the code is written.
• Travel between the state history in development, and re-evaluate
the current state from the action history when the code changes,
a la TDD.
• Provide full inspection and control capabilities to the development
tooling so that product developers can build custom tools for their
apps.
• Provide alternative UIs while reusing most of the business logic.
Why Redux
• Persist state to a local storage and then boot up from it, out of
the box.
• Pre-fill state on the server, send it to the client in HTML, and boot
up from it, out of the box.
• Serialize user actions and attach them, together with a state
snapshot, to automated bug reports, so that the product
developers can replay them to reproduce the errors.
• Pass action objects over the network to implement collaborative
environments without dramatic changes to how the code is
written.
• Maintain an undo history or implement optimistic mutations
without dramatic changes to how the code is written.
• Travel between the state history in development, and re-evaluate
the current state from the action history when the code changes,
a la TDD.
• Provide full inspection and control capabilities to the development
tooling so that product developers can build custom tools for their
apps.
• Provide alternative UIs while reusing most of the business logic.
MobX State Tree
Some Facts
15K
stars
G I T H U B
3
latest commit
D AYS A G O
5.0.3
version on npm
L AT E S T
28
on egghead.io
F R E E V I D E O S
Battlefield 1
MS Outlook
Datorama
AWS
Simplee
Sap
Coinbase
Mendix
And many more…
Used
By
Tool for Making Objects Reactive
MobX
class Model {
email = ‘adam@500tech.com’;
setEmail(email) {
this.email = email;
}
}
Plain Object
<input type="email"/>
input.value = model.email;
model.setEmail(‘nir@500tech.com’)
input.value = model.email;
model.setEmail(‘ilya@500tech.com’)
input.value = model.email;
...
Reaction
<input type="email"/>
import { autorun } from 'mobx';
autorun(() => {
input.value = model.email;
});
model.setEmail(‘nir@500tech.com’)
model.setEmail(‘ilya@500tech.com’)
MobX API
class Model {
email = ‘adam@500tech.com’;
setEmail(email) {
this.email = email;
}
}
Plain Object
import { observable } from 'mobx';
class Model {
@observable email = ‘adam@500tech.com’;
setEmail(email) {
this.email = email;
}
}
Reactive Object
@observable prop => getter and setter
Under the hood
autorun(() => {
input.value = model.email;
});
model.setEmail(‘nir@500tech.com’)
model.setEmail(‘ilya@500tech.com’)
...
Our Code MobX
autorun(() => {
input.value = model.email;
});
model.setEmail(‘nir@500tech.com’)
model.setEmail(‘ilya@500tech.com’)
...
Our Code MobX
// create reaction
{
name: ‘Autorun1’
}
autorun(() => {
input.value = model.email;
});
model.setEmail(‘nir@500tech.com’)
model.setEmail(‘ilya@500tech.com’)
...
Our Code MobX
// access getter
{
name: ‘Autorun1’
}
autorun(() => {
input.value = model.email;
});
model.setEmail(‘nir@500tech.com’)
model.setEmail(‘ilya@500tech.com’)
...
Our Code MobX
// add dependency
{
name: ‘Autorun1’,
dependencies: [
{ name: ‘model.email’ }
]
}
autorun(() => {
input.value = model.email;
});
model.setEmail(‘nir@500tech.com’)
model.setEmail(‘ilya@500tech.com’)
...
Our Code MobX
// invoke setter
autorun(() => {
input.value = model.email;
});
model.setEmail(‘nir@500tech.com’)
model.setEmail(‘ilya@500tech.com’)
...
Our Code MobX
// look for reactions
autorun(() => {
input.value = model.email;
});
model.setEmail(‘nir@500tech.com’)
model.setEmail(‘ilya@500tech.com’)
...
Our Code MobX
// invoke reaction (sync)
autorun1();
Duplicate State
import { observable } from 'mobx';
class Model {
@observable email = ‘adam@500tech.com’;
@observable isValid = true;
setEmail(email) {
this.email = email;
this.isValid = this.email.match(regexp);
}
}
Duplicate State
import { observable, computed } from 'mobx';
class Model {
@observable email = ‘adam@500tech.com’;
@computed get isValid() {
return this.email.match(regexp);
}
setEmail(email) {
this.email = email;
}
}
Computed Value
import { observable } from 'mobx';
class Model {
@observable data;
fetchData() {
serverApi.getData().then((data) => {
this.data = data;
});
}
}
Async Operations
class Input extends React.Component {
render() {
return (
<form>
<input value={ model.email }/>
<button disabled={ model.isValid }>Go</button>
</form>
);
}
}
React
import { observer } from 'mobx-react';
@observer
class Input extends React.Component {
render() {
return (
<form>
<input value={ model.email }/>
<button disabled={ model.isValid }>Go</button>
</form>
);
}
}
React
Shopping Cart Demo
g i t H u b . c o m / 5 0 0 t e c h / m o b x - s h o p p i n g - c a r t
Dynamic Observable
Properties
Provider <=> inject
Normalized State
Store Hierarchy
Auto persist to
localStorage
SHAMELESS PROMOTION
P O W E R
35
Thank You
@ _ 5 0 0 T e c h
s l i d e s h a r e . n e t / 5 0 0 T e c h

Mobx Internals

  • 1.
  • 2.
    ADAM KLEIN C EO / C O - F O U N D E R
  • 5.
    • Persist stateto a local storage and then boot up from it, out of the box. • Pre-fill state on the server, send it to the client in HTML, and boot up from it, out of the box. • Serialize user actions and attach them, together with a state snapshot, to automated bug reports, so that the product developers can replay them to reproduce the errors. • Pass action objects over the network to implement collaborative environments without dramatic changes to how the code is written. • Maintain an undo history or implement optimistic mutations without dramatic changes to how the code is written. • Travel between the state history in development, and re-evaluate the current state from the action history when the code changes, a la TDD. • Provide full inspection and control capabilities to the development tooling so that product developers can build custom tools for their apps. • Provide alternative UIs while reusing most of the business logic. Why Redux
  • 6.
    People often useMobX as alternative for Redux. Please note that MobX is just a library to solve a technical problem and not an architecture MICHEL WESTRATE M O B X C R E A T O R
  • 7.
    MobX has no •Stores • Data Flow • Architecture Paradigm
  • 9.
    • Persist stateto a local storage and then boot up from it, out of the box. • Pre-fill state on the server, send it to the client in HTML, and boot up from it, out of the box. • Serialize user actions and attach them, together with a state snapshot, to automated bug reports, so that the product developers can replay them to reproduce the errors. • Pass action objects over the network to implement collaborative environments without dramatic changes to how the code is written. • Maintain an undo history or implement optimistic mutations without dramatic changes to how the code is written. • Travel between the state history in development, and re-evaluate the current state from the action history when the code changes, a la TDD. • Provide full inspection and control capabilities to the development tooling so that product developers can build custom tools for their apps. • Provide alternative UIs while reusing most of the business logic. Why Redux
  • 10.
    • Persist stateto a local storage and then boot up from it, out of the box. • Pre-fill state on the server, send it to the client in HTML, and boot up from it, out of the box. • Serialize user actions and attach them, together with a state snapshot, to automated bug reports, so that the product developers can replay them to reproduce the errors. • Pass action objects over the network to implement collaborative environments without dramatic changes to how the code is written. • Maintain an undo history or implement optimistic mutations without dramatic changes to how the code is written. • Travel between the state history in development, and re-evaluate the current state from the action history when the code changes, a la TDD. • Provide full inspection and control capabilities to the development tooling so that product developers can build custom tools for their apps. • Provide alternative UIs while reusing most of the business logic. MobX State Tree
  • 11.
    Some Facts 15K stars G IT H U B 3 latest commit D AYS A G O 5.0.3 version on npm L AT E S T 28 on egghead.io F R E E V I D E O S
  • 12.
  • 13.
    Tool for MakingObjects Reactive MobX
  • 14.
    class Model { email= ‘adam@500tech.com’; setEmail(email) { this.email = email; } } Plain Object
  • 15.
    <input type="email"/> input.value =model.email; model.setEmail(‘nir@500tech.com’) input.value = model.email; model.setEmail(‘ilya@500tech.com’) input.value = model.email; ... Reaction
  • 16.
    <input type="email"/> import {autorun } from 'mobx'; autorun(() => { input.value = model.email; }); model.setEmail(‘nir@500tech.com’) model.setEmail(‘ilya@500tech.com’) MobX API
  • 17.
    class Model { email= ‘adam@500tech.com’; setEmail(email) { this.email = email; } } Plain Object
  • 18.
    import { observable} from 'mobx'; class Model { @observable email = ‘adam@500tech.com’; setEmail(email) { this.email = email; } } Reactive Object
  • 19.
    @observable prop =>getter and setter Under the hood
  • 20.
    autorun(() => { input.value= model.email; }); model.setEmail(‘nir@500tech.com’) model.setEmail(‘ilya@500tech.com’) ... Our Code MobX
  • 21.
    autorun(() => { input.value= model.email; }); model.setEmail(‘nir@500tech.com’) model.setEmail(‘ilya@500tech.com’) ... Our Code MobX // create reaction { name: ‘Autorun1’ }
  • 22.
    autorun(() => { input.value= model.email; }); model.setEmail(‘nir@500tech.com’) model.setEmail(‘ilya@500tech.com’) ... Our Code MobX // access getter { name: ‘Autorun1’ }
  • 23.
    autorun(() => { input.value= model.email; }); model.setEmail(‘nir@500tech.com’) model.setEmail(‘ilya@500tech.com’) ... Our Code MobX // add dependency { name: ‘Autorun1’, dependencies: [ { name: ‘model.email’ } ] }
  • 24.
    autorun(() => { input.value= model.email; }); model.setEmail(‘nir@500tech.com’) model.setEmail(‘ilya@500tech.com’) ... Our Code MobX // invoke setter
  • 25.
    autorun(() => { input.value= model.email; }); model.setEmail(‘nir@500tech.com’) model.setEmail(‘ilya@500tech.com’) ... Our Code MobX // look for reactions
  • 26.
    autorun(() => { input.value= model.email; }); model.setEmail(‘nir@500tech.com’) model.setEmail(‘ilya@500tech.com’) ... Our Code MobX // invoke reaction (sync) autorun1();
  • 27.
  • 28.
    import { observable} from 'mobx'; class Model { @observable email = ‘adam@500tech.com’; @observable isValid = true; setEmail(email) { this.email = email; this.isValid = this.email.match(regexp); } } Duplicate State
  • 29.
    import { observable,computed } from 'mobx'; class Model { @observable email = ‘adam@500tech.com’; @computed get isValid() { return this.email.match(regexp); } setEmail(email) { this.email = email; } } Computed Value
  • 30.
    import { observable} from 'mobx'; class Model { @observable data; fetchData() { serverApi.getData().then((data) => { this.data = data; }); } } Async Operations
  • 31.
    class Input extendsReact.Component { render() { return ( <form> <input value={ model.email }/> <button disabled={ model.isValid }>Go</button> </form> ); } } React
  • 32.
    import { observer} from 'mobx-react'; @observer class Input extends React.Component { render() { return ( <form> <input value={ model.email }/> <button disabled={ model.isValid }>Go</button> </form> ); } } React
  • 33.
    Shopping Cart Demo gi t H u b . c o m / 5 0 0 t e c h / m o b x - s h o p p i n g - c a r t Dynamic Observable Properties Provider <=> inject Normalized State Store Hierarchy Auto persist to localStorage
  • 34.
  • 35.
    P O WE R 35 Thank You @ _ 5 0 0 T e c h s l i d e s h a r e . n e t / 5 0 0 T e c h