<?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: Andrew Kao</title>
    <description>The latest articles on DEV Community by Andrew Kao (@andykao1213).</description>
    <link>https://dev.to/andykao1213</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%2F283156%2F1848fa0a-b293-4c41-a8f5-7d8fe2ca90ff.jpeg</url>
      <title>DEV Community: Andrew Kao</title>
      <link>https://dev.to/andykao1213</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/andykao1213"/>
    <language>en</language>
    <item>
      <title>How to cleanup local branches which tracking branch has been removed</title>
      <dc:creator>Andrew Kao</dc:creator>
      <pubDate>Mon, 28 Jun 2021 08:03:49 +0000</pubDate>
      <link>https://dev.to/andykao1213/how-to-cleanup-untracked-local-branches-4l31</link>
      <guid>https://dev.to/andykao1213/how-to-cleanup-untracked-local-branches-4l31</guid>
      <description>&lt;p&gt;We can use &lt;code&gt;git fetch --prune&lt;/code&gt; to remove the remote-tracking branches that no longer exist on the remote. However, the local branches that track on them still exist. This post aims to tell you how to remove them using the git alias &lt;code&gt;git cleanup&lt;/code&gt; and explain how it works.&lt;/p&gt;

&lt;h2&gt;
  
  
  TLDR
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Step 1&lt;/strong&gt;: Create a file &lt;code&gt;git-cleanup&lt;/code&gt; under your PATH&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2&lt;/strong&gt;: Paste the following scripts in &lt;code&gt;git-cleanup&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
git fetch &lt;span class="nt"&gt;--prune&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; git branch &lt;span class="nt"&gt;-r&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $1}'&lt;/span&gt; | egrep &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /dev/fd/0 &amp;lt;&lt;span class="o"&gt;(&lt;/span&gt;git branch &lt;span class="nt"&gt;-vv&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;origin&lt;span class="o"&gt;)&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $1}'&lt;/span&gt; | xargs git branch &lt;span class="nt"&gt;-D&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note: The first line(&lt;a href="https://en.wikipedia.org/wiki/Shebang_(Unix)"&gt;shebang&lt;/a&gt;) should be either &lt;code&gt;#!/bin/bash&lt;/code&gt; or &lt;code&gt;#!/bin/zsh&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Step 3&lt;/strong&gt;: Make it executable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x ./git-cleanup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 4&lt;/strong&gt;: Add git alias:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git config alias.cleanup &lt;span class="s2"&gt;"!git-cleanup"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, you can call &lt;code&gt;git cleanup&lt;/code&gt; directly in your command line!&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;Let's look at the shell script &lt;code&gt;git-cleanup&lt;/code&gt;. Assume that we have the following branches in the local:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;main -&amp;gt; origin/main
branch1 -&amp;gt; origin/branch1
branch3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note: &lt;code&gt;-&amp;gt;&lt;/code&gt; means track on&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And the branches in the remote&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;origin/main
origin/branch2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;branch1&lt;/code&gt; is merged and has been removed in the remote. And the &lt;code&gt;branch3&lt;/code&gt; is still under development and hasn't been pushed to remote yet.&lt;/p&gt;

