Goodbye, useEffect - David Khourshid
Summary
TLDRThe speaker delivers an in-depth tutorial on the proper use of React's useEffect hook, emphasizing its purpose for synchronization rather than as a lifecycle hook. They address common misconceptions, illustrate the pitfalls of misuse, and provide guidance on alternative approaches for handling side effects, such as using event handlers for 'fire and forget' actions and leveraging new hooks like useSyncExternalStore for subscriptions. The talk concludes with a live demonstration of utilizing state machines for effect management, showcasing a simplified and efficient way to handle complex component behaviors in React.
Takeaways
- 🌟 The speaker emphasizes the importance of using `useEffect` correctly, highlighting that many developers struggle with it, even at a senior level.
- 🔄 React 18 introduces changes that can cause effects to run twice on mount in strict mode, which can be confusing and needs to be managed properly.
- 🤔 The speaker suggests that `useEffect` should be thought of as a synchronization tool rather than a lifecycle hook, aligning with the mental model proposed by Dan Abramov.
- 🚫 It's advised against using `useEffect` for transforming data, communicating with parents, or subscribing to external stores, as there are better alternatives.
- 📈 The script discusses the misuse of `useEffect` for fetching data, recommending instead to render as you fetch using libraries like React Query or framework-specific solutions.
- 🛑 The speaker warns against setting state inside `useEffect`, as it can lead to infinite loops and performance issues.
- 🔍 The script highlights the new React documentation at beta.reactjs.org as a valuable resource for understanding the proper use of `useEffect` and other hooks.
- 📚 The speaker introduces the concept of using state machines to model effects, making the logic clearer and more maintainable.
- 🔌 The script mentions `useSyncExternalStore` as a powerful hook for subscribing to external stores in a more efficient and less error-prone way.
- 🎯 The speaker concludes by summarizing that `useEffect` is for synchronization, state transitions trigger effects, and action effects should be handled in event handlers.
Q & A
What is the main focus of the talk at React Brussels?
-The main focus of the talk is to provide a crash course on the correct usage of the useEffect hook in React, and to address common issues and misconceptions about it.
Why might a React developer struggle with useEffect?
-A developer might struggle with useEffect due to its complexity, especially when dealing with large dependency arrays, conditional statements, and issues arising from React 18's behavior of running effects twice on mount in strict mode.
What is the 'frustrated react developer Smiley' mentioned in the script?
-The 'frustrated react developer Smiley' is a humorous reference to the common struggles developers face when dealing with complex or confusing aspects of React, such as the useEffect hook.
What is the difference between 'fire and forget' effects and synchronized effects in React?
-Fire and forget effects are those where the result of the effect is not important, like a console log or an analytics call. Synchronized effects, on the other hand, involve communication with an external system and may be long-lived, requiring synchronization with the component's state.
Why should you avoid setting state inside useEffect?
-Setting state inside useEffect can lead to unexpected behavior and potential infinite loops, especially when the state update triggers the effect again, creating a cycle of state changes and effect executions.
What is the correct mental model for understanding useEffect according to the talk?
-The correct mental model for understanding useEffect is 'synchronization' rather than 'lifecycle'. It should be used to synchronize the component's state with external changes or side effects that are not directly related to the component's rendering.
What is the purpose of the 'use sync external store' hook mentioned in the script?
-The 'use sync external store' hook is used for subscribing to external data stores. It simplifies the process of subscribing, reading, and unsubscribing from an external store, making it easier to manage state that comes from outside the React component.
Why is 'render-as-you-fetch' considered a better approach than using useEffect for fetching data?
-'Render-as-you-fetch' is considered better because it allows the component to render immediately with the fetched data, avoiding unnecessary re-renders and complexity associated with managing promises and cancellation inside useEffect.
What are some alternative solutions to using useEffect for fetching data?
-Alternative solutions include using framework-specific solutions like Remix's loader functions, Next.js's getServerSideProps, or third-party libraries like React Query, which are designed to handle data fetching and caching more efficiently.
What is the 'use' hook mentioned in the script, and what does it offer?
-The 'use' hook, which is part of an RFC for first-class support for promises and async, is a new approach that might become the future of using suspense inside of React. It allows components to automatically suspend when data is being fetched, providing a more streamlined way to handle asynchronous data.
How can state machines be used to model effects in React components?
-State machines can be used to model effects by defining state transitions and associating effects with those transitions. This approach helps visualize and reason about the component's behavior, making it easier to understand when and how effects should be triggered.
Outlines
📚 Introduction to Effective Use of React's useEffect Hook
The speaker begins with a warm welcome to the React Brussels audience, expressing excitement about being back in Belgium. They set the stage for a crash course on the proper use of React's useEffect hook, aiming to eliminate confusion and unnecessary use of useEffect in applications. The speaker acknowledges the challenges even senior developers face with useEffect and reassures the audience that struggles are common in building complex React applications. They introduce the topic by discussing the typical problems that arise with useEffect, especially with the introduction of React 18, which can cause effects to run twice on mount in strict mode. The speaker emphasizes that useEffect is not a lifecycle hook and should be thought of in terms of synchronization rather than lifecycle events.
🔧 The Evolution and Misuse of useEffect
This paragraph delves into the evolution of effects in React, from class components with componentDidMount, componentDidUpdate, and componentWillUnmount to the functional approach with hooks. The speaker critiques the common misuse of useEffect, which often results in complex and hard-to-maintain code, especially as applications grow. They discuss the issues that arise from trying to control the 'fire hose' of changes in a React application, leading to tangled and confusing useEffect dependencies and conditionals. The paragraph highlights the problems that React 18's strict mode brings to light, forcing developers to reconsider their use of useEffect and prompting a reevaluation of the mental model for effects in React.
🚀 useEffect for Synchronization, Not Just Effects
The speaker clarifies that useEffect is intended for synchronization, distinguishing it from 'fire and forget' effects like logging or analytics calls that don't require a response. They use the example of synchronizing with an external API, where the effect is long-lived and can safely remount and unmount as the state changes. The React documentation is referenced to differentiate between effects and event handlers, with the former being long-lived and the latter being short-lived actions. The speaker emphasizes the importance of using useEffect for synchronization with external systems rather than for one-off actions.
🛑 Avoiding Common Pitfalls with useEffect
The paragraph discusses common pitfalls with useEffect, such as setting state within an effect, which can lead to infinite loops and performance issues. It advises against using useEffect for data transformation, communication with parent components, and subscribing to external stores, suggesting better alternatives for each case. The speaker introduces 'use-sync-external-store' as a hook that simplifies subscription logic and mentions the benefits of render-as-you-fetch patterns for data fetching, as opposed to using useEffect. They also touch on the upcoming 'use' hook, which aims to provide first-class support for promises and asynchronous operations in React.
🔄 Refactoring useEffect to Improve Code Clarity
The speaker provides guidance on refactoring code to avoid unnecessary useEffect hooks. They demonstrate how to move logic related to user events and state changes into event handlers or separate hooks, which can improve code clarity and maintainability. The paragraph includes a live demo of a video player component, showing how to use a state machine approach to handle complex logic involving video playback, closing behavior, and user interactions. The speaker emphasizes the importance of modeling effects with state transitions and event handling for better declarative code.
🎉 Conclusion: Best Practices for useEffect and Event Handling
In conclusion, the speaker summarizes the best practices for using React's useEffect and handling events. They reiterate that useEffect is for synchronization, not all effects, and that state transitions should trigger effects, while action effects belong in event handlers. The speaker also highlights the importance of render-as-you-fetch strategies and introduces stately.ai studio, a new tool for modeling state transitions and effects. The talk ends with an encouragement for the audience to explore these best practices and the new tools available to simplify React application development.
Mindmap
Keywords
💡useEffect
💡dependency array
💡synchronization
💡lifecycle hooks
💡declarative vs imperative
💡React 18
💡useSyncExternalStore
💡action effects
💡render as you fetch
💡useState
💡useMemo
Highlights
Introduction to the crash course on the correct use of React's useEffect hook.
The speaker's enthusiasm about being back in Belgium and the React Brussels event.
The common struggle with useEffect even among senior React developers due to its complexity.
The misconception that useEffect is a lifecycle hook, when it's actually about synchronization.
React 18's behavior of running effects twice on mount in strict mode and how it affects existing useEffect implementations.
The difference between fire and forget effects and synchronized effects in the context of React.
The recommendation to avoid using useEffect for transforming data or calculating derived state, suggesting useMemo or direct function calls instead.
The pitfalls of setting state within useEffect and the potential for infinite loops.
Advice against using useEffect for communicating with parent components to prevent unnecessary re-renders.
Introduction of useSyncExternalStore for subscribing to external stores, as an alternative to useEffect.
The argument against using useEffect for fetching data, promoting render-as-you-fetch patterns instead.
The announcement and explanation of the new useJustUse hook for handling promises and async operations.
The recommendation to move action effects to event handlers rather than useEffect for clarity and simplicity.
The use of state machines for modeling effects and state transitions, providing a visual and intuitive way to understand complex logic.
Live coding demonstration of using state machines to handle complex video player logic in React.
The release of stately.ai studio and the introduction of its v1.0, offering tools for state management and effect handling.
Final summary emphasizing the correct use cases for useEffect, the role of state transitions in triggering effects, and the placement of action effects in event handlers.
Transcripts
all right
all right hello everyone hello react
Brussels it's been many years since I've
been in Belgium so I'm so glad to be
back here again this is basically going
to be a crash course where we are going
to learn the right way to use effect and
saying goodbye to all of the other use
effects that we really don't need in our
application so buckle up we are we are
in for a ride hopefully you will learn a
lot of things today but first of all I'm
extremely happy to be here who's happy
to be here at reacts Brussels yeah
all right
who's uh who's a little sad that you
know it's it's ending so soon I mean we
we had we had a lot of amazing talks
like some of my favorite talks today uh
how many of you feel like this have you
seen this smiley before this is the
frustrated react developer Smiley so
yeah
so of course
take care
now I I learned hooks I um I I was
actually fortunate enough to get a
preview of hooks when they first came
out and they all looked really
interesting except use effect I'm like
all right that's gonna be an interesting
one and then uh you know people started
saying okay use the fact I have an
effect this is where it goes but then
the problems kept creeping up and I'm
sure in your code bases if you're using
react uh you know you might have some
really nasty use effects in there
but if you're struggling with use
effects don't worry even senior react
developers struggle with it if anyone
tells you otherwise they're not making
you know good enough react applications
because you do need use effects in your
application and you might have this big
nasty dependency array and if statements
it's all very typical it's just a really
awkward hook all right
so uh typically this is what our you
know use effects looks like we have a
use effect that does something we have a
cleanup dependencies all is fine you
know it might have worked before but
then guess what react 18 came out
and it rendered this again so it ran the
effects twice on Mount in straight mode
how many of you have actually ran into
that or is that just a me problem okay a
bunch of you
so uh use the fact if I were to
summarize this talking just one slide
it's not for all effects in fact I would
say it's even confusingly named it
shouldn't be used effect it should be
used synchronized but we're going to be
talking about that in a minute so what
was life before like before use effects
well we had component did Mount
component did update and component will
unmount and these were all convenient
places to put your effects especially
the effects that were long lived inside
of your class-based react components and
so when we moved to hooks thankfully uh
we we need to figure out okay I have
these please these effects in my life
cycle hooks so where do they go now well
we put all of our componented mounts
effects inside of this one with an empty
dependency array we put the ones where
it happened on component did update in a
non-empty dependency arrayed use effects
and then this awkward looking uh
component will unmount it goes in use
effects with this return function and
this just looks really really awkward so
I want to say first and foremost that
use effect is not a life cycle hook and
while you could use it that way and it
is expected to run at the exact same
time as you mount your component
unmounts and change it's not the way
that you should be thinking about things
uh Danny abramov even said that the
mental model of use effect is
synchronization not life cycle and so
we're going to be talking about why
exactly that is
all right so uh you know we have our use
effects we have the effect in there
we're doing something and the dependency
array it's uh you know this is when that
effect is going to be executed now react
is supposed to be this declarative
framework but honestly this might feel
like okay we're doing our effects in a
declarative way but in reality there is
a ton of indirection over here so take
the imperative approach first like when
something happens like an event or you
know something else a button is pushed a
form is submitted execute this effect
you might be looking at this and saying
okay that's the imperative approach
the declarative approach with use effect
looks more like this when something
happens and uh you know it causes the
state to change then depending on which
parts of that state change which is the
dependency array this effect should be
executed see how it's more declarative
right but only if some condition is true
inside of my use effects also reacts May
execute it again for some future reason
but only in strict mode which you
shouldn't disable for some future reason
so I mean honestly whatever your opinion
is on imperative versus declarative I
prefer the imperative approach and you
could express it in this imperative
approach in a declarative way we'll be
talking about that later too
but some of you might be thinking you
know what I didn't really have a problem
with use effects like I just do
something I return a cleanup and I put
things in my dependency array everything
is fine but the more you add features
and and changes to your application your
use effects start to look more like this
where we have a bigger dependency array
we have multiple use effects we forget
the cleanup and we have this nasty
conditional in here and we're doing
things depending on what's inside there
so we're trying to control the fire hose
of changes happening so that our effects
happens at exactly the right time and
I've seen this code all over the place
I've searched Source graph for examples
and there's just plenty of examples this
is a particularly nasty one and so it
really uh it really showed me that
dependencies are really the wrong mental
model for effects we want effects to
execute when things happen not exactly
when things change so let's get back to
the original issue react 18 running
effects twice on mounts in strict mode
how do we fix this in first of all why
does this happen so
react is actually doing this on purpose
behind the scenes it's not a bug or
anything it's mounting the components
and then it's doing a simulated unmount
of that component which is calling the
cleanup of the effect and immediately
afterwards it's remounting uh the effect
so
um you get your double execution of the
effects and so uh you know when I first
ran into this I was like this is a bad
hook it's use defect you know it feels
like a major major foot gun but honestly
this was reacts way at least react to
18's way of telling you hey you're using
the use effect hook wrong so what is use
effects for it's for synchronization and
so there's a difference between fire and
forget effects and synchronizing
something in your component with some
outside source
so uh take this example we're
synchronizing with some external API
some story API so that uh whenever the
item changes we're we're getting this
item data and we return an uh an
unsubscribe function and this is going
to change whenever our item changes
because we need to unsubscribe to the
old item and re-subscribe to the new
item now doing something like this means
because you're just keeping track of
some external thing we could unsubscribe
and resubscribe multiple times it
doesn't matter it's like watching TV if
you put on the news you could turn the
TV on and off you could change channels
you could go back to the previous
channel that news channel is still going
to be the same so that's sort of the
mental model that you should be thinking
of with use effects
um the react documentation distinguishes
between effects and event handlers so uh
when react is talking about effects with
the capital E they're talking about
long-lived effects so these
subscriptions that I'm talking about
when uh we're talking about fire and
forget effects uh reacts in the docs
mentions that as event handlers so
here's the difference a fire and forget
effect you don't care what the results
of this could be a console log an
analytics call maybe you're sending some
data asynchronously but you're not
awaiting a response a synchronized
effect is when you're actually
communicating with an external system so
this effect could actually be long-lived
and so that's why it's fine for it to
unmount and remounts because just like
changing channels on the TV you are just
changing
um you know like you're changing the
subscription but you still get the same
values
okay so where exactly do the action
effects those fire and forget effects
where exactly do those go
we know that you know we shouldn't
really be putting side effects in render
even though in some instances it's
actually okay but let's just assume that
you can't do that
and we already know by now hopefully
that putting it in use effect is awkward
so where where else do we have space in
this function to put it and don't say
the gap between that because I just
forgot to fill that in
outside the component Maybe
let's explore this
so when we um when we mentioned that
that the um that use effect is going to
run twice when you mount a component
here's what's happening we're attaching
that effect to the components mounting
and unmounting so when an event handler
causes a state change that is going to
cause the components to re-render but
also remember that react can remount
that component and so this effect might
be executing multiple times so if we put
it outside of the render say over here
it doesn't matter how many times that
component's unmounts and remounts and
how often react re-executes that use
effect the effects that we put outside
of the component rendering and outside
of use effect is only going to be
executed once so these action event
effects should actually happen outside
of rendering
so then where exactly do action effects
go inside of event handlers at least
sort of so we have this submit data
inside of this form on submit event
handler and this is actually going to be
a much better pattern than trying to do
this in the use effect and we're going
to see an example of this shortly
so by doing it this way you have this
pattern of when an event happens in
effect is executed
and so uh if you do it using use effects
then this is the mental model when an
effect happens you're changing some
states which can trigger an effect
because that effect is listening for a
state change and especially if you have
multiple use effects other states may
change and you get a chain of triggered
State changes which might trigger
another effect and this becomes really
really hard to visualize really hard to
think about
all right so everything I'm going to
explain including when to execute action
effects and uh when to use use effects
this is all actually explained in the
new react docs at
beta.reactsjs.org uh when I first
started giving a talk like this these
actually did not exist so I'm actually
really thankful if you go to the normal
reacts.js.org documentation site they
have a nice Banner on top that points
you to
beta.react.js.org I Really encourage you
to visit it because there's a lot of
great information in there and one of my
favorite sections is you might not need
an effect so I'm going to explain to you
all of the different points that they
make
first one
is you don't need a use effect for
transforming data I mentioned use memo
gear you don't even have to use memo so
let's take this example we have a cart
we're keeping track of the items we're
keeping track of the total and so
whenever the items change we have to
update the total right your first
thought might be okay that's an effect
when items change set the total to the
new number of items but guess what you
could do this directly
inside of the uh inside the function so
a derived value is just you're reducing
the items or if you don't want to use
reduce you could have a function that
just calculates the total price but you
could do it directly inside of the
components and if this is an expensive
operation and only if it's an expensive
operation you could take this and you
could put it inside of a used memo if
you really want to don't overload your
components with use memo because uh You
Know You're basically trading
performance for memory and yeah only use
this when you really need to when you
have expensive calculations but yeah you
don't need use effects to calculate
derived State and I actually ran into
this problem like basically whenever you
see a set State inside of a use effect
it should be sort of a warning sign to
you especially if this happens I've had
this happen before I've had it happen
with a fetch which is really terrible
because you know that makes a million
API calls so much that react has
actually had to add a warning saying
like hey this is rendering a thousand
times and you're probably doing
something wrong and so that's why you
know some people think that the default
behavior of use effect is an infinite
Loop but this is now mentioned in the
beta docs that this is actually a
pitfall and you should not be setting
States or at least you should avoid
sending State inside of use effect and
also don't forget that dependency array
it's extremely important
all right second thing you don't need
use effects for communicating with
parents so sometimes we have this
pattern where we have on open and on
closed in the parents and so depending
on the state of something we are calling
on open or on close uh so the problem
with this is that you you might be
accidentally introducing additional
renders because uh the use effects
because of a state change
it's re-rendering and then it is in the
next um the next cycle like when use
effect is called it is telling the
parents to do something which might tell
the component to do something so you
might be introducing additional
re-renders inside of there so a better
pattern to do is move these effects like
on open on closed so these fire and
forget effects move them closer to where
the state change actually happens so I'm
calculating if it's going to be open or
if it's going to be closed I'm keeping
track of state which I might not
actually need to do here and then
depending on whether it's open or closed
I called directly in the event handler
this toggle view event handler on open
or on closed
and you could have also when you do that
you could easily refactor it to a
separate hook and then you have this
nice used toggle hook that you could
just use directly in your component it's
a much much simpler way to uh to express
that logic and to contain it in a in a
in a hook
all right so third thing you don't need
use effects for subscribing to external
stores so I know what you're thinking
like I just said that this is the one
thing that you should use use effect for
and it is true most of the time however
there is a really cool hook that was
mentioned in the last Talk use sync
external store and um you might think
okay that's a very complicated sounding
hook and it seems like it's for advanced
use cases for Library authors but it
actually makes things a lot simpler so
going back to a previous example where
we're subscribing to a story API I'm
checking for the connection status and
I'm setting is connected which again if
you're setting State over here it might
be a warning sign that you might be able
to refactor out this used effect and so
I'm subscribing to it that I'm calling
unsubscribe and I'm reading data from
this uh store API so instead of doing
this
I could use the use sync external store
hook and it actually makes things a lot
simpler because we're getting is
connected from this snapshot over here
this door API dot get status and we're
reading whether it's connected or not so
this is going to be a Boolean we pass in
the subscription function or the
function that will actually subscribe to
the store and we also provide the server
snapshots so this could run uh on server
side rendering
all right this one is actually a big one
because this accounts to like so many of
my previous uses of use effect which is
fetching data we think okay I need to
fetch data I need to call an API so I'm
just going to stick it in the in an
effect but the better way to do this is
actually render as you fetch so here's
an example you all have probably seen
this a hundred times where we have to do
this weird dance of uh having a
cancellation flag and then we get our
items and you know if it's canceled so
if we navigate away or we don't want to
call This Promise anymore we're going to
ignore the response from that promise
and then we set the item switch again if
you see this in the use effect it's a
warning sign and then we return this
cleanup where if anything changes is
canceled is true also I forgot the
dependency array I legitimately forgot
it I just realized that now so this is a
very very bad use effect
all right so what are some Alternatives
well uh like was mentioned in previous
talks remix has a great API so long
story short Frameworks use whatever the
Frameworks provide you and if you don't
have that then use Query works well too
but uh with remix you could Define a
loader function and you just get your
items and that's going to be available
to your component immediately you don't
have to do that use effect dance next JS
has something similar with get server
side props so you could just awake get
items in that function and return it as
props over here into your actual
components and so react query I'm sure a
lot of you are using react query it's an
excellent Library it's not a state
management Library it's not even the
fetching Library it's a caching library
that works really well with fetching
data so um in in this case I'm actually
doing prefetch so I'm prefetching this
data I'm populating it in and then I'm
reading it so instead of use effect in
summary
you should either use Query or use a
hook like that or use a framework or use
another hook that was actually recently
it's not out yet it's it was recently
announced its use
just use
so I I'm serious you might be thinking
like
what kind of hook name is this I mean
it's a legitimate hook name but it is
actually an RFC first class support for
promises and async the weight and so
this is actually probably maybe going to
be the future of using suspense inside
of react so basically you would fetch a
post and
um you would have some sort of caching
mechanism which react is still trying to
figure out but again this is how use
Query Works under the hood as well and
so this is going to automatically
suspend your components so use it seems
really cool terribly named
um but you know that's the future
all right and so Danny ibrahimov
actually said there's a lot of problems
with fetching and use effect you might
have race conditions no instant back
button so basically when you um go back
to a page you have to load that data
again
um no initial HTML content when you
render your page you're going to see a
lot of nasty loading Spinners and also
chasing waterfalls so if you're fetching
inside of your parent component you have
to wait for that and then when your
child component renders after that's
done touching you have to wait for that
it gets really annoying
um there's also the fact that you don't
need to use effect for initializing
Global Singletons so um for example we
know that this is now going to run twice
so instead of it uh running twice we
could use a ref to track whether it was
called or not but that gets really
annoying
um and so we could you know just move
that ref outside of the component
especially if you're running this effect
inside of the root components uh but
you're still using a use effect so
instead honestly just call it outside of
the component there's really no harm in
it now you might be you know saying what
about server side rendering what about
testing just move it into a function the
point of it is that you don't need to
put everything inside of a component
and so finally the one that I really
want to get into you don't need to use
use effects for handling user events so
like we talked about before this is
submitting logic when we submit a form
uh it looks very similar to The Promise
example except now we have extra
variables for whether it's loading
whether it's canceled we also have to
keep track of Errors instead of this you
could just put it inside of a side or a
side effect inside of the event handler
so this is on submit right over here and
this you know it also gets pretty nasty
so that's why I would say that when you
are working on logic like this you
should extract it out to a hook and so
my favorite hooks are of this form where
we get the states and we could also send
in events some of you might know me
because I created X date this is how
xdate works this is how Redux works this
is how use reducer works and it is a
very very useful API because all of our
actions and events that happen are
reduced to a single line where you're
just sending an event object so it makes
things very clear and very easy and
succinct and so I'll actually give you a
really quick demo of this
um including like just a you know a use
effect demo so this is an example
application and here's how it works when
I click the video
it opens and plays when I click outside
of it it closes and when the video is
finished right now it immediately closes
so
um right now
um actually in the back can you all see
these use effects over here can you read
them
I I can't read them either because
there's too many of them and uh they're
really really complicated so I I have a
bunch of use effects here this one is
controlling whether the video is playing
or paused this one is controlling
whether the video has ended and you know
we have that nasty if statement in there
uh and this one is controlling whether
we have pressed the Escape key because I
could press the Escape key and close it
now I also want the user behavior of
when the video ends I wanted to wait two
seconds before closing and so that
that's probably going to be another use
effect we need to add code to you know
all of the other three use effects just
to make sure that we're handling those
correctly and we're not closing it
prematurely uh so instead I want to show
you by ways of diagramming how I would
model this instead so here
uh right now we have the behavior where
we start in the mini state where our
video player is nice and small and on
some toggle we transition to a full
state
so you know we just toggle back and
forth
we could toggle like this now in the
full State this is what I mean by
declarative effects so um in full when
this is open I actually want to play the
video so I'm just going to add this
as an action
like that let me zoom in and when I exit
the full so when I go from Full to mini
I want to pause the video because the
video might not be done so I just want
to make sure it's being paused so this
it's sort of like a flowchart you could
Envision how it works like we're mini
and then when we click we're in the full
mode where we see the video playing and
when we toggle we're back to Mini
now uh there's a couple of other things
that we could do so um I'm going to add
an invocation and so basically we're
going to add some listeners this is
going to uh listen for
um whether the video ended or not
and I also want to listen for
um
or actually before that I want to do
this so we are going to also add events
for video ended
and we are going to add an event
for
he dot Escape
all right so this is our logic so far so
when we're in full mode whether the
video ends or you press the Escape key
or you click outside the video it should
go back to mini and it should pause the
video so you know that makes sense so
far so um
I I actually also want the additional
behavior of when I'm in the full States
um like let's just say that this is
playing
I also want to
um wait for two seconds so how can we do
this
in like this diagram so I could just you
know have a state for when it stopped
and I could move this video dot ended
I'm going to move this over here drag it
a little
and so when the video stops here's the
logic and this is logic that you might
be sharing with a designer or a project
manager that when the video stops I want
to wait for two seconds so
oops let me reload that real quick all
right so I want to wait
huh weird uh I want to wait for two
seconds so here's how we can do that
pretend you didn't see that all right so
after I'm gonna do
two seconds I'm going to transition to
mini so if you're trying to explain this
logic to someone you could simulate it
here and say we're going to toggle to
full and then when you press either
toggle or key Escape it goes back to
mini but when the video ends then after
two seconds we want it to close and go
back to the mini state where the video
is paused and it's you know where we're
no longer seeing the full video
so a couple of other things I have to
add in order to listen to these events
key escaping video ended I need to
um add some invocations so
video ended and also
uh key Escape so basically we're
listening for these two things to happen
and
this is our complete Logic for how I
want this to work now I only have a
minute and 44 seconds so let's see how
quickly I could live code this thing in
fact actually I probably don't have time
to do that so I am just going to copy
the code over here
and right now this is not working no
magic tricks okay not working
so I'm gonna go here
paste this machine in this is an X8
machine and
um
oh I I forgot something
actually it literally says David don't
forget this so oops all right
Don't Clap yet um
all right so
we so when I click the player I have to
send the toggle event and that's all I
have to do so
hopefully this works if I click here if
I click outside if I click here if I
press escape and if I click here and I
wait for the video to end
give it two seconds one two close there
we go
[Applause]
all right so this is now available at
stately.ai studio and uh we actually
released our v1.0 today so please check
this out if you if you want to
um but yeah I'm really excited that we
have this out so um in short just to
summarize because I have 20 seconds when
do effects happen in these State
transitions where an event is occurring
and then you model that as an effect so
where do these action effects go inside
of these State transitions which most of
the time happen to be executed at the
same time as those event handlers so in
short use effect is not for all effects
it's for synchronization State
transitions are what trigger effects
action effects go in event handlers you
should render as you Fetch and also it
might be nice to model effects with
steam machines so thank you very much
react Brussels
Browse More Related Video
![](https://i.ytimg.com/vi/LIYiLpO4brM/hq720.jpg)
A First Look at Effects | Lecture 141 | React.JS 🔥
![](https://i.ytimg.com/vi/gN-Bclvf8yI/hq720.jpg)
The useEffect Dependency Array | Lecture 145 | React.JS 🔥
![](https://i.ytimg.com/vi/yHdX4dCl5CY/hq720.jpg)
ReactJS Course [6] - Component Lifecycle | UseEffect Tutorial
![](https://i.ytimg.com/vi/o-Bm_rGIBIk/hq720.jpg)
useEffect to the Rescue | Lecture 140 | React.JS 🔥
![](https://i.ytimg.com/vi/StkNmef11Xc/hq720.jpg)
The useEffect Cleanup Function | Lecture 151 | React.JS 🔥
![](https://i.ytimg.com/vi/VQd8DKV1D2M/hq720.jpg)
How NOT to Fetch Data in React | Lecture 139 | React.JS 🔥
5.0 / 5 (0 votes)