{"id":33132,"date":"2023-04-25T10:42:42","date_gmt":"2023-04-25T17:42:42","guid":{"rendered":"https:\/\/coderpad.io\/?p=33132"},"modified":"2023-06-05T13:19:42","modified_gmt":"2023-06-05T20:19:42","slug":"a-guide-to-using-reacts-usecallback-hook","status":"publish","type":"post","link":"https:\/\/coderpad.io\/blog\/development\/a-guide-to-using-reacts-usecallback-hook\/","title":{"rendered":"A Guide To Using React&#8217;s useCallback() Hook"},"content":{"rendered":"\n<p>Are you looking to optimize your React applications? Have you heard of the useCallback hook? <code>useCallback<\/code> is a powerful React hook that helps you optimize your application by preventing unnecessary re-renders. It can help you increase the performance of your React components, resulting in a better user experience.&nbsp;With <code>useCallback<\/code>, you can improve the performance of your React applications, ensuring users have a smooth and efficient experience.&nbsp;Read on to find out how you can use <code>useCallback<\/code> to get the most out of your React applications.<\/p>\n\n\n\n<p>In this post, we review how to use React&#8217;s <code>useCallback()<\/code> hook. But for you to comfortably follow this guide, we first need to define referential equality and callback functions.<\/p>\n\n\n\n<p><strong>What Is Referential Equality?<\/strong><\/p>\n\n\n\n<p>Referential <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Operators\/Equality\" target=\"_blank\" rel=\"noopener\">equality<\/a> compares two variables pointing to the same object in memory. This is determined using the strict equality <code>===<\/code> operator in JavaScript.<\/p>\n\n\n\n<p>On the other hand, structural equality is the comparison of two objects to see if they have the same value. This means that we consider two objects equal if they have the same properties and values, even if they are stored in different places in memory. This is determined using the loose equality <code>==<\/code> operator.<\/p>\n\n\n\n<p>For example, the following two objects are equal in structure but not in reference:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">const<\/span> person\u00a0= { <span class=\"hljs-attr\">name<\/span>: <span class=\"hljs-string\">\"Doe\"<\/span> };\n\n<span class=\"hljs-keyword\">const<\/span> anotherPerson\u00a0= { <span class=\"hljs-attr\">name<\/span>: <span class=\"hljs-string\">\"Doe\"<\/span> };\n\nperson === anotherPerson; <span class=\"hljs-comment\">\/\/ false<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Structural equality can only be true when both objects have the same content or values. Referential equality is more flexible\u2014it only requires that both variables <a href=\"https:\/\/coderpad.io\/blog\/development\/guide-to-react-router\/\">point<\/a> to the exact memory location, even if they don&#8217;t have all the same content.<\/p>\n\n\n\n<p><strong>What Is a Callback Function in JavaScript?<\/strong><\/p>\n\n\n\n<p>A callback <a href=\"https:\/\/coderpad.io\/blog\/development\/what-you-never-learned-about-javascript-functions\/\">function<\/a> is a function passed as an argument of another function. JavaScript executes the callback after the first JavaScript function executes. For example, let&#8217;s say you have a function that retrieves some data from a remote server. This operation could take some time to complete, and you don&#8217;t want your program to block or freeze while waiting for the data to be returned. Here, you could use a callback function to specify what should happen once you&#8217;ve retrieved the data. The callback function would be executed after the data has been successfully returned, allowing you to handle it and continue with the rest of your program.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">import<\/span> React, { useState, useEffect } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'react'<\/span>;\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">MyComponent<\/span>(<span class=\"hljs-params\">props<\/span>) <\/span>{\n\n\u00a0\u00a0<span class=\"hljs-keyword\">const<\/span> &#91;data, setData] = useState(<span class=\"hljs-literal\">null<\/span>);\n\n\u00a0\u00a0useEffect(<span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-comment\">\/\/ Send a GET request to the server to retrieve the data<\/span>\n\n\u00a0\u00a0\u00a0\u00a0fetch(<span class=\"hljs-string\">'\/api\/data'<\/span>)\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.then(<span class=\"hljs-function\"><span class=\"hljs-params\">response<\/span> =&gt;<\/span> response.json())\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.then(<span class=\"hljs-function\"><span class=\"hljs-params\">data<\/span> =&gt;<\/span> {\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0setData(data);\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-keyword\">if<\/span> (props.onDataLoaded) {\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-comment\">\/\/ Invoke the callback function passed as a prop<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0props.onDataLoaded(data);\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0});\n\n\u00a0\u00a0}, &#91;]);\n\n\u00a0\u00a0<span class=\"hljs-keyword\">return<\/span> (\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{data ? <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span>{data}<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span> : <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span>Loading data...<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>}\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n\n\u00a0\u00a0);\n\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>We often use callback functions to handle asynchronous events. For example, click events. A primary function could pass another function that handles a button click event as an argument. When you click the button, you trigger the callback function, which handles the click event.<\/p>\n\n\n\n<p><strong>What Is a useCallback() Hook?<\/strong><\/p>\n\n\n\n<p>A react <code>useCallback<\/code>&nbsp;hook is a callback that takes the components you want to optimize and a callback variable. JavaScript memoizes the variable for you and creates it on each render to remain the same. This eliminates the need to recalculate values unnecessarily.<\/p>\n\n\n\n<p>The <code>useCallback<\/code> <a href=\"https:\/\/coderpad.io\/blog\/development\/rules-of-react-hooks\/\">hook<\/a> takes two arguments: a memoization function and an array of dependencies. When elements in the dependency array change, the memoized function is recreated.<\/p>\n\n\n\n<p>You can use useCallback to control when things happen. One useful case is preventing idempotent mutations, such as rendering a component more than once in the same request.<\/p>\n\n\n\n<p><strong>How to Use useCallback() Hook<\/strong><\/p>\n\n\n\n<p>You can use the <code>useCallback<\/code> hook to memoize a function so that it is only recreated if one of the dependencies has changed. This is useful if you have a performance-intensive function that you call often. See the example below of how to use the <code>useCallback<\/code> hook with a functional component:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">import<\/span> {useState, useEffect} <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'react'<\/span>\n\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">App<\/span>(<span class=\"hljs-params\"><\/span>)<\/span>{\n    <span class=\"hljs-keyword\">const<\/span> &#91;word,setWord]=useState(<span class=\"hljs-string\">\"doe\"<\/span>)\n    <span class=\"hljs-keyword\">const<\/span> say = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span>=&gt;<\/span><span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">`Your word is: <span class=\"hljs-subst\">${word}<\/span>)\n\n    useEffect(()=&gt;{\n        say()\n    },&#91;say])\n    return &lt;div&gt;Welcome!&lt;\/div&gt;\n}\n<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In this example, the <code>useEffect<\/code> hook takes the <code>say<\/code> function as a dependency. This means that you should only call <a href=\"https:\/\/coderpad.io\/blog\/development\/rules-of-reacts-useeffect\/\">useEffect<\/a> when the function changes. However, since react uses referential equality checks, the <code>say<\/code> function will evaluate to true upon every rerender, even when there&#8217;s no change. As such, the <code>useEffect<\/code> callback gets invoked on every render. This is not optimal for performance, and now we have to find a way to fix this.<\/p>\n\n\n\n<p>One approach is to move the function to the <code>useEffect<\/code> block. This would solve the problem, but it&#8217;s not optimal because you couldn\u2019t use that function anywhere else.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">import<\/span> {useState, useEffect}<span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'react'<\/span>\u00a0\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">App<\/span>(<span class=\"hljs-params\">{\n\n    const &#91;word,setWord]=useState(<span class=\"hljs-string\">\"doe\"<\/span><\/span>)\n\n    <span class=\"hljs-title\">const<\/span> <span class=\"hljs-title\">say<\/span> = (<span class=\"hljs-params\"><\/span>)=&gt; <span class=\"hljs-title\">console<\/span>.<span class=\"hljs-title\">log<\/span>(<span class=\"hljs-params\"><span class=\"hljs-string\">`Your word is: <span class=\"hljs-subst\">${word}<\/span>`<\/span><\/span>)\n    <span class=\"hljs-title\">useEffect<\/span>(<span class=\"hljs-params\">(<\/span>)=&gt;<\/span>{ say() },\n        &#91;say]\n    ) \n    <span class=\"hljs-keyword\">return<\/span> <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span>Welcome!<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span> \n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>The other option is to use the <code>useCallback<\/code> hook. To do this, wrap it around your <code>say<\/code> function. You should note that the <code>useCallback<\/code> function, like <code>useEffect<\/code>, takes a dependency as a second value. If your function accepts variables, you&#8217;ll pass them in the array; otherwise, you can leave it blank. For our case, since the function depends on the word, we&#8217;ll pass it.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"SAS\" data-shcb-language-slug=\"sas\"><span><code class=\"hljs language-sas shcb-wrap-lines\">import {useState, useEffect,useCallback} <span class=\"hljs-meta\">from<\/span> <span class=\"hljs-string\">'react'<\/span>\n\nfunction App(){\n\n   \u00a0const &#91;word,setWord]=useState(<span class=\"hljs-string\">\"doe\"<\/span>)\n\n    const say = useCallback(()=&gt;console<span class=\"hljs-meta\">.log(<\/span>`Your word is: ${word}`),&#91;word])\n\n    useEffect(()=&gt;{\n\n   \u00a0    say()\u00a0\n\n   \u00a0},&#91;say])\u00a0\n\n    <span class=\"hljs-meta\">return<\/span> &lt;div&gt;Welcome!&lt;\/div&gt; \n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">SAS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">sas<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p><strong>Best Practices to Follow When Using useCallback() Hook<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Only use <code>useCallback<\/code> when you actually need to memoize a function. Memoization can improve the performance of your application, but it comes at a cost in terms of added complexity and potential bugs. So, only use <code>useCallback<\/code> if you have a specific need for it.<\/li>\n\n\n\n<li>Pass a callback to useCallback as a reference, rather than defining it inline. This allows <code>useCallback<\/code> to track the dependencies of the callback and determine when it needs to be recreated.<\/li>\n\n\n\n<li>Be aware of your callback&#8217;s dependencies. When you pass a callback to <code>useCallback<\/code>, you also need to pass a list of its dependencies as the second argument. Ensure this list is accurate and up-to-date so that the callback is only recreated when necessary.<\/li>\n\n\n\n<li>Avoid passing expensive functions to <code>useCallback<\/code>. Because <code>useCallback<\/code> will only recreate the function when one of its dependencies has changed, it&#8217;s important to avoid passing expensive functions that may need to execute frequently. This can cause performance issues, as the function must be recreated and re-executed on every render.<\/li>\n<\/ol>\n\n\n\n<p><strong>When Should You Avoid Using useCallback() Hook?<\/strong><\/p>\n\n\n\n<p>You should not use the <code>useCallback<\/code> hook if you have no dependencies in your callback function. For example, if you have a callback function that only uses a prop from the parent component, you don&#8217;t need to use it.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">const<\/span> MyComponent = <span class=\"hljs-function\"><span class=\"hljs-params\">props<\/span> =&gt;<\/span> {\n\n\u00a0\u00a0  <span class=\"hljs-keyword\">const<\/span> handleClick = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n\n\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-comment\">\/\/ write handleclick logic\u00a0 <\/span>\n    };\n\n  \u00a0\u00a0<span class=\"hljs-keyword\">return<\/span> (\n\n\u00a0\u00a0  \u00a0\u00a0  <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Button<\/span> <span class=\"hljs-attr\">onClick<\/span>=<span class=\"hljs-string\">{handleClick}<\/span> \/&gt;<\/span>\n\n    \u00a0\u00a0\u00a0\u00a0<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n\n\u00a0\u00a0);\n\n};<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In the above example, the <code>handleClick<\/code> function only uses handle click logic, which is passed in from the parent component. Since there are no dependencies in the <code>handleClick<\/code> function, you don&#8217;t need to use the <code>useCallback<\/code> hook.<\/p>\n\n\n\n<p><strong>React&#8217;s useCallback() Hook: Final Thoughts<\/strong><\/p>\n\n\n\n<p>This guide showed you how to use React useCallback to improve performance and avoid re-rendering issues. UseCallback allows you to memoize functions that are only recreated if one dependency or state has changed. This can be a useful optimization technique, particularly when working with expensive functions. However, only use it when necessary, and be aware that useCallback will prevent your function from garbage collection if the function is not being used. useCallback is a powerful tool that can improve performance in React applications but it should be used judiciously.<\/p>\n\n\n\n<p><em>This post was written by Mercy Kibet. <\/em><a href=\"https:\/\/hashnode.com\/@eiMJay\" target=\"_blank\" rel=\"noopener\"><em>Mercy<\/em><\/a><em> is a full-stack developer with a knack for learning and writing about new and intriguing tech stacks.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Are you looking to optimize your React applications? Have you heard of the useCallback hook? useCallback is a powerful React hook that helps you optimize your application by preventing unnecessary re-renders. In this post, we&#8217;ll dive into React&#8217;s useCallback() hook, define referential equality and callback functions and how to tie it all together.<\/p>\n","protected":false},"author":1,"featured_media":33166,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[9],"tags":[],"persona":[29],"blog-programming-language":[61],"keyword-cluster":[],"class_list":["post-33132","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-development"],"acf":[],"_links":{"self":[{"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/posts\/33132","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/comments?post=33132"}],"version-history":[{"count":38,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/posts\/33132\/revisions"}],"predecessor-version":[{"id":33516,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/posts\/33132\/revisions\/33516"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/media\/33166"}],"wp:attachment":[{"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/media?parent=33132"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/categories?post=33132"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/tags?post=33132"},{"taxonomy":"persona","embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/persona?post=33132"},{"taxonomy":"blog-programming-language","embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/blog-programming-language?post=33132"},{"taxonomy":"keyword-cluster","embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/keyword-cluster?post=33132"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}