{"id":9975,"date":"2022-09-07T13:25:37","date_gmt":"2022-09-07T18:25:37","guid":{"rendered":"https:\/\/upmostly.com\/?p=9975"},"modified":"2022-09-08T04:07:27","modified_gmt":"2022-09-08T09:07:27","slug":"react-uselayouteffect-hook","status":"publish","type":"post","link":"http:\/\/upmostly.com\/tutorials\/react-uselayouteffect-hook","title":{"rendered":"When should you use the useLayoutEffect hook in React?"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Introduction<\/h2>\n\n\n\n<p>React has, not so long ago, come with a major update to its Functional Components (In <strong>v16.8<\/strong>, back in March of 2019), which has finally provided those components with a way to become <strong><a href=\"https:\/\/www.codecademy.com\/learn\/react-component-state\/modules\/react-102-stateless-inherit-stateful-u\/cheatsheet\" data-type=\"URL\" data-id=\"https:\/\/www.codecademy.com\/learn\/react-component-state\/modules\/react-102-stateless-inherit-stateful-u\/cheatsheet\" target=\"_blank\" rel=\"noreferrer noopener\">stateful<\/a><\/strong>.<\/p>\n\n\n\n<p>The addition of Hooks not only meant that <strong>Functional Components would be able to provide their own state<\/strong> but also <strong>manage their own lifecycle events<\/strong> through the introduction of the <strong>useEffect<\/strong> hook.<\/p>\n\n\n\n<p>Moreover, the update has also introduced a brand-new, <strong>useLayoutEffect<\/strong> hook, which, according to the <strong><a href=\"https:\/\/reactjs.org\/docs\/hooks-reference.html#uselayouteffect\" data-type=\"URL\" data-id=\"https:\/\/reactjs.org\/docs\/hooks-reference.html#uselayouteffect\" target=\"_blank\" rel=\"noreferrer noopener\">React documentation<\/a><\/strong>, does a pretty similar thing to what the <strong><a href=\"http:\/\/upmostly.com\/tutorials\/introduction-to-the-useeffect-hook-in-react(opens in a new tab)\" target=\"_blank\" data-type=\"URL\" data-id=\"http:\/\/upmostly.com\/tutorials\/introduction-to-the-useeffect-hook-in-react(opens in a new tab)\" rel=\"noreferrer noopener\">useEffect<\/a><\/strong> hook does; so this begs the question: <strong><em>what&#8217;s really the difference between the two?<\/em><\/strong><\/p>\n\n\n\n<p>If you aren&#8217;t already familiar with hooks, I do recommend checking out <a href=\"https:\/\/upmostly.com\/tutorials\/react-hooks-simple-introduction\" target=\"_blank\" data-type=\"URL\" data-id=\"https:\/\/upmostly.com\/tutorials\/react-hooks-simple-introduction\" rel=\"noreferrer noopener\"><strong>this article<\/strong><\/a> where you&#8217;ll get a good understanding of what they are, what they are used for, and how you can use them in your applications.<\/p>\n\n\n\n<p>In this article, we will be looking in more depth at what does each hook do, what are the differences between the two, and, towards the end, you should be having a better understanding of how each of them works, when you should be using one over the other, and some common pitfalls of falling in love with either.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Overview of the <strong>useEffect<\/strong> hook<\/h2>\n\n\n\n<p>This hook has been initially added as an alternative way of handling side effects in Functional Components, similarly to the <strong>componentDidMount<\/strong> and <strong>componentDidUpdate<\/strong> methods in Class-based Components (They also run at the same time in comparison).<\/p>\n\n\n\n<p>Thus, its equivalent in Class-based Components would be a combination of the <strong>componentDidMount<\/strong>, <strong>componentDidUpdate<\/strong>, <strong>and<\/strong> <strong>componentWillUnmount<\/strong> methods, the latter being an effect of the return statement within the callback passed as an argument to the hook.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Hook Flow<\/h3>\n\n\n\n<ol class=\"wp-block-list\" id=\"block-449bfe8a-ba0e-4327-b74e-c88962c887a1\"><li>You cause a render somehow (the state has been updated or the parent re-renders)<\/li><li>React renders your component (calls it)<\/li><li>The screen is visually updated<\/li><li>Then&nbsp;<strong>useEffect<\/strong>&nbsp;runs<\/li><\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Overview of the <strong>useLayoutEffect<\/strong> hook<\/h2>\n\n\n\n<p>Similarly to <strong>useEffect<\/strong>, it runs at the same time that <strong>componentDidMount<\/strong> and <strong>componentDidUpdate<\/strong> do in Class Components. However, <strong>useLayoutEffect<\/strong> runs synchronously, as opposed to <strong>useEffect<\/strong>, which means that the callback that it receives will only be invoked after the V-DOM computations have taken place in the component, but before they have been painted to the actual DOM.<\/p>\n\n\n\n<p>That means that in case we do need to make any JavaScript queries for any DOM elements, <strong>useLayoutEffect<\/strong> is the hook we might need.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Hook Flow:<\/h3>\n\n\n\n<ol class=\"wp-block-list\"><li>You cause a render somehow (change state, or the parent re-renders)<\/li><li>React renders your component (calls it)<\/li><li><strong>useLayoutEffect<\/strong>&nbsp;runs, and React waits for it to finish.<\/li><li>The screen is visually updated<\/li><\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">When to use the <strong>useLayoutEffect<\/strong> hook?<\/h2>\n\n\n\n<p>There is a common issue when using the <strong>useEffect<\/strong> hook where a component might &#8220;flicker&#8221; when its state is updated. That&#8217;s because the component will first render in a partially-ready state as it&#8217;s continuing the async computations process, and only then will it re-render in its final state.<\/p>\n\n\n\n<p>That&#8217;s a good indication that you might want to use the <strong>useLayoutEffect<\/strong> hook instead.<\/p>\n\n\n\n<p>Such an example would be trying to generate and render an extremely high numeric value at the click of a button like in this example:<\/p>\n\n\n\n<div class=\"wp-block-cgb-block-codeplus\"><div class=\"upmostly-block better-code-block\"><div class=\"dark\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><div><span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> useState<span class=\"token punctuation\">,<\/span> useEffect <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">'react'<\/span><span class=\"token punctuation\">;<\/span>\n<span class=\"token keyword\">import<\/span> <span class=\"token string\">'.\/App.css'<\/span><span class=\"token punctuation\">;<\/span>\n<span class=\"token keyword\">function<\/span> <span class=\"token function\">App<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span>\n  <span class=\"token keyword\">const<\/span> <span class=\"token punctuation\">[<\/span>value<span class=\"token punctuation\">,<\/span> setValue<span class=\"token punctuation\">]<\/span> <span class=\"token operator\">=<\/span> <span class=\"token function\">useState<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\n  <span class=\"token function\">useEffect<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">=&gt;<\/span> <span class=\"token punctuation\">{<\/span>\n    <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>value <span class=\"token operator\">===<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span>\n      <span class=\"token function\">setValue<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">10<\/span> <span class=\"token operator\">+<\/span> Math<span class=\"token punctuation\">.<\/span><span class=\"token function\">random<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">*<\/span> <span class=\"token number\">200<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\n    <span class=\"token punctuation\">}<\/span>\n  <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">[<\/span>value<span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\n  console<span class=\"token punctuation\">.<\/span><span class=\"token function\">log<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'render'<\/span><span class=\"token punctuation\">,<\/span> value<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\n  <span class=\"token keyword\">return<\/span> <span class=\"token punctuation\">(<\/span>\n    <span class=\"token operator\">&lt;<\/span>div className<span class=\"token operator\">=<\/span><span class=\"token string\">\"App\"<\/span><span class=\"token operator\">&gt;<\/span>\n      <span class=\"token operator\">&lt;<\/span>p<span class=\"token operator\">&gt;<\/span>Value<span class=\"token punctuation\">:<\/span> <span class=\"token punctuation\">{<\/span>value<span class=\"token punctuation\">}<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>p<span class=\"token operator\">&gt;<\/span>\n      <span class=\"token operator\">&lt;<\/span>button onClick<span class=\"token operator\">=<\/span><span class=\"token punctuation\">{<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">=&gt;<\/span> <span class=\"token function\">setValue<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">}<\/span><span class=\"token operator\">&gt;<\/span>\n        Generate Random Value\n      <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>button<span class=\"token operator\">&gt;<\/span>\n    <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>div<span class=\"token operator\">&gt;<\/span>\n  <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\n<span class=\"token punctuation\">}<\/span>\n<span class=\"token keyword\">export<\/span> <span class=\"token keyword\">default<\/span> App<span class=\"token punctuation\">;<\/span><\/div><\/code><\/pre><\/div><\/div><\/div>\n\n\n\n<p>If we were to check how our application behaves, we shall see a changing flickering number each time we were to press the button:<\/p>\n\n\n\n<figure class=\"wp-block-video\"><video height=\"154\" style=\"aspect-ratio: 320 \/ 154;\" width=\"320\" controls src=\"https:\/\/upmostly.com\/wp-content\/uploads\/Screen-Recording-2022-09-07-at-18.26.41.mov\"><\/video><figcaption>Flickering Component On State Update<\/figcaption><\/figure>\n\n\n\n<p>If we were to use the <strong>useLayoutEffect<\/strong> hook instead, we would be able to get rid of this visual bug:<\/p>\n\n\n\n<div class=\"wp-block-cgb-block-codeplus\"><div class=\"upmostly-block better-code-block\"><div class=\"dark\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><div><span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> useState<span class=\"token punctuation\">,<\/span> useLayoutEffect <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">'react'<\/span><span class=\"token punctuation\">;<\/span>\n<span class=\"token keyword\">import<\/span> <span class=\"token string\">'.\/App.css'<\/span><span class=\"token punctuation\">;<\/span>\n<span class=\"token keyword\">function<\/span> <span class=\"token function\">App<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span>\n  <span class=\"token keyword\">const<\/span> <span class=\"token punctuation\">[<\/span>value<span class=\"token punctuation\">,<\/span> setValue<span class=\"token punctuation\">]<\/span> <span class=\"token operator\">=<\/span> <span class=\"token function\">useState<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\n  <span class=\"token function\">useLayoutEffect<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">=&gt;<\/span> <span class=\"token punctuation\">{<\/span>\n    <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>value <span class=\"token operator\">===<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span>\n      <span class=\"token function\">setValue<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">10<\/span> <span class=\"token operator\">+<\/span> Math<span class=\"token punctuation\">.<\/span><span class=\"token function\">random<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">*<\/span> <span class=\"token number\">200<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\n    <span class=\"token punctuation\">}<\/span>\n  <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">[<\/span>value<span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\n  console<span class=\"token punctuation\">.<\/span><span class=\"token function\">log<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'render'<\/span><span class=\"token punctuation\">,<\/span> value<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\n  <span class=\"token keyword\">return<\/span> <span class=\"token punctuation\">(<\/span>\n    <span class=\"token operator\">&lt;<\/span>div className<span class=\"token operator\">=<\/span><span class=\"token string\">\"App\"<\/span><span class=\"token operator\">&gt;<\/span>\n      <span class=\"token operator\">&lt;<\/span>p<span class=\"token operator\">&gt;<\/span>Value<span class=\"token punctuation\">:<\/span> <span class=\"token punctuation\">{<\/span>value<span class=\"token punctuation\">}<\/span><span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>p<span class=\"token operator\">&gt;<\/span>\n      <span class=\"token operator\">&lt;<\/span>button onClick<span class=\"token operator\">=<\/span><span class=\"token punctuation\">{<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">=&gt;<\/span> <span class=\"token function\">setValue<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">}<\/span><span class=\"token operator\">&gt;<\/span>\n        Generate Random Value\n      <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>button<span class=\"token operator\">&gt;<\/span>\n    <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>div<span class=\"token operator\">&gt;<\/span>\n  <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\n<span class=\"token punctuation\">}<\/span>\n<span class=\"token keyword\">export<\/span> <span class=\"token keyword\">default<\/span> App<span class=\"token punctuation\">;<\/span><\/div><\/code><\/pre><\/div><\/div><\/div>\n\n\n\n<figure class=\"wp-block-video\"><video height=\"154\" style=\"aspect-ratio: 320 \/ 154;\" width=\"320\" controls src=\"https:\/\/upmostly.com\/wp-content\/uploads\/Screen-Recording-2022-09-07-at-18.28.53.mov\"><\/video><\/figure>\n\n\n\n<p>And, as you can see from the last video sample, we have been able to get rid of the flickering effect.<\/p>\n\n\n\n<p>That&#8217;s because of the slight difference in behavior between the two hooks; while the first handles the computation and DOM rendering asynchronously, the latter does the computation first, and only then handles the rendering of the result of that computation to the screen.<\/p>\n\n\n\n<p>In our case, that means that the <strong>useEffect<\/strong> hook is trying to generate the random value and also render it to the screen at the same time. On the other hand, the <strong>useLayoutEffect<\/strong> hook is trying to finish the computation first, and only then present us with the generated number.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Summary<\/h2>\n\n\n\n<p>As you&#8217;ve noticed, the <strong>useLayoutEffect<\/strong> hook provided us with a clean solution to a frequent issue we might find ourselves fighting with oftentimes, and that would be getting entangled in React&#8217;s way of handling DOM painting and computations simultaneously.<\/p>\n\n\n\n<p>As a takeaway, you might want to use the useLayoutEffect hook whenever you are working with ref values or need to do any type of work revolving around querying for DOM elements through vanilla JavaScript methods such as <strong>querySelector<\/strong>, <strong>querySelectorAll<\/strong>, or any other way of doing that.<\/p>\n\n\n\n<p>Keep in mind, though, that despite the usefulness that the <strong>useLayoutEffect<\/strong> hook provides us with, in 99% of cases you would still be better off using the <strong>useEffect<\/strong> hook, as it is oftentimes much more performant due to its async nature.<\/p>\n\n\n\n<p>So, that was it.<\/p>\n\n\n\n<p>Hopefully, you&#8217;ve now got a better understanding of the usage of both hooks, as well as the scenarios where each might come in handy; that&#8217;s also especially common since it is rather underused either due to developers not knowing about it, or knowing about it, but being unsure about what it does exactly.<\/p>\n\n\n\n<p>In case you feel I&#8217;ve missed something, or you would like to debate any aspect further, or even leave any feedback for this article, feel free to leave a comment below.<\/p>\n\n\n\n<p>See you on the next one. Cheers!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction React has, not so long ago, come with a major update to its Functional Components (In v16.8, back in March of 2019), which has finally provided those components with a way to become stateful. The addition of Hooks not only meant that Functional Components would be able to provide their own state but also [&hellip;]<\/p>\n","protected":false},"author":126,"featured_media":10122,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[33,4,35],"class_list":["post-9975","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tutorials","tag-beginner-react-tutorials","tag-react","tag-react-hooks"],"acf":[],"_links":{"self":[{"href":"https:\/\/upmostly.com\/wp-json\/wp\/v2\/posts\/9975","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/upmostly.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/upmostly.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/upmostly.com\/wp-json\/wp\/v2\/users\/126"}],"replies":[{"embeddable":true,"href":"https:\/\/upmostly.com\/wp-json\/wp\/v2\/comments?post=9975"}],"version-history":[{"count":5,"href":"https:\/\/upmostly.com\/wp-json\/wp\/v2\/posts\/9975\/revisions"}],"predecessor-version":[{"id":10143,"href":"https:\/\/upmostly.com\/wp-json\/wp\/v2\/posts\/9975\/revisions\/10143"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/upmostly.com\/wp-json\/wp\/v2\/media\/10122"}],"wp:attachment":[{"href":"https:\/\/upmostly.com\/wp-json\/wp\/v2\/media?parent=9975"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/upmostly.com\/wp-json\/wp\/v2\/categories?post=9975"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/upmostly.com\/wp-json\/wp\/v2\/tags?post=9975"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}