Skip to content

Instantly share code, notes, and snippets.

@ramnathv

ramnathv/index.js

Forked from jimthedev/index.js
Created Jul 5, 2016
Embed
What would you like to do?
requirebin sketch
var mobx = require('mobx');
var _ = require('lodash');
/*
MOBX in VANILLA ES5
Notes are based on Matt Ruby's Open Source North Talk:
Practical React with MobX
https://www.youtube.com/watch?v=XGwuM_u7UeQ
*/
// SINGLE OBJECT MOBX OBSERVABLE
// This is the simplest example of using mobx on a single object
var person = mobx.observable({ // Observable
firstName: 'Jim',
lastName: 'Cummins',
age: 32,
fullName: function() { // COMPUTED
// console.log('---- HIT SINGLE OBJECT COMPUTED FULL NAME ----');
return this.firstName + ' ' + this.lastName;
}
});
// AUTORUN
//
// This is run once when the page loads, then again
// whenenver person.age or person.fullName changes
//console.log('----AUTORUN----');
mobx.autorun(() => console.log(person.fullName + ' is ' +person.age + " years old!"));
// REACTION ON A SPECIFIC PROP ON A SINGLE OBJECT
mobx.reaction(function() {
// TRACKING FUNCTION
// EVERYTHING IN HERE WILL GET WATCHED
// - This fn is run once when the page loads to get initial values
// - There should be no side-effects in this function
// - You can optionally return results that will be passed
// in as parameters to the side effects function.
console.log('---- TRACKING: SINGLE OBJECT ----', person.age);
return person.age;
}, function(age) {
// SIDE EFFECTS FUNCTION
// EVERYTHING IN HERE GETS FIRED ONLY ON CHANGE OF THE TRACKING FUNCTION
// - Might get args passed from the TRACKING function
// - Should encapsulate expensive side effects
// - Is not run once on page load, only when tracking detects a change
console.log('---- SIDE EFFECTS: SINGLE OBJECT ----', person.age);
console.log(person.fullName + ': ' + age);
});
person.age = 40;
// ARRAY MOBX OBSERVABLE
// Very similar example to the simple object except now we have an
// array of objects that we're observing.
var artists = mobx.observable([{
firstName: 'Yo yo',
lastName: 'Ma',
age: 38,
fullName: function() { // COMPUTED
// console.log('---- HIT ARRAY COMPUTED FULL NAME (FIRST PERSON) ----');
return this.firstName + ' ' + this.lastName;
}
}, {
firstName: 'Miles',
lastName: 'Davis',
age: 60,
fullName: function() { // COMPUTED
// console.log('---- HIT ARRAY COMPUTED FULL NAME (SECOND PERSON) ----');
return this.firstName + ' ' + this.lastName;
}
}]);
// REACTION TO A CHANGE IN SPECIFIC PROPS IN AN ARRAY OF OBJECTS
//
// When: the age changes on any artist
// Perform: log the age and full name of all artists
mobx.reaction(function() {
// TRACKING FUNCTION
// - Fires once when page loads to get initial values
// - Also fires when any tracked value changes
// - May return a value to be used as a param in
// the side effects function
console.log('---- TRACKING: ARRAY OF OBJECTS ----');
return artists.map(function(artist) {
return {
age: artist.age,
firstName: artist.firstName
};
});
}, function(newArtists) {
// SIDE EFFECTS FUNCTION
console.log();
console.log('---- SIDE EFFECTS: ARRAY OF OBJECTS ----');
console.log(artists.map(function(artist){
return { fullName: artist.fullName, age: artist.age };
}));
});
// side effects triggered properly
artists[0].age = 3;
// side effects triggered again... not ideal.
artists[0].firstName = 'Twista';
// How can we batch the last two mutations on artists?
// Soooo we use: transactions!
// TRANSACTIONS (TX) are used to batch mutations so that
// side effects only happen once!
// Notice that these will be batched as a single change
mobx.transaction(function() {
console.log('---- TRANSACTIONS BATCH AND AVOID DUPLICATE SIDE EFFECTS ----');
artists[0].age = 59;
artists[0].firstName = 'Busta';
// Note that mobx will properly resolve nested TXs
// this is the primary reason you'd use TXs over
// actions
mobx.transaction(function() {
artists[0].age = 30;
artists[0].firstName = 'Busted';
console.log('---- TRANSACTIONS ARE NESTABLE ----');
});
});
// ACTIONS
// Here we are adding an action to the person object. An action is
// just a decorated function
// that when run, wraps all of the changes in a transaction
// We should generally be using actions instead of transactions
_.assign(person, {
setFirstAndLastName: mobx.action(function setFirstAndLastName(firstName, lastName) {
console.log('---- ACTIONS BATCHES THESE CHANGES FOR US ----');
this.firstName = firstName;
this.lastName = lastName;
})
});
person.setFirstAndLastName('Barry', 'Manilow');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.