<?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: Abel Varga</title>
    <description>The latest articles on DEV Community by Abel Varga (@rangeoshun).</description>
    <link>https://dev.to/rangeoshun</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%2F45659%2F33ec5bc3-42de-47db-8734-0f53b42edeae.jpg</url>
      <title>DEV Community: Abel Varga</title>
      <link>https://dev.to/rangeoshun</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rangeoshun"/>
    <language>en</language>
    <item>
      <title>Cluster Specific Template Overrides in ArgoCD ApplicationSets Using Cluster Generators</title>
      <dc:creator>Abel Varga</dc:creator>
      <pubDate>Wed, 10 Aug 2022 08:36:00 +0000</pubDate>
      <link>https://dev.to/rangeoshun/cluster-specific-template-overrides-in-argocd-applicationsets-using-cluster-generators-4e1</link>
      <guid>https://dev.to/rangeoshun/cluster-specific-template-overrides-in-argocd-applicationsets-using-cluster-generators-4e1</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Creating &lt;code&gt;ApplicationSets&lt;/code&gt; is a great tool dry up application templates in ArgoCD. You can generate similar applications where the only difference is the namespace for &lt;code&gt;staging&lt;/code&gt; and &lt;code&gt;production&lt;/code&gt;, or the labeling for tracks like &lt;code&gt;canary&lt;/code&gt; and &lt;code&gt;stable&lt;/code&gt;. So consider this use-case:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;argoproj.io/v1alpha1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ApplicationSet&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;example-application&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;argocd&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;syncPolicy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;preserveResourcesOnDeletion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;
  &lt;span class="na"&gt;generators&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;clusters&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;#...&lt;/span&gt;
        &lt;span class="na"&gt;values&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;staging&lt;/span&gt;
          &lt;span class="na"&gt;track&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;stable&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;clusters&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;#...&lt;/span&gt;
        &lt;span class="na"&gt;values&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;production&lt;/span&gt;
          &lt;span class="na"&gt;track&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;stable&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;clusters&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;#...&lt;/span&gt;
        &lt;span class="na"&gt;values&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;production&lt;/span&gt;
          &lt;span class="na"&gt;track&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;canary&lt;/span&gt;
&lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;#...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These values are easy to set as they are mere strings. You can use simple interpolation to use these. In our case, we use several different values files based on these values in the template specs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;valueFiles&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;values.yaml&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;values.{{values.env}}.yaml'&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;values.{{values.track}}.yaml'&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;secrets.{{values.env}}.yaml'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;This is all fine and dandy until you need something more complex. Imagine the case where you would like to set only one of these clusters to do automatic syncing. In our case, whenever we change the version in the helm chart, we'd like staging to be synced right away. We can set the &lt;code&gt;syncPolicy&lt;/code&gt;, but its interface is an object, and you cannot interpolate that in a cluster specific way. To enable this we need to use the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;syncPolicy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;automated&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where do you set these overrides if you want it to be merged only for staging for example?&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution
&lt;/h2&gt;

&lt;p&gt;You can set template overrides in the &lt;code&gt;cluster&lt;/code&gt; object. This will be merged with the template defined in this chart.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;clusters&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;#...&lt;/span&gt;
    &lt;span class="na"&gt;values&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;staging&lt;/span&gt;
      &lt;span class="na"&gt;track&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;stable&lt;/span&gt;
    &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;syncPolicy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;automated&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But one does not simply set template override, for some reason there are mandatory keys to be set, even if they are just placeholders. This means there is a minimal shape that you need to set to set anything for the cluster in hand. That looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;  template:
&lt;span class="gi"&gt;+   metadata: {}
&lt;/span&gt;    spec:
&lt;span class="gi"&gt;+     project: app
+     destination: {}
+     source:
+       repoURL: http://github.com/example/helm-charts
&lt;/span&gt;      syncPolicy:
        automated: {}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So the staging cluster should look like this to be valid:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;clusters&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;#...&lt;/span&gt;
    &lt;span class="na"&gt;values&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;staging&lt;/span&gt;
      &lt;span class="na"&gt;track&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;stable&lt;/span&gt;
    &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{}&lt;/span&gt;
      &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;project&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;web&lt;/span&gt;
        &lt;span class="na"&gt;destination&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{}&lt;/span&gt;
        &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;repoURL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http://github.com/example/helm-charts&lt;/span&gt;
        &lt;span class="na"&gt;syncPolicy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;automated&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So there you go, if you're using cluster generators and would like a cluster specific override of the sync policy, now you know how to do that. &lt;/p&gt;

</description>
      <category>ops</category>
      <category>argocd</category>
      <category>kubernetes</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Why testing-library fails to do what it set out to do</title>
      <dc:creator>Abel Varga</dc:creator>
      <pubDate>Wed, 08 Apr 2020 09:31:08 +0000</pubDate>
      <link>https://dev.to/rangeoshun/why-testing-library-fails-to-do-what-it-set-out-to-do-4mcf</link>
      <guid>https://dev.to/rangeoshun/why-testing-library-fails-to-do-what-it-set-out-to-do-4mcf</guid>
      <description>&lt;p&gt;The problem that &lt;code&gt;testing-library&lt;/code&gt; aims to solve is that when we write tests for our components, we rely upon the implementation details of said component, which in turn make our tests fragile, and not refactor proof. This goal is an admirable one and something which could help every developer to ship reliable and maintainable code.&lt;/p&gt;

&lt;p&gt;The problem with this is not a conceptual one, but an execution one.&lt;/p&gt;

