useEffect vs useLayoutEffect vs useMutationEffect
The simple rules for when to use each.
> Note: If the words “React Hooks” doesn’t ring any bells for you, then stop for a moment and go here to read/watch about them.
All three of these can be used to do basically the same thing, but some are more optimal than others. So here are some rules for you to consider when deciding which of these React Hooks to use.
useEffect
99% of the time this is what you want to use. When hooks are stable and if you refactor any of your class components to use hooks, you’ll likely move any code from componentDidMount
, componentDidUpdate
, and componentWillUnmount
to useEffect
.
The one catch is that this runs after react renders your component and ensures that your effect callback does not block browser painting. This differs from the behavior in class components where componentDidMount
and componentDidUpdate
run synchronously after rendering. It’s more performant this way and most of the time this is what you want.
However, if your effect is mutating the DOM (via a DOM node ref) and the DOM mutation will change the appearance of the DOM node between the time that it is rendered and your effect mutates it, then you don’t want to use useEffect
. You’ll want to use either useMutationEffect
or useLayoutEffect
. Otherwise the user could see a flicker when your DOM mutations take effect. This is pretty much the only time you want to avoid useEffect
and use the other two hooks instead.
So what’s the difference between the other two?
useMutationEffect
This runs synchronously at the same time React renders your component. If you need to mutate the DOM then this could be appropriate but only if you don’t need to read values from within the DOM. So this would work well if you need to insert DOM nodes or hook up a jQuery plugin that doesn’t need to get computed styles, but it would not be appropriate if you need to measure heights/widths for example. For that, you’ll want useLayoutEffect
.
useLayoutEffect
This runs synchronously immediately after React has performed all DOM mutations. This can be useful if you need to make DOM measurements (like getting the scroll position or other styles for an element) and then make DOM mutations or trigger a synchronous re-render by updating state.
Summary
- useMutationEffect: If you need to mutate the DOM but don’t need to perform measurements
- useLayoutEffect: If you need to mutate the DOM and/or DO need to perform measurements
- useEffect: If you don’t need to interact with the DOM at all or your DOM changes are unobservable (seriously, most of the time you should use this).
Conclusion
I am extremely excited about React’s upcoming hooks feature. I think it’s going to make React much easier to learn and use.
Learn more about React from me: Hooks & Suspense Playlist on Egghead.io - A free 35 minute list of videos demoing how to use the new React Hooks and Suspense features. (Note: these features are still pretty alpha and likely to change).
Things to not miss:
- useHooks.com - One new React Hook recipe every day. Really cool resource by Gabe Ragland.
- fresh-concurrent-react by Shawn Wang - an as up-to-date-as-possible resource about the upcoming features in concurrent react! Really helpful if you want to play around with Suspense and Concurrent React.
Some tweets from this last week:
> I’m honored to be listed among these fantastic people. See you at @ReactAmsterdam 2019!!! > > (CFP is still open!) – Nov 8, 2018
> Oops… > > my useEffect() that made this request had a mistake on the inputs argument. I think I made several thousand requests 😳 > > Don’t mess those up folks. 🤭 – Nov 8, 2018
> People, writing a novel is HARD WORK and TIME CONSUMING. But it’s SUPER DUPER FUN. – Nov 11, 2018 (I’m at 20k words so far!)
> This email from @jhooks is full of great gems about how to get the most out of your learning experience with @eggheadio. A quick 2 minute read for you: getdrip.com/deliv… – Nov 7, 2018
This week’s blog post is “Common Testing Mistakes”. It’s the published version of my newsletter from 2 weeks ago. If you thought it was good, go ahead and give it some claps (👏x50) and a retweet:
P.S. If you like this, make sure to subscribe, follow me on twitter, buy me lunch, support me on patreon, and share this with your friends 😀
👋 Hi! I’m Kent C. Dodds. I work at PayPal as a full stack JavaScript engineer. I represent PayPal on the TC39. I’m actively involved in the open source community. I’m the creator of TestingJavaScript.com and I’m an instructor on egghead.io and Frontend Masters. I’m also a Google Developer Expert. I’m happily married and the father of four kids. I like my family, code, JavaScript, and React.