Kyle Shevlin

Software Engineer
August 26, 2020
0 strokes bestowed

Mental Model of Use Effect

or Don't Use the Dependencies Array as a Conditional

edit

One thing I have found challenging about React.useEffect is the mental model regarding the dependencies array.

It's very easy to get it in your head to use the dependency array as a means to constrain the calling of the effect, essentially treating it as a guard or conditional.

"If this value changes, do that effect."

The problem is that you'll often run into issues where you only want to run an effect when a single value changes, and thus you'll be tempted to leave out the other dependencies from the dependency array. Next thing you know, you'll be facing an ESLint warning about it. Like with the following code:

React.useEffect(() => {
  // Pretend these values are in the parent scope
  const diff = prevQuantity - quantity
  someHandlerFunction(diff)
}, [quantity])

This, more or less, works like we want it to. When quantity changes, we call the effect and call the handling function. However, this will also warn you that you haven't added all the dependencies. You might think, "I don't want this effect to run when the handler function changes! That'll break the code!"

Trust me, I get stuck in this loop a lot, too.

Here's what you need to understand. Simply put, not calling the effect whenever a dependency changes means you'll have stale values and functions. It will lead to bugs.

Instead, you must make the mental shift to:

Call this effect whenever the dependencies change, but add a conditional in the effect function that only triggers the changes you need, when you need them to happen.

The more correct code looks like this:

React.useEffect(() => {
  if (prevQuantity !== quantity) {
    const diff = prevQuantity - quantity
    someHandlerFunction(diff)
  }
}, [prevQuantity, quantity, someHandlerFunction])

Now we can call the effect whenever a dependency changes, while still not calling our handler function when we don't intend to.

Fixing this small mental model issue helps you avoid the ESLint warnings and write better code. Hope this helps you.


Update - August 27, 2020

I had an additional thought regarding this topic and wanted to add it to the post. Another way to think about the useEffect hook is to write the code as if the hook and the dependency array wasn't there first, and then wrap it in the hook and add the dependencies later.

If I think about this outside of the hook, my mental model for the functionality is, "If there's a difference between these two values, send the difference to this handling function." When we write that code, it looks like the body of our effect, but it makes sense in isolation.

if (prevQuantity !== quantity) {
  const diff = prevQuantity - quantity
  someHandlerFunction(diff)
}

Now that we've written the functionality we desire, the next step is to put React in charge of tracking all of these values for us.

React.useEffect(() => {  if (prevQuantity !== quantity) {
    const diff = prevQuantity - quantity
    someHandlerFunction(diff)
  }
}, [prevQuantity, quantity, someHandlerFunction])

Hope this little update also helps you in your mental understanding of the useEffect hook.


Finished reading?

Liked the post? Give the author a dopamine boost with a few "beard strokes". Click it up to 50 times show your appreciation.

Newer Post: Multiple Boolean Props are a Code Smell
Tags
JavaScriptReactReact Hooks

Are you, or the company you work for, struggling with something mentioned in this article?
Would you benefit from a live training session?
Let's Talk
Kyle Shevlin's face, which is mostly a beard with eyes
Kyle Shevlin is a software engineer who specializes in JavaScript, TypeScript, React and frontend web development.

Let's talk some more about JavaScript, TypeScript, React, and software engineering.

I write a newsletter to share my thoughts and the projects I'm working on. I would love for you to join the conversation. You can unsubscribe at any time.

Introduction to State Machines and XState Logo
Introduction to State Machines and XState

Check out my courses!

Liked the post? You might like my courses, too. Click the button to view this course or go to Courses for more information.
View on egghead.io
I would like give thanks to those who have contributed fixes and updates to this blog. If you see something that needs some love, you can join them. This blog is open sourced at https://github.com/kyleshevlin/blog
alexloudenjacobwsmithbryndymentJacobMGEvanseclectic-codingjhsukgcreativeerikvorhesHaroenvmarktnoonandependabotmarcuslyonsbrentmclarkfederico-fiorinimedayzTowardsDeathFanchGadjonoahmateenbrandonpittmanmattridley
©2023 Kyle Shevlin. All Rights Reserved.