&lt;p&gt;I was testing a custom input component because I found a bug. In a specific situation, the user could not type in it. Yes, it was a bug I introduced but thought before fixing it, I'll write tests to cover this. TDD, right? It turns out you cannot cover this scenario with &lt;code&gt;react-testing-library&lt;/code&gt; and &lt;code&gt;jest&lt;/code&gt;, because how it only partially implements a DOM.&lt;/p&gt;

&lt;p&gt;What I needed was to test if, in the given situation, the user focuses the input and starts typing, the value of the input changes accordingly. The test has failed as it should have. So I began fixing the issue. It was quick and easy and could confirm the fix in my browser. When I went back to check up on my tests, they still failed.&lt;/p&gt;

&lt;p&gt;My test consisted of using &lt;code&gt;keyDown&lt;/code&gt; events to emulate typing. Because this is the user does, right? Well, it turns out that according to &lt;code&gt;testing-library&lt;/code&gt;, the user is not pressing buttons, but fires &lt;code&gt;change&lt;/code&gt; events! AS we all do when we do a Google search. We hit it up, and fire &lt;code&gt;change&lt;/code&gt; event left and right and boom, here comes the search result.&lt;/p&gt;

&lt;p&gt;My issue with this concept is that there are cases when firing a change event works, but pressing keys does not. And I could not find a solution for this since.&lt;/p&gt;

&lt;p&gt;This issue is similar to not being able to query &lt;code&gt;innerText&lt;/code&gt; because you'd need a layout engine for that. As if the user would be using your components without one. But worry not, there is &lt;code&gt;data-test-id&lt;/code&gt;. Which is a way of saying, do not test implementation details, but implement details to test the thing.&lt;/p&gt;

&lt;p&gt;I think while the concept is excellent, the tools are not in place to deliver yet. You still need &lt;code&gt;puppeteer&lt;/code&gt;, &lt;code&gt;playwright&lt;/code&gt; or &lt;code&gt;selenium&lt;/code&gt; to get into the shoes of your end-user. If you know of any ways to run my existing &lt;code&gt;testing-library&lt;/code&gt; specs in a browser a way that allows for querying elements by input text, like an &lt;code&gt;xPath&lt;/code&gt; selector or something, and has a complete chain of events, please let me know.&lt;/p&gt;

&lt;p&gt;Thank you, rant over&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Optimize useEffect by using a condition as a dependency</title>
      <dc:creator>Abel Varga</dc:creator>
      <pubDate>Fri, 03 Apr 2020 11:14:10 +0000</pubDate>
      <link>https://dev.to/rangeoshun/optimize-useeffect-by-using-the-condition-itself-as-a-dependency-1c2j</link>
      <guid>https://dev.to/rangeoshun/optimize-useeffect-by-using-the-condition-itself-as-a-dependency-1c2j</guid>
      <description>&lt;p&gt;The &lt;code&gt;useEffect&lt;/code&gt; hook is a great way to wrap side effects since the release of React 16.8. To quickly recap, this hook allows you to create functional components with behaviour akin to React classes' &lt;code&gt;componentDidMount&lt;/code&gt; and &lt;code&gt;componentDidUpdate&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;But because of the way functional components work, this would mean performing a side effect on each render. This behaviour is suboptimal; hence dependency array was introduced. This array passed as the second argument of a &lt;code&gt;useEffect&lt;/code&gt; call allows React to perform only when a reference passed in the dependency array changes.&lt;/p&gt;

&lt;p&gt;While this is great in many cases when you need to perform a specific task when one of the dependencies changes, there are times when the reference update in itself does not mean the task in hand is needed. These are the cases when you add a condition to the function passed as the first argument. For example, when you want to update the state when a query is running. You want to run the effect when the query is running, but you do not need to run it when the state is already set to the correct value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;loading&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&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;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="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;initial&lt;/span&gt;&lt;span class="dl"&gt;'&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;loading&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;loading&lt;/span&gt;&lt;span class="dl"&gt;'&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;loading&lt;/span&gt;&lt;span class="dl"&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;You cannot conditionally call &lt;code&gt;useEffect&lt;/code&gt; or any other hook for that matter. In these cases, you add the condition in the function performing the side effect itself, while the variables checked in the condition go into the dependency array.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&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="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;loading&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;loading&lt;/span&gt;&lt;span class="dl"&gt;'&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;loading&lt;/span&gt;&lt;span class="dl"&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="nx"&gt;loading&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now to optimize even further, you need to think about what React is doing in the background. When you call &lt;code&gt;useEffect&lt;/code&gt;, React checks your dependencies one-by-one. It has to, to be sure that your side effect takes place when &lt;em&gt;any&lt;/em&gt; of the dependencies change. After this, your function runs and evaluates the condition it needs to. If it turns out that it needs to perform what it has to it's excellent, no time wasted. On the other hand, when it turns out, it does not have to perform anything, all React's work was in vain.&lt;/p&gt;

&lt;p&gt;In the latter scenario, you can consider passing the condition evaluated right away. This way React only needs to check the one value in your dependencies, a &lt;code&gt;boolean&lt;/code&gt;, and you already have the value ready for your function to decide whether it should perform or not.&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;shouldSetStateToLoading&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;loading&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;loading&lt;/span&gt;&lt;span class="dl"&gt;'&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="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;shouldSetStateToLoading&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;loading&lt;/span&gt;&lt;span class="dl"&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="nx"&gt;shouldSetStateToLoading&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The only caveat is that the condition itself needs to be cheaper then what React does. The odds are that it is.&lt;/p&gt;

&lt;p&gt;You can check out the fiddle benchmark below:&lt;br&gt;
&lt;a href="https://jsfiddle.net/rangeoshun/j5a7qpbL/"&gt;https://jsfiddle.net/rangeoshun/j5a7qpbL/&lt;/a&gt;&lt;/p&gt;

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