&lt;p&gt;According to the assumptions, let's look at how the script works!&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;git fetch --prune&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This command removes the remote-tracking branch in your local. &lt;br&gt;
See the &lt;a href="https://git-scm.com/docs/git-fetch"&gt;git documentation&lt;/a&gt; for more information.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;code&gt;git branch -r&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Show all the remote branches. &lt;a href="https://git-scm.com/docs/git-branch"&gt;Documentation&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;code&gt;awk '{print $1}'&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;awk&lt;/code&gt; is a program that helps you parse your stdin. In this case the stdin is the result of &lt;code&gt;git branch -r&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;origin/HEAD -&amp;gt; origin/main
origin/main
origin/branch2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are interested in the first field of each line. So we use the action 'print $1' to list out all the remote branches. The result will be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;origin/HEAD
origin/main
origin/branch2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;egrep -v -f /dev/fd/0 &amp;lt;(git branch -vv | grep origin)&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This is the most important part of this script. Let's look at &lt;code&gt;git branch -vv | grep origin&lt;/code&gt; first.&lt;br&gt;
&lt;code&gt;git branch -vv&lt;/code&gt; shows the local branches with their tracking branches in the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;main       &amp;lt;SHA&amp;gt; [origin/main] last commit message
branch1    &amp;lt;SHA&amp;gt; [origin/branch1] last commit message
branch3    &amp;lt;SHA&amp;gt; last commit message
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thus, we use &lt;code&gt;grep&lt;/code&gt; to filter the lines with &lt;code&gt;origin&lt;/code&gt;, which means it has a remote-tracking branch. So the output of &lt;code&gt;git branch -vv | grep origin&lt;/code&gt; will be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;main    &amp;lt;SHA&amp;gt; [origin/main] last commit message
branch1 &amp;lt;SHA&amp;gt; [origin/branch1] last commit message
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, we are going to compare the result of &lt;code&gt;git branch -r&lt;/code&gt; and &lt;code&gt;git branch -vv | grep origin&lt;/code&gt; to find the local branches which remote-tracking branch has been removed. We are using &lt;code&gt;egrep&lt;/code&gt; with &lt;code&gt;-v&lt;/code&gt; options to select the lines which is not in the &lt;code&gt;git branch -r&lt;/code&gt;. We use &lt;code&gt;-f&lt;/code&gt; option because &lt;code&gt;&amp;lt;()&lt;/code&gt;, which we call &lt;a href="https://en.wikipedia.org/wiki/Process_substitution"&gt;Process Substitution&lt;/a&gt;, will be treat as a file. &lt;code&gt;/dev/fd/0&lt;/code&gt; means stdin, which is &lt;code&gt;git branch -r&lt;/code&gt; in our case.&lt;br&gt;
Thus until here, the result should be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;branch1 &amp;lt;SHA&amp;gt; [origin/branch1] last commit message
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;awk '{print $1}'&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Again, we are using &lt;code&gt;awk&lt;/code&gt; to parse the stdin. The result should be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;branch1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;xargs git branch -D&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Finally, we are going to delete the branches in the previous result one-by-one using xargs. You can think of &lt;code&gt;xargs&lt;/code&gt; works like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;stdin&lt;/span&gt;
 &lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;branch&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;D&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here I use &lt;code&gt;-D&lt;/code&gt; to force delete even though the branch isn't fully merged. If you don't want to delete the branches that aren't fully merged, please use &lt;code&gt;-d&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;#!/bin/bash&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;It is very important to add this line at the first of the script. This is called &lt;a href="https://en.wikipedia.org/wiki/Shebang_(Unix)"&gt;shebang&lt;/a&gt; and it is use to specify which shell are we going to execute this script.  We are leveraging Process Substitution, which isn't supported in &lt;code&gt;sh&lt;/code&gt;. So if not specifying this, the script may be triggered by &lt;code&gt;sh&lt;/code&gt; and throws error because &lt;code&gt;sh&lt;/code&gt; doesn't recognize &lt;code&gt;&amp;lt;()&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reference
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/questions/13064613/how-to-prune-local-tracking-branches-that-do-not-exist-on-remote-anymore"&gt;stack overflow - How to prune local tracking branches that do not exist on remote anymore&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>git</category>
      <category>bash</category>
    </item>
    <item>
      <title>How to understand the request deduplication in SWR</title>
      <dc:creator>Andrew Kao</dc:creator>
      <pubDate>Sat, 17 Apr 2021 07:52:53 +0000</pubDate>
      <link>https://dev.to/andykao1213/how-to-understand-the-request-deduplication-in-swr-28bb</link>
      <guid>https://dev.to/andykao1213/how-to-understand-the-request-deduplication-in-swr-28bb</guid>
      <description>&lt;p&gt;&lt;a href="https://swr.vercel.app/"&gt;SWR&lt;/a&gt; is an amazing react library that makes fetching data easier and more performant. What I really like about the library is the cache and &lt;a href="https://swr.vercel.app/advanced/performance#deduplication"&gt;deduplication&lt;/a&gt;. However, if we don't understand the mechanism correctly, it will lead you to a disaster. This post aims to take a look at some tricky cases of SWR caching and explain the reason.&lt;/p&gt;

