<?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: Peter Shershov</title>
    <description>The latest articles on DEV Community by Peter Shershov (@petershershov).</description>
    <link>https://dev.to/petershershov</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%2F902773%2F53b044b3-9f1d-4f34-b835-354df865b7af.png</url>
      <title>DEV Community: Peter Shershov</title>
      <link>https://dev.to/petershershov</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/petershershov"/>
    <language>en</language>
    <item>
      <title>React: Lessons from the Trenches - useEffect x Infinity</title>
      <dc:creator>Peter Shershov</dc:creator>
      <pubDate>Thu, 23 Mar 2023 13:21:46 +0000</pubDate>
      <link>https://dev.to/codux/react-lessons-from-the-trenches-useeffect-x-infinity-1e3d</link>
      <guid>https://dev.to/codux/react-lessons-from-the-trenches-useeffect-x-infinity-1e3d</guid>
      <description>&lt;p&gt;Hey! My name is Peter and I’m a software team-lead, working on &lt;a href="https://codux.com/?utm_source=peterArticle1&amp;amp;utm_medium=Top" rel="noopener noreferrer"&gt;Codux&lt;/a&gt; by Wix.com.&lt;/p&gt;

&lt;p&gt;I’ve been building user interfaces with React for more than 6 years and have made tons of mistakes during this time. From memoizing almost everything in my component to drilling props like I’m looking for oil — I fell into every trap. I’ll try to break down a couple of issues I’ve dealt with and hopefully, it’ll help you jump over pitfalls in the future. Some articles in this series will address bad practices and design concerns while others focus on specific bugs in special use cases.&lt;/p&gt;

&lt;p&gt;Let’s start with a prevalent one, updating a state within &lt;code&gt;useEffect&lt;/code&gt; can cause an infinite loop by re-rendering the component to infinity.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgb5unv6pd3hf6e5wu986.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgb5unv6pd3hf6e5wu986.gif" alt=" raw `Maximum update depth exceeded` endraw  warning"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What we see above is a warning (“Maximum update depth exceeded”) indicating that there’s an operation occurring too many times, one after the other.&lt;/p&gt;

