That feeling in the pit of your stomach…
As you delicately type out that useEffect
, crossing your fingers, you realize…
Deep down, you have no idea what this code is really doing.
Whether you’re new to React, or you’ve been using it since the days of classes… the useEffect
hook is… not very intuitive.
When does it run? How often? Does it “watch” things or not? And what is it actually meant for, exactly?
Lifecycle methods felt natural – componentDidMount
explains exactly when it runs! – but useEffect and its dependency array feel like black magic.
So you mostly just try your best to silence the warnings.
React Hook useEffect has a missing dependency: 'regret'. Either include it or remove the dependency array. react-hooks/exhaustive-deps
Dunno why it works, or what I did wrong… but the warning went away! Yay?? 😒
When you don’t get it right, things break in weird unexpected ways. Maybe the app does nothing at all – or worse, your component gets stuck in an infinite loop 😱
One tiny function, infinite uses
useEffect is like a Swiss Army knife. It’s used for everything from fetching data, to handling scroll events, to initializing components after they mount – all with one concise, expressive little function.
But with great expressive power comes great… confusion.
Let me walk you through the basics of how useEffect works. Hopefully you’ll get something out of reading this page, even if you don’t buy the recipe pack.
A quick primer on useEffect
The useEffect hook comes built in to React, so either import it, or access it as React.useEffect
.
Like every hook, it’s a function. And also like every hook, it needs to be called unconditionally. (read: put it near the top, above any return
’s or if
’s)
You’ll always pass a function as the first argument: this is the “effect” to run.
The second argument is the optional dependency array. It can be empty, filled, or omitted.
When the array is empty, the effect depends on nothing and will only run once, after the first render:
useEffect(() => {
// once
}, [])
When filled with variables, the effect will be restricted to run only when those dependencies change.
useEffect(() => {
// on change
}, [thing1, thing2])
When omitted, the effect will run after every render.
useEffect(() => {
// every render!
})
Then there’s the return value. You can return a cleanup function or nothing.
If you return a function, it’ll get called before the next effect kicks off – great for cleaning up from the previous call. If you leave out the return
, nothing special happens.
useEffect(() => {
return () => {
/* clean up! */
}
})
That’s the mechanics of useEffect in a nutshell.
Real problems are… more of a challenge
The syntax is important of course, but as with most things, the tools are necessary but not sufficient. Owning a brush and 10 tubes of paint doesn’t turn you into Bob Ross.
Once you know the mechanics – your palette, if you will – how can you paint a happy component with them? 🌲 🌲 🌲
How can you…
- Handle events like scrolling or network disconnection?
- Set up timers and intervals without firing duplicates?
- Know when useEffect is the right tool, and when it’s unnecessary?
- Run code before or after a state change occurs?
- Run code when a prop changes?
- Understand useEffect in terms of the lifecycle methods you already know?
You could spend hours trying and flailing with your own code before useEffect starts to make a glimmer of sense…
Piecing together the mental model from blog posts and docs will get you there eventually. But how about a shortcut?
What if you knew exactly what your component would do before you ran it?
With a few short videos and a little bit of practice, you can turn the corner from “this seems confusing” to “oh… OH! It all makes sense now!”
I’ll help you understand the bigger picture: not just how useEffect works and when it runs, but how to use it to solve common UI problems, with practical examples from real apps I’ve worked on.
These quick lessons will make useEffect seem easy. You’ll wonder why you got stuck 😎
And if you’ve been clinging to lifecycles and classes for dear life, I think this will help you break their spell.
Over the course of a handful of quick videos, you’ll learn…
- what a side effect is and why we need useEffect
- how to run code before and after a render, and why “before” goes against the grain of React
- when to use useLayoutEffect instead of useEffect (it’s rare)
- what exactly to put in the dependency array and what to leave out, so you never see that
exhaustive-deps
warning again - how to avoid infinite render loops
- how useEffect maps to all the old lifecycle methods…
componentDidUpdate
componentDidMount
componentWillUnmount
- and what to do with the code you wanted to put in
componentWillUpdate
orcomponentWillReceiveProps
You’ll learn all this while also getting a pack of useEffect Recipes – a set of prewritten code solutions to common UI problems, showing you how to:
- Manage a websocket connection with useEffect
- Respond to changing network connection status, online/offline
- Show and hide components based on scroll position
- Pop up a notification when an error occurs
- Load the current user from localStorage when the app mounts
The whole package launches on September 18th. Sign up to be notified and I’ll send you the first video for free, right now.