-
Notifications
You must be signed in to change notification settings - Fork 0
/
blogData.json
1 lines (1 loc) · 75.8 KB
/
blogData.json
1
{"posts":[{"reward":{"type":"xlm"},"sourcedFromGithub":false,"isAnonymous":false,"views":6,"slugOverridden":false,"coverImage":"https://cdn.hashnode.com/res/hashnode/image/upload/v1632333332776/1UvPdEcZZ.png","autoGeneratedCover":"","brief":"As a web developer, having a decent understanding of HTTP request methods, headers and status codes increases your overall productivity as a developer in the long run by helping you debug 🐞, develop and understand code faster⚡.\nWhat better way to ga...","content":"<p>As a web developer, having a decent understanding of HTTP request methods, headers and status codes increases your overall productivity as a developer in the long run by helping you debug 🐞, develop and understand code faster⚡.</p>\n<p>What better way to gain a better understanding of HTTP requests than writing them raw right from your terminal 🖥️.</p>\n<p>In this blog, I'm going to help you write a raw basic HTTP GET request from your terminal using netcat in a beginner friendly way. </p>\n<p>Let's begin by understanding what an HTTP request is! </p>\n<p><img src=\"https://cdn.hashnode.com/res/hashnode/image/upload/v1632334692110/TH6LOmXQa.gif\" alt=\"start.gif\" /></p>\n<hr />\n\n<h1 id=\"what-is-an-http-request\">What is an HTTP request?</h1>\n<p>HTTP (Hyper Text Transfer Protocol) is the underlying format used to structure requests and responses for effective communication between a client and a server.</p>\n<p>The message that is sent by a client to a server is known as an HTTP request.</p>\n<p>We will be using <a target=\"_blank\" href=\"example.com\">example.com</a> for analyzing and making HTTP requests in this blog.</p>\n<p>If we go to example.com and switch to <strong>doc</strong> option in the <strong>networks</strong> tab in chrome devtools, we will see a HTTP GET request just like this one:</p>\n<pre><code><span class=\"hljs-attr\">Request URL:</span> <span class=\"hljs-string\">https://example.com/</span>\n<span class=\"hljs-attr\">Request Method:</span> <span class=\"hljs-string\">GET</span>\n<span class=\"hljs-attr\">Status Code:</span> <span class=\"hljs-number\">200</span> \n<span class=\"hljs-attr\">Remote Address:</span> [<span class=\"hljs-number\">2606</span><span class=\"hljs-string\">:2800:220:1:248:1893:25c8:1946</span>]<span class=\"hljs-string\">:443</span>\n<span class=\"hljs-attr\">Referrer Policy:</span> <span class=\"hljs-string\">strict-origin-when-cross-origin</span>\n</code></pre><p>You can read more about HTTP at MDN <a target=\"_blank\" href=\"https://developer.mozilla.org/en-US/docs/Web/HTTP/Overview\">here</a>.</p>\n<p>Now, let's discuss what Netcat is.</p>\n<h1 id=\"what-is-netcat\">What is Netcat?</h1>\n<p><img src=\"https://cdn.hashnode.com/res/hashnode/image/upload/v1632363907936/qUUcMUxSy.jpeg\" alt=\"loki.jpg\" /></p>\n<p>Netcat is a Unix utility which reads and writes data across network connections using TCP or UDP protocol. </p>\n<p>To what we'll need, Netcat allows us to setup client-server connections from our terminal. It actually can do much more than that, but that is another topic in itself.</p>\n<p>You can use Netcat in your terminal using the <strong>nc</strong> keyword in your commands.</p>\n<p>If it went above your head, don't worry, implementation next.</p>\n<h2 id=\"lets-get-to-it-shall-we\">Let's get to it, shall we?</h2>\n<p>In order to send off a request, first we need to setup a connection to the HTTP server.</p>\n<p>To do that, we run the following command:</p>\n<pre><code><span class=\"hljs-section\">myPC:~$ nc example.com 80 -vvv</span>\n</code></pre><p><strong>nc</strong>, as mentioned above, stands for netcat, next comes the domain and the server port number (80 is the default port number for HTTP connections).</p>\n<p>The <strong><em>-vvv</em></strong> command turns on the verbose mode which prints additional information about the connection.</p>\n<p><img src=\"https://cdn.hashnode.com/res/hashnode/image/upload/v1632376273959/a_YY978a0H.png\" alt=\"connection.png\" /></p>\n<p>Now that the connection is setup, we are all set to send off a GET HTTP Request to the server.</p>\n<p>The request format requires three must things:</p>\n<ul>\n<li>the request method (which is GET here)</li>\n<li>the version (HTTP/1.1), and</li>\n<li>the Host Domain (example.com)</li>\n</ul>\n<p>Here's how it'll look:</p>\n<p><img src=\"https://cdn.hashnode.com/res/hashnode/image/upload/v1632377842687/HI3za_XID.png\" alt=\"request.png\" /></p>\n<p>Inorder to send the request, you just need to leave a line (press enter twice)</p>\n<p><img src=\"https://cdn.hashnode.com/res/hashnode/image/upload/v1632378456754/HB8kSOzls.gif\" alt=\"enter.gif\" /></p>\n<p>You can now see the response sent from the server, it has all the things the browser would need to display <a target=\"_blank\" href=\"http://example.com\">example.com</a> 's webpage.</p>\n<p><img src=\"https://cdn.hashnode.com/res/hashnode/image/upload/v1632378756803/4RCJ3f2vB.png\" alt=\"response.png\" /></p>\n<p>There you go, you wrote your own raw HTTP GET Request, would recommend you to study more about status code, different headers and all that from MDN, or just google it.</p>\n<hr />\n\n<p>Thanks for reading it till now, do share if this helped you.</p>\n<p>If you are into react, would recommend reading my blog on <a target=\"_blank\" href=\"https://adityasaxena.hashnode.dev/how-to-create-a-custom-debounce-react-hook-using-useeffect\">Creating a custom debounce react hook</a>, it makes a great interview and also is widely used in daily use applications.</p>\n<p><img src=\"https://cdn.hashnode.com/res/hashnode/image/upload/v1632379011542/6gNyKI_SU.gif\" alt=\"thankyou.gif\" /></p>\n","contentMarkdown":"As a web developer, having a decent understanding of HTTP request methods, headers and status codes increases your overall productivity as a developer in the long run by helping you debug 🐞, develop and understand code faster⚡.\n\nWhat better way to gain a better understanding of HTTP requests than writing them raw right from your terminal 🖥️.\n\nIn this blog, I'm going to help you write a raw basic HTTP GET request from your terminal using netcat in a beginner friendly way. \n\nLet's begin by understanding what an HTTP request is! \n\n![start.gif](https://cdn.hashnode.com/res/hashnode/image/upload/v1632334692110/TH6LOmXQa.gif)\n\n<hr/>\n\n# What is an HTTP request?\n\nHTTP (Hyper Text Transfer Protocol) is the underlying format used to structure requests and responses for effective communication between a client and a server.\n\nThe message that is sent by a client to a server is known as an HTTP request.\n\nWe will be using [example.com](example.com) for analyzing and making HTTP requests in this blog.\n\nIf we go to example.com and switch to **doc** option in the **networks** tab in chrome devtools, we will see a HTTP GET request just like this one:\n\n\n```\nRequest URL: https://example.com/\nRequest Method: GET\nStatus Code: 200 \nRemote Address: [2606:2800:220:1:248:1893:25c8:1946]:443\nReferrer Policy: strict-origin-when-cross-origin\n``` \n\nYou can read more about HTTP at MDN [here](https://developer.mozilla.org/en-US/docs/Web/HTTP/Overview).\n\nNow, let's discuss what Netcat is.\n\n# What is Netcat?\n\n![loki.jpg](https://cdn.hashnode.com/res/hashnode/image/upload/v1632363907936/qUUcMUxSy.jpeg)\n\nNetcat is a Unix utility which reads and writes data across network connections using TCP or UDP protocol. \n\nTo what we'll need, Netcat allows us to setup client-server connections from our terminal. It actually can do much more than that, but that is another topic in itself.\n\nYou can use Netcat in your terminal using the **nc** keyword in your commands.\n\nIf it went above your head, don't worry, implementation next.\n\n## Let's get to it, shall we?\n\nIn order to send off a request, first we need to setup a connection to the HTTP server.\n\nTo do that, we run the following command:\n\n```\nmyPC:~$ nc example.com 80 -vvv\n``` \n\n**nc**, as mentioned above, stands for netcat, next comes the domain and the server port number (80 is the default port number for HTTP connections).\n\nThe ***-vvv*** command turns on the verbose mode which prints additional information about the connection.\n\n![connection.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1632376273959/a_YY978a0H.png)\n\nNow that the connection is setup, we are all set to send off a GET HTTP Request to the server.\n\nThe request format requires three must things:\n\n- the request method (which is GET here)\n- the version (HTTP/1.1), and\n- the Host Domain (example.com)\n\nHere's how it'll look:\n\n![request.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1632377842687/HI3za_XID.png)\n\nInorder to send the request, you just need to leave a line (press enter twice)\n\n![enter.gif](https://cdn.hashnode.com/res/hashnode/image/upload/v1632378456754/HB8kSOzls.gif)\n\nYou can now see the response sent from the server, it has all the things the browser would need to display [example.com](http://example.com) 's webpage.\n\n![response.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1632378756803/4RCJ3f2vB.png)\n\nThere you go, you wrote your own raw HTTP GET Request, would recommend you to study more about status code, different headers and all that from MDN, or just google it.\n\n<hr/>\n\nThanks for reading it till now, do share if this helped you.\n\nIf you are into react, would recommend reading my blog on [Creating a custom debounce react hook](https://adityasaxena.hashnode.dev/how-to-create-a-custom-debounce-react-hook-using-useeffect), it makes a great interview and also is widely used in daily use applications.\n\n![thankyou.gif](https://cdn.hashnode.com/res/hashnode/image/upload/v1632379011542/6gNyKI_SU.gif)\n","hasPolls":false,"totalPollVotes":0,"upvotes":0,"downvotes":0,"tags":["56744721958ef13879b94c04","56744722958ef13879b94f1b","56744723958ef13879b952af","56744722958ef13879b950bd"],"untaggedFrom":[],"upvotedBy":[],"downvotedBy":[],"popularity":4963.7387,"responses":[],"responseCount":0,"replyCount":0,"followers":[],"isActive":true,"isFeatured":false,"isEngaging":false,"answeredByTarget":false,"inviters":[],"isDelisted":false,"isNotified":false,"duplicatePosts":[],"numCollapsed":0,"hasReward":false,"bookmarkedIn":[],"similarPostIds":[],"reactions":[],"totalReactions":0,"reactionsByCurrentUser":[],"isPinnedToBlog":false,"disableComments":false,"hasLatex":true,"syncAlgolia":false,"numUniqueUsersWhoReacted":0,"_id":"614c2231544e242e0c93e356","title":"How to write raw HTTP requests using Netcat 🌐","subtitle":"A step towards better understanding of HTTP requests","type":"story","ogImage":"https://cdn.hashnode.com/res/hashnode/image/upload/v1632379365222/fHhMqz-f1S.png","metaTitle":"Writing raw HTTP requests using Netcat","metaDescription":"A sstep towards better understanding of HTTP by writing a raw HTTP GET Request from the terminal.","isRepublished":false,"originalArticleURL":"","partOfPublication":true,"publication":"613ec61122b7a41dfe5ff33d","slug":"how-to-write-raw-http-requests-using-netcat","importedFromMedium":false,"dateAdded":"2021-09-23T06:44:01.553Z","hasCustomDate":false,"stickCoverToBottom":true,"pollOptions":[],"badges":[],"questionReplies":[],"contributors":[],"cuid":"cktwkkmbg0aro3gs1hi83hymr","author":"60d8b19ecb0aa8118c23d01c","followersCount":1,"draft":"614b66d9544e242e0c93d6b6","hasPinnedTag":false,"readTime":3,"__v":0,"uniqueReactions":[],"reactionToCountMapUnique":{"any":1},"id":"614c2231544e242e0c93e356"},{"reward":{"type":"xlm"},"sourcedFromGithub":false,"isAnonymous":false,"views":0,"slugOverridden":false,"coverImage":"https://cdn.hashnode.com/res/hashnode/image/upload/v1631504916965/y33GsRGVG.png","autoGeneratedCover":"","brief":"Introduction\nWhen you type into google docs, does it save your changes at every keystroke? \nNo, it does not, it waits, holds on for some time after your last keystroke/change and then fires up the save functionality. That right there was debouncing.\n...","content":"<h1 id=\"introduction\">Introduction</h1>\n<p>When you type into google docs, does it save your changes at every keystroke? \nNo, it does not, it waits, holds on for some time after your last keystroke/change and then fires up the save functionality. That right there was debouncing.</p>\n<p>Debouncing is the process of bouncing off the execution of a function triggered from some event until the user is done firing that event for some time.\nThis is done to reduce unnecessary api calls to the server and prevents the UI to process a drastic number of events. More about it later on.</p>\n<p><img src=\"https://cdn.hashnode.com/res/hashnode/image/upload/v1631128142515/bSBjEUmXO.gif\" alt=\"debouncing.gif\" /></p>\n<p>If you carefully notice, debouncing is a concept implemented in most of our daily use applications, be it Google Docs, auto code completion suggestions in VS Code, searching at say e-commerce websites and more.</p>\n<p>This blog will help you integrate debouncing into an image searching app input through creating a custom react hook. Let's dive into what a custom hook is, more details on how debouncing works and what's the need for debouncing.</p>\n<hr />\n\n<h1 id=\"what-is-a-custom-react-hook\">What is a custom react hook</h1>\n<p>If you already know the rules for creating a custom react hook, I'd recommend you to move on to the next part. For those who don't, carry on, it's actually quite simple.</p>\n<p>A custom react hook is basically a JavaScript function that may call other hooks, whose name starts with 'use', so that react knows that this function has to follows the <a target=\"_blank\" href=\"https://reactjs.org/docs/hooks-rules.html\">Rules of Hooks</a>.</p>\n<p>Now why does react wants to apply the <a target=\"_blank\" href=\"https://reactjs.org/docs/hooks-rules.html\">Rules of Hooks</a> on a custom react hook?Because like I said, a custom react hook usually uses other react hooks in it's internal implementation.</p>\n<p>To sum up, creating a custom hook is quite simple, just create a function with it's name starting with 'use' and you are good to do. Just like a function, you can decide what argument this hook takes and what or if it should return something.</p>\n<h1 id=\"what-is-debouncing\">What is debouncing</h1>\n<p>Debouncing is a technique used to prevent the UI from processing unnecessary events, improving the app's performance and making the overall UX better.</p>\n<p><img src=\"https://cdn.hashnode.com/res/hashnode/image/upload/v1631162076514/J8cp6lrnn5.png\" alt=\"resized.png\" /></p>\n<p>Whenever an event that needs to be processed is fired up, a timer starts. If the same event is not fired up again until the timer ends, the handler function for that event is run and the processing takes place. But if the same event is fired up again while the timer is running, the timer restarts, bascially debouncing the processing part.</p>\n<p>Let's understand this better using an example.</p>\n<p>Say you want to implement auto save functionality into a todo app.\nYou would have an API to make a POST request to the server with the updated text.</p>\n<p>Now, if you are using react, you'll probably have a state for the todo text which will be updated at each and every change in the text, every keystoke.</p>\n<p>Saving the updated todo in the database at every small change/every keystroke is unnecessary. It will increase the load on your server and is time taking, making the app slower.</p>\n<p>How debouncing comes into picture here is, using the concept of debouncing, you can define a time period (<em>debounceTime</em>) until the last change made and then make the API call (<em>debounceFunction</em>) to save the updated text, all at once. </p>\n<p><img src=\"https://cdn.hashnode.com/res/hashnode/image/upload/v1631163440296/VX_WkseoW.gif\" alt=\"debouncing2.gif\" /></p>\n<p>The first keystroke starts the timer, the next change if made under the defined <em>debounceTime</em> ends the previous timer and starts the timer again, this process keeps happening until the last keystoke/change made. For the last keystoke/change made, the timer will eventually end, leading to a callback to the <em>debounceFunction</em> (the save API call) which will finally save all the changes made, at once.</p>\n<p>If the concept still seems a bit confusing, don't worry, the upcoming implementation part will make it crystal clear for you.</p>\n<hr />\n\n<h1 id=\"implementation\">Implementation</h1>\n<h3 id=\"the-boilerplate-image-searching-app\">The boilerplate - Image Searching App</h3>\n<p>It's a basic react app through which user can search for images across the web given some input keyword.</p>\n<p>The API we are using for fetching images based on a keyword is <a target=\"_blank\" href=\"https://rapidapi.com/contextualwebsearch/api/web-search/\">Web Search API</a>.</p>\n<p>I'd recommend going though the codesandbox below, play around with the app to get an idea what it does. If it seems too much, my recommendation would be to implement the boilerplate from scratch yourself.</p>\n<div class=\"embed-wrapper\"><div class=\"embed-loading\"><div class=\"loadingRow\"></div><div class=\"loadingRow\"></div></div><a class=\"embed-card\" href=\"https://codesandbox.io/s/boilerplate-custom-debounce-hook-mt5wj?file=/src/App.js\">https://codesandbox.io/s/boilerplate-custom-debounce-hook-mt5wj?file=/src/App.js</a></div>\n<h3 id=\"what-changes-we-want-to-do\">What changes we want to do</h3>\n<p>In the boilerplate app, we are making the API call on a button click, now what we want to do is to make the API call automatically when the user stops typing. </p>\n<p>Let's start by calling the API at every state (keyword) change. \nHow do we implement that? Let's break it down.</p>\n<p>We want to cause a side effect (fetchAndUpdate call) and re-render our app depending on a variable. </p>\n<p>Well <a target=\"_blank\" href=\"https://reactjs.org/docs/hooks-effect.html\">useEffect</a> was made for this, isn't it? </p>\n<p><img src=\"https://cdn.hashnode.com/res/hashnode/image/upload/v1631205045358/GEHRICnlk.gif\" alt=\"hulk.gif\" /></p>\n<pre><code><span class=\"hljs-comment\">// Depending Variable -> keyword state</span>\n<span class=\"hljs-comment\">// Side Effect -> fetchAndUpdate</span>\n\n<span class=\"hljs-selector-tag\">useEffect</span>(() => {\n <span class=\"hljs-selector-tag\">fetchAndUpdate</span>();\n }, <span class=\"hljs-selector-attr\">[keyword]</span>);\n</code></pre><p><em>fetchAndUpdate</em> will be called whenever the state keyword changes.</p>\n<p>Take a look at the networks tab when we type the word 'doggo':</p>\n<p><img src=\"https://cdn.hashnode.com/res/hashnode/image/upload/v1631204225502/0qH5Iu05p.gif\" alt=\"networkCall1.gif\" /></p>\n<p>As expected, we made a search call for every change, 'd', 'do', 'dog', ...\nFor a moment, it fetched and rendered Snoop Dog's images.</p>\n<p>So, we see where the problem is with this approach: unnecessary API calls, computations and rendering. \nI don't wanna see Snoop Dog's images when I'm looking for cute doggo images, right?</p>\n<p>Well, the solution to this problem is <strong>debouncing</strong>. We can keep debouncing the trigger until some time after the user has made it's last change. </p>\n<h3 id=\"creating-our-custom-hook-usedebounce\">Creating our custom hook - useDebounce</h3>\n<p>We'll start by building our logic on how to actually debounce the side effect.</p>\n<p>For now let's assume that we keep the <em>debounceTime</em> as <strong>500ms</strong>.</p>\n<p>That means after a state change, we will wait for 500ms to actually call the side effect. If the state changes again before 500ms are spent, we will forget about the previous change and wait for 500ms again to call the side effect.</p>\n<p>We can use <em> <a target=\"_blank\" href=\"https://developer.mozilla.org/en-US/docs/Web/API/setTimeout\">setTimeout</a> </em> to implement this logic. </p>\n<ul>\n<li>Whenever the state changes, we start the timer with our side effect function (<em>fetchAndUpdate</em>) as the callback, and 500ms (debounceTime) as the time to be spent before making the call</li>\n<li>If the state changes again, we will clear the previous timeout (clearTimeout(timer)) and the timer will start again because of the re-render</li>\n</ul>\n<p>Let's create a custom hook useDebounce which takes in the debounceFunction, the dependency array and the debounceTime. </p>\n<p>Here's how it'll look:</p>\n<pre><code><span class=\"hljs-keyword\">import</span> { useEffect } <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">\"react\"</span>;\n\n<span class=\"hljs-keyword\">export</span> <span class=\"hljs-keyword\">const</span> useDebounce = <span class=\"hljs-function\">(<span class=\"hljs-params\">\n debounceFunction,\n monitoringVariables = [],\n debounceTime = <span class=\"hljs-number\">500</span>\n</span>) =></span> {\n useEffect(<span class=\"hljs-function\">() =></span> {\n <span class=\"hljs-keyword\">let</span> timer = <span class=\"hljs-built_in\">setTimeout</span>(debounceFunction, debounceTime);\n <span class=\"hljs-keyword\">return</span> <span class=\"hljs-function\">() =></span> {\n <span class=\"hljs-built_in\">clearTimeout</span>(timer);\n };\n }, monitoringVariables);\n};\n</code></pre><p>This is how the custom hook will be called in <em>Searcher</em> component:</p>\n<pre><code>const Searcher = <span class=\"hljs-function\"><span class=\"hljs-params\">({ updateList, updateLoading })</span> =></span> {\n const [keyword, setKeyword] = useState(<span class=\"hljs-string\">\"\"</span>);\n\n const fetchAndUpdate = <span class=\"hljs-function\"><span class=\"hljs-params\">()</span> =></span> {\n ...\n };\n\n useDebounce(fetchAndUpdate, [keyword]);\n\n <span class=\"hljs-keyword\">return</span> (\n ...\n );\n};\n</code></pre><p>Let's discuss how this hook implements our debouncing logic:</p>\n<ul>\n<li>When the keyword state changes, the <em>Searcher</em> component re-renders, due to which the <em>useDebounce</em> hook is called again.</li>\n<li>Now calling the hook again actually means that it first <strong>unmounts</strong> and then <strong>remounts</strong></li>\n<li>When the useEffect sees an <strong>unmount</strong>, it fires up the clean up function, which clears the timeout, erasing any previously run timer.</li>\n<li>The <strong>remounting</strong> then re-initializes the timer and sets up a new timeout.</li>\n</ul>\n<p>To sum up, on state change the timer <strong>restarts</strong> or the side effect <strong>debounces</strong>.</p>\n<p>If you don't get it, don't worry this might help clear things up: </p>\n<p>Putting console logs at the API Call, re-initilization and timeout clearing (clean up function):</p>\n<p>Typing the word 'dog': </p>\n<p><img src=\"https://cdn.hashnode.com/res/hashnode/image/upload/v1631208420879/8XpIMrGvF.gif\" alt=\"consoleLogs.gif\" /></p>\n<p>Another look the network calls now, remember the keyword, 'doggo':\n<img src=\"https://cdn.hashnode.com/res/hashnode/image/upload/v1631208717456/W8OAZIyOw.gif\" alt=\"networkCall2.gif\" /></p>\n<p>Better, right? Just one API call. </p>\n<p>That's it, you can now use this hook anywhere to implement state dependent debouncing.</p>\n<p>Here is the codesandbox for you to play with it:</p>\n<div class=\"embed-wrapper\"><div class=\"embed-loading\"><div class=\"loadingRow\"></div><div class=\"loadingRow\"></div></div><a class=\"embed-card\" href=\"https://codesandbox.io/s/integrating-debounce-hook-forked-3ctei?file=/src/custom-hooks.js\">https://codesandbox.io/s/integrating-debounce-hook-forked-3ctei?file=/src/custom-hooks.js</a></div>\n<p>If you played with it good, you'd have seen an issue with this solution.\nThe unnecessary API call at the initial render. Let's solve that too, shall we?</p>\n<h3 id=\"solving-the-unnecessary-initial-render-call\">Solving the unnecessary initial render call</h3>\n<p>Although this solution might work, there still exists an optimization we can make. </p>\n<p>Let's take a look at the console logs on initial render:</p>\n<p><img src=\"https://cdn.hashnode.com/res/hashnode/image/upload/v1631454306373/aeYSIcm4t.gif\" alt=\"initialRender.gif\" /></p>\n<p>The side effect takes place on the initial render, thus the unnecessary API call. That's what useEffect does, it by default runs whatever is inside it on initial render.</p>\n<p>A possible and simple solution is to keep a flag that stores whether current run is an initial render or not, and based on that flag we condition our side effect inside useEffect.</p>\n<pre><code><span class=\"hljs-keyword\">import</span> { useEffect, useState } <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">\"react\"</span>;\n\n<span class=\"hljs-keyword\">export</span> <span class=\"hljs-keyword\">const</span> useDebounce = <span class=\"hljs-function\">(<span class=\"hljs-params\">\n debounceFunction,\n monitoringVariables = [],\n debounceTime = <span class=\"hljs-number\">500</span>\n</span>) =></span> {\n <span class=\"hljs-keyword\">const</span> initialRender = <span class=\"hljs-literal\">true</span>;\n useEffect(<span class=\"hljs-function\">() =></span> {\n <span class=\"hljs-keyword\">if</span>(initialRender){\n initialRender = <span class=\"hljs-literal\">false</span>;\n <span class=\"hljs-keyword\">let</span> timer = <span class=\"hljs-built_in\">setTimeout</span>(debounceFunction, debounceTime);\n <span class=\"hljs-keyword\">return</span> <span class=\"hljs-function\">() =></span> {\n <span class=\"hljs-built_in\">clearTimeout</span>(timer);\n }; \n }\n }, monitoringVariables);\n};\n</code></pre><p>See the problem with this solution is every render is an initial render, every time the function runs, the value will be re-initialized.</p>\n<p>We need the initial render value to persist between renders, well, do we have a hook for it? </p>\n<p>You guessed it right, <a target=\"_blank\" href=\"https://reactjs.org/docs/hooks-state.html\">useState</a>.</p>\n<p>Storing the flag as a state will do the job, but updating the state will in turn lead to re-renders itself.</p>\n<p>There has to be a neater solution, and there is, something like an instance variable in react.\nQuoting the <a target=\"_blank\" href=\"https://reactjs.org/docs/hooks-faq.html#is-there-something-like-instance-variables\">react documentation FAQ</a> : </p>\n<blockquote>\n<p>Is there something like instance variables?\nYes! The useRef() Hook isn’t just for DOM refs. The “ref” object is a generic container whose current property is mutable and can hold any value, similar to an instance property on a class.</p>\n</blockquote>\n<p>The <a target=\"_blank\" href=\"https://reactjs.org/docs/hooks-reference.html#useref\">useRef</a> Hook, can actually persist it's value through out the component's lifecycle.</p>\n<p>Let's see the solution using useRef:</p>\n<pre><code><span class=\"hljs-keyword\">import</span> { useEffect, useRef } <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">\"react\"</span>;\n\n<span class=\"hljs-keyword\">export</span> <span class=\"hljs-keyword\">const</span> useDebounce = <span class=\"hljs-function\">(<span class=\"hljs-params\">\n debounceFunction,\n monitoringVariables = [],\n debounceTime = <span class=\"hljs-number\">500</span>\n</span>) =></span> {\n <span class=\"hljs-keyword\">const</span> initialRender = useRef(<span class=\"hljs-literal\">true</span>);\n\n useEffect(<span class=\"hljs-function\">() =></span> {\n <span class=\"hljs-keyword\">if</span> (initialRender.current) {\n initialRender.current = <span class=\"hljs-literal\">false</span>;\n <span class=\"hljs-keyword\">return</span> <span class=\"hljs-function\">() =></span> {};\n } <span class=\"hljs-keyword\">else</span> {\n <span class=\"hljs-keyword\">let</span> timer = <span class=\"hljs-built_in\">setTimeout</span>(debounceFunction, debounceTime);\n <span class=\"hljs-keyword\">return</span> <span class=\"hljs-function\">() =></span> {\n <span class=\"hljs-built_in\">clearTimeout</span>(timer);\n };\n }\n }, monitoringVariables);\n};\n</code></pre><p>This solution works elegantly, leaving the final codesandbox for you to try it out.</p>\n<div class=\"embed-wrapper\"><div class=\"embed-loading\"><div class=\"loadingRow\"></div><div class=\"loadingRow\"></div></div><a class=\"embed-card\" href=\"https://codesandbox.io/s/integrating-useref-hthcf?file=/src/custom-hooks.js\">https://codesandbox.io/s/integrating-useref-hthcf?file=/src/custom-hooks.js</a></div>\n<hr />\n\n<h1 id=\"conclusion\">Conclusion</h1>\n<p>This custom useDebounce hook we created today can be used to implement auto save, search suggestions, auto code completion and more. </p>\n<p>On another note, debouncing also makes a really good interview problem for Frontend/Fullstack roles</p>\n<p>Thank you for reading it this long, and if you liked my efforts, it would mean the world to me if you could share this among your peers. </p>\n<p>If something seems wrong or is not clear, I would love to address doubts in comments! </p>\n<p>Thanks again! Happy Learning.</p>\n<p><img src=\"https://cdn.hashnode.com/res/hashnode/image/upload/v1631210335788/HGJkEMLaq.gif\" alt=\"thankyou.gif\" /></p>\n","contentMarkdown":"# Introduction\n\nWhen you type into google docs, does it save your changes at every keystroke? \nNo, it does not, it waits, holds on for some time after your last keystroke/change and then fires up the save functionality. That right there was debouncing.\n\nDebouncing is the process of bouncing off the execution of a function triggered from some event until the user is done firing that event for some time.\nThis is done to reduce unnecessary api calls to the server and prevents the UI to process a drastic number of events. More about it later on.\n\n![debouncing.gif](https://cdn.hashnode.com/res/hashnode/image/upload/v1631128142515/bSBjEUmXO.gif)\n\nIf you carefully notice, debouncing is a concept implemented in most of our daily use applications, be it Google Docs, auto code completion suggestions in VS Code, searching at say e-commerce websites and more.\n\nThis blog will help you integrate debouncing into an image searching app input through creating a custom react hook. Let's dive into what a custom hook is, more details on how debouncing works and what's the need for debouncing.\n\n<hr>\n\n# What is a custom react hook\n\nIf you already know the rules for creating a custom react hook, I'd recommend you to move on to the next part. For those who don't, carry on, it's actually quite simple.\n\nA custom react hook is basically a JavaScript function that may call other hooks, whose name starts with 'use', so that react knows that this function has to follows the [Rules of Hooks](https://reactjs.org/docs/hooks-rules.html).\n\nNow why does react wants to apply the [Rules of Hooks](https://reactjs.org/docs/hooks-rules.html) on a custom react hook?Because like I said, a custom react hook usually uses other react hooks in it's internal implementation.\n\nTo sum up, creating a custom hook is quite simple, just create a function with it's name starting with 'use' and you are good to do. Just like a function, you can decide what argument this hook takes and what or if it should return something.\n\n# What is debouncing\nDebouncing is a technique used to prevent the UI from processing unnecessary events, improving the app's performance and making the overall UX better.\n\n![resized.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1631162076514/J8cp6lrnn5.png)\n\nWhenever an event that needs to be processed is fired up, a timer starts. If the same event is not fired up again until the timer ends, the handler function for that event is run and the processing takes place. But if the same event is fired up again while the timer is running, the timer restarts, bascially debouncing the processing part.\n\nLet's understand this better using an example.\n\nSay you want to implement auto save functionality into a todo app.\nYou would have an API to make a POST request to the server with the updated text.\n\nNow, if you are using react, you'll probably have a state for the todo text which will be updated at each and every change in the text, every keystoke.\n\nSaving the updated todo in the database at every small change/every keystroke is unnecessary. It will increase the load on your server and is time taking, making the app slower.\n\nHow debouncing comes into picture here is, using the concept of debouncing, you can define a time period (*debounceTime*) until the last change made and then make the API call (*debounceFunction*) to save the updated text, all at once. \n\n![debouncing2.gif](https://cdn.hashnode.com/res/hashnode/image/upload/v1631163440296/VX_WkseoW.gif)\n\nThe first keystroke starts the timer, the next change if made under the defined *debounceTime* ends the previous timer and starts the timer again, this process keeps happening until the last keystoke/change made. For the last keystoke/change made, the timer will eventually end, leading to a callback to the *debounceFunction* (the save API call) which will finally save all the changes made, at once.\n\nIf the concept still seems a bit confusing, don't worry, the upcoming implementation part will make it crystal clear for you.\n\n<hr>\n\n# Implementation\n\n### The boilerplate - Image Searching App\n\nIt's a basic react app through which user can search for images across the web given some input keyword.\n\nThe API we are using for fetching images based on a keyword is [Web Search API](https://rapidapi.com/contextualwebsearch/api/web-search/).\n\nI'd recommend going though the codesandbox below, play around with the app to get an idea what it does. If it seems too much, my recommendation would be to implement the boilerplate from scratch yourself.\n\n%[https://codesandbox.io/s/boilerplate-custom-debounce-hook-mt5wj?file=/src/App.js]\n\n### What changes we want to do\n\nIn the boilerplate app, we are making the API call on a button click, now what we want to do is to make the API call automatically when the user stops typing. \n\nLet's start by calling the API at every state (keyword) change. \nHow do we implement that? Let's break it down.\n\nWe want to cause a side effect (fetchAndUpdate call) and re-render our app depending on a variable. \n\nWell [useEffect](https://reactjs.org/docs/hooks-effect.html) was made for this, isn't it? \n\n![hulk.gif](https://cdn.hashnode.com/res/hashnode/image/upload/v1631205045358/GEHRICnlk.gif)\n\n```\n// Depending Variable -> keyword state\n// Side Effect -> fetchAndUpdate\n\nuseEffect(() => {\n fetchAndUpdate();\n }, [keyword]);\n``` \n*fetchAndUpdate* will be called whenever the state keyword changes.\n\nTake a look at the networks tab when we type the word 'doggo':\n\n![networkCall1.gif](https://cdn.hashnode.com/res/hashnode/image/upload/v1631204225502/0qH5Iu05p.gif)\n\nAs expected, we made a search call for every change, 'd', 'do', 'dog', ...\nFor a moment, it fetched and rendered Snoop Dog's images.\n\nSo, we see where the problem is with this approach: unnecessary API calls, computations and rendering. \nI don't wanna see Snoop Dog's images when I'm looking for cute doggo images, right?\n\nWell, the solution to this problem is **debouncing**. We can keep debouncing the trigger until some time after the user has made it's last change. \n\n### Creating our custom hook - useDebounce\n\nWe'll start by building our logic on how to actually debounce the side effect.\n\nFor now let's assume that we keep the *debounceTime* as **500ms**.\n\nThat means after a state change, we will wait for 500ms to actually call the side effect. If the state changes again before 500ms are spent, we will forget about the previous change and wait for 500ms again to call the side effect.\n\nWe can use * [setTimeout](https://developer.mozilla.org/en-US/docs/Web/API/setTimeout) * to implement this logic. \n\n- Whenever the state changes, we start the timer with our side effect function (*fetchAndUpdate*) as the callback, and 500ms (debounceTime) as the time to be spent before making the call\n- If the state changes again, we will clear the previous timeout (clearTimeout(timer)) and the timer will start again because of the re-render\n\nLet's create a custom hook useDebounce which takes in the debounceFunction, the dependency array and the debounceTime. \n\nHere's how it'll look:\n```\nimport { useEffect } from \"react\";\n\nexport const useDebounce = (\n debounceFunction,\n monitoringVariables = [],\n debounceTime = 500\n) => {\n useEffect(() => {\n let timer = setTimeout(debounceFunction, debounceTime);\n return () => {\n clearTimeout(timer);\n };\n }, monitoringVariables);\n};\n\n``` \n\nThis is how the custom hook will be called in *Searcher* component:\n\n\n```\nconst Searcher = ({ updateList, updateLoading }) => {\n const [keyword, setKeyword] = useState(\"\");\n\n const fetchAndUpdate = () => {\n ...\n };\n\n useDebounce(fetchAndUpdate, [keyword]);\n\n return (\n ...\n );\n};\n\n``` \n\nLet's discuss how this hook implements our debouncing logic:\n\n- When the keyword state changes, the *Searcher* component re-renders, due to which the *useDebounce* hook is called again.\n- Now calling the hook again actually means that it first **unmounts** and then **remounts**\n- When the useEffect sees an **unmount**, it fires up the clean up function, which clears the timeout, erasing any previously run timer.\n- The **remounting** then re-initializes the timer and sets up a new timeout.\n\nTo sum up, on state change the timer **restarts** or the side effect **debounces**.\n\nIf you don't get it, don't worry this might help clear things up: \n\nPutting console logs at the API Call, re-initilization and timeout clearing (clean up function):\n\nTyping the word 'dog': \n\n![consoleLogs.gif](https://cdn.hashnode.com/res/hashnode/image/upload/v1631208420879/8XpIMrGvF.gif)\n\nAnother look the network calls now, remember the keyword, 'doggo':\n![networkCall2.gif](https://cdn.hashnode.com/res/hashnode/image/upload/v1631208717456/W8OAZIyOw.gif)\n\nBetter, right? Just one API call. \n\nThat's it, you can now use this hook anywhere to implement state dependent debouncing.\n\nHere is the codesandbox for you to play with it:\n\n%[https://codesandbox.io/s/integrating-debounce-hook-forked-3ctei?file=/src/custom-hooks.js]\n\nIf you played with it good, you'd have seen an issue with this solution.\nThe unnecessary API call at the initial render. Let's solve that too, shall we?\n\n### Solving the unnecessary initial render call\n\nAlthough this solution might work, there still exists an optimization we can make. \n\nLet's take a look at the console logs on initial render:\n\n![initialRender.gif](https://cdn.hashnode.com/res/hashnode/image/upload/v1631454306373/aeYSIcm4t.gif)\n\nThe side effect takes place on the initial render, thus the unnecessary API call. That's what useEffect does, it by default runs whatever is inside it on initial render.\n\nA possible and simple solution is to keep a flag that stores whether current run is an initial render or not, and based on that flag we condition our side effect inside useEffect.\n\n```\nimport { useEffect, useState } from \"react\";\n\nexport const useDebounce = (\n debounceFunction,\n monitoringVariables = [],\n debounceTime = 500\n) => {\n const initialRender = true;\n useEffect(() => {\n if(initialRender){\n initialRender = false;\n let timer = setTimeout(debounceFunction, debounceTime);\n return () => {\n clearTimeout(timer);\n }; \n }\n }, monitoringVariables);\n};\n\n``` \n \nSee the problem with this solution is every render is an initial render, every time the function runs, the value will be re-initialized.\n\nWe need the initial render value to persist between renders, well, do we have a hook for it? \n\nYou guessed it right, [useState](https://reactjs.org/docs/hooks-state.html).\n\nStoring the flag as a state will do the job, but updating the state will in turn lead to re-renders itself.\n\nThere has to be a neater solution, and there is, something like an instance variable in react.\nQuoting the [react documentation FAQ](https://reactjs.org/docs/hooks-faq.html#is-there-something-like-instance-variables) : \n\n> Is there something like instance variables?\nYes! The useRef() Hook isn’t just for DOM refs. The “ref” object is a generic container whose current property is mutable and can hold any value, similar to an instance property on a class.\n\nThe [useRef](https://reactjs.org/docs/hooks-reference.html#useref) Hook, can actually persist it's value through out the component's lifecycle.\n\nLet's see the solution using useRef:\n\n```\nimport { useEffect, useRef } from \"react\";\n\nexport const useDebounce = (\n debounceFunction,\n monitoringVariables = [],\n debounceTime = 500\n) => {\n const initialRender = useRef(true);\n\n useEffect(() => {\n if (initialRender.current) {\n initialRender.current = false;\n return () => {};\n } else {\n let timer = setTimeout(debounceFunction, debounceTime);\n return () => {\n clearTimeout(timer);\n };\n }\n }, monitoringVariables);\n};\n\n``` \n\nThis solution works elegantly, leaving the final codesandbox for you to try it out.\n\n%[https://codesandbox.io/s/integrating-useref-hthcf?file=/src/custom-hooks.js]\n\n<hr/>\n\n# Conclusion\n\nThis custom useDebounce hook we created today can be used to implement auto save, search suggestions, auto code completion and more. \n\nOn another note, debouncing also makes a really good interview problem for Frontend/Fullstack roles\n\nThank you for reading it this long, and if you liked my efforts, it would mean the world to me if you could share this among your peers. \n\nIf something seems wrong or is not clear, I would love to address doubts in comments! \n\nThanks again! Happy Learning.\n\n![thankyou.gif](https://cdn.hashnode.com/res/hashnode/image/upload/v1631210335788/HGJkEMLaq.gif)\n","hasPolls":false,"totalPollVotes":0,"upvotes":0,"downvotes":0,"tags":["56744723958ef13879b95434","5f8523be6ad92638db4944a9","56744721958ef13879b94cad","56a399f292921b8f79d3633c","56744721958ef13879b94d0f"],"untaggedFrom":[],"upvotedBy":[],"downvotedBy":[],"popularity":4944.3089,"responses":[],"responseCount":0,"replyCount":0,"followers":[],"isActive":false,"isFeatured":false,"isEngaging":false,"answeredByTarget":false,"inviters":[],"isDelisted":false,"isNotified":false,"duplicatePosts":[],"numCollapsed":0,"hasReward":false,"bookmarkedIn":[],"similarPostIds":[],"reactions":[],"totalReactions":0,"reactionsByCurrentUser":[],"isPinnedToBlog":false,"disableComments":false,"hasLatex":false,"syncAlgolia":false,"numUniqueUsersWhoReacted":0,"_id":"613ecacb1821961e25521632","title":"How to create a custom debounce react hook using useEffect","subtitle":"Debouncing, it's need and creating a custom react hook around it to improve your application's performance","type":"story","ogImage":"https://cdn.hashnode.com/res/hashnode/image/upload/v1631505058542/FFyR4OjFK.png","metaTitle":"Custom debounce react hook using useEffect","metaDescription":"An explanation of debouncing, it's need and creating a custom react hook around it to improve your application's performance","isRepublished":true,"originalArticleURL":"https://hashnode.com/edit/ckti2xi6t0tbhyds1fmnda1gi","partOfPublication":true,"publication":"613ec61122b7a41dfe5ff33d","slug":"how-to-create-a-custom-debounce-react-hook-using-useeffect--deleted","stickCoverToBottom":true,"pollOptions":[],"dateAdded":"2021-09-13T03:51:39.858Z","badges":[],"questionReplies":[],"contributors":[],"cuid":"ckti40g030tm6yds1775t7omk","author":"60d8b19ecb0aa8118c23d01c","followersCount":1,"draft":"613ec9e522b7a41dfe5ff3a7","hasPinnedTag":false,"readTime":9,"__v":0,"uniqueReactions":[],"reactionToCountMapUnique":{"any":1},"id":"613ecacb1821961e25521632"},{"reward":{"type":"xlm"},"sourcedFromGithub":false,"isAnonymous":false,"views":245,"slugOverridden":true,"coverImage":"https://cdn.hashnode.com/res/hashnode/image/upload/v1631085529470/VHp8wQXXg.png","autoGeneratedCover":"","brief":"Introduction\nWhen you type into google docs, does it save your changes at every keystroke? \nNo, it does not, it waits, holds on for some time after your last keystroke/change and then fires up the save functionality. That right there was debouncing.\n...","content":"<h1 id=\"introduction\">Introduction</h1>\n<p>When you type into google docs, does it save your changes at every keystroke? \nNo, it does not, it waits, holds on for some time after your last keystroke/change and then fires up the save functionality. That right there was debouncing.</p>\n<p>Debouncing is the process of bouncing off the execution of a function triggered from some event until the user is done firing that event for some time.\nThis is done to reduce unnecessary api calls to the server and prevents the UI to process a drastic number of events. More about it later on.</p>\n<p><img src=\"https://cdn.hashnode.com/res/hashnode/image/upload/v1631128142515/bSBjEUmXO.gif\" alt=\"debouncing.gif\" /></p>\n<p>If you carefully notice, debouncing is a concept implemented in most of our daily use applications, be it Google Docs, auto code completion suggestions in VS Code, searching at say e-commerce websites and more.</p>\n<p>This blog will help you integrate debouncing into an image searching app input through creating a custom react hook. Let's dive into what a custom hook is, more details on how debouncing works and what's the need for debouncing.</p>\n<hr />\n\n<h1 id=\"what-is-a-custom-react-hook\">What is a custom react hook</h1>\n<p>If you already know the rules for creating a custom react hook, I'd recommend you to move on to the next part. For those who don't, carry on, it's actually quite simple.</p>\n<p>A custom react hook is basically a JavaScript function that may call other hooks, whose name starts with 'use', so that react knows that this function has to follows the <a target=\"_blank\" href=\"https://reactjs.org/docs/hooks-rules.html\">Rules of Hooks</a>.</p>\n<p>Now why does react wants to apply the <a target=\"_blank\" href=\"https://reactjs.org/docs/hooks-rules.html\">Rules of Hooks</a> on a custom react hook?Because like I said, a custom react hook usually uses other react hooks in it's internal implementation.</p>\n<p>To sum up, creating a custom hook is quite simple, just create a function with it's name starting with 'use' and you are good to do. Just like a function, you can decide what argument this hook takes and what or if it should return something.</p>\n<h1 id=\"what-is-debouncing\">What is debouncing</h1>\n<p>Debouncing is a technique used to prevent the UI from processing unnecessary events, improving the app's performance and making the overall UX better.</p>\n<p><img src=\"https://cdn.hashnode.com/res/hashnode/image/upload/v1631162076514/J8cp6lrnn5.png\" alt=\"resized.png\" /></p>\n<p>Whenever an event that needs to be processed is fired up, a timer starts. If the same event is not fired up again until the timer ends, the handler function for that event is run and the processing takes place. But if the same event is fired up again while the timer is running, the timer restarts, bascially debouncing the processing part.</p>\n<p>Let's understand this better using an example.</p>\n<p>Say you want to implement auto save functionality into a todo app.\nYou would have an API to make a POST request to the server with the updated text.</p>\n<p>Now, if you are using react, you'll probably have a state for the todo text which will be updated at each and every change in the text, every keystoke.</p>\n<p>Saving the updated todo in the database at every small change/every keystroke is unnecessary. It will increase the load on your server and is time taking, making the app slower.</p>\n<p>How debouncing comes into picture here is, using the concept of debouncing, you can define a time period (<em>debounceTime</em>) until the last change made and then make the API call (<em>debounceFunction</em>) to save the updated text, all at once. </p>\n<p><img src=\"https://cdn.hashnode.com/res/hashnode/image/upload/v1631163440296/VX_WkseoW.gif\" alt=\"debouncing2.gif\" /></p>\n<p>The first keystroke starts the timer, the next change if made under the defined <em>debounceTime</em> ends the previous timer and starts the timer again, this process keeps happening until the last keystoke/change made. For the last keystoke/change made, the timer will eventually end, leading to a callback to the <em>debounceFunction</em> (the save API call) which will finally save all the changes made, at once.</p>\n<p>If the concept still seems a bit confusing, don't worry, the upcoming implementation part will make it crystal clear for you.</p>\n<hr />\n\n<h1 id=\"implementation\">Implementation</h1>\n<h3 id=\"the-boilerplate-image-searching-app\">The boilerplate - Image Searching App</h3>\n<p>It's a basic react app through which user can search for images across the web given some input keyword.</p>\n<p>The API we are using for fetching images based on a keyword is <a target=\"_blank\" href=\"https://rapidapi.com/contextualwebsearch/api/web-search/\">Web Search API</a>.</p>\n<p>I'd recommend going though the codesandbox below, play around with the app to get an idea what it does. If it seems too much, my recommendation would be to implement the boilerplate from scratch yourself.</p>\n<div class=\"embed-wrapper\"><div class=\"embed-loading\"><div class=\"loadingRow\"></div><div class=\"loadingRow\"></div></div><a class=\"embed-card\" href=\"https://codesandbox.io/s/boilerplate-custom-debounce-hook-mt5wj?file=/src/App.js\">https://codesandbox.io/s/boilerplate-custom-debounce-hook-mt5wj?file=/src/App.js</a></div>\n<h3 id=\"what-changes-we-want-to-do\">What changes we want to do</h3>\n<p>In the boilerplate app, we are making the API call on a button click, now what we want to do is to make the API call automatically when the user stops typing. </p>\n<p>Let's start by calling the API at every state (keyword) change. \nHow do we implement that? Let's break it down.</p>\n<p>We want to cause a side effect (fetchAndUpdate call) and re-render our app depending on a variable. </p>\n<p>Well <a target=\"_blank\" href=\"https://reactjs.org/docs/hooks-effect.html\">useEffect</a> was made for this, isn't it? </p>\n<p><img src=\"https://cdn.hashnode.com/res/hashnode/image/upload/v1631205045358/GEHRICnlk.gif\" alt=\"hulk.gif\" /></p>\n<pre><code><span class=\"hljs-comment\">// Depending Variable -> keyword state</span>\n<span class=\"hljs-comment\">// Side Effect -> fetchAndUpdate</span>\n\n<span class=\"hljs-selector-tag\">useEffect</span>(() => {\n <span class=\"hljs-selector-tag\">fetchAndUpdate</span>();\n }, <span class=\"hljs-selector-attr\">[keyword]</span>);\n</code></pre><p><em>fetchAndUpdate</em> will be called whenever the state keyword changes.</p>\n<p>Take a look at the networks tab when we type the word 'doggo':</p>\n<p><img src=\"https://cdn.hashnode.com/res/hashnode/image/upload/v1631204225502/0qH5Iu05p.gif\" alt=\"networkCall1.gif\" /></p>\n<p>As expected, we made a search call for every change, 'd', 'do', 'dog', ...\nFor a moment, it fetched and rendered Snoop Dog's images.</p>\n<p>So, we see where the problem is with this approach: unnecessary API calls, computations and rendering. \nI don't wanna see Snoop Dog's images when I'm looking for cute doggo images, right?</p>\n<p>Well, the solution to this problem is <strong>debouncing</strong>. We can keep debouncing the trigger until some time after the user has made it's last change. </p>\n<h3 id=\"creating-our-custom-hook-usedebounce\">Creating our custom hook - useDebounce</h3>\n<p>We'll start by building our logic on how to actually debounce the side effect.</p>\n<p>For now let's assume that we keep the <em>debounceTime</em> as <strong>500ms</strong>.</p>\n<p>That means after a state change, we will wait for 500ms to actually call the side effect. If the state changes again before 500ms are spent, we will forget about the previous change and wait for 500ms again to call the side effect.</p>\n<p>We can use <em> <a target=\"_blank\" href=\"https://developer.mozilla.org/en-US/docs/Web/API/setTimeout\">setTimeout</a> </em> to implement this logic. </p>\n<ul>\n<li>Whenever the state changes, we start the timer with our side effect function (<em>fetchAndUpdate</em>) as the callback, and 500ms (debounceTime) as the time to be spent before making the call</li>\n<li>If the state changes again, we will clear the previous timeout (clearTimeout(timer)) and the timer will start again because of the re-render</li>\n</ul>\n<p>Let's create a custom hook useDebounce which takes in the debounceFunction, the dependency array and the debounceTime. </p>\n<p>Here's how it'll look:</p>\n<pre><code><span class=\"hljs-keyword\">import</span> { useEffect } <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">\"react\"</span>;\n\n<span class=\"hljs-keyword\">export</span> <span class=\"hljs-keyword\">const</span> useDebounce = <span class=\"hljs-function\">(<span class=\"hljs-params\">\n debounceFunction,\n monitoringVariables = [],\n debounceTime = <span class=\"hljs-number\">500</span>\n</span>) =></span> {\n useEffect(<span class=\"hljs-function\">() =></span> {\n <span class=\"hljs-keyword\">let</span> timer = <span class=\"hljs-built_in\">setTimeout</span>(debounceFunction, debounceTime);\n <span class=\"hljs-keyword\">return</span> <span class=\"hljs-function\">() =></span> {\n <span class=\"hljs-built_in\">clearTimeout</span>(timer);\n };\n }, monitoringVariables);\n};\n</code></pre><p>This is how the custom hook will be called in <em>Searcher</em> component:</p>\n<pre><code>const Searcher = <span class=\"hljs-function\"><span class=\"hljs-params\">({ updateList, updateLoading })</span> =></span> {\n const [keyword, setKeyword] = useState(<span class=\"hljs-string\">\"\"</span>);\n\n const fetchAndUpdate = <span class=\"hljs-function\"><span class=\"hljs-params\">()</span> =></span> {\n ...\n };\n\n useDebounce(fetchAndUpdate, [keyword]);\n\n <span class=\"hljs-keyword\">return</span> (\n ...\n );\n};\n</code></pre><p>Let's discuss how this hook implements our debouncing logic:</p>\n<ul>\n<li>When the keyword state changes, the <em>Searcher</em> component re-renders, due to which the <em>useDebounce</em> hook is called again.</li>\n<li>Now calling the hook again actually means that it first <strong>unmounts</strong> and then <strong>remounts</strong></li>\n<li>When the useEffect sees an <strong>unmount</strong>, it fires up the clean up function, which clears the timeout, erasing any previously run timer.</li>\n<li>The <strong>remounting</strong> then re-initializes the timer and sets up a new timeout.</li>\n</ul>\n<p>To sum up, on state change the timer <strong>restarts</strong> or the side effect <strong>debounces</strong>.</p>\n<p>If you don't get it, don't worry this might help clear things up: </p>\n<p>Putting console logs at the API Call, re-initilization and timeout clearing (clean up function):</p>\n<p>Typing the word 'dog': </p>\n<p><img src=\"https://cdn.hashnode.com/res/hashnode/image/upload/v1631208420879/8XpIMrGvF.gif\" alt=\"consoleLogs.gif\" /></p>\n<p>Another look the network calls now, remember the keyword, 'doggo':\n<img src=\"https://cdn.hashnode.com/res/hashnode/image/upload/v1631208717456/W8OAZIyOw.gif\" alt=\"networkCall2.gif\" /></p>\n<p>Better, right? Just one API call. </p>\n<p>That's it, you can now use this hook anywhere to implement state dependent debouncing.</p>\n<p>Here is the codesandbox for you to play with it:</p>\n<div class=\"embed-wrapper\"><div class=\"embed-loading\"><div class=\"loadingRow\"></div><div class=\"loadingRow\"></div></div><a class=\"embed-card\" href=\"https://codesandbox.io/s/integrating-debounce-hook-forked-3ctei?file=/src/custom-hooks.js\">https://codesandbox.io/s/integrating-debounce-hook-forked-3ctei?file=/src/custom-hooks.js</a></div>\n<p>If you played with it good, you'd have seen an issue with this solution.\nThe unnecessary API call at the initial render. Let's solve that too, shall we?</p>\n<h3 id=\"solving-the-unnecessary-initial-render-call\">Solving the unnecessary initial render call</h3>\n<p><img src=\"https://cdn.hashnode.com/res/hashnode/image/upload/v1632305267854/przJ6WH8X.gif\" alt=\"bounceFunny.gif\" /></p>\n<p>Although this solution might work, there still exists an optimization we can make. </p>\n<p>Let's take a look at the console logs on initial render:</p>\n<p><img src=\"https://cdn.hashnode.com/res/hashnode/image/upload/v1631454306373/aeYSIcm4t.gif\" alt=\"initialRender.gif\" /></p>\n<p>The side effect takes place on the initial render, thus the unnecessary API call. That's what useEffect does, it by default runs whatever is inside it on initial render.</p>\n<p>A possible and simple solution is to keep a flag that stores whether current run is an initial render or not, and based on that flag we condition our side effect inside useEffect.</p>\n<pre><code><span class=\"hljs-keyword\">import</span> { useEffect, useState } <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">\"react\"</span>;\n\n<span class=\"hljs-keyword\">export</span> <span class=\"hljs-keyword\">const</span> useDebounce = <span class=\"hljs-function\">(<span class=\"hljs-params\">\n debounceFunction,\n monitoringVariables = [],\n debounceTime = <span class=\"hljs-number\">500</span>\n</span>) =></span> {\n <span class=\"hljs-keyword\">const</span> initialRender = <span class=\"hljs-literal\">true</span>;\n useEffect(<span class=\"hljs-function\">() =></span> {\n <span class=\"hljs-keyword\">if</span>(initialRender){\n initialRender = <span class=\"hljs-literal\">false</span>;\n <span class=\"hljs-keyword\">let</span> timer = <span class=\"hljs-built_in\">setTimeout</span>(debounceFunction, debounceTime);\n <span class=\"hljs-keyword\">return</span> <span class=\"hljs-function\">() =></span> {\n <span class=\"hljs-built_in\">clearTimeout</span>(timer);\n }; \n }\n }, monitoringVariables);\n};\n</code></pre><p>See the problem with this solution is every render is an initial render, every time the function runs, the value will be re-initialized.</p>\n<p>We need the initial render value to persist between renders, well, do we have a hook for it? </p>\n<p>You guessed it right, <a target=\"_blank\" href=\"https://reactjs.org/docs/hooks-state.html\">useState</a>.</p>\n<p>Storing the flag as a state will do the job, but updating the state will in turn lead to re-renders itself.</p>\n<p>There has to be a neater solution, and there is, something like an instance variable in react.\nQuoting the <a target=\"_blank\" href=\"https://reactjs.org/docs/hooks-faq.html#is-there-something-like-instance-variables\">react documentation FAQ</a> : </p>\n<blockquote>\n<p>Is there something like instance variables?\nYes! The useRef() Hook isn’t just for DOM refs. The “ref” object is a generic container whose current property is mutable and can hold any value, similar to an instance property on a class.</p>\n</blockquote>\n<p>The <a target=\"_blank\" href=\"https://reactjs.org/docs/hooks-reference.html#useref\">useRef</a> Hook, can actually persist it's value through out the component's lifecycle.</p>\n<p>Let's see the solution using useRef:</p>\n<pre><code><span class=\"hljs-keyword\">import</span> { useEffect, useRef } <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">\"react\"</span>;\n\n<span class=\"hljs-keyword\">export</span> <span class=\"hljs-keyword\">const</span> useDebounce = <span class=\"hljs-function\">(<span class=\"hljs-params\">\n debounceFunction,\n monitoringVariables = [],\n debounceTime = <span class=\"hljs-number\">500</span>\n</span>) =></span> {\n <span class=\"hljs-keyword\">const</span> initialRender = useRef(<span class=\"hljs-literal\">true</span>);\n\n useEffect(<span class=\"hljs-function\">() =></span> {\n <span class=\"hljs-keyword\">if</span> (initialRender.current) {\n initialRender.current = <span class=\"hljs-literal\">false</span>;\n <span class=\"hljs-keyword\">return</span> <span class=\"hljs-function\">() =></span> {};\n } <span class=\"hljs-keyword\">else</span> {\n <span class=\"hljs-keyword\">let</span> timer = <span class=\"hljs-built_in\">setTimeout</span>(debounceFunction, debounceTime);\n <span class=\"hljs-keyword\">return</span> <span class=\"hljs-function\">() =></span> {\n <span class=\"hljs-built_in\">clearTimeout</span>(timer);\n };\n }\n }, monitoringVariables);\n};\n</code></pre><p>This solution works elegantly, leaving the final codesandbox for you to try it out.</p>\n<div class=\"embed-wrapper\"><div class=\"embed-loading\"><div class=\"loadingRow\"></div><div class=\"loadingRow\"></div></div><a class=\"embed-card\" href=\"https://codesandbox.io/s/integrating-useref-hthcf?file=/src/custom-hooks.js\">https://codesandbox.io/s/integrating-useref-hthcf?file=/src/custom-hooks.js</a></div>\n<hr />\n\n<h1 id=\"conclusion\">Conclusion</h1>\n<p>This custom useDebounce hook we created today can be used to implement auto save, search suggestions, auto code completion and more. </p>\n<p>On another note, debouncing also makes a really good interview problem for Frontend/Fullstack roles</p>\n<p>Thank you for reading it this long, and if you liked my efforts, it would mean the world to me if you could share this among your peers. </p>\n<p>If something seems wrong or is not clear, I would love to address doubts in comments! </p>\n<p>Thanks again! Happy Learning.</p>\n<p><img src=\"https://cdn.hashnode.com/res/hashnode/image/upload/v1631210335788/HGJkEMLaq.gif\" alt=\"thankyou.gif\" /></p>\n","contentMarkdown":"# Introduction\n\nWhen you type into google docs, does it save your changes at every keystroke? \nNo, it does not, it waits, holds on for some time after your last keystroke/change and then fires up the save functionality. That right there was debouncing.\n\nDebouncing is the process of bouncing off the execution of a function triggered from some event until the user is done firing that event for some time.\nThis is done to reduce unnecessary api calls to the server and prevents the UI to process a drastic number of events. More about it later on.\n\n![debouncing.gif](https://cdn.hashnode.com/res/hashnode/image/upload/v1631128142515/bSBjEUmXO.gif)\n\nIf you carefully notice, debouncing is a concept implemented in most of our daily use applications, be it Google Docs, auto code completion suggestions in VS Code, searching at say e-commerce websites and more.\n\nThis blog will help you integrate debouncing into an image searching app input through creating a custom react hook. Let's dive into what a custom hook is, more details on how debouncing works and what's the need for debouncing.\n\n<hr>\n\n# What is a custom react hook\n\nIf you already know the rules for creating a custom react hook, I'd recommend you to move on to the next part. For those who don't, carry on, it's actually quite simple.\n\nA custom react hook is basically a JavaScript function that may call other hooks, whose name starts with 'use', so that react knows that this function has to follows the [Rules of Hooks](https://reactjs.org/docs/hooks-rules.html).\n\nNow why does react wants to apply the [Rules of Hooks](https://reactjs.org/docs/hooks-rules.html) on a custom react hook?Because like I said, a custom react hook usually uses other react hooks in it's internal implementation.\n\nTo sum up, creating a custom hook is quite simple, just create a function with it's name starting with 'use' and you are good to do. Just like a function, you can decide what argument this hook takes and what or if it should return something.\n\n# What is debouncing\nDebouncing is a technique used to prevent the UI from processing unnecessary events, improving the app's performance and making the overall UX better.\n\n![resized.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1631162076514/J8cp6lrnn5.png)\n\nWhenever an event that needs to be processed is fired up, a timer starts. If the same event is not fired up again until the timer ends, the handler function for that event is run and the processing takes place. But if the same event is fired up again while the timer is running, the timer restarts, bascially debouncing the processing part.\n\nLet's understand this better using an example.\n\nSay you want to implement auto save functionality into a todo app.\nYou would have an API to make a POST request to the server with the updated text.\n\nNow, if you are using react, you'll probably have a state for the todo text which will be updated at each and every change in the text, every keystoke.\n\nSaving the updated todo in the database at every small change/every keystroke is unnecessary. It will increase the load on your server and is time taking, making the app slower.\n\nHow debouncing comes into picture here is, using the concept of debouncing, you can define a time period (*debounceTime*) until the last change made and then make the API call (*debounceFunction*) to save the updated text, all at once. \n\n![debouncing2.gif](https://cdn.hashnode.com/res/hashnode/image/upload/v1631163440296/VX_WkseoW.gif)\n\nThe first keystroke starts the timer, the next change if made under the defined *debounceTime* ends the previous timer and starts the timer again, this process keeps happening until the last keystoke/change made. For the last keystoke/change made, the timer will eventually end, leading to a callback to the *debounceFunction* (the save API call) which will finally save all the changes made, at once.\n\nIf the concept still seems a bit confusing, don't worry, the upcoming implementation part will make it crystal clear for you.\n\n<hr>\n\n# Implementation\n\n### The boilerplate - Image Searching App\n\nIt's a basic react app through which user can search for images across the web given some input keyword.\n\nThe API we are using for fetching images based on a keyword is [Web Search API](https://rapidapi.com/contextualwebsearch/api/web-search/).\n\nI'd recommend going though the codesandbox below, play around with the app to get an idea what it does. If it seems too much, my recommendation would be to implement the boilerplate from scratch yourself.\n\n%[https://codesandbox.io/s/boilerplate-custom-debounce-hook-mt5wj?file=/src/App.js]\n\n### What changes we want to do\n\nIn the boilerplate app, we are making the API call on a button click, now what we want to do is to make the API call automatically when the user stops typing. \n\nLet's start by calling the API at every state (keyword) change. \nHow do we implement that? Let's break it down.\n\nWe want to cause a side effect (fetchAndUpdate call) and re-render our app depending on a variable. \n\nWell [useEffect](https://reactjs.org/docs/hooks-effect.html) was made for this, isn't it? \n\n![hulk.gif](https://cdn.hashnode.com/res/hashnode/image/upload/v1631205045358/GEHRICnlk.gif)\n\n```\n// Depending Variable -> keyword state\n// Side Effect -> fetchAndUpdate\n\nuseEffect(() => {\n fetchAndUpdate();\n }, [keyword]);\n``` \n*fetchAndUpdate* will be called whenever the state keyword changes.\n\nTake a look at the networks tab when we type the word 'doggo':\n\n![networkCall1.gif](https://cdn.hashnode.com/res/hashnode/image/upload/v1631204225502/0qH5Iu05p.gif)\n\nAs expected, we made a search call for every change, 'd', 'do', 'dog', ...\nFor a moment, it fetched and rendered Snoop Dog's images.\n\nSo, we see where the problem is with this approach: unnecessary API calls, computations and rendering. \nI don't wanna see Snoop Dog's images when I'm looking for cute doggo images, right?\n\nWell, the solution to this problem is **debouncing**. We can keep debouncing the trigger until some time after the user has made it's last change. \n\n### Creating our custom hook - useDebounce\n\nWe'll start by building our logic on how to actually debounce the side effect.\n\nFor now let's assume that we keep the *debounceTime* as **500ms**.\n\nThat means after a state change, we will wait for 500ms to actually call the side effect. If the state changes again before 500ms are spent, we will forget about the previous change and wait for 500ms again to call the side effect.\n\nWe can use * [setTimeout](https://developer.mozilla.org/en-US/docs/Web/API/setTimeout) * to implement this logic. \n\n- Whenever the state changes, we start the timer with our side effect function (*fetchAndUpdate*) as the callback, and 500ms (debounceTime) as the time to be spent before making the call\n- If the state changes again, we will clear the previous timeout (clearTimeout(timer)) and the timer will start again because of the re-render\n\nLet's create a custom hook useDebounce which takes in the debounceFunction, the dependency array and the debounceTime. \n\nHere's how it'll look:\n```\nimport { useEffect } from \"react\";\n\nexport const useDebounce = (\n debounceFunction,\n monitoringVariables = [],\n debounceTime = 500\n) => {\n useEffect(() => {\n let timer = setTimeout(debounceFunction, debounceTime);\n return () => {\n clearTimeout(timer);\n };\n }, monitoringVariables);\n};\n\n``` \n\nThis is how the custom hook will be called in *Searcher* component:\n\n\n```\nconst Searcher = ({ updateList, updateLoading }) => {\n const [keyword, setKeyword] = useState(\"\");\n\n const fetchAndUpdate = () => {\n ...\n };\n\n useDebounce(fetchAndUpdate, [keyword]);\n\n return (\n ...\n );\n};\n\n``` \n\nLet's discuss how this hook implements our debouncing logic:\n\n- When the keyword state changes, the *Searcher* component re-renders, due to which the *useDebounce* hook is called again.\n- Now calling the hook again actually means that it first **unmounts** and then **remounts**\n- When the useEffect sees an **unmount**, it fires up the clean up function, which clears the timeout, erasing any previously run timer.\n- The **remounting** then re-initializes the timer and sets up a new timeout.\n\nTo sum up, on state change the timer **restarts** or the side effect **debounces**.\n\nIf you don't get it, don't worry this might help clear things up: \n\nPutting console logs at the API Call, re-initilization and timeout clearing (clean up function):\n\nTyping the word 'dog': \n\n![consoleLogs.gif](https://cdn.hashnode.com/res/hashnode/image/upload/v1631208420879/8XpIMrGvF.gif)\n\nAnother look the network calls now, remember the keyword, 'doggo':\n![networkCall2.gif](https://cdn.hashnode.com/res/hashnode/image/upload/v1631208717456/W8OAZIyOw.gif)\n\nBetter, right? Just one API call. \n\nThat's it, you can now use this hook anywhere to implement state dependent debouncing.\n\nHere is the codesandbox for you to play with it:\n\n%[https://codesandbox.io/s/integrating-debounce-hook-forked-3ctei?file=/src/custom-hooks.js]\n\nIf you played with it good, you'd have seen an issue with this solution.\nThe unnecessary API call at the initial render. Let's solve that too, shall we?\n\n### Solving the unnecessary initial render call\n\n![bounceFunny.gif](https://cdn.hashnode.com/res/hashnode/image/upload/v1632305267854/przJ6WH8X.gif)\n\nAlthough this solution might work, there still exists an optimization we can make. \n\nLet's take a look at the console logs on initial render:\n\n![initialRender.gif](https://cdn.hashnode.com/res/hashnode/image/upload/v1631454306373/aeYSIcm4t.gif)\n\nThe side effect takes place on the initial render, thus the unnecessary API call. That's what useEffect does, it by default runs whatever is inside it on initial render.\n\nA possible and simple solution is to keep a flag that stores whether current run is an initial render or not, and based on that flag we condition our side effect inside useEffect.\n\n```\nimport { useEffect, useState } from \"react\";\n\nexport const useDebounce = (\n debounceFunction,\n monitoringVariables = [],\n debounceTime = 500\n) => {\n const initialRender = true;\n useEffect(() => {\n if(initialRender){\n initialRender = false;\n let timer = setTimeout(debounceFunction, debounceTime);\n return () => {\n clearTimeout(timer);\n }; \n }\n }, monitoringVariables);\n};\n\n``` \n \nSee the problem with this solution is every render is an initial render, every time the function runs, the value will be re-initialized.\n\nWe need the initial render value to persist between renders, well, do we have a hook for it? \n\nYou guessed it right, [useState](https://reactjs.org/docs/hooks-state.html).\n\nStoring the flag as a state will do the job, but updating the state will in turn lead to re-renders itself.\n\nThere has to be a neater solution, and there is, something like an instance variable in react.\nQuoting the [react documentation FAQ](https://reactjs.org/docs/hooks-faq.html#is-there-something-like-instance-variables) : \n\n> Is there something like instance variables?\nYes! The useRef() Hook isn’t just for DOM refs. The “ref” object is a generic container whose current property is mutable and can hold any value, similar to an instance property on a class.\n\nThe [useRef](https://reactjs.org/docs/hooks-reference.html#useref) Hook, can actually persist it's value through out the component's lifecycle.\n\nLet's see the solution using useRef:\n\n```\nimport { useEffect, useRef } from \"react\";\n\nexport const useDebounce = (\n debounceFunction,\n monitoringVariables = [],\n debounceTime = 500\n) => {\n const initialRender = useRef(true);\n\n useEffect(() => {\n if (initialRender.current) {\n initialRender.current = false;\n return () => {};\n } else {\n let timer = setTimeout(debounceFunction, debounceTime);\n return () => {\n clearTimeout(timer);\n };\n }\n }, monitoringVariables);\n};\n\n``` \n\nThis solution works elegantly, leaving the final codesandbox for you to try it out.\n\n%[https://codesandbox.io/s/integrating-useref-hthcf?file=/src/custom-hooks.js]\n\n<hr/>\n\n# Conclusion\n\nThis custom useDebounce hook we created today can be used to implement auto save, search suggestions, auto code completion and more. \n\nOn another note, debouncing also makes a really good interview problem for Frontend/Fullstack roles\n\nThank you for reading it this long, and if you liked my efforts, it would mean the world to me if you could share this among your peers. \n\nIf something seems wrong or is not clear, I would love to address doubts in comments! \n\nThanks again! Happy Learning.\n\n![thankyou.gif](https://cdn.hashnode.com/res/hashnode/image/upload/v1631210335788/HGJkEMLaq.gif)\n","hasPolls":false,"totalPollVotes":0,"upvotes":0,"downvotes":0,"tags":["5f8523be6ad92638db4944a9","56744721958ef13879b94cad","56744721958ef13879b948d4","56a399f292921b8f79d3633c","56744721958ef13879b94d0f"],"untaggedFrom":[],"upvotedBy":[],"downvotedBy":[],"popularity":4945.2228,"responses":[],"responseCount":0,"replyCount":0,"followers":[],"isActive":true,"isFeatured":false,"isEngaging":false,"answeredByTarget":false,"inviters":[],"isDelisted":false,"isNotified":false,"duplicatePosts":[],"numCollapsed":0,"hasReward":false,"bookmarkedIn":[],"similarPostIds":[],"reactions":["5d9dd859f31791c942dc5b52","567453d0b73d6a82ac8c5abd","5c090d96c2a9c2a674d35485"],"totalReactions":9,"reactionsByCurrentUser":[],"isPinnedToBlog":true,"disableComments":false,"hasLatex":false,"syncAlgolia":true,"numUniqueUsersWhoReacted":0,"_id":"613ec3b31821961e25521590","title":"How to create a custom debounce react hook using useEffect","subtitle":"Debouncing, its need and creating a custom react hook around it to improve your application's performance","type":"story","ogImage":"https://cdn.hashnode.com/res/hashnode/image/upload/v1631244778915/hbdXXKUR-.png","metaTitle":"Custom debounce react hook using useEffect","metaDescription":"An explanation of debouncing, it's need and creating a custom react hook around it to improve your application's performance","partOfPublication":true,"publication":"613ec61122b7a41dfe5ff33d","slug":"how-to-create-a-custom-debounce-react-hook-using-useeffect","stickCoverToBottom":true,"pollOptions":[],"dateAdded":"2021-09-13T03:21:23.128Z","badges":[],"questionReplies":[],"contributors":[],"cuid":"ckti2xi6t0tbhyds1fmnda1gi","author":"60d8b19ecb0aa8118c23d01c","followersCount":1,"draft":"6137805b83248670799bee50","isRepublished":false,"hasPinnedTag":false,"readTime":9,"__v":0,"nonPublication":true,"series":null,"dateUpdated":"2021-09-23T12:12:39.191Z","pendingPublicationApproval":false,"reactionToCountMap":{"reaction_5d9dd859f31791c942dc5b52":3,"reaction_567453d0b73d6a82ac8c5abd":5,"reaction_5c090d96c2a9c2a674d35485":1},"uniqueReactions":["5d9dd859f31791c942dc5b52","567453d0b73d6a82ac8c5abd","5c090d96c2a9c2a674d35485"],"reactionToCountMapUnique":{"reaction_5d9dd859f31791c942dc5b52":3,"reaction_567453d0b73d6a82ac8c5abd":5,"reaction_5c090d96c2a9c2a674d35485":1,"reaction_5c090d96c2a9c2a674d35484":0},"id":"613ec3b31821961e25521590"}]}