Welcome to our source speech repository about mobx-state-tree and powerpuffs.
- All the information is in the README π
- Source code of our livecoding is described here too ! π
- Feel free to open issues / PR π€
Final application link : https://powerpuff.herokuapp.com/
This is about creating our first model
#30 - Create the first model and instanciate it
Writing our first model of Powerpuff is pretty simple. We'll call it
Powerpuff(damn, clever π€)
- Import
typesfrommobx-state-tree, this is the most common used API typesis used to ... type fields π, we can also use it to describe models ! Andtypes.modelis the way to go !- Here we create a model with only one field, a
namewhich is a string ! - Ok, let's instanciate our model with
Powerpuff.create({})Powerpuffis our modelcreatemeans we instanciate a new tree, a new instance{}is the snapshot, the raw data, to use to instanciate a new powerpuff !
- Let's print it with a
console.log!- As you can see, we use
powerpuff.toJSON()to convert our tree to a snapshot
- As you can see, we use
- π€ oups, it doesn't work at all ! This is because, by default, a field is required
- Let's instanciate our powerpuff, it will be... hm...
Rebelle(the french name of Buttercup) - Print it
- It works π
#31 - Make fields optional
Sometimes we don't want fields to be required at creation
- To do so, we can use the type
maybe, which sets the field tonullif it's not defined - So now, when we instanciate our powerpuff with an empty snapshot, it works !
- And if we want to instanciate the model with a valued name, we still can do it π
#32 - Use more complex types
There are lots of available types provided by mobx-state-tree, find the entire list in the documentation
- Because a Powerpuff is not only a name but also has feelings π‘π, we add the field
moodto describe her - Powerpuffs' personalities are simple thus possibilities are limited. Let's use an enumeration to define them
- If you try to create a Powerpuff with a mood which is not in the enumeration, it fails (Don't try to counterfeit a Powerpuff πͺ)
- Use a mood of the enumeration and now you can instanciate a new Powerpuff !
This is how we update our model
#33 - Updating the model, the natural way
As you must be aware, Buttercup is more
aggressiverather thanhappy. But the powerpuff is now instanciated, the damage is done. The unique solution to repair this mistake is to modify the instance.
- The natural way would be to set directly the
moodattribute of the instance - As you can guess, it crashes π₯
#34 - Updating the model, mobx-state-tree way
To mutate the model, mobx-state-tree wants you to create an action. That way mobx-state-tree can create snapshots and the immutability of the state is kept π
- Describe the action within the function
actionscalled on the model - We give a callback to
actionsfunction. This callback takesselfas parameter, it represents the instance itself. The function returns an object of defined actions - Here our action is very simple : we set the
moodfield of the instance with the givenmood - Use this action to modify the instance, it works π
There are functions that return values deduced from attributes: this is what we call views
#35 - Create a view
Do you know how old is our Powerpuffs now ?
- The best way to know is to add a
birthdayfield to our model and then deduce the age from it π‘ - Btw, you can assign a value to a field when you create the model and mobx-state-tree will deduct the types like a grown up π
- Now we can create a view which computes the actual age of our powerpuff. Use the function
viewson the model to describe it - Like actions, views is given a callback which takes
selfas parameter and return an object of functions computing results - Here we write a simple getter to have the current age of the powerpuff and use it like an attribute
- Calling this view on the instance gives us the current age of the powerpuff π
- Note that when we print the powerpuff, her age isn't part of the snapshot but it's memoized by mobx-state-tree
It can be handy to do some computing during the model lifecycle. mobx-state-tree exposes lifecycle hooks that you can find in the documentation
#36 - preProcessSnapshot
Instead of injecting a snapshot to create a new Powerpuff, we want to use a string describing her.
preProcessSnapshotis called before the model instanciation πββοΈ- It takes the snapshot given to create the instance and returns a new snapshot matching the model
- Here we test if the given snapshot is a string
- If no, we assume it's a well formed snapshot and return it
- If yes, we extract the mood and the name and create a new object with this attributes matching the targeted model
- We can now use a sentence to instanciate our powerpuff, far much simpler β¨
#37 - afterCreate
Say we want Powerpuff's name to be always capitalized (it happens to forget to do it at instanciation, yes everybody can be mistaken, even better ones π)
afterCreateis called after the model instanciation πββοΈ- It should be defined as actions to access the
selfof the instance - Here we simply capitalize the name and the job is done π
With mobx-state-tree, it's possible to define models that depends on others
#38 - Nest models
Now it's easy to create a Powerpuff, they are spreading and it's becoming a mess ! Let's create a store to bring back some order
- We create a new model, which will be our centralized Store, called
Store(yeah, still clever π€) - This model has a list of powerpuffs as attribute, which is an array of Powerpuff
- You can notice we introduced a new type :
optional. It's likemaybebut you can define the default value. Here we want an empty list of powerpuff if the snapshot doesn't have one - The model has also a function to add a new Powerpuff into the list
- Instanciate a store without snapshot, you get a Store with an empty list of Powerpuff π
- Instanciate some powerpuffs using the store action
addPowerpuffon the store instance and its list of Powerpuff is filled β¨
We have a centralized Store which contains a list of Powerpuffs and we can edit one from its index in the array. What if the edited one is always store.edited ?
#39 - Creating a reference
First of all we add the
editedfield and declare it as a reference
- We create a new field named
editedwhich contains the reference to the currently edited Powerpuff π‘. You can see it like a reference which an editing screen can work with - This field is typed
types.referenceof thePowerpuffmodel - We create an action to set this field, go on and call it
setEdited! - Set the first powerpuff as the edited one π
- Print the
storesnapshot - Oups, it doesn't work π
#40 - Reference an identifier
A reference needs an identifier
- We must add an
identifierto our Powerpuff, a number is fine, let's call it... hm...idπ !! - The
idis now required, we add it topreProcessSnapshotas a random number (π€’, this is just for the demo) and to thebellePowerpuff instance as an arbitary number - Let's try to print the
Storesnapshot now! - π it works π, you can see the snapshot doesn't copy the value into
editedfield (which is a reference), mobx-state-tree takes care of optimisations, what a good boy πΆ!
We are sick of console.log everywhere, maybe mobx-state-tree can help us ? Yes it can! π Let's see some debugging tools it provides
#41 - onPatch
How can we track each changes done on our store ?
- We import
onPatchfrom mobx-state-tree: it allows us to listen to all patches applied to our store. Here we use it to simply print these patches - We remove all the
console.logand add theonPatchlistener to ourstoreinstance, right after we created it - Now as we run the demo and we see patches applied to the
storeprinted to the console - You can see π that a patch contains:
- path
- action type
- value
- This is our favorite tool to debug our store π!
#42 - onSnapshot
What if we want to print the complete store snapshot after each mutation ? π€
- Ok this one, the last one, is an easy one!
- Replace all the
onPatchbyonSnapshotand tada π π!! - You can see on the console, all the
store's snapshots for each mutation π - This is great and this is what allows mobx-state-tree to behave like a Redux store. You can see a demo from mobx-state-tree repository!
If you like this demonstration/livecoding, you can tweet about it! - @MilletDelphine and @fabienjuif

