<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: chetanism</title>
    <description>The latest articles on DEV Community by chetanism (@chetanism).</description>
    <link>https://dev.to/chetanism</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F503943%2F83a724a0-48f5-46f6-8cad-c2f86f8101b9.png</url>
      <title>DEV Community: chetanism</title>
      <link>https://dev.to/chetanism</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/chetanism"/>
    <language>en</language>
    <item>
      <title>useLayoutEffect and the SSR warning</title>
      <dc:creator>chetanism</dc:creator>
      <pubDate>Mon, 02 Nov 2020 06:34:47 +0000</pubDate>
      <link>https://dev.to/chetanism/uselayouteffect-and-the-ssr-warning-3ad9</link>
      <guid>https://dev.to/chetanism/uselayouteffect-and-the-ssr-warning-3ad9</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;Ever saw this dreaded warning in your application logs:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Warning: useLayoutEffect does nothing on the server, because its effect cannot be encoded into the server renderer's output format. This will lead to a mismatch between the initial, non-hydrated UI and the intended UI. To avoid this, useLayoutEffect should only be used in components that render exclusively on the client&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I recently saw this while using the &lt;a href="https://github.com/Setsun/react-transition-components"&gt;react-transition-components&lt;/a&gt; library in my &lt;a href="https://nextjs.org/"&gt;Next.js&lt;/a&gt; application. Let's take a brief moment to understand what's the difference between &lt;code&gt;useEffect&lt;/code&gt; and &lt;code&gt;useLayoutEffect&lt;/code&gt; and what this warning means, then we can jump to a couple of simple tricks to avoid this warning.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Tip: Always treat warnings as errors, they are there for a reason! 
Get rid of them as soon as you see them.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  useEffect and useLayoutEffect
&lt;/h1&gt;

&lt;p&gt;React developers have gone to a great length to explain &lt;a href="https://reactjs.org/docs/hooks-effect.html"&gt;Using the Effect Hook&lt;/a&gt;, so we'll just try to focus here on the core difference between the two APIs and what the warning means in this context.&lt;/p&gt;

&lt;p&gt;The key phrase here from the &lt;a href="https://reactjs.org/docs/hooks-reference.html#useeffect"&gt;useEffect&lt;/a&gt; documentation is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The function passed to the useEffect will run after the render is committed to the screen.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Not much to explain here!&lt;/p&gt;

&lt;p&gt;The equivalent section for &lt;a href="https://dev.toaa"&gt;useLayoutEffect&lt;/a&gt; says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;it fires synchronously after all DOM mutations. Use this to read layout from the DOM and synchronously re-render. Updates scheduled inside useLayoutEffect will be flushed synchronously, before the browser has a chance to paint.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This means that the function passed to the &lt;code&gt;useLayoutEffect&lt;/code&gt; will be executed after changes have been updated to the DOM, but before those changes get painted on the browser screen. Thus you have a chance to read any DOM element's attributes such as position and size and cause a re-render again before browser gets a chance to update the screen. This ensures that your users don't see a glitch of things changing position/size determined by your layout-effect function.&lt;/p&gt;

&lt;h1&gt;
  
  
  The warning
&lt;/h1&gt;

&lt;p&gt;Both &lt;code&gt;useEffect&lt;/code&gt; and &lt;code&gt;useLayoutEffect&lt;/code&gt; do nothing on SSR, still the warning is only for &lt;code&gt;useLayoutEffect&lt;/code&gt;. The reason being that &lt;code&gt;useEffect&lt;/code&gt; doesn't concerns the render cycle of the component and won't affect the first render. However, the &lt;code&gt;useLayoutEffect&lt;/code&gt; concerns specifically with rendering and is intended to do stuff that would affect the first render (i.e. what user sees on the screen). Thus the warning that using &lt;code&gt;useLayoutEffect&lt;/code&gt; on SSR will cause a mismatch between the intended UI and what you get from the server. Or, in simple terms, your users will see the glitch that you wanted to avoid by using &lt;code&gt;useLayoutEffect&lt;/code&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Solutions
&lt;/h1&gt;

&lt;p&gt;The solution for this warning is simple - do what the warning says, don't use &lt;code&gt;useLayoutEffect&lt;/code&gt; on SSR! &lt;br&gt;
Following are couple of approaches that I found useful:&lt;/p&gt;
&lt;h2&gt;
  
  
  1. use useIsomorphicLayoutEffect
&lt;/h2&gt;

&lt;p&gt;You can simply use &lt;code&gt;useEffect&lt;/code&gt; or &lt;code&gt;useLayoutEffect&lt;/code&gt; depending whether the component is rendering on browser or server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useIsomorphicLayoutEffect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;undefined&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;useLayoutEffect&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// Then simply use useIsomorphicLayoutEffect in place of useLayoutEffect&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Read &lt;a href="https://medium.com/@alexandereardon/uselayouteffect-and-ssr-192986cdcf7a"&gt;Alex's Post&lt;/a&gt; for more on this approach.&lt;/p&gt;

&lt;p&gt;I find this approach useful when I am the author of the component that needs to use &lt;code&gt;useLayoutEffect&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. use useIsClient
&lt;/h2&gt;

&lt;p&gt;This approach is better suited when I am using a component that uses &lt;code&gt;useLayoutEffect&lt;/code&gt; but doesn't applies the first approach.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;useIsClient&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;isClient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setIsClient&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// The following effect will be ignored on server, &lt;/span&gt;
  &lt;span class="c1"&gt;// but run on the browser to set the flag true&lt;/span&gt;
  &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;setIsClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;isClient&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Then in my parent component:&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;ParentComponent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useIsClient&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="c1"&gt;// render the component only on client&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;isClient&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ComponentThatUsesUseLayoutEffect&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. use renderOnlyOnClient HOC
&lt;/h2&gt;

&lt;p&gt;The second approach doesn't work with class components and adds an ugly condition check in the jsx. So, my preferred approach is to use an HOC which works well with both the class and functional components:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;renderOnlyOnClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;TheComponent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;ClientOnlyComponent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useIsClient&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Yes, the hook is still useful!&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;isClient&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TheComponent&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/TheComponent&amp;gt; : &amp;lt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Now we can just safe-wrap the component and use it freely&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SafeComponentThatUsesUseLayoutEffect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;renderOnlyOnClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ComponentThatUsesUseLayoutEffect&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Hope this helps!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
    </item>
  </channel>
</rss>