&lt;p&gt;This can happen in several scenarios.&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;superheroes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setSuperheroes&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&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;updateSuperheroes&lt;/span&gt; &lt;span class="o"&gt;=&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newSuperhero&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;generateSuperhero&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
   &lt;span class="nf"&gt;setSuperheroes&lt;/span&gt;&lt;span class="p"&gt;([...&lt;/span&gt;&lt;span class="nx"&gt;superheroes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;newSuperhero&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nf"&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="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;updateSuperheroes&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="nx"&gt;updateSuperheroes&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Consider the example above.&lt;br&gt;
First of all, we know that every state update triggers a re-render, meaning that the code written inside the component function gets executed. We also know that &lt;code&gt;useEffect&lt;/code&gt; executes when one of two conditions is met after a render:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;A component is mounted&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;One of the dependencies (declared in &lt;code&gt;useEffect&lt;/code&gt;’s dependency array) has changed.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;Keep in mind that &lt;code&gt;useEffect&lt;/code&gt;’s dependency array should reflect the usage. Omitting a dependency that is used inside the &lt;code&gt;useEffect&lt;/code&gt; can cause stale data issues, while including a dependency that does not impact the effect can cause unnecessary re-renders.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;With these in mind, we can start debugging the code above.&lt;br&gt;
We can see that &lt;code&gt;updateSuperheroes()&lt;/code&gt; is executed inside a &lt;code&gt;useEffect&lt;/code&gt;, which requires us to declare it as a dependency.&lt;br&gt;
&lt;code&gt;updateSuperheroes&lt;/code&gt; adds superheroes to the state by creating a copy of the &lt;code&gt;superheroes&lt;/code&gt; array and adding new entries to it.&lt;/p&gt;

&lt;p&gt;When the &lt;code&gt;superheroes&lt;/code&gt; state gets updated, the component re-renders with the new state, the &lt;code&gt;updateSuperheroes&lt;/code&gt; function is created anew which causes &lt;code&gt;useEffect&lt;/code&gt; to trigger, restarting this cycle.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to do?
&lt;/h2&gt;

&lt;p&gt;To prevent something from being created multiple times over multiple renders we often take advantage of memoization. React offers several tools to memoize our functions and values. &lt;code&gt;useCallback&lt;/code&gt; is used for functions and &lt;code&gt;useMemo&lt;/code&gt; is used for values such as objects or arrays.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Primitives that require a minimal computation don't need to be memoized since they are easily comparable, on the other hand, objects, functions, arrays and other complex data structures, could be created anew with every render if declared inside the component.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In our case, &lt;code&gt;updateSuperheroes&lt;/code&gt; is a function, and should be memoized, therefore, we should leverage &lt;code&gt;useCallback&lt;/code&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;superheroes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setSuperheroes&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&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;updateSuperheroes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useCallback&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newSuperhero&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;generateSuperhero&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
   &lt;span class="nf"&gt;setSuperheroes&lt;/span&gt;&lt;span class="p"&gt;([...&lt;/span&gt;&lt;span class="nx"&gt;superheroes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;newSuperhero&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="nx"&gt;superheroes&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="nf"&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="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;updateSuperheroes&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="nx"&gt;updateSuperheroes&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;But this is not enough. We can see that &lt;code&gt;useCallback&lt;/code&gt; has a dependency on &lt;code&gt;superheroes&lt;/code&gt; that gets changed on every run of &lt;code&gt;useEffect&lt;/code&gt;, making this memoization redundant. For such cases, React provides us with another way to update the state without being dependent on the value.&lt;/p&gt;

&lt;p&gt;Every state setter can get two types of the first argument.&lt;/p&gt;

&lt;p&gt;One, a new state:&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;([])&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;([...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;something new&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Or two, a function that gets the previous state as an argument and returns a new state.&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;([])&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;previousState&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;previousState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;something new&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Using the latter way in our example will fix the infinite loop since there is no dependency on the state anymore. It will trigger only when the component mounts.&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;superheroes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setSuperheroes&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&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;updateSuperheroes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useCallback&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newSuperhero&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;generateSuperhero&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
   &lt;span class="nf"&gt;setSuperheroes&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;previousSuperheroes&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="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;previousSuperheroes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;newSuperhero&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="nf"&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="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;updateSuperheroes&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="nx"&gt;updateSuperheroes&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In some cases, you can extract values to an outer scope (outside of the component) when a value is not dependent on any specific component code.&lt;/p&gt;

&lt;p&gt;For example, instead of:&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;emptyObject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useMemo&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="p"&gt;[]);&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Move &lt;code&gt;emptyObject&lt;/code&gt; outside of the component code:&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;emptyObject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Superheroes&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This will prevent the creation of a new object instance for every render without the need to memoize it over time.&lt;/p&gt;

&lt;h2&gt;
  
  
  What can be so complex?
&lt;/h2&gt;

&lt;p&gt;Now that we know how to handle the simple case of a state update within a &lt;code&gt;useEffect&lt;/code&gt;, let’s delve into the more complex scenarios.&lt;/p&gt;

&lt;p&gt;In the example above we could very easily tell which dependency in our &lt;code&gt;useEffect&lt;/code&gt; is causing the infinite loop. Debugging more complex cases where &lt;code&gt;useEffect&lt;/code&gt; has a large number of dependencies (and each one of them might have its own set of dependencies) is a bit harder. Finding the culprit and maintaining this code in general requires more effort.&lt;/p&gt;

&lt;p&gt;I’ve seen colossal dependency arrays across many projects, and here are a couple of recommendations for how to deal with them.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Separate your gigantic &lt;code&gt;useEffect&lt;/code&gt; into a few smaller ones
&lt;/h3&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="nf"&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="p"&gt;{&lt;/span&gt;
   &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
   &lt;span class="nx"&gt;peopleProvider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="nx"&gt;engineersProvider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="nx"&gt;doctorsProvider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="nx"&gt;generateUniqueId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="nx"&gt;initializeApp&lt;/span&gt;
&lt;span class="p"&gt;]);&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Converting this example, where a &lt;code&gt;useEffect&lt;/code&gt; gets a large number of possibly non-related dependencies, into this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="nf"&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="p"&gt;{&lt;/span&gt;
   &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;peopleProvider&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="nf"&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="p"&gt;{&lt;/span&gt;
   &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;engineersProvider&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="nf"&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="p"&gt;{&lt;/span&gt;
   &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;doctorsProvider&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="nf"&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="p"&gt;{&lt;/span&gt;
   &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;generateUniqueId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;initializeApp&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This way we can scope our side effects into separate, smaller &lt;code&gt;useEffect&lt;/code&gt; declarations to prevent triggering irrelevant handlers.&lt;br&gt;
In other words, updated dependencies will not trigger a side effect or a state update for a non-relevant functionality.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Debug the dependencies that are changing on every render
&lt;/h3&gt;

&lt;p&gt;If you still couldn’t find the main cause of an infinite render and you still don’t know which state gets updated and what handler is causing it, I recommend implementing or using a helper hook (&lt;a href="https://github.com/damiangreen/use-trace-update" rel="noopener noreferrer"&gt;such as this&lt;/a&gt;) that logs the changed dependencies for each render.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="nf"&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="p"&gt;{&lt;/span&gt;
   &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
   &lt;span class="nx"&gt;peopleProvider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="nx"&gt;engineersProvider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="nx"&gt;doctorsProvider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="nx"&gt;generateUniqueId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="nx"&gt;initializeApp&lt;/span&gt;
&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="nf"&gt;useTraceUpdate&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
   &lt;span class="nx"&gt;peopleProvider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="nx"&gt;engineersProvider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="nx"&gt;doctorsProvider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="nx"&gt;generateUniqueId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="nx"&gt;initializeApp&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This will log only the changed values, indicating which dependency is changing every render leading to an infinite loop.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Fixing and avoiding &lt;code&gt;useEffect&lt;/code&gt;’s infinite renders can be achieved by applying the following measures:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep your dependency arrays short and concise. Scope the &lt;code&gt;useEffect&lt;/code&gt; you’re creating to a specific minimal context and avoid mixing dependencies that have different intents.&lt;/li&gt;
&lt;li&gt;Memoize complex values and functions passed to your hooks and components.&lt;/li&gt;
&lt;li&gt;Avoid depending on a state and setting it in the same &lt;code&gt;useEffect&lt;/code&gt;, this is a &lt;em&gt;very&lt;/em&gt; fragile situation that can break easily. If you must have such a case, you can take advantage of the option to set the state using a function provided to &lt;code&gt;setState&lt;/code&gt; and not be dependent on the previous value.&lt;/li&gt;
&lt;li&gt;Find the always-changing dependency (the one that is causing the infinite render) by debugging your dependencies. Try locating the value that is causing the infinite renders and memoize it correctly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I hope you've found this article helpful, and I look forward to see y'all at the next one!&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>frontend</category>
    </item>
    <item>
      <title>How I improved my React development experience by leveraging visual tools</title>
      <dc:creator>Peter Shershov</dc:creator>
      <pubDate>Wed, 03 Aug 2022 15:57:35 +0000</pubDate>
      <link>https://dev.to/petershershov/how-i-improved-my-react-development-experience-by-leveraging-visual-tools-256n</link>
      <guid>https://dev.to/petershershov/how-i-improved-my-react-development-experience-by-leveraging-visual-tools-256n</guid>
      <description>&lt;p&gt;When we’re developing a UI project, being able to run and debug our components fast is the key to a good dev experience. Commonly, we do this in an isolated development environment where we render and interact with our UI.&lt;/p&gt;

&lt;p&gt;Working in a tool that provides both rendering and editing capabilities, developers can reach even shorter cycles, and in turn, improve the development experience.&lt;/p&gt;

&lt;p&gt;Wix Component Studio (WCS) is an editor that lets developers visually develop React components in isolation through a UI. WCS understands your code structure and edits it as a developer would, letting you focus on the features and behavior of your business logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building the component
&lt;/h2&gt;

&lt;p&gt;In this post, I’ll walk you through the basics of building a React gift card component for a fictional fintech company called CloudCash. I’ll show you how I did it from scratch through a combination of visual editing in WCS, through the built-in code editor, and using my own IDE.&lt;/p&gt;

&lt;p&gt;Here’s what we’re going for:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F24lnsujynf7ix5jkf48v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F24lnsujynf7ix5jkf48v.png" alt="GiftCard component"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Creating the new component
&lt;/h2&gt;

&lt;p&gt;The first thing I did after opening Component Studio on my project was create a new component. I clicked on the New Component button and gave it the name “GiftCard”.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftx4vgd7u7mqccuksj0zi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftx4vgd7u7mqccuksj0zi.png" alt="New component creation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Behind the scenes, WCS created three files – gift-card.tsx in our source directory for the component, gift-card.board.tsx containing what WCS needs to render in isolation as a “board” onscreen, and gift-card.module.scss, the stylesheet for the component.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbo1p0af62r8a4yoeaqxw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbo1p0af62r8a4yoeaqxw.png" alt="Empty component"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Elements Panel on the left shows three nested elements – Window, Canvas, and our component, GiftCard. Let’s first resize the component so that it begins to look like an actual gift card by selecting the Canvas element, opening the Properties panel on the right side, and giving it a canvas size of 320px by 205px.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6i6ebpuelzmcdw207h6w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6i6ebpuelzmcdw207h6w.png" alt="Canvas resize"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I’ll edit the GiftCard component now by selecting it in the Elements panel and clicking Edit Component. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F54bmemp2a7cj93iech54.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F54bmemp2a7cj93iech54.png" alt="Scoping in"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This changes our editing context from the playground (board) to the actual gift card component, and any changes that I now make are made to the component’s code and affect all instances of it.&lt;/p&gt;
&lt;h2&gt;
  
  
  Styling the component’s root HTML element
&lt;/h2&gt;

&lt;p&gt;Now that I’ve moved into the scope of the component, I’ll be applying all the styles that belong to the root HTML element. First, I’ll match the height of the component to the canvas by setting it to 100%. This is done by selecting the root node of the component, ‘div.root’ in the Elements panel, and in the Styles panel, selecting the ‘.root’ selector and setting its height.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcehbiw5nuhbm1x11yng6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcehbiw5nuhbm1x11yng6.png" alt="Styling root"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, I’ll set the background color to ‘#282B2D’, the text color to white, and the border radius for the corners to 18px. Finally, I’ll set the display to flex, the alignment to center, the justification to center, and the direction to column. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fds4ay6huvzsrzyf2x1qf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fds4ay6huvzsrzyf2x1qf.png" alt="Color change"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Adding an element to the component
&lt;/h2&gt;

&lt;p&gt;Right now, I have the layout of the gift card, but my component has only a single element. I'm going to need to add an h2 element to it to give it a proper title. While I can do this in the code, WCS allows me to do it visually. I'll click the Add button in the Elements panel to open the Add Elements panel, where I can search for the h2 element and drag it over as the first child of the root element.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv49abr548qh6tij1nh2g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv49abr548qh6tij1nh2g.png" alt="Adding an element"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now I’ll set the text by selecting the Heading 2 text element and giving it the “CloudCash” value in the Properties panel.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flsdr97hnltr0yruky8ak.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flsdr97hnltr0yruky8ak.png" alt="Text change"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Adding a class to an element
&lt;/h2&gt;

&lt;p&gt;When I dragged the h2 element to the Elements panel, WCS added an h2 element to my code. It does not have any class applied to it yet. To style it, I’ll need to add a class to it, and then add a selector to target this class in the component stylesheet. I’ll do this part visually through the Styles panel.&lt;/p&gt;

&lt;p&gt;While still selected on the h2 element, I can give it the class name “title” by clicking “Create or apply a class”. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F40vqajs9af5lhsqftpuw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F40vqajs9af5lhsqftpuw.png" alt="Adding a class"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Creating the class through WCS saves effort by suggesting the component CSS file, adding the class selector to it, and applying the class to my component file in one action.&lt;/p&gt;

&lt;p&gt;I have a new class at this point, but it doesn’t have any styling yet. Let’s fix the margin and tweak our fonts to make our gift card look a bit better. While I can edit it visually using the Styles panel, in this case I’ll choose to add my CSS through the code editor to show how the code, the stage, and the Styles panel are always in sync. I’ll jump directly to the relevant point in the code by hovering over the selector that I created above and clicking Edit Code.&lt;/p&gt;

&lt;p&gt;This brings us to the ‘.title’ selector in the code, where I’ll add a couple of declarations to refine our component some more. I’ll copy and paste the following code snippet to my code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.title&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;-8px&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;12px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;200&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;font-style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;normal&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;36px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvv7cso9pulquxjfzpskm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvv7cso9pulquxjfzpskm.png" alt="Styling with the code drawer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding a new prop to the component
&lt;/h2&gt;

&lt;p&gt;To make our component truly reusable, I’ll need to have it accept a property to allow controlling the gift card amount from the outside.&lt;/p&gt;

&lt;p&gt;We’ve already seen how I can make changes to my component visually and through the code drawer, but WCS also syncs changes to the project code on my file system. This means that I can use my own IDE.&lt;/p&gt;

&lt;p&gt;Let's take a look at the component code created by WCS so far by opening the “gift-card.tsx” file in VS Code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzwvrn9pxsulefk5t3kb2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzwvrn9pxsulefk5t3kb2.png" alt="Adding a prop"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now let’s add a property called “amount” of the string type. I’ll then destructure it in our component props, give it a default value of “$100”, and lastly, replace the “GiftCard” text in our component with the {amount} expression.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjrlhuu84jaec1b3bqj52.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjrlhuu84jaec1b3bqj52.png" alt="IDE next to WCS"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To demonstrate how easily WCS allows you to create examples for your components, I’ll go back up our scope to our original starting board, and through there, give our component an alternative prop value of “$200”. As you might imagine, this capability is very useful for complex components with multiple properties.&lt;/p&gt;

&lt;p&gt;And with that, I’ve completed everything I set out to do, and the component is ready for use! I tried to keep this example simple to keep this post focused and concise, but I can create any design that CSS supports.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhuw8iv3l6g7syg7fuj6b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhuw8iv3l6g7syg7fuj6b.png" alt="Final result"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Check it out for yourself
&lt;/h2&gt;

&lt;p&gt;Interested in learning more about WCS? It’s currently in alpha stage, and we’re expanding user access as we iron out the kinks and refine the overall experience.&lt;br&gt;
Visit &lt;a href="https://www.wixcomponentstudio.com" rel="noopener noreferrer"&gt;wixcomponentstudio.com&lt;/a&gt; to sign up for early access and try out our demo. &lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>typescript</category>
      <category>css</category>
    </item>
  </channel>
</rss>
