[Music]
yeah I'm Zen pathani I'm Jane on Twitter
and github and almost everything else
today I'm going to talk about state
machines meat we are cooks who knows
sits machines here alright so yeah I
know that you're a bit all this because
state machines are all the odd things
right it has been around for decades and
now we are bringing this old stuff into
react cooks which is just probably a few
months ago released on stable version of
react so yeah I have somebody I have two
kids and I'm living in Singapore working
as a ninja fan working at ninja friend
as a front-end stuff previously I was a
back-end developer but I just moved to
from n for one and a half years and I'll
react and it's hooks will Oh sucks here
great okay what this talk is here I'm
going to give you a very brief
introduction to state machines so for
you who just born yesterday who will
just who never heard of state machines
probably you need to get some basic
concepts of it and then I'm going to
walk you through to my personal journey
when I was working on a feature in in
Japan but that journey is too long too
crammed up in 30 minutes right that's
why I cram I cut it down and I simplify
those things so what you're seeing here
is not the real thing that I'm good but
it's just a simulation of of my journey
at the time so and since it's a code
journey so there will be a lot of code
so
luckily this is my this is the first
talk in the morning so I hope you're
fresh enough to digest more good this
morning and what this talk is not is
this is not an introduction to react
cooks so I'm not gonna introduce you to
any concept of records and it's not also
dig deep down to state machines concept
because it has a lot of concepts we if
you talk about it thoroughly it will
take a few days for review so what is
state machines
well when I'm mentioning state machines
I am referring to this finite state
machines which is on Wikipedia yeah it's
like this definition and we have some
states and
and why are we bringing this old stuff
into foreign stuff because you soul is
that machines are only used in critical
systems in oil and gas company in NASA
for building the rover to send to Mars
because they can afford to have error or
a new bug in production like us we can
afford it right we can afford a bug in
production and we can immediately push
some code and deploy it but that's not
the case for them they cannot just push
a code to Mars right because it take
months to get there so but why why
bringing this this complicated stuff in
the front end there are a lot of there
are a lot of explanations which is
explained by the creator of X state in
this talk so you can just go through the
accommodation and take a look at why
that's this important but the one of the
idea that I am getting sold out is
because it provides a common language
for designers and developers so let me
explain Italy
anybody ever get this kind of flow from
designers or yep one two three okay so
are we the only ones doing the complex
stuff so I got I have a pitch in in our
product in in Japan which is basically a
calendar so this calendar you know an
interaction in a calendar is a lot right
there could be creating new staff or
feeding the staff or filling the list of
items in calendar and since we are a
start-up we do it lean so instead of
having all requirements given up at the
first place we we just get the
requirements gradually one by one so
initially I got only probably one of
this diagram but then I'm the next
period I get another one on the next one
I get another one then this diagram
getting more and more
complex and it's it's getting harder for
me to understand my code and really my
code to this diagram but luckily I'm
getting pitch this idea so somebody so
when I watched the top it he said that
that machine provided common language
for designers and developers and I
thought it is it quite make sense
because we're having this by using state
machines we can actually code in a way
that the diagram is presented to us and
I will show you later that we can do
vice-versa so my problem at the time was
the complex UI flows that I get it
requires multiple states by States here
I mean states in react so I can it can
be in hooks and it can be in in class
components but it's basically the react
States and multiple states are generally
two implicit which means probably some
let's say we have three states we have a
combination of three states on that
company right and then we are four
states we have combination for this and
imagine if the UI is too complex we can
get the state explore it and it's
getting harder to manage the states
inside the company yep so those implicit
States for me it's harder to reason
about
that's why bugs keep showing up on
production due to this invisible state
so I thought that I covered all the
states but apparently there are some
other combination of states that is not
covered yet and it's appearing
production so yeah let's try using state
machines to solve this problem so my
hypothesis is by using state machines we
can make our States visible which means
if we have my own physical States
means no hidden bugs anymore right so
let's hope it turns out that way
enough talk so I told you that there
will be a lot of good a lot of good
we're starting to jump into the code I
will give you a brief solution
interaction through the x-step API so
this is a simple toggle machine example
so I'm just importing a machine function
from X depth and I pass down a
configuration object to the machine
this configuration object configuration
object should contain at least the first
is the initial State so which state that
it initially on when it started and then
all the available States so in this case
I have inactive State and then I have
active state as well and within those
states we can define state transitions
so which is a way to to move between
between states so in this case on toggle
events we move to active state and on
and from the active State on toggle
offense to the same event we move to
inactive State so this is the bare
minimum of a state machine so we can try
to copy this line and we can visualize
it from the code yep here it is so now
we cut our code visualize like this so
it looks like the diagram that I shown
you before the diagram that I that we
cut from the designers it seems a bit
overkill right I mean talker stuff what
can be more complex than this what why
do we need this ceremony just for
toggling stuff but we will get to it
soon so let's start the journey
here I'm gonna walk you through my
journey and I'm gonna split them step by
step so it step consists of first the
conventional implementation of it using
hoops and then next we will get into
this state machine definition and then
next we will integrate that state
machine into our app so for the first
let's say imagine this is we are doing
it in Sprint's and this is ours for
spring so the first feature is simple
this just toggle the model feasibility
which I have button and I click and the
militia up and I close and it closes
it's impressive
this is our bear component which uses a
button and a model and I feels nothing
here yet so for tracking the
traceability step usually we use you
step and then we just initiate the state
with force and on button click we set it
to true on closed model click we set it
to false so this is our implementation
it seems simple right why do we need set
machines but let's try doing this simple
thing using Sigma shins so I just add
not the I just had an ID here so this is
a machine for this case so we have an
infeasible state as an easy L and then
we put an open event so that it can go
to visible state and this visible step
has a closed event to invisible state so
this is our simple machine which looks
like our total machine before and when
we select it it has similar thing the
difference the only difference is that
we have different events that occur so
by having different events there
no way for this state to let's say we're
in physical state and we send clothes
even it will do nothing because there's
no clothes even on this state so that's
what makes it contain we cannot go to
any other state which is not defined
here so let's integrate that solution
into our app this is the same barebone
app but I just imported not stuff use
machine here is react cooked react
custom hooks which is written in X state
and you can look at the expression on
the recommendation I wouldn't walk you
through and this custom hooks accept
first the machine itself the machine
definition that we just did and then it
accept some options which is one of them
is the dev tools which means that we can
debug our our app or our tension in
redux dev tools and next we accept we
get the concept and send even send a
function to send even so for opening the
model this simply sent an open even and
for closing the Mirage is simply send
close event and here to determine that
whether the model is shown or not
instead of placing physical state before
we pass down the current state and the
value of the current state and if the
state is feasible then we display the
model this is it and we still have the
same working what our company but the
only the difference is we can track it
down in redux so we have an open even
here changing state visible invisible to
visible and we have closed even here
changing state from visible to invisible
okay that seems simple but now let's go
to the spring this spear into a garment
to which is we have to differentiate
between view and edit screens like then
our model was just no contain right but
now it has a content and it has added
button when I when we so it is feeling
the thing here and then when you click
the edit it is editing that thing and it
can submit so that's the second
requirement this is our old code in
conventional hooks we have to add
another state because we were checking
another thing right here so we just add
a editing step and then the ref the
state value that we are passing down to
the model so we are passing down this
view and edit state value based on those
two states before so the feasible and
editing if it is feasible then it's not
editing then this view and yeah
something like this and that's for this
for getting the state and now for
changing the state we should propagate
to the events of clicking or some or a
grow of clicking these buttons to
setting the States
so right here we we set editing to false
when we want to crystal when we are
crossing the model so it gets to the
initial set and then on edit button we
just set it to true so that's our
implementation it's still mini 2 plus so
far so why don't we but why we better is
writing state machines but we do some
unusual stuff sometimes right now let's
write state machine and right here I'm
going to introduce you to a new concept
part here a hierarchical state so here
we have a new state but it's not in it's
not sibling of the existing state but
has to be children of an existing state
because this state is actually inside
the visible because this state is only
exists when the model is visible right
and we can just add those states inside
it so this is called hierarchical
straight state and inside the visible
said we have a few state which is an
initial state and then we can go to the
Edit State but then from edit state we
need to go to the parent State right so
there is no the the default when it
accepts the state it can only access
this its siblings it so how do we we
access the parent step luckily actually
provide a way to do it by defining an ID
on appearances or or any any data or
anywhere on the machine and then we can
just refer to that ID but by just by
putting a hash in front of it so this is
our state machine definition then it
looks like this when we visualize it so
on invisible this invisible and physical
thing is the same thing that we have
previously but then we have two new
states inside the visible state so when
we are on view we can edit it and if you
can submit it and when we are inside in
any of this we can still close the model
that's how it works right so let's
implement this in our state machine this
our previous one we need to change the
value that we are passing to the model
because now our feasible set is not
string it's not always a string because
unfeasible we have to inner states so it
will be an object so we are passing on
that object so if if that if the state
is an object and contains visible and
visible contains in state then we press
that inner state otherwise it will be
undefined so that that's why this is
still valid for our model tomorrow will
show when we have
inner state in the feasible state and
then for editing some defense it's
simply sending those events out using
the send function that's it
and when we try doing this it works and
we can also see the redux yeah so now
when we are opening the state yeah now
now we have this visible edit so when we
were close the value is the field is
invisible and when you open it the fella
is now visible good view and now it's
physical edit so it's how X that
represents the state okay
so far we are getting with more
complicated here now so on the Sprint 3
we had a new feature to show the create
screen when opening Moodle with empty
data remember that my case was a
calendar when we click a date there
could be something in it which is this
is our it is this case but there could
be nothing on it which we don't have
anything to show right so that's why we
have to go to immediate little editing
mode which is called create because
we're creating something so we have two
cases now and to accommodate it to
accommodate that in our conventional
implementation we add another state
called data the data object or the thing
in the country and we initialize it with
an empty array so now it's getting more
complicated well we have to incorporate
these three states feasible editing and
data to and derive a state value from
that then we have to write these
conditional stars this seems a bit still
more manageable but we are still far
away forwards so this update buttons to
have two things now now we
of an empty which is the old stuff and
then we can open access which is we are
setting we are opening the water and we
are setting the data to have some
content here it's just an empty string
to simplify and don't forget to clean up
the data when we are crossing the motor
or submitting so there's our
implementation okay now it's getting
more complex because now all of those
additional logic are scattered
everywhere
and it's harder to understand because
it's too implicit which that is this
list oh and which tests actually so
let's try implementing this with set
machines and here here is where it got
more useful now so in this case we are
triggering the same event which is
opening the model so we need to
transition the step from invisible to
visible and here is how we define the
transition but there is another way of
defining this transition which is
defining it is an object so that we can
add some more things here so this
actually the same thing with the
previous one and this another way to
define it as an array so that we can
target different things so that we so
now we can target different states from
the same state within using the same
event how do we differ between this
target and the target
we differ it using condition so this
condition inside machine is called car
which means like imagine a state is a
place and we have guards in front of the
in one of the state in front of the
place like like our grass which is
scanning or attack so even though if
somebody is trying to come into this
stage without having the proper tag they
wouldn't be allowed
- coming right so this like this is why
it called it's called God so here we are
guarding that if the data is zero if the
data length zero and then we go to this
state otherwise we go to the previous
one so just created add a create set and
that's it so this is our news visualized
a machine we have a new condition here
so it's the same event but different
condition with this condition we go
directly to create and the rest are the
same so when we implement this into the
scene let's rename the current button
and then so now it's open empty and
press down an object instead of just
passing out a string now we press it and
pass an object with the type of that
string and a payload in it so we pass
down an empty period and we also need to
have another another button which sends
the same event but with different data
here that's it that's our implementation
in our component so it still works the
same okay now we get to the final spring
in the stop we have to show this screen
when we are opening a model with
multiple data so imagine that there is a
date where we have multiple things there
so we don't know yet which one to feel
right which one to feel like this so if
you have multiple data which one to show
we don't know that's why we are
displaying a list of them and the user
can click on one of the lists and we can
show the view and it does the same thing
like before so now this is our old
component add another step which is
called index which
represents the index that we are seeing
and I enjoy it with with -1 so it's so
if we if you use now when we compare it
to other numbers it bit strange in
JavaScript so just let's use this
sentinel value then incorporated index
into our new state which is lys and
don't forget to add another condition
because now this condition is change
because of this
add new buttons with different data here
don't forget to reset that index to the
-1 when you cross the model so now it's
getting more and more complicated well
this is not mind-blowing yet because
it's still step 4 imagine that in
production I have like step 10 or step
20 so yes it blowed my mind so with in
solutions we can do it the other way we
can do it the same way that we did
before so it just add another guard and
another state to go but then now it's
getting harder to retry because then
what's the point of using insta machine
if we still get it hard to read we can
alias this state sorry we can elect this
guard into a simple string so it's more
readable so now we have if empty then
this if single then this if and else
this and we do find those cards into
this object in step so this is the
second object that we pass through the
machine and it's just naming the
condition as as a string and then define
another list 8 with any actions
interacting with it so that's here is
our new state we have a new open even
state with different condition but now
it's with a proper name so if it's empty
then it's going here if it's single
Danny screen here if it's nothing then
is going to the
stayed which is initialized to this yeah
now just add another button will open
even same of an event but with different
data now we have multiple data and and
inside the model we have an interaction
to view the details and go back to the
ListView so we just passed down the back
and few events and that's it our
implementation is now more readable and
it's easier to read yes
and now we can inspect this yeah it's
working all right so let's compare our
previous implementation the old way to
the state machine implementation so with
our solutions we usually use you state
right but in with this machine we don't
use it anymore we just use use machine
and replace those multiple states before
with just a single call out of the use
machine and we have to stew things here
now this is the state and is the event
and now instead of having those implicit
starts at state cost which we don't
really have any idea what does this - oh
this is doing the same thing actually
but it's harder to understand we need to
read this code probably two or three
more times to actually understand what's
happening on this code but by using the
machines we can just know what have
what's happening on this button what's
happening on this action just by looking
at once and now our app is more simple
and easier to understand but we're
actually just moving away the complexity
from death to the state machine right
but the situation is still complex right
yes it's still complex but the the
difference between the solution the
community of the state machine it and
the competitor of the very first
implementation is this the machine can
be visualized easily
so we're using the same visualizer we
can visualize all the state in a way
that that corresponds to the flow that
we have let me get from the designers so
this visualization for me it reduces the
cognitive overload so based on my
experience the appendage assist now
since I'll still are feeble it's easier
to test so we can just test from
whenever from whichever state to go to
whichever state and in fact I did all
the tests so I'm confident enough with
my machine I am confident that my
machine will break but a setback free si
hypothesize apparently not so it's not
completely bug free so the the bug comes
not from the state but it came from the
discrepancies between the state and the
rendered fuse so I had the correct state
but you know inside that model and we're
just so far we're just passing down the
state of the model right but what's
happening inside the model is some it's
kind of it can go wrong over there so
the box is coming from that model view
so instead of just testing the state we
should also have tested the rendered
view as well in this case we should have
tested Model View so that's why I'm
suggesting us to consider integration
tests so my lesson slot in this journey
is when we are using state machines it
must be designed thoroughly because it's
a complex stuff it so the state machines
will just work but it works as we design
so if we design it badly then it will go
spit and yes it's easy to pass the state
because just just testing the string
testing the object right but don't
forget to test the rendered fuse and
another thing that I learned is there's
no super about it we cannot use still
machines everywhere just like we cannot
use redux everywhere and we cannot use
get derived state from props
anyway yeah so just be mindful that we
might not need state machines as well so
my takeaway from this experience is
please use state machines sparingly so
use it when you need it and when you use
it it's all isolate the state management
into custom hooks so it's easier to
understand and do pass and always test
your code thoroughly which means testing
all the codes including the few so in
this talk I very scratch the surface of
state machines concepts there are a lot
of things more instead machines you can
just read out read up to the
documentation a lot of things even in
fact I didn't I also didn't learn all
the stuff there yet so I just explained
what I implemented so I asked suggesting
you to learn to testing trophy by
considered I actually took his course
and it seems much more useful to prevent
some bugs happening in our code now so
we can get enough confidence within our
code so I think that's all thank you for
your attention and I want to give a
special thanks to David courtship which
is the creator of X state and Rodrigo
Pombo for his amazing cool surfer that I
used here even though it is still in
alpha version but it's pretty good right
I think nothing wrong happens so you can
access this site in this ring and this
off thank you