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