&lt;h2&gt;
  
  
  The options &lt;code&gt;onSuccess&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Although we can configure &lt;a href="https://swr.vercel.app/docs/options#options"&gt;the options&lt;/a&gt; &lt;code&gt;onSuccess&lt;/code&gt; with the same key in multiple hooks, only the one in the first mounted hook will be fired.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Child&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;index&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="cm"&gt;/* ... */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useSWR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/user&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="na"&gt;onSuccess&lt;/span&gt;&lt;span class="p"&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`success &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)});&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="c1"&gt;// ....&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;App&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="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Child&lt;/span&gt; &lt;span class="na"&gt;index&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Child&lt;/span&gt; &lt;span class="na"&gt;index&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Child&lt;/span&gt; &lt;span class="na"&gt;index&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Child&lt;/span&gt; &lt;span class="na"&gt;index&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the console:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;success 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are four hooks with the key &lt;code&gt;/api/user&lt;/code&gt;, but due to the request deduplication in SWR, only the first hook will trigger the request. That's why only the &lt;code&gt;onSuccess&lt;/code&gt; in the first hooks is triggered.&lt;/p&gt;

&lt;p&gt;So now we know that only the first hook of the same key will trigger the request, let's look at the following example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Child&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;useSWR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/user&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="na"&gt;onSuccess&lt;/span&gt;&lt;span class="p"&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Child success&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)});&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="c1"&gt;// ....&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Parent&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;useSWR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/user&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="na"&gt;onSuccess&lt;/span&gt;&lt;span class="p"&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Parent success&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)});&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Child&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What will be the result in the console?&lt;/p&gt;

&lt;p&gt;If your answer is "Child success", well done! The reason is simple. Because the hook inside the &lt;code&gt;Child&lt;/code&gt; component will be mounted first, so the request will be triggered by it but not the one in &lt;code&gt;Parent&lt;/code&gt;. So only the &lt;code&gt;onSuccess&lt;/code&gt; in &lt;code&gt;Child&lt;/code&gt; will be triggered.&lt;/p&gt;

&lt;h2&gt;
  
  
  The options &lt;code&gt;dedupingInterval&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Awesome! Now we have a clear understanding of how the request is being triggered and which &lt;code&gt;onSuccess&lt;/code&gt; will be fired. Let's look at the following example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Child&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;index&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;data&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useSWR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/user&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="na"&gt;onSuccess&lt;/span&gt;&lt;span class="p"&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Child success&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)});&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="c1"&gt;// ....&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Parent&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;showChild&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setShowChild&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="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;useSWR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;onSuccess&lt;/span&gt;&lt;span class="p"&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Parent success&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="nx"&gt;setTimeout&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;setShowChile&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="mi"&gt;3000&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;showChild&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Child&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What will be the result in the console?&lt;/p&gt;

&lt;p&gt;In this case, both "Parent success" and "Child success" will be shown. The reason is all about the option &lt;code&gt;dedupingInterval&lt;/code&gt;, which defaults to 2000ms. &lt;code&gt;dedupingInterval&lt;/code&gt; means during the interval,  all the &lt;code&gt;useSWR&lt;/code&gt; with the same key will not fire request. So for the first and the second examples, the hooks are mounted within 2 seconds and this won't trigger another request. But for the third example,  the second hooks are mounted after 3 seconds, which is greater than the &lt;code&gt;dedupingInterval&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Also,  we should notice that the &lt;code&gt;data&lt;/code&gt; return from the hook in the &lt;code&gt;Child&lt;/code&gt; will be the cached data at first instead of &lt;code&gt;undefined&lt;/code&gt;. Please refer to this &lt;a href="https://codesandbox.io/s/swr-depuping-lexoz?file=/src/Deduping.jsx"&gt;codesandbox&lt;/a&gt; to see the behavior.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Finally, we can understand the life cycle of SWR as follow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When the hook mounted, it will first check if there is data in the cache. If there is, set it to the &lt;code&gt;data&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Then check if there is any hook with the same key mounted before during the &lt;code&gt;depupingInterval&lt;/code&gt;. If not, trigger the request. After the request success, the &lt;code&gt;onSuccess&lt;/code&gt; callback in the same hook will be fired.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
      <category>swr</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Reading a File through Related Path Using Fetch API</title>
      <dc:creator>Andrew Kao</dc:creator>
      <pubDate>Sun, 01 Dec 2019 09:20:52 +0000</pubDate>
      <link>https://dev.to/andykao1213/how-to-read-a-local-file-with-the-browser-using-fetch-api-2cjn</link>
      <guid>https://dev.to/andykao1213/how-to-read-a-local-file-with-the-browser-using-fetch-api-2cjn</guid>
      <description>&lt;p&gt;In some cases, we may want to read files (.csv, .txt ….) while building a web app. There are several ways to do this. Today, I am going to share an easy way to read these files using Fetch API.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is Fetch?
&lt;/h1&gt;

&lt;p&gt;Before we start, let's figure out what Fetch API exactly is. According to &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch"&gt;MDN&lt;/a&gt;, Fetch is described as below:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Fetch API provides a JavaScript interface for accessing and manipulating parts of the HTTP pipeline, such as requests and responses. It also provides a global fetch() method that provides an easy, logical way to fetch resources asynchronously across the network.&lt;br&gt;
Fetch is an API to request data through networks using Http request, and we could also use this to request local files!&lt;br&gt;
Start Fetching Local Data!&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fetch('../static/test.txt', {mode: 'no-cors'})
  .then(response =&amp;gt; response.text())
  .then(data=&amp;gt; console.log(data))
  .catch(error =&amp;gt; console.error(error));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Quite easy doesn't it? Now we can get our file in type of &lt;code&gt;string&lt;/code&gt; since we use the method &lt;code&gt;text()&lt;/code&gt;. If we are reading a JSON file, we can use &lt;code&gt;json()&lt;/code&gt; . &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#Body"&gt;See more method we can handle with the response here&lt;/a&gt;.&lt;/p&gt;

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