<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Keyur Paralkar - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Keyur Paralkar - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Fri, 15 May 2026 22:29:33 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/author/keyurparalkar/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Boost Web Performance with Prefetching – Improve User Experience by Reducing Load Time ]]>
                </title>
                <description>
                    <![CDATA[ We've all encountered the frustration of waiting through long loading screens, only to find ourselves stuck with unresponsive pages. You see loading spinners everywhere, but nothing seems to move forward. Let me paint a clearer picture for you: This... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/boost-web-performance-with-prefetching/</link>
                <guid isPermaLink="false">66f18dbb04f1822b270db01b</guid>
                
                    <category>
                        <![CDATA[ web performance ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Keyur Paralkar ]]>
                </dc:creator>
                <pubDate>Mon, 23 Sep 2024 15:48:11 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/-Vqn2WrfxTQ/upload/0657c02758973f4ea5701f2bd98469a7.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>We've all encountered the frustration of waiting through long loading screens, only to find ourselves stuck with unresponsive pages. You see loading spinners everywhere, but nothing seems to move forward. Let me paint a clearer picture for you:</p>
<p><a target="_blank" href="https://dribbble.com/shots/3358709-Skeleton-Loader#"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726397417280/bc56c517-c63f-433e-93c6-939c3b82c556.gif" alt="Multiple skeleton loader on a dashboard page" class="image--center mx-auto" width="600" height="400" loading="lazy"></a></p>
<p>This typically happens because the website is trying to fetch all the necessary data as soon as you land on the page. It could be that a API request is being processed, or multiple APIs are fetching data sequentially, causing delays in loading the page.</p>
<p>The result? A poor user experience. You might think, "How can such a large company not prioritize user experience? This is disappointing." Consequently, users often leave the site, affecting key metrics and potentially impacting revenue.</p>
<p>But what if you could fetch the data for these heavy pages ahead of time, so that by the time a user lands on the page, they can interact with it instantly?</p>
<p>This is where the concept of prefetching comes in, and that's exactly what we'll be diving into in this blog post. So without further ado, let's get started!</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-prefetching-as-a-solution">Prefetching as a Solution</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-prefetching-improves-user-experience">How Prefetching Improves User Experience</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-understanding-the-problem">Understanding The Problem</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-solution-1-prefetching-data-in-the-parent-component">Solution #1: Prefetching Data in the Parent Component</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-solution-2-prefetch-data-on-page-load">Solution #2: Prefetch Data on Page load</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-implement-prefetching-with-react">How to Implement Prefetching with React</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-implement-prefetching-with-react">Too much prefetching can also cause</a> <a class="post-section-overview" href="#heading-too-much-prefetching-can-also-cause-slowness">s</a><a class="post-section-overview" href="#heading-how-to-implement-prefetching-with-react">lowness</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-summary">Summary</a></p>
</li>
</ul>
<h2 id="heading-prefetching-as-a-solution">Prefetching as a Solution</h2>
<p>Here’s the revised version with just the grammar and spelling corrected:</p>
<p>For the problem above, what we want is to fetch the data for a given page before it's loaded onto the website so that the user doesn’t need to fetch the data on page load. This is called prefetching. From a technical perspective, its definition is as follows:</p>
<blockquote>
<p><em>It is a way to fetch the required data beforehand so that the main component doesn’t need to wait for the data, thus enhancing the experience.</em></p>
</blockquote>
<p>This can improve the user experience, boosting the customer’s confidence in your website.</p>
<p>Prefetching is a simple yet elegant solution that is more user-centric than a standard process. To implement prefetching, we need to understand the user’s behavior on the website. That is, the most visited pages, or which components fetch data on small interactions (such as hover).</p>
<p>After analyzing such scenarios, it makes sense to apply prefetching to them. However, as developers, we should be mindful of using this concept. Too much prefetching can also slow down your website since you're trying to fetch a lot of data for future scenarios, which might block the fetching of data for the main page.</p>
<h2 id="heading-how-prefetching-improves-user-experience">How Prefetching Improves User Experience</h2>
<p>Let us look at couple of scenarios where prefetching is beneficial:</p>
<ol>
<li><p>Loading data/page earlier for the most visited link from your landing page. For example, consider that you have a “contact us” link. Let’s assume that this is the link that users mostly check and it contains a lot of data when it loads. Rather than loading the data when the contact us page loads, you can simply fetch the data on the homepage so that you don’t have to wait at the Contact Us page for the data. You can read more about prefetching pages <a target="_blank" href="https://web.dev/articles/link-prefetch">here</a>.</p>
</li>
<li><p>Prefetching table data for later pages.</p>
</li>
<li><p>Fetching data from a parent component and loading it in the child component.</p>
</li>
<li><p>Prefetching data that needs to be displayed in a popover.</p>
</li>
</ol>
<p>These are some of the ways to achieve prefetching in your application and how it helps improve the user experience.</p>
<p>In this blog post we will be discussing about the last scenario: <em>“</em>prefetching data that needs to be displayed in the popover”. This is a classic example where prefetching can be beneficial and provides a smoother experience to the user.</p>
<h2 id="heading-understanding-the-problem">Understanding The Problem</h2>
<p>Let me define the problem here. Imagine the following scenario:</p>
<ol>
<li><p>You have a component that displays specific information.</p>
</li>
<li><p>There is an element inside this component that shows another popover/tooltip when you hover on it.</p>
</li>
<li><p>The popover fetches data when it loads.</p>
</li>
</ol>
<p>Now imagine that the user hovers on the element and needs to wait for the data to be fetched and displayed in the popover. During this wait, they see the skeleton loader.</p>
<p>The scenario will look like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726395720567/6ec88fab-ffe2-4f20-b934-94342f9cf3c0.gif" alt="Example of fetching data when the popover component mounts" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>It’s just frustrating how long the user has to wait whenever they hover on the image:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726395733461/3598da70-e8af-4a1a-b3cf-5c3ed62fe9cc.gif" alt="User hovering images to load popover component that fetches data" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>To solve this problem, there are two solutions that can help you get started and optimize the solution according to your needs.</p>
<h2 id="heading-solution-1-prefetching-data-in-the-parent-component">Solution #1: Prefetching Data in the Parent Component</h2>
<p>This solution is inspired from <a target="_blank" href="https://martinfowler.com/articles/data-fetch-spa.html?utm_source=cassidoo&amp;utm_medium=email&amp;utm_campaign=until-youre-ready-to-look-foolish-youll-never#prefetching">Martin Fowler’s blogpost</a>. It allows you to fetch the data before the popup appears, instead of fetching on component load.</p>
<p>The popup appears when you hover on it. We can fetch the data when the mouse enters the parent component. Before the actual component—the image—is hovered on, we’ll have the data for the popover and will pass it to the popover component.</p>
<p>This solution doesn’t remove the loading state all together but it helps to significantly lower the chances of seeing the loading state.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726395771616/69b6c536-8b62-4124-837a-f26746f6f305.gif" alt="Improving the UX by fetching the data from the parent component" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h2 id="heading-solution-2-prefetch-data-on-page-load">Solution #2: Prefetch Data on Page load</h2>
<p>This solution is inspired by <a target="_blank" href="http://x.com">x.com</a> where, for the popover component, they fetch the data partially on the main page load and fetch the rest of the data when the component mounts.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726395833198/c7f1fa64-986d-4bfc-83cb-f052cd560f3a.gif" alt="Twitter advertisement by XDevelopers. Text reads: &quot;Calling all #developers! Innovate with our real-time and historical data on the X API. Get started with Pro👇&quot;. Image shows a person in a white shirt with text &quot;Build what's next with our API @XDevelopers&quot; and &quot;Subscribe now!&quot; Used by permission. From twitter.com." class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>As you can see from the above video, the user’s profile details are viewed in the popover. If you look closely, the details related to followers are fetched later.</p>
<p>This technique is highly efficient when you have a lot of data to be displayed in the popover but fetching them can be costly on popover mount or on the main page load.</p>
<p>A better solution would be to partially load the required data on the main page and load the rest of the data when the component mounts.</p>
<p>In our example, we fetched the data for the popover when the cursor entered the image’s parent element. Now imagine that you need to fetch additional details once the popover data is loaded. So based on the above x.com’s method, we can fetch additional data on popover load. Here is the outcome of it:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726395913909/b5f6f231-5a1e-4c44-a4eb-bd5ed863ce3b.gif" alt="GIF explaining how we prefetch data from parent and load additional data on component mount for popover " class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Here, we do the following things:</p>
<ul>
<li><p>We fetch the main data which is just necessary to render the popover when mouse enters the parent component of the image.</p>
</li>
<li><p>This gives us enough time to fetch the main data.</p>
</li>
<li><p>On popover load, we fetch another data, which is the album count. While the user reads data like name and email, we’ll have the next data ready to be seen.</p>
</li>
</ul>
<p>This way, we can make small and smart tweaks to minimize the blank staring of loaders on the screen 😊.</p>
<h2 id="heading-how-to-implement-prefetching-with-react">How to Implement Prefetching with React</h2>
<p>In this section we’ll briefly go through the how to implement the above prefetching example app.</p>
<h3 id="heading-project-setup">Project Setup</h3>
<p>To get started with creating the prefetching app, follow the process below:</p>
<p>You can use <a target="_blank" href="https://vitejs.dev/">vitejs</a> (this is what I used) or <a target="_blank" href="https://create-react-app.dev/">create-react-app</a> to create your app. Paste the command below in your terminal:</p>
<pre><code class="lang-bash">yarn create vite prefetch-example --template react-ts
</code></pre>
<p>Once the app has been created, you should have the following folder structure when you open the <strong>prefetch-example</strong> folder with VS Code.</p>
<ul>
<li><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726764168271/2dc9bfa1-07d9-491e-96fd-e780c3623eeb.png" alt="Image of the folder structure once the vitejs app is created" class="image--center mx-auto" width="600" height="400" loading="lazy"></li>
</ul>
<p>Now let us dive into the components that we are going to be building for this app.</p>
<h3 id="heading-components">Components</h3>
<p>In this example we are going to be using 3 components:</p>
<ul>
<li><p><code>PopoverExample</code></p>
</li>
<li><p><code>UserProfile</code></p>
</li>
<li><p><code>UserProfileWithFetching</code></p>
</li>
</ul>
<h3 id="heading-popoverexample-component"><code>PopoverExample</code> Component</h3>
<p>Let us start with the first component which is the <code>PopoverExample</code>. This component displays an image avatar and some text to the right side of it. It should look like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727002319443/bcc28972-fce0-42ba-899c-274513c4a7c6.png" alt="Image of the PopoverExample component that contains image to the left and lorem ipsum text to the right" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>The purpose of this component is to serve as an example similar to the real life scenarios. The image in this component loads a popover component when it is hovered on.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727002429245/9af8f26e-f149-41f7-b124-3ec2a0f5c80a.png" alt="Image of popover element that contains user information when the image is hovered" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Here’s the code for the component:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { useFloating, useHover, useInteractions } <span class="hljs-keyword">from</span> <span class="hljs-string">"@floating-ui/react"</span>;
<span class="hljs-keyword">import</span> ContentLoader <span class="hljs-keyword">from</span> <span class="hljs-string">"react-content-loader"</span>;
<span class="hljs-keyword">import</span> UserProfile <span class="hljs-keyword">from</span> <span class="hljs-string">"./UserProfile"</span>;
<span class="hljs-keyword">import</span> UserProfileWithFetching <span class="hljs-keyword">from</span> <span class="hljs-string">"./UserProfileWithFetching"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> MyLoader = <span class="hljs-function">() =&gt;</span> (
    &lt;ContentLoader
        speed={<span class="hljs-number">2</span>}
        width={<span class="hljs-number">340</span>}
        height={<span class="hljs-number">84</span>}
        viewBox=<span class="hljs-string">"0 0 340 84"</span>
        backgroundColor=<span class="hljs-string">"#d1d1d1"</span>
        foregroundColor=<span class="hljs-string">"#fafafa"</span>
    &gt;
        &lt;rect x=<span class="hljs-string">"0"</span> y=<span class="hljs-string">"0"</span> rx=<span class="hljs-string">"3"</span> ry=<span class="hljs-string">"3"</span> width=<span class="hljs-string">"67"</span> height=<span class="hljs-string">"11"</span> /&gt;
        &lt;rect x=<span class="hljs-string">"76"</span> y=<span class="hljs-string">"0"</span> rx=<span class="hljs-string">"3"</span> ry=<span class="hljs-string">"3"</span> width=<span class="hljs-string">"140"</span> height=<span class="hljs-string">"11"</span> /&gt;
        &lt;rect x=<span class="hljs-string">"127"</span> y=<span class="hljs-string">"48"</span> rx=<span class="hljs-string">"3"</span> ry=<span class="hljs-string">"3"</span> width=<span class="hljs-string">"53"</span> height=<span class="hljs-string">"11"</span> /&gt;
        &lt;rect x=<span class="hljs-string">"187"</span> y=<span class="hljs-string">"48"</span> rx=<span class="hljs-string">"3"</span> ry=<span class="hljs-string">"3"</span> width=<span class="hljs-string">"72"</span> height=<span class="hljs-string">"11"</span> /&gt;
        &lt;rect x=<span class="hljs-string">"18"</span> y=<span class="hljs-string">"48"</span> rx=<span class="hljs-string">"3"</span> ry=<span class="hljs-string">"3"</span> width=<span class="hljs-string">"100"</span> height=<span class="hljs-string">"11"</span> /&gt;
        &lt;rect x=<span class="hljs-string">"0"</span> y=<span class="hljs-string">"71"</span> rx=<span class="hljs-string">"3"</span> ry=<span class="hljs-string">"3"</span> width=<span class="hljs-string">"37"</span> height=<span class="hljs-string">"11"</span> /&gt;
        &lt;rect x=<span class="hljs-string">"18"</span> y=<span class="hljs-string">"23"</span> rx=<span class="hljs-string">"3"</span> ry=<span class="hljs-string">"3"</span> width=<span class="hljs-string">"140"</span> height=<span class="hljs-string">"11"</span> /&gt;
        &lt;rect x=<span class="hljs-string">"166"</span> y=<span class="hljs-string">"23"</span> rx=<span class="hljs-string">"3"</span> ry=<span class="hljs-string">"3"</span> width=<span class="hljs-string">"173"</span> height=<span class="hljs-string">"11"</span> /&gt;
    &lt;/ContentLoader&gt;
);
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">PopoverExample</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">const</span> [isOpen, setIsOpen] = useState(<span class="hljs-literal">false</span>);
    <span class="hljs-keyword">const</span> [isLoading, setIsLoading] = useState(<span class="hljs-literal">false</span>);
    <span class="hljs-keyword">const</span> [data, setData] = useState({});

    <span class="hljs-keyword">const</span> { refs, floatingStyles, context } = useFloating({
        open: isOpen,
        onOpenChange: setIsOpen,
        placement: <span class="hljs-string">"top"</span>,
    });

    <span class="hljs-keyword">const</span> hover = useHover(context);

    <span class="hljs-keyword">const</span> { getReferenceProps, getFloatingProps } = useInteractions([hover]);

    <span class="hljs-keyword">const</span> handleMouseEnter = <span class="hljs-function">() =&gt;</span> {
        <span class="hljs-keyword">if</span> (<span class="hljs-built_in">Object</span>.keys(data).length === <span class="hljs-number">0</span>) {
            setIsLoading(<span class="hljs-literal">true</span>);
            fetch(<span class="hljs-string">"https://jsonplaceholder.typicode.com/users/1"</span>)
                .then(<span class="hljs-function">(<span class="hljs-params">resp</span>) =&gt;</span> resp.json())
                .then(<span class="hljs-function">(<span class="hljs-params">data</span>) =&gt;</span> {
                    setData(data);
                    setIsLoading(<span class="hljs-literal">false</span>);
                });
        }
    };

    <span class="hljs-keyword">return</span> (
        &lt;div
            id=<span class="hljs-string">"hover-example"</span>
            style={{
                display: <span class="hljs-string">"flex"</span>,
                flexDirection: <span class="hljs-string">"row"</span>,
                alignItems: <span class="hljs-string">"center"</span>,
                textAlign: <span class="hljs-string">"left"</span>,
            }}
            onMouseEnter={handleMouseEnter}
        &gt;
            &lt;span
                style={{
                    padding: <span class="hljs-string">"1rem"</span>,
                }}
            &gt;
                &lt;img
                    ref={refs.setReference}
                    {...getReferenceProps()}
                    style={{
                        borderRadius: <span class="hljs-string">"50%"</span>,
                    }}
                    src=<span class="hljs-string">"https://cdn.jsdelivr.net/gh/alohe/avatars/png/vibrent_5.png"</span>
                /&gt;
            &lt;/span&gt;
            &lt;p&gt;
                Lorem Ipsum is simply dummy text <span class="hljs-keyword">of</span> the printing and typesetting
                industry. Lorem Ipsum has been the industry<span class="hljs-string">'s standard dummy text ever
                since the 1500s, when an unknown printer took a galley of type and
                scrambled it to make a type specimen book. It has survived not only five
                centuries, but also the leap into electronic typesetting, remaining
                essentially unchanged. It was popularised in the 1960s with the release
                of Letraset sheets containing Lorem Ipsum passages, and more recently
                with desktop publishing software like Aldus PageMaker including versions
                of Lorem Ipsum.
            &lt;/p&gt;
            {isOpen &amp;&amp; (
                &lt;div
                    className="floating"
                    ref={refs.setFloating}
                    style={{
                        ...floatingStyles,
                        backgroundColor: "white",
                        color: "black",
                        padding: "1rem",
                        fontSize: "1rem",
                    }}
                    {...getFloatingProps()}
                &gt;
                    {isLoading ? (
                        &lt;MyLoader /&gt;
                    ) : (
                        &lt;UserProfile hasAdditionalDetails {...data} /&gt;
                    )}
                    {/* &lt;UserProfileWithFetching /&gt; */}
                &lt;/div&gt;
            )}
        &lt;/div&gt;
    );
}</span>
</code></pre>
<p>There are couple of things happening here, let me explain them step-by-step:</p>
<ul>
<li><p>We have a parent <code>div</code> named <code>hover-example</code> that contains an image and some text.</p>
</li>
<li><p>Next, we conditionally rendered a <code>div</code> with class name of <code>floating</code>. This is the actual popover component that opens when you hover on the image.</p>
<ul>
<li>We made use of the <a target="_blank" href="https://floating-ui.com/"><code>floating-ui</code> library</a> and its <a target="_blank" href="https://floating-ui.com/docs/useHover">basic hover example</a> to achieve the hover effect for the popover.</li>
</ul>
</li>
<li><p>Inside the popover we conditionally loaded the <code>UserProfile</code> and the skeleton loader. This loader appears when we are fetching the data for the user’s profile. More on this later.</p>
</li>
<li><p>We made use of the <a target="_blank" href="https://github.com/danilowoz/react-content-loader">react-content-loader</a> library in the <code>MyLoader</code> component. This library also has a website that helps you to create loaders, you can check it out <a target="_blank" href="https://skeletonreact.com/">here</a>.</p>
</li>
</ul>
<h3 id="heading-userprofile-component"><code>UserProfile</code> Component</h3>
<p>Now that we have defined our <code>Popover</code> example, it is time for us to get into the details of the <code>UserProfile</code> component.</p>
<p>This component appears inside the popover component. The purpose of this component is to load the <code>name</code> <code>email</code> <code>phone</code> <code>website</code> details which are fetched from <a target="_blank" href="https://jsonplaceholder.typicode.com/users/1">JSON placeholder API</a>.</p>
<p>To demonstrate the prefetching example, we have to make sure that the <code>UserProfile</code> component only acts as a presentational component; that is, no explicit fetching logic is present inside of it.</p>
<p>The key thing to note about this component is that fetching the data happens from the parent component which is the <code>PopoverExample</code> component. In this component, we start fetching the data when the mouse enters this component (the <code>mouseenter</code> event). This is the solution #1 we discussed previously.</p>
<p>This gives you enough time for fetching the data until the user hovers on the image. Here’s the code:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { useEffect, useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> ContentLoader <span class="hljs-keyword">from</span> <span class="hljs-string">"react-content-loader"</span>;

<span class="hljs-keyword">const</span> MyLoader = <span class="hljs-function">() =&gt;</span> (
    &lt;ContentLoader
        speed={<span class="hljs-number">2</span>}
        viewBox=<span class="hljs-string">"0 0 476 124"</span>
        backgroundColor=<span class="hljs-string">"#d1d1d1"</span>
        foregroundColor=<span class="hljs-string">"#fafafa"</span>
    &gt;
        &lt;rect x=<span class="hljs-string">"4"</span> y=<span class="hljs-string">"43"</span> rx=<span class="hljs-string">"0"</span> ry=<span class="hljs-string">"0"</span> width=<span class="hljs-string">"98"</span> height=<span class="hljs-string">"30"</span> /&gt;
    &lt;/ContentLoader&gt;
);

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">UserProfile</span>(<span class="hljs-params">props: Record&lt;<span class="hljs-built_in">string</span>, <span class="hljs-built_in">string</span> | <span class="hljs-built_in">boolean</span>&gt;</span>) </span>{
    <span class="hljs-keyword">const</span> { name, email, phone, website, hasAdditionalDetails } = props;
    <span class="hljs-keyword">const</span> [isLoading, setIsLoading] = useState(<span class="hljs-literal">false</span>);
    <span class="hljs-keyword">const</span> [additionalData, setAdditionalData] = useState(<span class="hljs-number">0</span>);

    useEffect(<span class="hljs-function">() =&gt;</span> {
        <span class="hljs-keyword">if</span> (hasAdditionalDetails) {
            setIsLoading(<span class="hljs-literal">true</span>);
            fetch(<span class="hljs-string">"https://jsonplaceholder.typicode.com/albums"</span>)
                .then(<span class="hljs-function">(<span class="hljs-params">resp</span>) =&gt;</span> resp.json())
                .then(<span class="hljs-function">(<span class="hljs-params">data: <span class="hljs-built_in">Array</span>&lt;unknown&gt;</span>) =&gt;</span> {
                    <span class="hljs-keyword">const</span> albumCount = data.reduce(<span class="hljs-function">(<span class="hljs-params">acc, curr</span>) =&gt;</span> {
                        <span class="hljs-keyword">if</span> (curr.userId === <span class="hljs-number">1</span>) acc += <span class="hljs-number">1</span>;

                        <span class="hljs-keyword">return</span> acc;
                    }, <span class="hljs-number">0</span>);
                    setAdditionalData(albumCount);
                })
                .finally(<span class="hljs-function">() =&gt;</span> {
                    setIsLoading(<span class="hljs-literal">false</span>);
                });
        }
    }, [hasAdditionalDetails]);

    <span class="hljs-keyword">return</span> (
        &lt;div id=<span class="hljs-string">"user-profile"</span>&gt;
            &lt;div id=<span class="hljs-string">"user-name"</span>&gt;name: {name}&lt;/div&gt;
            &lt;div id=<span class="hljs-string">"user-email"</span>&gt;email: {email}&lt;/div&gt;
            &lt;div id=<span class="hljs-string">"user-phone"</span>&gt;phone: {phone}&lt;/div&gt;
            &lt;div id=<span class="hljs-string">"user-website"</span>&gt;website: {website}&lt;/div&gt;
            {hasAdditionalDetails &amp;&amp; (
                &lt;&gt;
                    {isLoading ? (
                        &lt;MyLoader /&gt;
                    ) : (
                        &lt;div id=<span class="hljs-string">"user-albums"</span>&gt;Album Count: {additionalData}&lt;/div&gt;
                    )}
                &lt;/&gt;
            )}
        &lt;/div&gt;
    );
}
</code></pre>
<p>This component makes use of the <code>hasAdditionalDetails</code> prop. The purpose of this <code>prop</code> is to load additional data when the component mounts. It illustrates the solution #2 mentioned above.</p>
<h3 id="heading-userprofilewithfetching-component"><code>UserProfileWithFetching</code> Component</h3>
<p>This component is pretty similar to that of the <code>UserProfile</code> component. It just contains the logic for fetching data when the component loads. The purpose of this component is to show what the general solution without the prefetching technique would look like.</p>
<p>So this component will always load the data when the component mounts, which displays the skeleton loader.</p>
<p>Here is the code:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { useEffect, useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { MyLoader } <span class="hljs-keyword">from</span> <span class="hljs-string">"./PopoverExample"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">UserProfileWithFetching</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">const</span> [isLoading, setIsLoading] = useState(<span class="hljs-literal">false</span>);
    <span class="hljs-keyword">const</span> [data, setData] = useState&lt;Record&lt;<span class="hljs-built_in">string</span>, <span class="hljs-built_in">string</span>&gt;&gt;({});

    useEffect(<span class="hljs-function">() =&gt;</span> {
        setIsLoading(<span class="hljs-literal">true</span>);
        fetch(<span class="hljs-string">"https://jsonplaceholder.typicode.com/users/1"</span>)
            .then(<span class="hljs-function">(<span class="hljs-params">resp</span>) =&gt;</span> resp.json())
            .then(<span class="hljs-function">(<span class="hljs-params">data</span>) =&gt;</span> {
                setData(data);
                setIsLoading(<span class="hljs-literal">false</span>);
            });
    }, []);

    <span class="hljs-keyword">if</span> (isLoading) <span class="hljs-keyword">return</span> &lt;MyLoader /&gt;;

    <span class="hljs-keyword">return</span> (
        &lt;div id=<span class="hljs-string">"user-profile"</span>&gt;
            &lt;div id=<span class="hljs-string">"user-name"</span>&gt;name: {data.name}&lt;/div&gt;
            &lt;div id=<span class="hljs-string">"user-email"</span>&gt;email: {data.email}&lt;/div&gt;
            &lt;div id=<span class="hljs-string">"user-phone"</span>&gt;phone: {data.phone}&lt;/div&gt;
            &lt;div id=<span class="hljs-string">"user-website"</span>&gt;website: {data.website}&lt;/div&gt;
        &lt;/div&gt;
    );
}
</code></pre>
<p>The entire code for this app can be found <a target="_blank" href="https://github.com/keyurparalkar/prefetch-examples">here</a>.</p>
<h2 id="heading-too-much-prefetching-can-also-cause-slowness">Too much prefetching can also cause slowness</h2>
<p>A word of advice, too much prefetching is not good because:</p>
<ul>
<li><p>It might slow your app down.</p>
</li>
<li><p>It can degrade user experience if prefetching is not applied strategically.</p>
</li>
</ul>
<p>Prefetching needs to be applied when you know the behavior of the user. That is, you are able to predict the user movement by metrics and be able to tell if they visit a page often. In that case, prefetching is a good idea.</p>
<p>So remember to always apply prefetching strategically.</p>
<h2 id="heading-summary">Summary</h2>
<p>That’s all folks! Hope you like my blog post. In this blogpost, you learned that implementing prefetching can significantly enhance your web application’s speed and responsiveness, improving user satisfaction.</p>
<p>For further reading, please refer to the below articles:</p>
<ul>
<li><p><a target="_blank" href="https://www.patterns.dev/vanilla/prefetch/">Prefetching pages</a></p>
</li>
<li><p><a target="_blank" href="https://medium.com/reloading/preload-prefetch-and-priorities-in-chrome-776165961bbf">Preload, Prefetch And Priorities in Chrome</a></p>
</li>
<li><p><a target="_blank" href="https://addyosmani.com/blog/what-not-to-prefetch-prerender/">What not to prefetch</a></p>
</li>
</ul>
<p>For more content, you can follow me on <a target="_blank" href="https://twitter.com/keurplkar">Twitter</a>, <a target="_blank" href="http://github.com/keyurparalkar">GitHub</a>, and <a target="_blank" href="https://www.linkedin.com/in/keyur-paralkar-494415107/">LinkedIn</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Improve Your JavaScript Code with Powerful Build Tool Configs ]]>
                </title>
                <description>
                    <![CDATA[ I have been a frontend developer for over 6 years now, mostly working with Javascript, TypeScript, and React. When stepping into the world of the front end, the number of libraries and build tools available can be overwhelming – especially since each... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/improve-your-javascript-projects-with-build-tools/</link>
                <guid isPermaLink="false">66bb55462e21ea7332ef3762</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Keyur Paralkar ]]>
                </dc:creator>
                <pubDate>Tue, 02 Jul 2024 15:56:38 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/07/aaron-burden-4eWwSxaDhe4-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>I have been a frontend developer for over 6 years now, mostly working with Javascript, TypeScript, and React. When stepping into the world of the front end, the number of libraries and build tools available can be overwhelming – especially since each has its own configuration options.</p>
<p>At first these configuration choices might look like some sort of magic. But once you start to understand their purpose, it becomes clear that these configurations make sense.</p>
<p>Tools such as ESLint, Prettier, Git hooks, and others can help you maintain your code efficiently and judiciously. In this article, we will be diving into these tools that make your code maintainable and that can help you to boost your (and your team's) productivity as well.</p>
<p>So without further ado, let’s get started.</p>
<h2 id="heading-table-of-contents">Table of Contents:</h2>
<ul>
<li><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></li>
<li><a class="post-section-overview" href="#heading-what-tools-and-configs-are-we-looking-at">What Tools and Configs Are We Looking At?</a></li>
<li><a class="post-section-overview" href="#heading-why-these-conventions-are-useful">Why These Conventions Are Useful</a></li>
<li><a class="post-section-overview" href="#heading-how-to-setup-coding-conventions">How to Setup Coding Conventions</a></li>
<li><a class="post-section-overview" href="#heading-what-is-eslint">What is ESLint?</a></li>
<li><a class="post-section-overview" href="#heading-what-are-git-hooks">What are Git Hooks?</a></li>
<li><a class="post-section-overview" href="#heading-set-up-the-project">Set Up the Project</a></li>
<li><a class="post-section-overview" href="#heading-rule-1-no-unused-vars">Rule #1: <code>no-unused-vars</code></a></li>
<li><a class="post-section-overview" href="#heading-rule-2-no-console">Rule #2: <code>no-console</code></a></li>
<li><a class="post-section-overview" href="#heading-rule-3-no-duplicate-imports-and-sorting-imports">Rule #3: <code>no-duplicate-imports</code> and Sorting Imports</a></li>
<li><a class="post-section-overview" href="#heading-how-to-set-up-git-hooks">How to Set Up Git Hooks</a></li>
<li><a class="post-section-overview" href="#heading-gitleaks-remove-secrets-before-commits">Gitleaks: Remove Secrets Before Commits</a></li>
<li><a class="post-section-overview" href="#heading-run-unit-tests-before-commits">Run Unit Tests Before Commits</a></li>
<li><a class="post-section-overview" href="#heading-summary">Summary</a></li>
</ul>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Having some knowledge on the below topics might help you gain insights from this article. So I highly recommend that you go through the below resources (or make sure you're familiar with the tools/concepts listed):</p>
<ul>
<li>Basics of <a target="_blank" href="https://eslint.org/docs/latest/use/core-concepts/">ESLint</a></li>
<li>Setting up a simple JS project with <a target="_blank" href="https://docs.npmjs.com/cli/v10/commands/npm-init">npm</a> or <a target="_blank" href="https://classic.yarnpkg.com/lang/en/docs/cli/init/">yarn</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/bash-scripting-tutorial-linux-shell-script-and-command-line-for-beginners/">Bash Scripting</a></li>
<li><a target="_blank" href="https://www.youtube.com/watch?v=IPiUDhwnZxA">Testing code with Jest</a></li>
</ul>
<h2 id="heading-what-tools-and-configs-are-we-looking-at">What Tools and Configs Are We Looking At?</h2>
<p>I have seen many repositories that enforce their own strict conventions – and I totally agree with them. One such example I found is the <a target="_blank" href="https://github.com/CesiumGS/cesium">Cesium repository</a> and <a target="_blank" href="https://github.com/CesiumGS/cesium/blob/main/Documentation/Contributors/CodingGuide/README.md#coding-guide">their style guides</a>.</p>
<p>Taking inspiration from various other repositories, we are going to dive into the following guidelines in this article to help you have a better developer experience:</p>
<ul>
<li>No console statements</li>
<li>No unused imports and variables</li>
<li>Sorting import statements</li>
<li>Check if any passwords, API keys, or secrets are being pushed before a commit</li>
<li>Check if any tests are failing before pushing to a commit</li>
</ul>
<h3 id="heading-why-these-conventions-are-useful">Why These Conventions Are Useful</h3>
<p>I found these rules to be useful because they increase your productivity as a dev. They also align development teams so that everyone follows the same conventions/coding standards.</p>
<p>These conventions have also made me vigilant about writing good code and following coding standards. Now it has become my habit to think in these terms and standards because, for example, having unused imports and console statements clutters your code unnecessarily.</p>
<p>I find sorting imports makes them more readable and easy to manage. I now have a habit of looking at the imports in a React component based on:</p>
<ul>
<li>Library imports</li>
<li>Relative imports</li>
</ul>
<p>I've also found tools that check if passwords or secrets are being pushed to be super useful, since they might appear later in the commit history. </p>
<p>But above all, I like having a rule to check if any tests are failing or not before making a commit. I believe that this is a very smart strategy, because in this case you're checking beforehand for any unit test failures – so you'll know if anything needs to get fixed. This also avoids overloading the CI pipelines that you're running on remote repositories</p>
<h2 id="heading-how-to-setup-coding-conventions">How to Setup Coding Conventions</h2>
<p>Before we dive into incorporating these tools into your project, I would like to categorize them into the following:</p>
<ul>
<li>ESLint-based rules</li>
<li>Git hooks</li>
</ul>
<p>Let's first understand these categories.</p>
<h3 id="heading-what-is-eslint">What is ESLint?</h3>
<p>ESLint is a highly configurable JavaScript linter that helps you detect and fix the problems in your JavaScript code. Each configuration from plugins to rules and more are checked against your code and it applies the value against that rule if the condition is met.</p>
<p>You can read more about ESLint’s core concepts <a target="_blank" href="https://eslint.org/docs/latest/use/core-concepts/">here</a>.</p>
<h3 id="heading-what-are-git-hooks">What are Git Hooks?</h3>
<p>Git hooks is a feature of Git that helps Git tap into its workflows so that some custom actions can be performed based on certain events. For example, you can run a script that will prettify some staged changes before making a commit.</p>
<p>There are multiple local Git hooks available to you. Some of them are below:</p>
<pre><code>applypatch-msg.sample       pre-push.sample
commit-msg.sample           pre-rebase.sample
post-update.sample          prepare-commit-msg.sample
pre-applypatch.sample       update.sample
pre-commit.sample
</code></pre><p>You can read more about Git hooks <a target="_blank" href="https://www.atlassian.com/git/tutorials/git-hooks">here</a>.</p>
<p>Now that we know why we're dividing up these conventions into these categories, let's start our journey of understanding the rules and tools that you're going to learn about that you can use in your projects.</p>
<h2 id="heading-set-up-the-project">Set Up the Project</h2>
<p>To demonstrate all the rules and tools that we discussed above, we will need a simple vanilla JavaScript project. I've chosen a vanilla JS project because creating a React-based Vite project would be overkill for this guide.</p>
<p>So to start creating the project, first create a directory named <code>eslint-hook-examples</code> with the below command:</p>
<pre><code class="lang-bash">mkdir eslint-hook-examples
<span class="hljs-built_in">cd</span> eslint-hook-examples
</code></pre>
<p>Inside this folder run the below command to initialize a vanilla JS project:</p>
<pre><code class="lang-bash">yarn init
</code></pre>
<p>Answer the question stated in the prompt and you should be good to go.</p>
<p>Now let's create a file named <code>index.js</code> inside this project and place the following content in it:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { get, debounce } <span class="hljs-keyword">from</span> <span class="hljs-string">"lodash"</span>;
<span class="hljs-keyword">import</span> { throttle } <span class="hljs-keyword">from</span> <span class="hljs-string">"lodash"</span>;

<span class="hljs-keyword">const</span> num = <span class="hljs-number">1</span>;
<span class="hljs-keyword">const</span> x = <span class="hljs-number">2</span>;

<span class="hljs-built_in">console</span>.log({ num });
</code></pre>
<p>I have created the above code keeping in mind that I want to demonstrate different ESLint rules and Git hooks.</p>
<p>Now you need to add ESLint to your project. You can do that by running the following command:</p>
<pre><code class="lang-bash">yarn add --dev eslint @eslint/js
</code></pre>
<p>Next, you need to create a file named <code>eslint.config.js</code> into your root directory – that is, where you have your <code>package.json</code> file. Place the following content inside this file:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> js <span class="hljs-keyword">from</span> <span class="hljs-string">"@eslint/js"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> [
  js.configs.recommended,
  {
    <span class="hljs-attr">rules</span>: {
      <span class="hljs-string">"no-unused-vars"</span>: <span class="hljs-string">"warn"</span>,
    },
  },
];
</code></pre>
<p>ESLint works on the configuration files that we set in the <code>eslint.config.js</code> file. This format of configurations is called a flat file format configuration. This is now supported with newer versions of ESLint, greater than v 9. Versions below 9 use a different file naming convention <code>.eslintrc</code> file which is placed inside the root dir of the project.</p>
<p>You can read more about flat file configuration <a target="_blank" href="https://eslint.org/docs/latest/use/configure/configuration-files">here</a>.</p>
<p>The above content of the <code>eslint.config.js</code> file loads the recommend configs for JavaScript with the help of <code>js.configs.recommended</code>. It also introduces another object that defines the <code>rules</code> that this configurations enables.</p>
<p>Right now it enables <a target="_blank" href="https://eslint.org/docs/latest/rules/no-unused-vars#rule-details">no-unused-vars</a> which is set to a <code>warn</code> value. This <code>warn</code> value tells ESLint to show warning message while linting. You can also set this value to <code>error</code> if you want the linter to show this case as an error.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> js <span class="hljs-keyword">from</span> <span class="hljs-string">"@eslint/js"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> [
  js.configs.recommended,
  {
    <span class="hljs-attr">rules</span>: {
      <span class="hljs-string">"no-unused-vars"</span>: <span class="hljs-string">"error"</span>,
    },
  },
];
</code></pre>
<p>Let's give this setup a spin and run our ESLinting on <code>index.js</code> file. To do that, run the following command:</p>
<pre><code class="lang-shell">npx eslint ./index.js
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/image.png" alt="Image" width="600" height="400" loading="lazy">
<em>Output of running ESLint CLI</em></p>
<p>After running the linter, you'll get the above issues. All our unused variables are getting flagged under the <code>no-unused-vars</code> rule that you set in your <code>eslint-config.js</code> file.</p>
<p>So this is how linting works. But wouldn’t it be awesome if you could get these error messages in your IDE itself with a squiggly line below each variable name that is unused? Well, yes – it's absolutely possible. In VS Code you can do this by adding the <a target="_blank" href="https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint">ESLint VS code extension</a>.</p>
<p>Once the extension is installed in your VS Code, you'll want to configure it so that it picks up the configuration file that you have created (<code>eslint.config.js</code>).</p>
<p>To configure your extension, follow the gif/steps below to go through the settings of the extension.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/eslint_settings-3.gif" alt="Image" width="600" height="400" loading="lazy">
<em>VSCode ESLint Extension</em></p>
<ul>
<li>Click on the VSCode's extension</li>
<li>Click on the ESLint extension</li>
<li>Then below the extension name, click on the gear ⚙️ icon.</li>
<li>Next, click on the extension settings from the dropdown</li>
<li>Finally, click on <code>settings.json</code>.</li>
</ul>
<p>Inside the <code>settings.json</code> file, add the following code at the bottom of the file:</p>
<pre><code class="lang-jsx"><span class="hljs-string">"eslint.options"</span>: {
         <span class="hljs-string">"overrideConfigFile"</span>: <span class="hljs-string">"./eslint.config.js"</span> 
    },
</code></pre>
<p>This makes sure that the extension picks up the config file that you created at the project’s root location.</p>
<p>A quick thing to note is that all the rules can also be set to <code>warn</code> so that VSCode can give warning lints when the rule is met.</p>
<p>Here is how the configured extension will look like on a file:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/image-2.png" alt="Image" width="600" height="400" loading="lazy">
<em>Linter when configured</em></p>
<p>Let's now dive into our first rule: the <code>no unused variable</code> rule.</p>
<h2 id="heading-rule-1-no-unused-vars">Rule #1: <code>no-unused-vars</code></h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/rule_1_banner.jpg" alt="Image" width="600" height="400" loading="lazy">
_Photo by [Unsplash](https://unsplash.com/@v2osk?utm_content=creditCopyText&amp;utm_medium=referral&amp;utm_source=unsplash"&gt;v2osk on &lt;a href="https://unsplash.com/photos/assorted-armchair-on-wall-near-door-1hUY8SpJ8Cw?utm_content=creditCopyText&amp;utm_medium=referral&amp;utm<em>source=unsplash)</em></p>
<p>This is one of those ESLint rules that doesn’t allow you to keep unused variables in your codebase. You can read more about this rule <a target="_blank" href="https://eslint.org/docs/latest/rules/no-unused-vars#rule-details">here</a>.</p>
<p>To setup this rule in your codebase, you'll add it in the <code>rules</code> section of the <code>eslint.config.js</code> file:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> [
  {
    <span class="hljs-attr">rules</span>: {
      <span class="hljs-string">"no-unused-vars"</span>: <span class="hljs-string">"error"</span>,
    },
  },
];
</code></pre>
<p>We already looked at this rule in the setting up the project section. But there is no harm in re-visiting it.</p>
<blockquote>
<p>💡 NOTE: This rule is already present in the <code>js.configs.recommended</code> which consists of all the recommended ESLint rules</p>
</blockquote>
<p>In action, this rule will highlight your unused variables like below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/rule_1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Output of rule#1 is configured</em></p>
<h2 id="heading-rule-2-no-console">Rule #2: <code>no-console</code></h2>
<p><img src="https://media3.giphy.com/media/v1.Y2lkPTc5MGI3NjExczIxMjJja2s5NWxjbHBsY3A2OXhzM2U4NW93d3NuYzhweWVlcmJ3eiZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/ge7l7e5EiHUYI3e71P/giphy.webp" alt="A wild thought image" width="600" height="400" loading="lazy"></p>
<p>I find this rule super useful because unnecessary logs that aren’t important shouldn’t be present in the codebase. We generally just add these logs for debugging purposes. </p>
<p>This can be dangerous because <code>console.log</code> statements can reveal sensitive personal data from your users in the browser’s console if you are dealing with personal data. So you have to be careful about that.</p>
<p>For example, the chance is high that you might forget to remove a console statement. Later the same thing will bite you when audits happen.</p>
<p>I understand that these logs are helpful in development mode. So in those cases where the logs are environment-dependent, it's better if you wrap these <code>console.log</code> statements with a custom wrapper that helps you to enable/disable the logs based on the environment.</p>
<p>So to avoid all this hassle, ESLint has the <a target="_blank" href="https://eslint.org/docs/latest/rules/no-console#rule-details">no-console</a> rule. This rule will provide linting whenever it finds console statement in your code base.</p>
<p>To configure this rule, you need to do the same thing that we did earlier:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> [
  {
    <span class="hljs-attr">rules</span>: {
      <span class="hljs-string">"no-unused-vars"</span>: <span class="hljs-string">"error"</span>,
      <span class="hljs-string">"no-console"</span>: <span class="hljs-string">"error"</span>, <span class="hljs-comment">// &lt;---- Add rule here</span>
    },
  },
];
</code></pre>
<p>In action, this rule will lint your codebase like below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/Rule_2.png" alt="Rule_2.png" width="600" height="400" loading="lazy">
<em>console.log becomes an error when rule #2 is configured</em></p>
<h2 id="heading-rule-3-no-duplicate-imports-and-sorting-imports">Rule #3: <code>no-duplicate-imports</code> and Sorting Imports</h2>
<figure>
    <img src="https://i.giphy.com/26FmPNdnmllMwkoTK.webp" alt="import cargo" width="600" height="400" loading="lazy">
      <figcaption>Cargos sorted on the ship</figcaption>
</figure>


<p>What I love about this rule is that it helps you to keep your imports super readable. Have you seen a big React component file that has all its imports and that looks messed up? Yeah it's not fun.</p>
<p>You might even have different imports that are from the same library. These kinds of ways of importing libs can be chaotic and hard to follow. This is where the <a target="_blank" href="https://eslint.org/docs/latest/rules/no-duplicate-imports#rule-details">no-duplicate-imports</a> ESLint rule and <a target="_blank" href="https://github.com/lydell/eslint-plugin-simple-import-sort">eslint-plugin-simple-import-sort</a> ESLint plugin comes into play.</p>
<p><code>no-duplicate-imports</code> is an ESLint rule that states that all the imports from a single module can be grouped into a single import statement. </p>
<p>Consider the following example:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { get, set } <span class="hljs-keyword">from</span> <span class="hljs-string">'lodash'</span>;
<span class="hljs-keyword">import</span> { zip } <span class="hljs-keyword">from</span> <span class="hljs-string">'lodash'</span>; <span class="hljs-comment">// &lt;----- error as per the no-duplicate-imports</span>
<span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
</code></pre>
<p>As you can see, the imports in the first two lines belong to the same module – that is, the Lodash library. If the rule is followed, then the code will look like this:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { get, set, zip } <span class="hljs-keyword">from</span> <span class="hljs-string">'lodash'</span>;
<span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
</code></pre>
<p>ESLint doesn’t have any rule that will help you sort your imports. In this case, you can get help from different community-based plugins on <a target="_blank" href="https://github.com/dustinspecker/awesome-eslint?tab=readme-ov-file">awesome-eslint</a>.</p>
<p><code>awesome-eslint</code> is a repository of ESLint configs, plugins, parsers, formatters, and so on. I found this plugin called <code>eslint-plugin-simple-import-sort</code> that helps you sort your imports alphabetically, with library imports first and then the relative imports.</p>
<p>Here is a snippet of the example from the actual plugin repo:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> Button <span class="hljs-keyword">from</span> <span class="hljs-string">"../Button"</span>;

<span class="hljs-keyword">import</span> styles <span class="hljs-keyword">from</span> <span class="hljs-string">"./styles.css"</span>;
<span class="hljs-keyword">import</span> type { User } <span class="hljs-keyword">from</span> <span class="hljs-string">"../../types"</span>;
<span class="hljs-keyword">import</span> { getUser } <span class="hljs-keyword">from</span> <span class="hljs-string">"../../api"</span>;

<span class="hljs-keyword">import</span> PropTypes <span class="hljs-keyword">from</span> <span class="hljs-string">"prop-types"</span>;
<span class="hljs-keyword">import</span> classnames <span class="hljs-keyword">from</span> <span class="hljs-string">"classnames"</span>;
<span class="hljs-keyword">import</span> { truncate, formatNumber } <span class="hljs-keyword">from</span> <span class="hljs-string">"../../utils"</span>;
</code></pre>
<p>⬇️</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> classnames <span class="hljs-keyword">from</span> <span class="hljs-string">"classnames"</span>;
<span class="hljs-keyword">import</span> PropTypes <span class="hljs-keyword">from</span> <span class="hljs-string">"prop-types"</span>;
<span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-keyword">import</span> { getUser } <span class="hljs-keyword">from</span> <span class="hljs-string">"../../api"</span>;
<span class="hljs-keyword">import</span> type { User } <span class="hljs-keyword">from</span> <span class="hljs-string">"../../types"</span>;
<span class="hljs-keyword">import</span> { formatNumber, truncate } <span class="hljs-keyword">from</span> <span class="hljs-string">"../../utils"</span>;
<span class="hljs-keyword">import</span> Button <span class="hljs-keyword">from</span> <span class="hljs-string">"../Button"</span>;
<span class="hljs-keyword">import</span> styles <span class="hljs-keyword">from</span> <span class="hljs-string">"./styles.css"</span>;
</code></pre>
<p>You can also set the sorting order of this plugin to something different, which you can read more about <a target="_blank" href="https://github.com/lydell/eslint-plugin-simple-import-sort?tab=readme-ov-file#sort-order">here</a>.</p>
<p>Let's incorporate these rules and plugins in our project. First, you'll add the <code>no-duplicate-imports</code> rule in your config:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> [
    {
        <span class="hljs-attr">rules</span>: {
            <span class="hljs-string">"no-duplicate-imports"</span>: <span class="hljs-string">"error"</span>, <span class="hljs-comment">// &lt;---- HERE</span>
            <span class="hljs-string">"no-unused-vars"</span>: <span class="hljs-string">"error"</span>,
            <span class="hljs-string">"no-console"</span>: <span class="hljs-string">"error"</span>,
        },
    },
];
</code></pre>
<p>It's very similar to the rules that we configured earlier. We set the rule’s value to be <code>error</code>.</p>
<p>Next, start with configuring the <strong><code>eslint-plugin-simple-import-sort</code></strong> plugin in your project. First, install this plugin with the following command:</p>
<pre><code class="lang-bash">yarn add --dev eslint-plugin-simple-import-sort
</code></pre>
<p>Once this is installed, make sure this plugin is enabled by adding it into your <code>eslint.config.js</code> file like below:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> simpleImportSort <span class="hljs-keyword">from</span> <span class="hljs-string">"eslint-plugin-simple-import-sort"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> [
  {
    <span class="hljs-attr">plugins</span>: {
      <span class="hljs-string">"simple-import-sort"</span>: simpleImportSort, <span class="hljs-comment">// &lt;--- add plugin</span>
    },
    <span class="hljs-attr">rules</span>: {
      <span class="hljs-string">"no-duplicate-imports"</span>: <span class="hljs-string">"error"</span>,
      <span class="hljs-string">"no-unused-vars"</span>: <span class="hljs-string">"error"</span>,
      <span class="hljs-string">"no-console"</span>: <span class="hljs-string">"error"</span>,
      <span class="hljs-string">"simple-import-sort/imports"</span>: <span class="hljs-string">"error"</span>, <span class="hljs-comment">// &lt;--- refer the rule of the plugin</span>
    },
  },
];
</code></pre>
<p>In this code, we first import the plugin as <code>simpleImportSort</code>. Then in the exported array, just above the <code>rules</code> property, we add the <code>plugins</code> property. This property will consist of all the plugins that we want to enable in the form of key being the plugin namespace and value being the plugin object.</p>
<p>In the above code, the <code>simple-import-sort</code> is the plugin namespace and its value is the plugin object which is <code>simpleImportSort</code>.</p>
<p>Now to use the rules that are present inside the plugins, all you have to do is refer to the plugin namespace followed by the rule name as the key and value to be the <code>error</code> – in our case inside the rules section. </p>
<p>In our config, we refer to the rule <code>imports</code> of the <code>simple-import-sort</code> plugin space as <code>simple-import-sort/imports</code>.</p>
<p>Once you've added this rule into the config, you can see it in action as below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/sorting_imports-ezgif.com-optimize.gif" alt="sorting_imports-ezgif.com-optimize.gif" width="600" height="400" loading="lazy">
<em>Imports getting sorted</em></p>
<p>You can also configure this sorting of imports when you save your code by enabling the <code>codeActionsOnSave</code> in the settings of the ESLint VSCode extension:</p>
<pre><code class="lang-jsx">{
    <span class="hljs-string">"[typescriptreact]"</span>: {
        <span class="hljs-string">"editor.defaultFormatter"</span>: <span class="hljs-string">"esbenp.prettier-vscode"</span>
    },
    <span class="hljs-string">"[typescript]"</span>: {
        <span class="hljs-string">"editor.defaultFormatter"</span>: <span class="hljs-string">"esbenp.prettier-vscode"</span>
    },
    <span class="hljs-string">"[javascript]"</span>: {
        <span class="hljs-string">"editor.defaultFormatter"</span>: <span class="hljs-string">"esbenp.prettier-vscode"</span>
    },
    <span class="hljs-string">"workbench.sideBar.location"</span>: <span class="hljs-string">"right"</span>,
    <span class="hljs-string">"diffEditor.ignoreTrimWhitespace"</span>: <span class="hljs-literal">false</span>,
    <span class="hljs-string">"workbench.colorTheme"</span>: <span class="hljs-string">"Default Dark+"</span>,
    <span class="hljs-string">"editor.stickyScroll.enabled"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-string">"prettier.useTabs"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-string">"editor.formatOnSave"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-string">"window.zoomLevel"</span>: <span class="hljs-number">1</span>,
    <span class="hljs-string">"eslint.options"</span>: {
         <span class="hljs-string">"overrideConfigFile"</span>: <span class="hljs-string">"./eslint.config.js"</span> 
    },
    <span class="hljs-string">"eslint.format.enable"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-string">"editor.codeActionsOnSave"</span>: { <span class="hljs-comment">//&lt; ------ Add this property</span>
        <span class="hljs-string">"source.fixAll.eslint"</span>: <span class="hljs-string">"explicit"</span>
    }
}
</code></pre>
<p>Now that you understand and have added the ESLint rules and plugins, let's now understand and implement Git hooks.</p>
<h2 id="heading-how-to-set-up-git-hooks">How to Set Up Git Hooks</h2>
<figure>
    <img src="https://i.giphy.com/2VOB4tK9qsQ7efC2Ub.webp" alt="A fish hook" width="600" height="400" loading="lazy">
      <figcaption>A fish hook</figcaption>
</figure>


<p>Git hooks are nothing but Git features on steroids. All the details and the origin or Git hooks are out of the scope of this article, so I highly recommend that you read more about them <a target="_blank" href="https://git-scm.com/docs/githooks">here</a>.</p>
<p>There are many libraries out there that will help you manage your Git hooks. I will use <a target="_blank" href="https://typicode.github.io/husky/">Husky</a> here. To install Husky in your codebase, run the below commands:</p>
<pre><code class="lang-bash">yarn add --dev husky
<span class="hljs-comment"># Add pinst ONLY if your package is not private</span>
yarn add --dev pinst
</code></pre>
<p>Once it's installed, make sure to initialize it by doing the following:</p>
<pre><code class="lang-bash">npx husky init
</code></pre>
<p>This makes sure that it creates the <code>.husky</code> folder that consists of the precommit script. It also adds the prepare script inside the <code>package.json</code> file.</p>
<p>Now that you've configured Husky in your project, we'll implement our first pre-commit hook feature.</p>
<h2 id="heading-gitleaks-remove-secrets-before-commits">Gitleaks: Remove Secrets Before Commits</h2>
<figure>
    <img src="https://i.giphy.com/yow6i0Zmp7G24.webp" alt="Shhhh" width="600" height="400" loading="lazy">
      <figcaption>Shhhh</figcaption>
</figure>


<p>Gitleaks is a tool that analyses your codebase for any API Keys, secrets, or passwords. According to the repository:</p>
<blockquote>
<p><em>"Gitleaks is a SAST tool for <strong>detecting</strong> and <strong>preventing</strong> hardcoded secrets like passwords, API keys, and tokens in Git repos. Gitleaks is an <strong>easy-to-use, all-in-one solution</strong> for detecting secrets, past or present, in your code."</em></p>
</blockquote>
<p>Let's now implement Gitleaks in our project with the help of <code>precommit</code> hooks with Husky.</p>
<p>First, install Gitleaks with the following command:</p>
<pre><code class="lang-bash">brew install gitleaks
</code></pre>
<p>Once this is installed, start by editing the <code>precommit</code> script file that is present inside the <code>.husky</code> folder.</p>
<p>Our aim here is to check that all the files that are staged are being analysed by the Gitleaks tool before the commit happens. The <code>precommit</code> hook is the best option where you can run different scripts before any commit happens.</p>
<p>Gitleaks already has one example in the Python <code>precommit</code> hook. It checks if the Gitleaks hook is enabled. If it is enabled, then it runs the Gitleaks <code>protect</code> function on the staged files. You can find that code <a target="_blank" href="https://github.com/gitleaks/gitleaks/blob/26f34692fac6e9daec13c770421b4ed990d1c321/scripts/pre-commit.py">here</a>.</p>
<p>I converted this script into a bash script with the help of ChatGPT. Here is the result that it gave me:</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>

<span class="hljs-comment"># Helper script to be used as a pre-commit hook.</span>

<span class="hljs-function"><span class="hljs-title">gitleaksEnabled</span></span>() {
    <span class="hljs-comment"># Determine if the pre-commit hook for gitleaks is enabled.</span>
    <span class="hljs-built_in">local</span> out
    out=$(git config --bool hooks.gitleaks)
    <span class="hljs-keyword">if</span> [ <span class="hljs-string">"<span class="hljs-variable">$out</span>"</span> == <span class="hljs-string">"false"</span> ]; <span class="hljs-keyword">then</span>
        <span class="hljs-built_in">return</span> 1
    <span class="hljs-keyword">fi</span>
    <span class="hljs-built_in">return</span> 0
}

<span class="hljs-comment"># Check if gitleaks is installed</span>
<span class="hljs-keyword">if</span> ! <span class="hljs-built_in">command</span> -v gitleaks &amp;&gt; /dev/null; <span class="hljs-keyword">then</span>
    <span class="hljs-built_in">echo</span> <span class="hljs-string">'Error: gitleaks is not installed on your system.'</span>
    <span class="hljs-built_in">echo</span> <span class="hljs-string">'Please install gitleaks to use this pre-commit hook.'</span>
    <span class="hljs-built_in">exit</span> 1
<span class="hljs-keyword">fi</span>

<span class="hljs-keyword">if</span> gitleaksEnabled; <span class="hljs-keyword">then</span>
    gitleaks protect -v --staged
    exitCode=$?
    <span class="hljs-keyword">if</span> [ <span class="hljs-variable">$exitCode</span> -eq 1 ]; <span class="hljs-keyword">then</span>
        <span class="hljs-built_in">echo</span> <span class="hljs-string">'Warning: gitleaks has detected sensitive information in your changes.
To disable the gitleaks precommit hook run the following command:

    git config hooks.gitleaks false
'</span>
        <span class="hljs-built_in">exit</span> 1
    <span class="hljs-keyword">fi</span>
<span class="hljs-keyword">else</span>
    <span class="hljs-built_in">echo</span> <span class="hljs-string">'gitleaks precommit disabled (enable with `git config hooks.gitleaks true`)'</span>
<span class="hljs-keyword">fi</span>
</code></pre>
<p>In this script, I also asked ChatGPT to add an additional feature to check if Gitleaks is installed in the system or not. If it isn’t, then the <code>precommit</code> hook stops its execution with exit code 1.</p>
<p>Now to try out your <code>precommit</code> hook, you should first stage the changes:</p>
<pre><code class="lang-bash">git add .
</code></pre>
<p>Next, commit the changes as follows:</p>
<pre><code class="lang-bash">git commit -m <span class="hljs-string">'feat: added gitleaks precommit hook'</span>
</code></pre>
<p>This will run the <code>precommit</code> hook that you defined. It will look like below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/gitleaks.png" alt="gitleaks.png" width="600" height="400" loading="lazy">
<em>gitleaks tool running before commit</em></p>
<h2 id="heading-run-unit-tests-before-commits">Run Unit Tests Before Commits</h2>
<figure>
    <img src="https://i.giphy.com/gw3IWyGkC0rsazTi.webp" alt="A printer" width="600" height="400" loading="lazy">
      <figcaption>Shhhh</figcaption>
</figure>


<p>Another practical use of Git hooks is running unit tests on staged files. This is helpful as the check occurs locally and isn't pushed to the remote repository. </p>
<p>While running the unit test on CI isn't an issue, executing the test on staged and related files can save some time. This allows the CI to focus on running the complete unit test suite before merging the commit to the release branch.</p>
<p>So below is the flow for using the <code>precommit</code> hook that will run the unit tests on staged files:</p>
<ul>
<li>Find the staged files that have <code>*.test.js/ts</code> file extensions</li>
<li>Run these staged tests along with their related code</li>
<li>If there are any test failures or errors while testing, then exit the <code>precommit</code> hook (so the commit doesn't happen).</li>
</ul>
<h3 id="heading-step-1-find-the-files-that-are-staged">Step 1: Find the files that are staged</h3>
<p>The first step is to find all the file names that are staged with the extension <code>*.test.js</code>. To do that, you can use the <code>git diff</code> command:</p>
<pre><code class="lang-bash">git diff --cached --name-only --diff-filter=ACM | grep <span class="hljs-string">'\\.test\\.js$'</span>
</code></pre>
<p><code>git diff</code> helps you find the difference between the modified changes and the current file. You can read more about <code>git diff</code> and its options <a target="_blank" href="https://git-scm.com/docs/git-diff">here</a>.</p>
<p>Next, using the <a target="_blank" href="https://superuser.com/a/756259">pipe symbol</a>, we filter the output of the previous <code>git diff</code> command with the help of <a target="_blank" href="https://www.freecodecamp.org/news/grep-command-in-linux-usage-options-and-syntax-examples">grep</a>. We tell grep to find all the file names that end with the <code>.test.js</code> extension.</p>
<h3 id="heading-step-2-run-the-unit-test-on-staged-files">Step 2: Run the unit test on staged files</h3>
<p>Now to run the unit test, make sure that you have installed <a target="_blank" href="https://jestjs.io/docs/getting-started">Jest</a> in your project. To run the unit test on the staged files and the files related to it, run the below command:</p>
<pre><code class="lang-bash">yarn run <span class="hljs-built_in">test</span> --coverage --bail --findRelatedTests &lt;staged-files-ending-with-.test.js&gt;
</code></pre>
<p>The above command will run the test on the current staged files and the files related to it with the <code>--findRelatedTests</code> option. It will also provide a coverage report with the <code>--coverage</code> option and will interrupt the tests when any failure is found with the <code>--bail</code> option.</p>
<p>Now the main part of the above command that is you need to provide the files that are staged with the <code>.test.js</code> extension. To do that, use the command in step 1. Since you're using a bash script, store step 1’s output in a variable and pass it on to the unit test command:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># List the staged *.test.js files</span>
stagedTestFiles=$(git diff --cached --name-only --diff-filter=ACM | grep <span class="hljs-string">'\\.test\\.js$'</span>)

yarn run <span class="hljs-built_in">test</span> --coverage --bail --findRelatedTests <span class="hljs-variable">$stagedTestFiles</span>
</code></pre>
<p>You will add the above commands in your <code>precommit</code> script. The final pre-commit hook script will look like this:</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>

<span class="hljs-comment"># Helper script to be used as a pre-commit hook.</span>

<span class="hljs-function"><span class="hljs-title">gitleaksEnabled</span></span>() {
    <span class="hljs-comment"># Determine if the pre-commit hook for gitleaks is enabled.</span>
    <span class="hljs-built_in">local</span> out
    out=$(git config --bool hooks.gitleaks)
    <span class="hljs-keyword">if</span> [ <span class="hljs-string">"<span class="hljs-variable">$out</span>"</span> == <span class="hljs-string">"false"</span> ]; <span class="hljs-keyword">then</span>
        <span class="hljs-built_in">return</span> 1
    <span class="hljs-keyword">fi</span>
    <span class="hljs-built_in">return</span> 0
}

<span class="hljs-comment"># For ============================= UNIT TESTING =============================</span>
<span class="hljs-comment"># List the staged *.test.js files</span>
stagedTestFiles=$(git diff --cached --name-only --diff-filter=ACM | grep <span class="hljs-string">'\\.test\\.js$'</span>)

<span class="hljs-keyword">if</span> [ -n <span class="hljs-string">"<span class="hljs-variable">$stagedTestFiles</span>"</span> ]; <span class="hljs-keyword">then</span>
    <span class="hljs-built_in">echo</span> <span class="hljs-string">"Staged *.test.js files:"</span>
    yarn run <span class="hljs-built_in">test</span> --coverage --bail --findRelatedTests <span class="hljs-variable">$stagedTestFiles</span>
<span class="hljs-keyword">else</span>
    <span class="hljs-built_in">echo</span> <span class="hljs-string">"No *.test.js files are staged."</span>
<span class="hljs-keyword">fi</span>

<span class="hljs-comment"># Check if gitleaks is installed</span>
<span class="hljs-keyword">if</span> ! <span class="hljs-built_in">command</span> -v gitleaks &amp;&gt; /dev/null; <span class="hljs-keyword">then</span>
    <span class="hljs-built_in">echo</span> <span class="hljs-string">'Error: gitleaks is not installed on your system.'</span>
    <span class="hljs-built_in">echo</span> <span class="hljs-string">'Please install gitleaks to use this pre-commit hook.'</span>
    <span class="hljs-built_in">exit</span> 1
<span class="hljs-keyword">fi</span>

<span class="hljs-comment"># For ============================= CHECKING SECRETS =============================</span>
<span class="hljs-keyword">if</span> gitleaksEnabled; <span class="hljs-keyword">then</span>
    gitleaks protect -v --staged
    exitCode=$?
    <span class="hljs-keyword">if</span> [ <span class="hljs-variable">$exitCode</span> -eq 1 ]; <span class="hljs-keyword">then</span>
        <span class="hljs-built_in">echo</span> <span class="hljs-string">'Warning: gitleaks has detected sensitive information in your changes.
To disable the gitleaks precommit hook run the following command:

    git config hooks.gitleaks false
'</span>
        <span class="hljs-built_in">exit</span> 1
    <span class="hljs-keyword">fi</span>
<span class="hljs-keyword">else</span>
    <span class="hljs-built_in">echo</span> <span class="hljs-string">'gitleaks precommit disabled (enable with `git config hooks.gitleaks true`)'</span>
<span class="hljs-keyword">fi</span>
</code></pre>
<p>To test the precommit hook on the unit test, I created a sample test file: <code>index.test.js</code>:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> sum = <span class="hljs-number">1</span> + <span class="hljs-number">2</span>;

describe(<span class="hljs-string">"test suite"</span>, <span class="hljs-function">() =&gt;</span> {
    it(<span class="hljs-string">"check sum suit"</span>, <span class="hljs-function">() =&gt;</span> {
        expect(sum).toBe(<span class="hljs-number">3</span>);
    });
});
</code></pre>
<p>Here is how the <code>precommit</code> hook generates the output when the test passes and fails. </p>
<blockquote>
<p>Note: Here I tried to purposefully generate the error in the <code>index.test.js</code> file.</p>
</blockquote>
<p>Run the below command to see the output:</p>
<pre><code class="lang-shell">git commit -m 'test commit'
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/Unit-test-failure.png" alt="Unit test failure.png" width="600" height="400" loading="lazy">
<em>Failed Unit Tests</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/Unit-test-passing.png" alt="Unit test passing.png" width="600" height="400" loading="lazy">
<em>Passing Unit Tests</em></p>
<h2 id="heading-summary">Summary</h2>
<p>To summarise, here's what you learned about in this article:</p>
<ul>
<li>What ESLint is and how you can configure it with rules and plugins</li>
<li>We also looked at VSCode’s ESLint extension and configured it to use our existing flat configuration file</li>
<li>We learned about Git hooks and how you can use Husky to manage your hooks.</li>
<li>We looked into how you can remove secrets and perform unit testing before any commit.</li>
</ul>
<p>I learned a lot while writing this guide, and I hope you got a lot out of it!</p>
<p>You can find the final code <a target="_blank" href="https://github.com/keyurparalkar/eslint-githooks-example">here</a>.</p>
<p>Thanks a lot for reading my article! You can follow me on <a target="_blank" href="https://twitter.com/keurplkar">Twitter</a>, <a target="_blank" href="http://github.com/keyurparalkar">GitHub</a>, and <a target="_blank" href="https://www.linkedin.com/in/keyur-paralkar-494415107/">LinkedIn</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build an Image Carousel Component with TypeScript and Styled-Components ]]>
                </title>
                <description>
                    <![CDATA[ In recent years, OTT (over-the-top) video streaming platforms have become more innovative and convenient to use. In their user interfaces, movies and series titles are arranged so that the titles are clearly visible. In this tutorial, I’ll guide you ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-build-an-image-carousel-component/</link>
                <guid isPermaLink="false">66bb5540e326dc37a9d68ee0</guid>
                
                    <category>
                        <![CDATA[ CSS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ TypeScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Keyur Paralkar ]]>
                </dc:creator>
                <pubDate>Mon, 05 Jun 2023 17:28:08 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/05/sunder-muthukumaran-I4eKHN1KaZ0-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In recent years, OTT (over-the-top) video streaming platforms have become more innovative and convenient to use. In their user interfaces, movies and series titles are arranged so that the titles are clearly visible.</p>
<p>In this tutorial, I’ll guide you through the process of creating an image carousel component that looks just like the ones you see on many OTT platforms (think Netflix). </p>
<p>We'll start by creating atomic components, such as <code>Tags</code>,<code>Description</code>, <code>Title</code>, and so on that will display various information about each movie title. Then, we'll stitch these components together via a compound pattern to create a <code>Banner</code> component that displays each movie title in the form of an image. Finally, we'll use the <code>HeroBanner</code> component to build the image carousel component using the <code>Swiper</code> package. </p>
<p>By the end of this post, you'll have the knowledge and skills to create a beautiful and functional image carousel component that will impress your users. Let's get started!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/image-97.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></li>
<li><a class="post-section-overview" href="#heading-how-to-build-the-banner-component">How to Build the Banner component</a></li>
<li><a class="post-section-overview" href="#heading-how-to-build-the-individual-components">How to Build the Individual Components</a></li>
<li><a class="post-section-overview" href="#heading-how-to-stitch-all-the-components-together-with-the-compound-pattern">How to Stitch All the Components Together with the Compound Pattern</a></li>
<li><a class="post-section-overview" href="#heading-how-to-build-the-image-carousel-component">How to Build the Image Carousel Component</a></li>
<li><a class="post-section-overview" href="#heading-summary">Summary</a></li>
</ul>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Before heading on to the next sections, make sure you're comfortable with the following topics:</p>
<ul>
<li><strong>CSS</strong> – An Intermediate knowledge of CSS is required to style the small components that we will be creating in this Post.</li>
<li><strong>Styled components</strong> – You'll need to be familiar with what styled-components are since we will be using it to create a version of a component that contains static/dynamic css in it. You can learn more about styled-components <a target="_blank" href="https://styled-components.com/">here</a>.</li>
<li><strong>Compound</strong> <strong>pattern</strong> – We'll use this pattern to stitch individual components together so that they can be used later in a convenient way. You can read more about compound pattern <a target="_blank" href="https://www.patterns.dev/posts/compound-pattern">here</a>.</li>
<li><strong>TypeScript</strong> – We'll use <a target="_blank" href="https://www.typescriptlang.org/docs/">TypeScript</a> in this entire tutorial. It provides good type-safety on top of JavaScript. Having some basic knowledge of it will definitely be fruitful here.</li>
</ul>
<h2 id="heading-how-to-build-the-banner-component">How to Build the Banner Component</h2>
<p>The below gif represents an image carousel component. If you don’t know what an image carousel is, then let me give you a brief overview.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/image-98.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>An image carousel is a component that consists of images that rotate a fixed number of times or can be rotated with the help of navigation icons. </p>
<p>In this tutorial, we'll create this component. But before jumping into the image carousel, we'll start with a very basic component which is the Banner component. </p>
<p>Banner Component is going to be a component that will help us to display:</p>
<ul>
<li>Title</li>
<li>Tags</li>
<li>Description</li>
<li>Background image</li>
</ul>
<p>After that, with the help of <a target="_blank" href="https://styled-components.com/">styled-components</a> and CSS, we'll make it look beautiful just like we see on most OTT platforms.</p>
<p>Building this component involves the below steps:</p>
<ol>
<li>Building the individual components</li>
<li>Stitching all the components together with the compound pattern</li>
</ol>
<h2 id="heading-how-to-build-the-individual-components">How to Build the Individual Components</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/Screenshot-2023-06-03-at-8.33.17-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Our banner component will comprise of some basic smaller components that cannot be further broken down. These components are known as <a target="_blank" href="https://blog.logrocket.com/atomic-design-react-native/">atomic components</a>. Let's first build the simplest component which is the Title component:</p>
<p>First, create a functional component like below:</p>
<pre><code class="lang-tsx">const Title = (props: { title: string }) =&gt; &lt;div&gt;{props.title}&lt;/div&gt;;
</code></pre>
<p>We'll also need to style this component. We create a styled div component and place it inside the above Title component like this:</p>
<pre><code class="lang-tsx">const StyledTitle = styled.div`
  font-size: 28px;
  font-weight: 600;
  color: white;
`;

const Title = (props: { title: string }) =&gt; (
  &lt;StyledTitle&gt;{props.title}&lt;/StyledTitle&gt;
);
</code></pre>
<p>The next component in our line-up is the <code>Tags</code> component. It's a div element that maps over the string (tags) and displays them in the <code>span</code> element:</p>
<p>Create a functional component that accepts an array of strings as a prop and displays them in the span element with a map function:</p>
<pre><code class="lang-tsx">const Tags = (props: { tags: string[] }) =&gt; {
  return (
    &lt;div&gt;
      {props.tags.map((tag: string, index: number) =&gt; (
        &lt;span key={`tag-${tag}-index`}&gt;{tag}&lt;/span&gt;
      ))}
    &lt;/div&gt;
  );
};
</code></pre>
<p>Now let's create a styled div component that acts as a replacement for the above div element. We create this wrapper component to apply styles to the children's elements:</p>
<pre><code class="lang-tsx">const StyledTag = styled.div`
  padding: 0.5rem 0;

  &amp; span {
    margin-right: 0.5rem;
    font-size: 1rem;
    font-weight: 500;
    color: rgba(255, 255, 255, 0.6);
  }
`;
</code></pre>
<p>Finally, we stitch these components together:</p>
<pre><code class="lang-tsx">const Tags = (props: { tags: string[] }) =&gt; {
  return (
    &lt;StyledTag&gt;
      {tags.map((tag: string, index: number) =&gt; (
        &lt;span key={`tag-${tag}-index`}&gt;{tag}&lt;/span&gt;
      ))}
    &lt;/StyledTag&gt;
  );
};
</code></pre>
<p>Similarly, we create another component called the <code>Description</code> component. It helps to display the description of the movie title. It’s also a functional component that accepts a description prop and displays it using a styled-component:</p>
<pre><code class="lang-tsx">const StyledDescription = styled.div`
  text-align: start;
  color: rgba(255, 255, 255, 0.8);
  display: -webkit-box;
  max-width: 50%;
  -webkit-line-clamp: 4;
  -webkit-box-orient: vertical;
  overflow: hidden;
`;

const Description = (props: { description: string }) =&gt; (
  &lt;StyledDescription&gt;{description}&lt;/StyledDescription&gt;
);
</code></pre>
<p>Finally, we'll create the <code>Banner</code> component. The purpose of this component is to display the background image of the movie title along with the children passed to it. Let's create a very basic version of this component:</p>
<pre><code class="lang-tsx">const Banner = (props) =&gt; {
  return (
    &lt;div
      style={{
        backgroundImage: `url(${props.image})`,
        width: "100%",
        height: "400px",
      }}
    &gt;
      &lt;div&gt;{props.children}&lt;/div&gt;
    &lt;/div&gt;
  );
};

&lt;Banner image="https://m.media-amazon.com/images/M/MV5BZjRlNDUxZjAtOGQ4OC00OTNlLTgxNmQtYTBmMDgwZmNmNjkxXkEyXkFqcGdeQXVyNzkwMjQ5NzM@._V1_.jpg"&gt;
  &lt;h1 style={{ color: "yellow" }}&gt;Die hard&lt;/h1&gt;
&lt;/Banner&gt;;
</code></pre>
<p>If we execute this component, it does what we expect it to do, <em>“Show a background Image along with children component”</em> like below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/image-101.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>But the style seems to be off – we don’t want this component to look this ugly. What we need is to apply CSS to get things in the right places at the right positions 🙂 (pun intended). </p>
<p>We want the movie poster to be at the right and all the children components should be to the left of it. Now let's create a styled component to do this:</p>
<pre><code class="lang-tsx">const StyledContainer = styled.div`
  height: 400px;
  width: 100%;
  display: flex;
  background-image: linear-gradient(90deg, rgba(0, 0, 0, 1) 60%, transparent),
    url(${(props) =&gt; props.image});
  background-size: contain;
  background-repeat: no-repeat;
  background-position: right;

  &amp; &gt; div {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: flex-start;
    padding-left: 10px;
  }
`;

const Banner = (props) =&gt; {
  return (
    &lt;StyledContainer image={props.image}&gt;
      &lt;div&gt;{props.children}&lt;/div&gt;
    &lt;/StyledContainer&gt;
  );
};

&lt;Banner image="https://m.media-amazon.com/images/M/MV5BZjRlNDUxZjAtOGQ4OC00OTNlLTgxNmQtYTBmMDgwZmNmNjkxXkEyXkFqcGdeQXVyNzkwMjQ5NzM@._V1_.jpg"&gt;
  &lt;h1 style={{ color: "yellow" }}&gt;Die hard&lt;/h1&gt;
&lt;/Banner&gt;;
</code></pre>
<p>We have created a new styled component called <code>StyledContainer</code>. It consists of CSS that will align the image to the right and apply a black gradient around the container so that only the movie title is visible. </p>
<p>Next, in the <code>&amp; &gt; div</code> section we make sure the all the children components are aligned to the left. Here is what it will look like:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/image-103.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Yupiee! our Banner component is all set. Let's now test this banner component with all the components that we created above. Place the <code>Title</code>, <code>Tags</code>, and <code>Description</code> component inside the <code>Banner</code> component like below:</p>
<pre><code class="lang-tsx">&lt;Banner image="https://m.media-amazon.com/images/M/MV5BZjRlNDUxZjAtOGQ4OC00OTNlLTgxNmQtYTBmMDgwZmNmNjkxXkEyXkFqcGdeQXVyNzkwMjQ5NzM@._V1_.jpg"&gt;
  &lt;Title title="Die Hard" /&gt;
  &lt;Tags tags={["Action", "Thriller"]} /&gt;
  &lt;Description description="NYPD cop John McClane's plan to reconcile with his estranged wife is thrown for a serious loop when, minutes after he arrives at her office, the entire building is overtaken by a group of terrorists. With little help from the LAPD, wisecracking McClane sets out to single-handedly rescue the hostages and bring the bad guys down." /&gt;
&lt;/Banner&gt;;
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/image-104.png" alt="Image" width="600" height="400" loading="lazy">
<em>This is how our Banner component will look like.</em></p>
<h2 id="heading-how-to-stitch-all-the-components-together-with-the-compound-pattern">How to Stitch All the Components Together with the Compound Pattern</h2>
<p>We want our Banner component to be easy to use, and it should be flexible. We can stitch the Title, Tags, and Description components into the Banner component with the help of a compound pattern. </p>
<p>Components created with this pattern share the state and logic between their internal components. An example of such a compound pattern is a <a target="_blank" href="https://react.semantic-ui.com/collections/menu/#types-basic">Menu component provided by semantic UI.</a></p>
<pre><code class="lang-tsx">&lt;Menu&gt;
  &lt;Menu.Item /&gt;
&lt;/Menu&gt;;
</code></pre>
<p>The advantage of using such a pattern is that we just need to import one component – in our case we will just import the Banner component. All its internal components can be used directly like below:</p>
<pre><code class="lang-tsx">&lt;Banner.Title /&gt;
&lt;Banner.Tags /&gt;
&lt;Banner.Description /&gt;
</code></pre>
<p>Now let's start doing the same for our Banner component.</p>
<p>Since we have all the components ready, I have placed the same inside one file:</p>
<pre><code class="lang-tsx">import "./styles.css";
import styled from "styled-components";
import React from "react";

export type BannerProps = {
  title: string,
  tags: string[],
  description: string,
  image: string,
};

const StyledTitle = styled.div`
  font-size: 28px;
  font-weight: 600;
  color: white;
`;

const StyledTag = styled.div`
  padding: 0.5rem 0;

  &amp; span {
    margin-right: 0.5rem;
    font-size: 1rem;
    font-weight: 500;
    color: rgba(255, 255, 255, 0.6);
  }
`;

const StyledDescription = styled.div`
  text-align: start;
  color: rgba(255, 255, 255, 0.8);
  display: -webkit-box;
  max-width: 50%;
  -webkit-line-clamp: 4;
  -webkit-box-orient: vertical;
  overflow: hidden;
`;
const Container = styled.div`
  height: 400px;
  width: 100%;
  display: flex;
  background-image: linear-gradient(90deg, rgba(0, 0, 0, 1) 60%, transparent),
    url(${(props: Pick&lt;BannerProps, "image"&gt;) =&gt; props.image});
  background-size: contain;
  background-repeat: no-repeat;
  background-position: right;

  &amp; &gt; div {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: flex-start;
    padding-left: 10px;
  }
`;

const Title = ({ title }: Pick&lt;BannerProps, "title"&gt;) =&gt; (
  &lt;StyledTitle&gt;{title}&lt;/StyledTitle&gt;
);

const Tags = ({ tags }: Pick&lt;BannerProps, "tags"&gt;) =&gt; {
  return (
    &lt;StyledTag&gt;
      {tags.map((tag) =&gt; (
        &lt;span key={`tag-${tag}`}&gt;{tag}&lt;/span&gt;
      ))}
    &lt;/StyledTag&gt;
  );
};

const Description = ({ description }: Pick&lt;BannerProps, "description"&gt;) =&gt; (
  &lt;StyledDescription&gt;{description}&lt;/StyledDescription&gt;
);

const Banner = (props: any) =&gt; {
  return (
    &lt;Container image={props.image}&gt;
      &lt;div&gt;{props.children}&lt;/div&gt;
    &lt;/Container&gt;
  );
};

Banner.Title = Title;
Banner.Tags = Tags;
Banner.Description = Description;

export default Banner;
</code></pre>
<p>Quick explanation of the above code:</p>
<p>First, we create the typings for the Banner Component called BannerProps. It looks like this:</p>
<pre><code class="lang-tsx">export type BannerProps = {
  title: string;
  tags: string[];
  description: string;
  image: string;
};
</code></pre>
<p>Next, we place all the atomic components that we created here. We also make sure that we use the BannerProps type in each function definition of the atomic components, for example:</p>
<pre><code class="lang-tsx">const Title = ({ title }: Pick&lt;BannerProps, "title"&gt;) =&gt; (
  &lt;StyledTitle&gt;{title}&lt;/StyledTitle&gt;
);
</code></pre>
<p>As you can see, we use the Pick utility function of TypeScript to pick up only the title prop from the Banner props.</p>
<p>Lastly, we stitch all these components by creating a new property to the Banner component like below and export this component:</p>
<pre><code class="lang-tsx">Banner.Title = Title;
Banner.Tags = Tags;
Banner.Description = Description;

export default Banner;
</code></pre>
<p><strong>NOTE:</strong> For the purpose of this tutorial, we are using the compound pattern, but you can use these atomic components independently. I chose to use the compound pattern here to teach you how to use it. You can apply it in different scenarios like when building a select button or a menu component.</p>
<p>Nice job – we have finally stitched all our atomic components into a single Banner component. In the next section, we are going to talk about using this component.</p>
<h2 id="heading-how-to-build-the-image-carousel-component">How to Build the Image Carousel Component</h2>
<p>Finally, we have arrived at the point where we can build the image carousel component. In this section we are going to do the following things:</p>
<ul>
<li>Build a Banner Tile component that will act as a single image inside the carousel</li>
<li>Build the image carousel component.</li>
</ul>
<p>Let's create the Banner Tile component first. The intention of this component is to use the <code>Banner</code> component. </p>
<p>First, we will start by creating sample data which we can iterate over. Create a file named <code>sampledata.json</code> and place the following content inside it:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"data"</span>: [
    {
      <span class="hljs-attr">"title"</span>: <span class="hljs-string">"The Last of Us"</span>,
      <span class="hljs-attr">"genres"</span>: [<span class="hljs-string">"Drama"</span>],
      <span class="hljs-attr">"cover_url"</span>: <span class="hljs-string">"https://www.themoviedb.org/t/p/w600_and_h900_bestv2/uKvVjHNqB5VmOrdxqAt2F7J78ED.jpg"</span>,
      <span class="hljs-attr">"description"</span>: <span class="hljs-string">"Twenty years after modern civilization has been destroyed, Joel, a hardened survivor, is hired to smuggle Ellie, a 14-year-old girl, out of an oppressive quarantine zone. What starts as a small job soon becomes a brutal, heartbreaking journey, as they both must traverse the United States and depend on each other for survival."</span>
    },
    {
      <span class="hljs-attr">"title"</span>: <span class="hljs-string">"Fight Club"</span>,
      <span class="hljs-attr">"genres"</span>: [<span class="hljs-string">"Drama"</span>, <span class="hljs-string">"Thriller"</span>, <span class="hljs-string">"Comedy"</span>],
      <span class="hljs-attr">"cover_url"</span>: <span class="hljs-string">"https://www.themoviedb.org/t/p/w300_and_h450_bestv2/pB8BM7pdSp6B6Ih7QZ4DrQ3PmJK.jpg"</span>,
      <span class="hljs-attr">"description"</span>: <span class="hljs-string">"A ticking-time-bomb insomniac and a slippery soap salesman channel primal male aggression into a shocking new form of therapy. Their concept catches on, with underground fight clubs forming in every town, until an eccentric gets in the way and ignites an out-of-control spiral toward oblivion."</span>
    },
    {
      <span class="hljs-attr">"title"</span>: <span class="hljs-string">"Creed III"</span>,
      <span class="hljs-attr">"genres"</span>: [<span class="hljs-string">"Drama"</span>, <span class="hljs-string">"Thriller"</span>],
      <span class="hljs-attr">"cover_url"</span>: <span class="hljs-string">"https://www.themoviedb.org/t/p/w600_and_h900_bestv2/cvsXj3I9Q2iyyIo95AecSd1tad7.jpg"</span>,
      <span class="hljs-attr">"description"</span>: <span class="hljs-string">"After dominating the boxing world, Adonis Creed has been thriving in both his career and family life. When a childhood friend and former boxing prodigy, Damien Anderson, resurfaces after serving a long sentence in prison, he is eager to prove that he deserves his shot in the ring. The face-off between former friends is more than just a fight. To settle the score, Adonis must put his future on the line to battle Damien - a fighter who has nothing to lose."</span>
    },
    {
      <span class="hljs-attr">"title"</span>: <span class="hljs-string">"Die Hard"</span>,
      <span class="hljs-attr">"genres"</span>: [<span class="hljs-string">"Action"</span>, <span class="hljs-string">"Thriller"</span>],
      <span class="hljs-attr">"cover_url"</span>: <span class="hljs-string">"https://www.themoviedb.org/t/p/w1280/yFihWxQcmqcaBR31QM6Y8gT6aYV.jpg"</span>,
      <span class="hljs-attr">"description"</span>: <span class="hljs-string">"NYPD cop John McClane's plan to reconcile with his estranged wife is thrown for a serious loop when, minutes after he arrives at her office, the entire building is overtaken by a group of terrorists. With little help from the LAPD, wisecracking McClane sets out to single-handedly rescue the hostages and bring the bad guys down."</span>
    }
  ]
}
</code></pre>
<p><strong>NOTE:</strong>  I used the <a target="_blank" href="http://themoviedb.org/">themoviedb.org</a> to get the above data.</p>
<p>Next, create a file named <code>BannerTile.tsx</code> inside the <code>components</code> directory. Then create a functional component that makes use of the Banner component like below:</p>
<pre><code class="lang-tsx">import Banner, { BannerProps } from "./Banner";

export default function BannerTile(props: BannerProps) {
  const { title, image, tags, description } = props;
  return (
    &lt;Banner image={image}&gt;
      &lt;Banner.Title title={title} /&gt;
      &lt;Banner.Tags tags={tags} /&gt;
      &lt;Banner.Description description={description} /&gt;
    &lt;/Banner&gt;
  );
}
</code></pre>
<p>Now to test this component, we can use <code>sampledata.json</code>. Go through the following steps to test the <code>BannerTile</code> component:</p>
<p>First, we should import the data from the sampledata.json:</p>
<pre><code class="lang-tsx">const sampleData = require('./sampledata.json');
</code></pre>
<p>Next, we iterate over this data with the map function. We also make sure that we call the <code>BannerTile</code> component on each of the data:</p>
<pre><code class="lang-tsx">&lt;div&gt;
  {sampleData.data.map((item: SampleData, index: number) =&gt; (
    &lt;BannerTile
      key={`key-${item.title}-${index}`}
      title={item.title}
      tags={item.genres}
      image={item.cover_url}
      description={item.description}
    /&gt;
  ))}
&lt;/div&gt;;
</code></pre>
<p>The output after running this code will look like the below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/image-121.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>To implement the image carousel we can use a package called <a target="_blank" href="https://swiperjs.com/get-started">Swiper</a>. We just need to place all the <code>BannerTiles</code> inside the component that is provided by the swiper. Now without any further delay, let's get started.</p>
<p>To install the swiper package, use the below command:</p>
<pre><code class="lang-shell">npm i swiper
</code></pre>
<p>Now let's create a new file named <code>HeroBanner.tsx</code>. This file will contain the <code>HeroBanner</code> component. The purpose of this component is to iterate over the movie data and display them via the image carousel and the <code>BannerTile</code> component.</p>
<p>Once we have installed the swiper library we can start consuming it. As per the swiper.js documentation, we need to import the CSS provided by it:</p>
<pre><code class="lang-tsx">import "swiper/css";
import "swiper/css/navigation";
</code></pre>
<p>Next, we also need to import the components from swiper.js that will help us to build the image carousel. Import the following components:</p>
<pre><code class="lang-tsx">import { Swiper, SwiperSlide } from "swiper/react";
import { Navigation } from "swiper";
</code></pre>
<p>Now let's also import the <code>BannerTile</code>, the types associated with the Banner, and the <code>sampleData</code> from the <code>sampledata.json</code>:</p>
<pre><code class="lang-tsx">import "swiper/css";
import "swiper/css/navigation";

import { Swiper, SwiperSlide } from "swiper/react";
import { Navigation } from "swiper";

import BannerTile from "./BannerTile";
import { BannerProps } from "./Banner";

const sampleData = require("../utilities/sampledata.json");
</code></pre>
<p>The <code>sampleData</code> that we imported just now only contains the title, genres, cover_url, and description. This is the perfect time to make use of the type <code>BannerProps</code> to filter out only the types that we need. </p>
<pre><code class="lang-tsx">type SampleData = Pick&lt;BannerProps, 'title' | 'description'&gt; &amp; {
    genres: string[];
  cover_url: string;
}
</code></pre>
<p>Now let's start with actually building this component. Create a functional component called <code>HeroBanner</code> and place the following code inside it:</p>
<pre><code class="lang-tsx">const HeroBanner = () =&gt; (
  &lt;Swiper navigation modules={[Navigation]} slidesPerView={1}&gt;
    {sampleData.data.map((item: SampleData, index: number) =&gt; (
      &lt;SwiperSlide key={`key-${item.title}-${index}`}&gt;
        &lt;BannerTile
          title={item.title}
          tags={item.genres}
          image={item.cover_url}
          description={item.description}
        /&gt;
      &lt;/SwiperSlide&gt;
    ))}
  &lt;/Swiper&gt;
);
</code></pre>
<p>In the HeroBanner component we do the following things:</p>
<ul>
<li>We use the <code>Swiper</code> component provided by the swiper.js library that acts as a wrapper container around all the images, that is the <code>BannerTile</code> component. We made sure that there is only one slide per view.</li>
<li>While mapping over the <code>sampleData</code> we make sure that each of the <code>BannerTile</code> component is wrapped by the <code>SwiperSlide</code> component.</li>
</ul>
<p>To know more about the swiper’s React components you can refer to their <a target="_blank" href="https://swiperjs.com/react">documentation</a>.</p>
<p>The final output will look something like the below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/image-122.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>We finally got what we wanted: an image carousel component that just looks and functions like the ones on popular OTT platforms. </p>
<p>But there is one last thing we need to do here. We need to make sure that the left and the right arrow are white so they stand out. To do that we make use of styled-components:</p>
<pre><code class="lang-tsx">export const StyledSwiper = styled(Swiper)`
  &amp; .swiper-button-next,
  .swiper-button-prev {
    color: white;
  }
`;
</code></pre>
<p>Now we edit our HeroBanner component. We replace the Swiper component with the StyledSwiper component like below:</p>
<pre><code class="lang-tsx">const HeroBanner = () =&gt; (
  &lt;StyledSwiper navigation modules={[Navigation]} slidesPerView={1}&gt;
    {sampleData.data.map((item: SampleData, index: number) =&gt; (
      &lt;SwiperSlide key={`key-${item.title}-${index}`}&gt;
        &lt;BannerTile
          title={item.title}
          tags={item.genres}
          image={item.cover_url}
          description={item.description}
        /&gt;
      &lt;/SwiperSlide&gt;
    ))}
  &lt;/StyledSwiper&gt;
);
</code></pre>
<p>Here is how it will look:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/image-123.png" alt="Image" width="600" height="400" loading="lazy">
<em>Now that looks nice</em></p>
<h2 id="heading-summary">Summary</h2>
<p>This is how you can create an image carousel for movie titles. In this tutorial, you learned:</p>
<ul>
<li>How to create atomic components</li>
<li>How to stitch all the components together via the compound pattern</li>
<li>How to create a BannerTile component that displays the information related to each movie</li>
<li>How to build an image carousel component with swiper.js</li>
</ul>
<p>The entire code for this tutorial can be found <a target="_blank" href="https://codesandbox.io/s/image-carousel-52hnep?file=/src/App.tsx">here</a>.</p>
<p>Thank you for reading!</p>
<p>Follow me on <a target="_blank" href="https://twitter.com/keurplkar">twitter</a>, <a target="_blank" href="http://github.com/keyurparalkar">github</a>, and <a target="_blank" href="https://www.linkedin.com/in/keyur-paralkar-494415107/">linkedIn</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Separation of Concerns in React –How to Use Container and Presentational Components ]]>
                </title>
                <description>
                    <![CDATA[ Many new React developers combine logic and presentation inside the same React component. And they may not know why it's important to separate these two – they just want to make it work.  But later, they'll find that they need to make changes to the ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/separation-of-concerns-react-container-and-presentational-components/</link>
                <guid isPermaLink="false">66bb55554c9d249e52882f2f</guid>
                
                    <category>
                        <![CDATA[ components ]]>
                    </category>
                
                    <category>
                        <![CDATA[ hooks ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Keyur Paralkar ]]>
                </dc:creator>
                <pubDate>Tue, 06 Dec 2022 21:43:19 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/12/container-and-presentational-component-pattern-image.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Many new React developers combine logic and presentation inside the same React component. And they may not know why it's important to separate these two – they just want to make it work. </p>
<p>But later, they'll find that they need to make changes to the file and doing so becomes a humungous task. Then they'll have to re-work things to separate these two parts.</p>
<p>This comes from not knowing about the separation of concerns and the presentation and container components pattern. That's why I'm going to teach you about them so you can mitigate this problem early in your project's development lifecycle.</p>
<p>In this article, we are going to dive into container and presentational components and briefly touch on the concept of separation of concerns.</p>
<p>Without further ado, let's get started!</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><a class="post-section-overview" href="#heading-what-is-the-separation-of-concerns">What is the separation of concerns?</a></li>
<li><a class="post-section-overview" href="#heading-what-are-container-and-presentational-components">What are presentation and container components?</a></li>
<li><a class="post-section-overview" href="#heading-why-do-we-need-these-components">Why do we need these components?</a></li>
<li><a class="post-section-overview" href="#heading-presentation-and-container-component-example">Presentation and container component example</a></li>
<li><a class="post-section-overview" href="#heading-how-to-replace-container-components-with-react-hooks">How to replace container components with React hooks</a></li>
<li><a class="post-section-overview" href="#heading-summary">Summary</a></li>
</ul>
<h2 id="heading-what-is-the-separation-of-concerns">What is the Separation of Concerns?</h2>
<p>Separation of concerns is a concept that is widely used in programming. It states that logic that performs different actions should not be groupled or combined together. </p>
<p>For example, what we discussed in the introduction section violates the separation of concerns, because we placed the logic of fetching the data and presenting the data in the same component. </p>
<p>To solve this and to adhere to the separation of concerns, we should separate these two pieces of logic – that is, fetching data and presenting it on the UI – into two different components. </p>
<p>This is were the container and presentation component pattern will help us solve this issue. In the following sections, we are going to dive deep into this pattern.</p>
<h2 id="heading-what-are-container-and-presentational-components">What are Container and Presentational Components?</h2>
<p>To achieve a separation of concerns we have two types of components:</p>
<ul>
<li>Container components</li>
<li>Presentational components</li>
</ul>
<h3 id="heading-container-components">Container components</h3>
<p>These are the components that provide, create, or hold data for the children components. </p>
<p>The only job of a container component is to handle data. It does not consist of any UI of its own. Rather, it consists of presentational components as its children that uses this data. </p>
<p>A simple example would be a component named <code>FetchUserContainer</code> that consists of some logic that fetches all the users.</p>
<h3 id="heading-presentational-components">Presentational components</h3>
<p>These are the components whose primary responsibility is to present the data on the UI. They take in the data from the container components. </p>
<p>These components are stateless unless they need their own state for rendering the UI. They do not alter the data that they receive.</p>
<p>An example of this would be a <code>UserList</code> component that displays all the users.</p>
<h2 id="heading-why-do-we-need-these-components">Why Do We Need These Components?</h2>
<p>To understand this, let's take a simple example. We want to display a list of posts that we fetch from the <a target="_blank" href="https://jsonplaceholder.typicode.com/">JSON placeholder API</a>. Here is the code for the same:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { useEffect, useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-keyword">interface</span> Post {
  userId: <span class="hljs-built_in">number</span>;
  id: <span class="hljs-built_in">number</span>;
  title: <span class="hljs-built_in">string</span>;
  body: <span class="hljs-built_in">string</span>;
}

<span class="hljs-comment">/**
 * An example of how we shouldn't combine the logic and presentation of data.
 */</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">DisplayPosts</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [posts, setPosts] = useState&lt;Post[] | <span class="hljs-literal">null</span>&gt;(<span class="hljs-literal">null</span>);
  <span class="hljs-keyword">const</span> [isLoading, setIsLoading] = useState&lt;<span class="hljs-built_in">Boolean</span>&gt;(<span class="hljs-literal">false</span>);
  <span class="hljs-keyword">const</span> [error, setError] = useState&lt;unknown&gt;();

<span class="hljs-comment">// Logic</span>
  useEffect(<span class="hljs-function">() =&gt;</span> {
    (<span class="hljs-keyword">async</span> () =&gt; {
      <span class="hljs-keyword">try</span> {
        setIsLoading(<span class="hljs-literal">true</span>);
        <span class="hljs-keyword">const</span> resp = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">"https://jsonplaceholder.typicode.com/posts"</span>);
        <span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> resp.json();
        setPosts(data);
        setIsLoading(<span class="hljs-literal">false</span>);
      } <span class="hljs-keyword">catch</span> (err) {
        setError(err);
        setIsLoading(<span class="hljs-literal">false</span>);
      }
    })();
  }, []);

<span class="hljs-comment">// Presentation</span>
  <span class="hljs-keyword">return</span> isLoading ? (
    &lt;span&gt;Loading... &lt;/span&gt;
  ) : posts ? (
    &lt;ul&gt;
      {posts.map(<span class="hljs-function">(<span class="hljs-params">post: Post</span>) =&gt;</span> (
        &lt;li key={<span class="hljs-string">`item-<span class="hljs-subst">${post.id}</span>`</span>}&gt;
          &lt;span&gt;{post.title}&lt;/span&gt;
        &lt;/li&gt;
      ))}
    &lt;/ul&gt;
  ) : (
    &lt;span&gt;{<span class="hljs-built_in">JSON</span>.stringify(error)}&lt;/span&gt;
  );
}
</code></pre>
<p>Here is what this component does:</p>
<ul>
<li>It has 3 state variables: <code>posts</code>, <code>isLoading</code>, and <code>error</code>.</li>
<li>We have a <code>useEffect</code> hook that consists of the business logic. Here we are fetching the data from the API: <code>[https://jsonplaceholder.typicode.com/posts](https://jsonplaceholder.typicode.com/posts)</code> with the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch">fetch API</a>.</li>
<li>We make sure that when the data is fetched, we store it in the <code>posts</code> state variable using <code>setPosts</code>.</li>
<li>We also make sure that we toggle the <code>isLoading</code> and <code>error</code> values during the respective scenarios.</li>
<li>We put this entire logic inside an async IIFE.</li>
<li>Finally, we return the posts in the form of an unordered list and map through all the posts that we fetched earlier.</li>
</ul>
<p>The problem with the above is that the logic of fetching the data and displaying the data is coded into a single component. We can say that the component is now tightly coupled with the logic. This is the exact thing that we don’t want.</p>
<p>Below are some reasons as to why we require container and presentational components:</p>
<ul>
<li>They help us create components that are loosely coupled</li>
<li>They help us maintain separation of concerns</li>
<li>Code refactoring becomes much easier.</li>
<li>Code becomes more organized and maintainable</li>
<li>It makes testing much easier.</li>
</ul>
<h2 id="heading-presentation-and-container-component-example">Presentation and Container Component Example</h2>
<p>Ok, enough talk – let’s get things working by starting off with a simple example. We are going to use the same example as above – fetching the data from a JSON placeholder API.</p>
<p>Let's understand the file structure here: </p>
<ul>
<li>Our container component will be <code>PostContainer</code></li>
<li>We will be having two presentation components:<ul>
<li><code>Posts</code>: A component that has an unordered list.</li>
<li><code>SinglePost</code>: A component that renders a list tag. This will render each element of the list.</li>
</ul>
</li>
</ul>
<p>Note: We are going to store all the above components in a separate folder named <code>components</code>.</p>
<p>Now that we know which things go where, let's start off with the container component: <code>PostContainer</code>. Copy-paste the below code into the <code>components/PostContainer.tsx</code> file</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { useEffect, useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { ISinglePost } <span class="hljs-keyword">from</span> <span class="hljs-string">"../Definitions"</span>;
<span class="hljs-keyword">import</span> Posts <span class="hljs-keyword">from</span> <span class="hljs-string">"./Posts"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">PostContainer</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [posts, setPosts] = useState&lt;ISinglePost[] | <span class="hljs-literal">null</span>&gt;(<span class="hljs-literal">null</span>);
  <span class="hljs-keyword">const</span> [isLoading, setIsLoading] = useState&lt;<span class="hljs-built_in">Boolean</span>&gt;(<span class="hljs-literal">false</span>);
  <span class="hljs-keyword">const</span> [error, setError] = useState&lt;unknown&gt;();

  useEffect(<span class="hljs-function">() =&gt;</span> {
    (<span class="hljs-keyword">async</span> () =&gt; {
      <span class="hljs-keyword">try</span> {
        setIsLoading(<span class="hljs-literal">true</span>);
        <span class="hljs-keyword">const</span> resp = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">"https://jsonplaceholder.typicode.com/posts"</span>);
        <span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> resp.json();
        setPosts(data.filter(<span class="hljs-function">(<span class="hljs-params">post: ISinglePost</span>) =&gt;</span> post.userId === <span class="hljs-number">1</span>));
        setIsLoading(<span class="hljs-literal">false</span>);
      } <span class="hljs-keyword">catch</span> (err) {
        setError(err);
        setIsLoading(<span class="hljs-literal">false</span>);
      }
    })();
  }, []);

  <span class="hljs-keyword">return</span> isLoading ? (
    &lt;span&gt;Loading... &lt;/span&gt;
  ) : posts ? (
    &lt;Posts posts={posts} /&gt;
  ) : (
    &lt;span&gt;{<span class="hljs-built_in">JSON</span>.stringify(error)}&lt;/span&gt;
  );
}
</code></pre>
<p>From the example we saw in the previous section of this article, the above code just contains the logic of fetching the data. This logic is present in the <code>useEffect</code> hook. Here this container component passes this data to the <code>Posts</code> presentational component.</p>
<p>Let's have a look at the <code>Posts</code> presentational component. Copy-paste the below code in the <code>components/Posts.tsx</code> file:</p>
<pre><code class="lang-typescript"><span class="hljs-comment">/**
 * A presentational component
 */</span>

<span class="hljs-keyword">import</span> { ISinglePost } <span class="hljs-keyword">from</span> <span class="hljs-string">"../Definitions"</span>;
<span class="hljs-keyword">import</span> SinglePost <span class="hljs-keyword">from</span> <span class="hljs-string">"./SinglePost"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Posts</span>(<span class="hljs-params">props: { posts: ISinglePost[] }</span>) </span>{
  <span class="hljs-keyword">return</span> (
    &lt;ul
      style={{
        display: <span class="hljs-string">"flex"</span>,
        flexDirection: <span class="hljs-string">"column"</span>,
        alignItems: <span class="hljs-string">"center"</span>
      }}
    &gt;
      {props.posts.map(<span class="hljs-function">(<span class="hljs-params">post: ISinglePost</span>) =&gt;</span> (
        &lt;SinglePost {...post} /&gt;
      ))}
    &lt;/ul&gt;
  );
}
</code></pre>
<p>As you can see, this is a simple file that consists of a <code>ul</code> tag – an unordered list. This component then maps over the <code>posts</code> that are being passed as props. We pass each to the <code>SinglePost</code> component.</p>
<p>There is another presentational component that renders the list tag, that is the <code>li</code> tag. It displays the title and the body of the post. Copy-paste the below code in the <code>components/SinglePost.tsx</code> file:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { ISinglePost } <span class="hljs-keyword">from</span> <span class="hljs-string">"../Definitions"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">SinglePost</span>(<span class="hljs-params">props: ISinglePost</span>) </span>{
  <span class="hljs-keyword">const</span> { userId, id, title, body } = props;
  <span class="hljs-keyword">return</span> (
    &lt;li key={<span class="hljs-string">`item-<span class="hljs-subst">${userId}</span>-<span class="hljs-subst">${id}</span>`</span>} style={{ width: <span class="hljs-number">400</span> }}&gt;
      &lt;h4&gt;
        &lt;strong&gt;{title}&lt;/strong&gt;
      &lt;/h4&gt;
      &lt;span&gt;{body}&lt;/span&gt;
    &lt;/li&gt;
  );
}
</code></pre>
<p>These presentational components, as you can see, just display the data on the screen. That’s all. They don’t do anything else. Since they are just displaying the data here, they will also have their own styling.</p>
<p>Now that we have setup the components, let's look back on what we have achieved here:</p>
<ul>
<li>The concept of separation of concerns is not violated in this example.</li>
<li>Writing unit tests for each component becomes easier.</li>
<li>Code maintainability and readability are much better. Thus our codebase has become much more organized.</li>
</ul>
<p>We have achieved what we wanted here, but we can further enhance this pattern with the help of hooks.</p>
<h2 id="heading-how-to-replace-container-components-with-react-hooks">How to Replace Container Components with React Hooks</h2>
<p>Since <strong>React 16.8.0</strong>, it has become so much easier to build and develop components with the help of functional components and hooks. </p>
<p>We are going to leverage these capabilities here and replace the container component with a hook.</p>
<p>Copy-paste the below code in the <code>hooks/usePosts.ts</code> file:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { useEffect, useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { ISinglePost } <span class="hljs-keyword">from</span> <span class="hljs-string">"../Definitions"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">usePosts</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [posts, setPosts] = useState&lt;ISinglePost[] | <span class="hljs-literal">null</span>&gt;(<span class="hljs-literal">null</span>);
  <span class="hljs-keyword">const</span> [isLoading, setIsLoading] = useState&lt;<span class="hljs-built_in">Boolean</span>&gt;(<span class="hljs-literal">false</span>);
  <span class="hljs-keyword">const</span> [error, setError] = useState&lt;unknown&gt;();

  useEffect(<span class="hljs-function">() =&gt;</span> {
    (<span class="hljs-keyword">async</span> () =&gt; {
      <span class="hljs-keyword">try</span> {
        setIsLoading(<span class="hljs-literal">true</span>);
        <span class="hljs-keyword">const</span> resp = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">"https://jsonplaceholder.typicode.com/posts"</span>);
        <span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> resp.json();
        setPosts(data.filter(<span class="hljs-function">(<span class="hljs-params">post: ISinglePost</span>) =&gt;</span> post.userId === <span class="hljs-number">1</span>));
        setIsLoading(<span class="hljs-literal">false</span>);
      } <span class="hljs-keyword">catch</span> (err) {
        setError(err);
        setIsLoading(<span class="hljs-literal">false</span>);
      }
    })();
  }, []);

  <span class="hljs-keyword">return</span> {
    isLoading,
    posts,
    error
  };
}
</code></pre>
<p>Here we have,</p>
<ul>
<li>Extracted logic that was present in the <code>PostContainer</code> component into a hook.</li>
<li>This hook will return an object that contains the <code>isLoading</code>, <code>posts</code>, and <code>error</code> values.</li>
</ul>
<p>Now we can simply remove the container component <code>PostContainer</code>. Then, rather than passing the container's data to the presentational components as a prop, we can directly use this hook inside the <code>Posts</code> presentational component.</p>
<p>Make the following edits to the <code>Posts</code> component:</p>
<pre><code class="lang-typescript"><span class="hljs-comment">/**
 * A presentational component
 */</span>

<span class="hljs-keyword">import</span> { ISinglePost } <span class="hljs-keyword">from</span> <span class="hljs-string">"../Definitions"</span>;
<span class="hljs-keyword">import</span> usePosts <span class="hljs-keyword">from</span> <span class="hljs-string">"../hooks/usePosts"</span>;
<span class="hljs-keyword">import</span> SinglePost <span class="hljs-keyword">from</span> <span class="hljs-string">"./SinglePost"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Posts</span>(<span class="hljs-params">props: { posts: ISinglePost[] }</span>) </span>{
  <span class="hljs-keyword">const</span> { isLoading, posts, error } = usePosts();

  <span class="hljs-keyword">return</span> (
    &lt;ul
      style={{
        display: <span class="hljs-string">"flex"</span>,
        flexDirection: <span class="hljs-string">"column"</span>,
        alignItems: <span class="hljs-string">"center"</span>
      }}
    &gt;
      {isLoading ? (
        &lt;span&gt;Loading...&lt;/span&gt;
      ) : posts ? (
        posts.map(<span class="hljs-function">(<span class="hljs-params">post: ISinglePost</span>) =&gt;</span> &lt;SinglePost {...post} /&gt;)
      ) : (
        &lt;span&gt;{<span class="hljs-built_in">JSON</span>.stringify(error)}&lt;/span&gt;
      )}
    &lt;/ul&gt;
  );
}
</code></pre>
<p>By making use of hooks we have eliminated an extra layer of component that was present on top of these presentational components. </p>
<p>With hooks, we achieved the same results as that of the container/presentational components pattern.</p>
<h2 id="heading-summary">Summary</h2>
<p>So in this article, we learned about:</p>
<ul>
<li>Separation of concerns</li>
<li>Container and presentational components</li>
<li>Why we need these components</li>
<li>How hooks can replace container components</li>
</ul>
<p>For further reading I would highly recommend going through the <a target="_blank" href="https://tanstack.com/table/v8/">react-table:</a>. This library extensively uses hooks and it has great examples.</p>
<p>You can find the entire code for this article in this <a target="_blank" href="https://codesandbox.io/s/container-presentation-pattern-lm1osl?file=/src/components/PostContainer.tsx">codesandbox</a>.</p>
<p>Thanks for reading!</p>
<p>Follow me on <a target="_blank" href="https://twitter.com/keurplkar">Twitter</a>, <a target="_blank" href="https://github.com/keyurparalkar">GitHub</a>, and <a target="_blank" href="https://www.linkedin.com/in/keyur-paralkar-494415107/">LinkedIn</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How JavaScript's Proxy Object Works – Explained with Example Use Cases ]]>
                </title>
                <description>
                    <![CDATA[ In this tutorial, you are going to learn what a proxy object is, along with its limitations.  We will also look into some of the use cases that demonstrate how you can use proxy objects to solve various problems. Without further ado, let’s get starte... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/javascript-proxy-object/</link>
                <guid isPermaLink="false">66bb554fe326dc37a9d68ee5</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Keyur Paralkar ]]>
                </dc:creator>
                <pubDate>Mon, 31 Oct 2022 14:56:30 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/10/Image-defs.001-1.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this tutorial, you are going to learn what a proxy object is, along with its limitations. </p>
<p>We will also look into some of the use cases that demonstrate how you can use proxy objects to solve various problems.</p>
<p>Without further ado, let’s get started.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></li>
<li><a class="post-section-overview" href="#heading-what-is-a-proxy">What is a proxy?</a></li>
<li><a class="post-section-overview" href="#heading-how-to-restrict-an-object-to-have-a-specific-property">How to restrict an object to have a specific property</a></li>
<li><a class="post-section-overview" href="#heading-a-small-detour-what-is-the-reflect-api">A small detour – what is the Reflect API</a>?</li>
<li><a class="post-section-overview" href="#heading-array-slicing-like-python">Array slicing like Python</a></li>
<li><a class="post-section-overview" href="#heading-disadvantages-of-using-proxies">Disadvantages of using proxies</a></li>
<li><a class="post-section-overview" href="#heading-summary">Summary</a></li>
</ul>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>I would highly recommend going through the following topics to follow along with this tutorial:</p>
<ul>
<li><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Learn/Getting_started_with_the_web/JavaScript_basics">Basics of JavaScript</a>.</li>
<li><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object#instance_methods">Object instance methods.</a></li>
<li>How to use the <a target="_blank" href="https://www.freecodecamp.org/news/understand-call-apply-and-bind-in-javascript-with-examples/#how-to-use-the-apply-function-in-javascript">apply function in JavaScript.</a></li>
</ul>
<h2 id="heading-what-is-a-proxy">What is a proxy?</h2>
<p>From <a target="_blank" href="https://www.merriam-webster.com/dictionary/proxy">merriam-webster</a>:</p>
<blockquote>
<p><em>A proxy may refer to a person who is authorized to act for another or it may designate the function or authority of serving in another’s stead.</em></p>
</blockquote>
<p>So a proxy is nothing but a mediator that speaks or operates on behalf of the given party. </p>
<p>In terms of programming, the word proxy also means an entity that acts on behalf of an object or a system. Since we have this term sorted out, let's understand what it signifies in JavaScript. </p>
<p>In JavaScript, there is a special object called a Proxy. It helps you create another object on behalf of the original object. </p>
<p>This new proxy object will act as a mediator between the real world and the original object. In this way, we will have more control over the interaction with the original object. </p>
<p>Using a proxy is a powerful way to interact with the object rather than interacting directly with it. </p>
<p>Here is the syntax for declaring a proxy object:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">new</span> <span class="hljs-built_in">Proxy</span>(&lt;object&gt;, &lt;handler&gt;)
</code></pre>
<p>The <code>Proxy</code> takes two parameters:</p>
<ul>
<li><code>&lt;object&gt;</code>: The object that needs to be proxied.</li>
<li><code>&lt;handler&gt;</code>: An object that defines the list of methods that can be intercepted. These are also called traps.</li>
</ul>
<p>Let's have a look at a simple example:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> books = {
    <span class="hljs-string">"Deep work"</span>: <span class="hljs-string">"Cal Newport"</span>,
    <span class="hljs-string">"Atomic Habits"</span>: <span class="hljs-string">"James Clear"</span>
}
<span class="hljs-keyword">const</span> proxyBooksObj = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Proxy</span>(books, {
    <span class="hljs-attr">get</span>: <span class="hljs-function">(<span class="hljs-params">target, key</span>) =&gt;</span> {
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Fetching book <span class="hljs-subst">${key}</span> by <span class="hljs-subst">${target[key]}</span>`</span>);
        <span class="hljs-keyword">return</span> target[key];
    }
})
</code></pre>
<p>Here we would like to intercept the <code>get</code> functionality of the object <code>books</code> so we can log the book name and the author of the book to the console.</p>
<p>To achieve this, we created a new proxy object called <code>proxyBooksObj</code>. This object is constructed using the <code>Proxy</code> function that we saw earlier. It takes <code>books</code> as the object to be proxied, and an object that consists of handler functions that need to be trapped. </p>
<p>Since we need to intercept the <code>get</code> functionality, we added a <code>get</code> property that accepts a function. This handler function will accept a function that takes in <code>target</code> <code>key</code>. </p>
<p>This was a pretty simple example of proxy in JavaScript. There are various use cases of a proxy – for example, it can help in validation, formatting, notification, and debugging. </p>
<p>To learn more about the available handlers/traps here is the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy#a_complete_traps_list_example">list</a>.</p>
<p>Now let's look at an example that will provide us with more clarity on how proxies work.</p>
<h2 id="heading-how-to-restrict-an-object-to-have-a-specific-property">How to Restrict an Object to Have a Specific Property</h2>
<p>Sometimes it can be useful to restrict users so that they only have a specific property, just like what <code>useRef</code> does in React. It only allows editing the <code>current</code> property of the object that is returned by <code>useRef</code>. </p>
<p>Let's create a proxy function that will allow the user to only update the <code>current</code> property and not allow them to create any other properties.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> data = {};

<span class="hljs-keyword">const</span> newProxy = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Proxy</span>(data, {
  <span class="hljs-attr">set</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">target, key, value</span>) </span>{
    <span class="hljs-keyword">if</span> (key === <span class="hljs-string">"current"</span>) {
      <span class="hljs-built_in">Reflect</span>.set(target, key, value);
      <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
    }
    <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
  }
});

newProxy.current = <span class="hljs-number">1</span>;
newProxy.point = <span class="hljs-number">1</span>; <span class="hljs-comment">// Throws error</span>
</code></pre>
<p>Here, since we are dealing with assigning a new value to an existing property or creating a new property, we use the <code>set</code> trap function. We need to tap into the set’s internal behavior of the object. </p>
<p>The <code>set</code> handler function will take in the <code>target</code>, <code>key</code>, and <code>value</code> where the target will be the target object, and the key and value are the property and the actual value. </p>
<p>We make sure that the key is <code>current</code>. When it is, we set the value to that property and return true. </p>
<p>It is important that we return <code>true</code> because this handler function expects to follow some <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/set#invariants">invariants</a>. If we do not want to set the value then we should return <code>false</code>.</p>
<p>There is also something to note about each trap function available inside the proxy that is invariant. Invariant is nothing but a condition that needs to be followed by every trap function so that the basic functionality doesn’t change.</p>
<p>Quoting from MDN’s Meta-programming guide:</p>
<blockquote>
<p><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Meta_programming#handlers_and_traps">Semantics that remain unchanged when implementing custom operations are called <em>invariants</em></a></p>
</blockquote>
<h3 id="heading-a-small-detour-what-is-the-reflect-api">A small detour – what is the Reflect API?</h3>
<p>We can also make use of the Reflect API here. JavaScript provides a built-in object that has a set of functions that can help intercept JavaScript operations. This can be operations such as <code>set</code>, <code>get</code>, <code>apply</code>, and so on. </p>
<p>To know more about the methods the Reflect API provides, you can go through the following <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect#static_methods">link</a>. </p>
<p>With this API, it makes it really simple to manipulate the target object present inside the proxy. A fun fact about Reflect API is that it is not an object that can be instantiated. All the methods provided by it are static.</p>
<p>In the previous example, we tried to return the value present at the property of the object directly by accessing the original object like this: <code>target[key]</code>. </p>
<p>Instead, here we can make use of <code>get</code> method of Reflect. So now our above example will look something like this:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> books = {
    <span class="hljs-string">"Deep work"</span>: <span class="hljs-string">"Cal Newport"</span>,
    <span class="hljs-string">"Atomic Habits"</span>: <span class="hljs-string">"James Clear"</span>
}
<span class="hljs-keyword">const</span> proxyBooksObj = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Proxy</span>(books, {
    <span class="hljs-attr">get</span>: <span class="hljs-function">(<span class="hljs-params">target, key</span>) =&gt;</span> {
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Fetching book <span class="hljs-subst">${key}</span> by <span class="hljs-subst">${target[key]}</span>`</span>);
        <span class="hljs-keyword">return</span> <span class="hljs-built_in">Reflect</span>.get(target, key);
    }
})
</code></pre>
<p>Now we know that we can make use of Reflect, but a question arises - why use Reflect?</p>
<p>We use Reflect because it allows us to implement the default behavior of the functions that were present on the original object. Rephrasing in technical terms, this allows us to implement the default forwarding behavior inside the trap functions. </p>
<p>Also with Reflect we can access internal functions and apply them to the proxy-wrapped object. </p>
<p>So it's beneficial for us to use Reflect APIs inside our proxy.</p>
<h2 id="heading-array-slicing-like-python">Array Slicing Like Python</h2>
<p>Python is a really cool language. A really awesome feature it provides is the way you can slice your arrays. Even Python’s <a target="_blank" href="https://www.w3schools.com/python/numpy/numpy_array_slicing.asp">NumPy</a> library provides this feature of slicing the array. </p>
<p>You can simply provide a start index (optional) and end index (optional) separated by a colon. Here is the syntax for slicing an array in Python:</p>
<pre><code class="lang-python">arr[&lt;start&gt;:&lt;end&gt;]
</code></pre>
<p>From the above syntax it is clear that <code>start</code> and <code>end</code> signify the <code>start</code> and <code>end</code> (exclusive) index positions for slicing. </p>
<p>Here is an example of how you can slice an array in Python:</p>
<pre><code class="lang-python">data = [<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">3</span>,<span class="hljs-number">4</span>]
print(data[<span class="hljs-number">1</span>:<span class="hljs-number">3</span>]) <span class="hljs-comment"># Output: [2, 3]</span>
</code></pre>
<p>Here is how you can do the same in JavaScript:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> data = [<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">3</span>,<span class="hljs-number">4</span>]
<span class="hljs-built_in">console</span>.log(data.slice(<span class="hljs-number">1</span>,<span class="hljs-number">3</span>)) <span class="hljs-comment">// Output: [2, 3]</span>
</code></pre>
<p>You need to use the <code>slice</code> function to slice the <code>data</code> array from index position <code>1</code> to index position <code>3</code>. </p>
<p>Note that slicing an array excludes the end index provided in the slice function or in Python’s slicing mechanism.</p>
<p>Wouldn’t it be great if we could achieve Python’s slicing mechanism in JavaScript as well? </p>
<p>We have again the Proxy object in JavaScript to the rescue. As we have established in an earlier section, proxies are a wrapper around the original object. They help you manage the interaction with the original object. </p>
<p>Let's again create this proxy object – but this time so that it has the slicing mechanism. Below is the code for implementing the slicing mechanism in JavaScript:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> arr = [<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">3</span>,<span class="hljs-number">4</span>];

<span class="hljs-keyword">const</span> arrProxy = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Proxy</span>(arr, {
  <span class="hljs-attr">get</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">target, key</span>) </span>{
    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> key === <span class="hljs-string">"string"</span> &amp;&amp; key.includes(<span class="hljs-string">":"</span>)) {
      <span class="hljs-keyword">let</span> [start, end] = key.split(<span class="hljs-string">":"</span>);
      <span class="hljs-keyword">if</span> (start === <span class="hljs-string">""</span>) {
        start = <span class="hljs-number">0</span>;
      } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (end === <span class="hljs-string">""</span>) {
        end = target.length;
      } <span class="hljs-keyword">else</span> {
        start = <span class="hljs-built_in">parseInt</span>(start, <span class="hljs-number">10</span>);
        end = <span class="hljs-built_in">parseInt</span>(end, <span class="hljs-number">10</span>);
      }

      <span class="hljs-keyword">return</span> <span class="hljs-built_in">Reflect</span>.apply(<span class="hljs-built_in">Array</span>.prototype.slice, target, [start, end]);
    }
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">Reflect</span>.get(target, key);
  }
});

<span class="hljs-built_in">console</span>.log(arrProxy[<span class="hljs-string">"1:3"</span>]) <span class="hljs-comment">// [2,3]</span>
</code></pre>
<p>Ok a lot of code here, but let's take a step back and understand what’s happening:</p>
<ul>
<li>We created a new <code>proxy</code> object on top of the array <code>arr</code>. Since we are planning to achieve slicing by providing the start and end position separated by a colon, we need to make some modifications on how to do the get functionality of an array.</li>
<li>To do this, we are going to make use of the <code>get</code> trap function that modifies the get mechanism for an array. We make sure to add this trap function as a <code>get</code> property inside the <code>handler</code> object of the <code>Proxy</code>.</li>
<li>A <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/get">get</a> trap function accepts <code>target</code> and <code>key</code> as it arguments. We make use of this to write our logic.</li>
<li>Since we are doing something like this <code>arrProxy["1:3"]</code>, in this case, the key is going to be of type string and it’s going to include<code>:</code> in it. Our main condition will be to distinguish on this same condition.</li>
</ul>
<pre><code class="lang-jsx"><span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> key === <span class="hljs-string">"string"</span> &amp;&amp; key.includes(<span class="hljs-string">":"</span>))
</code></pre>
<p>Next, we write some conditions that are requirements for the slicing mechanism in Python. Below are the requirements:</p>
<ul>
<li>Whenever the <code>start</code> index is not provided we should set <code>start</code> to 0.</li>
<li>Whenever the <code>end</code> index is not provided we should set <code>end</code> to the original array’s length.</li>
<li>If both of them are provided, then we convert them to integers.</li>
</ul>
<p>To do this, we need to make use of the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice">slice</a> function in JavaScript.</p>
<p>We will be using the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect">Reflect API’s</a> <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/apply">apply</a> method, to execute the function <code>slice</code> with this context (<code>target</code>) being the original array and arguments to the <code>slice</code> function being <code>[start, end]</code>.</p>
<p>In the end, if the <code>key</code> argument is of any other data type apart from a string, then we directly return the array with the help of <code>Reflect.get</code>.</p>
<h2 id="heading-disadvantages-of-using-proxies">Disadvantages of Using Proxies</h2>
<p>We now know how a proxy works along with its use cases. But it is also important to know some disadvantages of using proxies. </p>
<p>First of all, while it's cool to use proxies, it is a really really bad choice in scenarios where performance is a critical factor.</p>
<p>Second, no operation proxy forwarding is the mechanism of forwarding all the functionality of the target using a proxy. Here is what proxy forwarding looks like:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> data = {};
<span class="hljs-keyword">const</span> newData = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Proxy</span>(data, {}); <span class="hljs-comment">// No trap function.</span>

data.point = { <span class="hljs-attr">x</span>: <span class="hljs-number">1</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">2</span>};

<span class="hljs-built_in">console</span>.log(data);
</code></pre>
<p>This works just fine on regular objects but it won’t work for objects such as DOM nodes or objects that have internal slots. </p>
<p>For example, doing something like the below will generate an error:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> x = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">"div"</span>)
x.className = <span class="hljs-string">"hello"</span>

<span class="hljs-keyword">const</span> domProxy = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Proxy</span>(x, {});

<span class="hljs-built_in">console</span>.log(domProxy.getAttribute(<span class="hljs-string">"class"</span>)); <span class="hljs-comment">// Throws typeError</span>
</code></pre>
<p>This happens because the <code>this</code> value refers to the proxy object rather than referring to the original object. We can solve this by a get trap function that helps refer to the original object.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> y = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Proxy</span>(x, {
  get(target, key) {
    <span class="hljs-keyword">const</span> value = <span class="hljs-built_in">Reflect</span>.get(target, key);
    <span class="hljs-keyword">if</span>(<span class="hljs-keyword">typeof</span> value === <span class="hljs-string">"function"</span>){
      <span class="hljs-keyword">return</span> value.bind(target)
    }
    <span class="hljs-keyword">return</span> value;
  }
});

<span class="hljs-built_in">console</span>.log(y.getAttribute(<span class="hljs-string">"class"</span>)); <span class="hljs-comment">// Output: hello</span>
</code></pre>
<h2 id="heading-summary">Summary</h2>
<p>In this article, we learned about proxies in JavaScript along with their use cases. We also took a peek into some disadvantages of proxies.</p>
<p>If you like the idea of using proxies, then you can take it up a notch and try using them in various scenarios of validation or replicating some library functions such as <a target="_blank" href="https://lodash.com/docs/4.17.15#get">lodash’s get</a> and <a target="_blank" href="https://lodash.com/docs/4.17.15#set">set</a> functions.</p>
<p>That’s all. Thanks for reading.</p>
<p>Follow me on <a target="_blank" href="https://twitter.com/keurplkar">Twitter</a>, <a target="_blank" href="https://github.com/keyurparalkar">GitHub</a>, and <a target="_blank" href="https://www.linkedin.com/in/keyur-paralkar-494415107/">LinkedIn</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Singleton Design Pattern – How it Works in JavaScript with Example Code ]]>
                </title>
                <description>
                    <![CDATA[ At one point or another, you might need to use global state inside your React apps. This lets you have your data in one place and make sure the required components can access it. To help you do this, you'll often use some sort of state management lib... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/singleton-design-pattern-with-javascript/</link>
                <guid isPermaLink="false">66bb5558bf1e2b114113ed98</guid>
                
                    <category>
                        <![CDATA[ design patterns ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ singleton ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Keyur Paralkar ]]>
                </dc:creator>
                <pubDate>Mon, 18 Jul 2022 19:26:56 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/07/sven-mieke-fteR0e2BzKo-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>At one point or another, you might need to use global state inside your React apps. This lets you have your data in one place and make sure the required components can access it.</p>
<p>To help you do this, you'll often use some sort of state management library like Redux, React Context, or Recoil.</p>
<p>But in this article we are going to learn about global state management with the help of design patterns.</p>
<p>We will look at what design patterns are, and we'll focus on the singleton design pattern in particular. Finally we will look at an example of the singleton design pattern along with its advantages and disadvantages.</p>
<p>So without any further ado, let's get started.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-is-a-design-pattern">What is a design pattern</a>?</p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-is-the-singleton-design-pattern">What is the singleton design pattern</a>?</p>
</li>
<li><p><a class="post-section-overview" href="#heading-pros-and-cons-of-the-singleton-design-pattern">Pros and cons of the singleton design pattern</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-summary">Summary</a></p>
</li>
</ul>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Before going through this article, I would highly recommend being familiar with the content in the following articles:</p>
<ul>
<li><p><a target="_blank" href="https://www.freecodecamp.org/news/javascript-classes-how-they-work-with-use-case/">What are classes in JavaScript</a>?</p>
</li>
<li><p><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction#accessing_the_dom">How to access DOM elements</a></p>
</li>
<li><p><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze">How object freeze works</a></p>
</li>
</ul>
<h2 id="heading-what-is-a-design-pattern">What is a Design Pattern?</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/07/ezgif.com-gif-maker--9-.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Design patterns provide conceptual solutions to common problems</em></p>
<p>A design pattern is a set of generalised instructions that provide a solution to commonly occurring problems in software design.</p>
<p>You can think about design patterns as a website that consists of multiple design templates you can use to build a site based on your specific needs.</p>
<p>So, now the question is – why is it important to know design patterns? Well, using design patterns has several benefits, such as:</p>
<ul>
<li><p>These patterns are proven – that is, these instructions are tried and tested, and they reflect the experience and insights of many developers.</p>
</li>
<li><p>They're patterns that you can re-use easily.</p>
</li>
<li><p>They are highly expressive.</p>
</li>
</ul>
<p>Note that design patterns provide just a conceptual solution to a recurring problem in an optimised way. It does not provide a piece of code that you can use in your project.</p>
<p>So now that we know what design patterns are, let's dive into our very first design pattern.</p>
<h2 id="heading-what-is-the-singleton-design-pattern">What is the Singleton Design Pattern?</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/07/singleton-def-gif.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Singleton design pattern exposes a single instance that can be used by multiple components</em></p>
<p>Singleton is a design pattern that tells us that we can create only one instance of a class and that instance can be accessed globally.</p>
<p>This is one of the basic types of design pattern. It makes sure that the class acts as a single source of entry for all the consumer components that want to access this state. In other words, it provides a common entry point for using global state.</p>
<p>So a singleton class should be one which:</p>
<ul>
<li><p>Ensures that it creates only one instance of the class</p>
</li>
<li><p>Provides a global access point to the state.</p>
</li>
<li><p>Makes sure that the instance is only created the first time.</p>
</li>
</ul>
<h3 id="heading-example-of-the-singleton-design-pattern">Example of the Singleton Design Pattern</h3>
<p>To understand this concept in a better way, let's look at an example. This example is a simple React application that demonstrates how the global state value is used across the components, how it is being changed, and how the same value gets updated in all the components. Let's get started.</p>
<p>Before we start with the actual implementation, let's have a look at the folder structure:</p>
<pre><code class="lang-yaml"><span class="hljs-string">.</span>
<span class="hljs-string">├──</span> <span class="hljs-string">index.html</span>
<span class="hljs-string">├──</span> <span class="hljs-string">package.json</span>
<span class="hljs-string">└──</span> <span class="hljs-string">src</span>
    <span class="hljs-string">├──</span> <span class="hljs-string">componentA.js</span>
    <span class="hljs-string">├──</span> <span class="hljs-string">componentB.js</span>
    <span class="hljs-string">├──</span> <span class="hljs-string">globalStyles.js</span>
    <span class="hljs-string">├──</span> <span class="hljs-string">index.js</span>
    <span class="hljs-string">├──</span> <span class="hljs-string">styles.css</span>
    <span class="hljs-string">└──</span> <span class="hljs-string">utilities.js</span>
</code></pre>
<p>Here are the details of each file:</p>
<ul>
<li><p><code>componentA.js</code> is a consumer component that uses the singleton class to access the global state object and manipulate it.</p>
</li>
<li><p><code>componentB.js</code> is similar to above component, as it has to access the global state object and can manipulate it.</p>
</li>
<li><p><code>globalStyles.js</code> is a module that consists of the singleton class and exports the instance of this class.</p>
</li>
<li><p><code>index.js</code> manages global JS operations, that is JavaScript changes that are required for other DOM elements.</p>
</li>
<li><p><code>styles.css</code> manages the styling of the application. Consists of basic CSS.</p>
</li>
<li><p><code>utilities.js</code> is a module that exports some utility functions.</p>
</li>
<li><p><code>index.html</code> consists of HTML code for the components that are required in the project.</p>
</li>
<li><p><code>package.json</code> is a boilerplate configuration emitted by the <code>npm init</code> command.</p>
</li>
</ul>
<p>Now that we know what each file does, we can start off by implementing them one by one.</p>
<p>But before we dive into this example, we need to understand the code flow. The aim of our example is to build a JavaScript application that demonstrates how the global style <code>color</code> is consumed by each of the components and how each component changes it.</p>
<p>Each component consists of a <code>color-picker</code>. When you change the global style <code>color</code> property via the color picker present inside each component, it automatically appears in other components and in the global state.</p>
<p>First, let's create a file: <code>index.html</code>. Then paste the below code into this file:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Parcel Sandbox<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"./src/styles.css"</span> /&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>

  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"global-state"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h3</span>&gt;</span>Global State<span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h4</span>&gt;</span>Color<span class="hljs-tag">&lt;/<span class="hljs-name">h4</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"selected-color"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"contents"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"component-a"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">strong</span>&gt;</span>Component A<span class="hljs-tag">&lt;/<span class="hljs-name">strong</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Pick color<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"selected-color"</span>&gt;</span>black<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"color"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"color-picker-a"</span> /&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"component-b"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">strong</span>&gt;</span>Component B<span class="hljs-tag">&lt;/<span class="hljs-name">strong</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Pick color<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"selected-color"</span>&gt;</span>black<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"color"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"color-picker-b"</span> /&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"src/index.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"src/componentA.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"src/componentB.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>Here at the top, we load our CSS via <code>&lt;link rel="stylesheet" href="./src/styles.css" /&gt;</code>.</p>
<p>Then we have divided our application in two parts via two classes:</p>
<ul>
<li><p><code>.global-state</code>: This will represent the HTML code for showcasing the current global state of the application.</p>
</li>
<li><p><code>.contents</code>: This will represent the HTML code that represents the two components.</p>
</li>
</ul>
<p>Each of the components (<code>component-a</code> and <code>component-b</code>) has a color picker input element.</p>
<p>Both of these components have a <code>span</code> with class <code>selected-color</code> element that will help display the current value of global state variable <code>color</code>.</p>
<p>As you can see on a change of the color picker inside <code>componentA</code>, the following values are also changing:</p>
<ul>
<li><p>Value inside the <code>.selected-color</code> span element inside the <code>componentB</code> and Global state.</p>
</li>
<li><p>Value of the color picker of <code>componentA</code> and <code>componentB</code>.</p>
</li>
</ul>
<p>We will see later how all these values are changing. But for now it is important for us to understand that if we change the global state value from one component, then the singleton classes make sure that the instance value is updated and all the components that are consuming this instance get the same value since they are referring to the same instance.</p>
<p>Next, we create a file named <code>globalStyles.js</code>. Copy-paste the below code in it:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> instance;
<span class="hljs-keyword">let</span> globalState = {
  <span class="hljs-attr">color</span>: <span class="hljs-string">""</span>
};

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">StateUtility</span> </span>{
  <span class="hljs-keyword">constructor</span>() {
    <span class="hljs-keyword">if</span> (instance) {
      <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"New instance cannot be created!!"</span>);
    }

    instance = <span class="hljs-built_in">this</span>;
  }

  getPropertyByName(propertyName) {
    <span class="hljs-keyword">return</span> globalState[propertyName];
  }

  setPropertyValue(propertyName, propertyValue) {
    globalState[propertyName] = propertyValue;
  }
}

<span class="hljs-keyword">let</span> stateUtilityInstance = <span class="hljs-built_in">Object</span>.freeze(<span class="hljs-keyword">new</span> StateUtility());

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> stateUtilityInstance;
</code></pre>
<p>The above piece of code is a module that has a singleton class <code>StateUtility</code> and default exports the instance of the same class.</p>
<p>Let's dive deeper into the class <code>StateUtility</code> to understand how it resolves to become a singleton class:</p>
<ul>
<li><p>It consists of <code>constructor</code> and two class methods called <code>getPropertyByName</code> and <code>setPropertyValue</code>. Both of these class method are pretty self explanatory: one gets the property's value and the other sets its value.</p>
</li>
<li><p>Next, we have the <code>constructor</code> function. It is a function that gets invoked whenever we create a new of object of this class.</p>
</li>
<li><p>But here is a catch: for a class to be a singleton we need to make sure that it creates only one instance, and that's all.</p>
</li>
<li><p>To make sure that this happens, we simply create a global variable called <code>instance</code>. We define it at the top of the module. This variable acts as a checker. We add a condition in the <code>constructor</code> function such that if <code>instance</code> variable has any value (that is, the object of the <code>StateUtility</code> class) then throw an error or else assign <code>instance</code> to the current class instance (the <code>this</code> object).</p>
</li>
<li><p>In this example, we implemented the class <code>StateUtility</code> so that it can expose and alter the <code>globalState</code> variable.</p>
</li>
<li><p>We make sure that we don't expose the <code>globalState</code>. We expose them using the class methods of <code>StateUtility</code>. In this way, we protect the global state from being altered directly.</p>
</li>
<li><p>Finally, we create the instance of the class as follows: <code>let stateUtilityInstance = Object.freeze(new StateUtility());</code>.</p>
</li>
<li><p>We have used <code>Object.freeze</code> so that no other class/component/module is able to modify the exposed <code>stateUtilityInstance</code>.</p>
</li>
</ul>
<p>Then let's create a file called <code>componentA.js</code> inside the <code>src</code> folder. Copy-paste the below code in this file:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> {
    setAllSelectedColor
} <span class="hljs-keyword">from</span> <span class="hljs-string">"./utilities"</span>;
<span class="hljs-keyword">import</span> globalStyle <span class="hljs-keyword">from</span> <span class="hljs-string">"./globalStyles"</span>;

<span class="hljs-comment">// Get respective dom elements</span>
<span class="hljs-keyword">const</span> selectedColor = <span class="hljs-built_in">document</span>.querySelectorAll(<span class="hljs-string">"#selected-color"</span>);
<span class="hljs-keyword">const</span> colorPickerA = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"color-picker-a"</span>);
<span class="hljs-keyword">const</span> colorPickerB = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"color-picker-b"</span>);

<span class="hljs-comment">// Event handler whenever a change event occurs</span>
colorPickerA.onchange = <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
    <span class="hljs-comment">// set the color property of the global state with current color picker's value;</span>
    globalStyle.setPropertyValue(<span class="hljs-string">"color"</span>, event.target.value);
    <span class="hljs-keyword">const</span> color = globalStyle.getPropertyByName(<span class="hljs-string">"color"</span>);

    <span class="hljs-comment">// A function thats sets the value of all the #selection-color dom elements;</span>
    setValueOfSimilarElements(selectedColor, color);

    <span class="hljs-comment">// make sure to set the component B's color picker value is set to color picker A;</span>
    <span class="hljs-comment">// this is done to make sure that both of the color picker have same value on change;</span>
    colorPickerB.value = color;
};
</code></pre>
<p>Here is the breakdown of the above piece of code:</p>
<ul>
<li><p>The aim of this code is to make sure that we attach the <code>onChange</code> handler for the color picker that is present inside the <code>component-a</code>. In this case, componentA's color picker is identified by id: <code>#color-picker-a</code>.</p>
</li>
<li><p>We need to make sure that this handler:</p>
<ol>
<li><p>Sets the value for the property color of the globalState.</p>
</li>
<li><p>Fetches the same property again.</p>
</li>
<li><p>Applies the same value to different areas of the DOM.</p>
</li>
<li><p>Also makes sure that we set the other color picker's value to the global state.</p>
</li>
</ol>
</li>
</ul>
<p>Now, let's take a look at all these steps one-by-one:</p>
<ul>
<li><p>First, let's fetch all the required DOM elements.</p>
</li>
<li><p>What we are planning here is to update all the color pickers and span elements with id <code>#selected-color</code> with the value of the current globalState property color whenever the on change event occurs.</p>
</li>
<li><p>In case of <code>componentA</code>, once we change the color via the color picker we need to update the same value in 2 span elements (<code>#selected-color</code>) – that is, one span element of <code>componentB</code> and one span element present in the <code>.global-state</code> div container.</p>
</li>
<li><p>We do this because we want to keep all the components in sync and demosntrate that the value of the global state remains the same across all the components.</p>
</li>
<li><p>We then go ahead and update the <code>color</code> property of the global state using the <code>StateUtility</code>'s class method <code>setPropertyValue</code>. We pass on to it <code>event.target.value</code> as this contains the current value present inside the <code>#color-picker-a</code> color picker input.</p>
</li>
<li><p>Once the value is set, we fetch the same property again by using <code>getPropertyByName</code>. We do this to demonstrate that the property <code>color</code> of the global state has been updated and is ready to be used.</p>
</li>
<li><p>Then, we use the <code>setValueOfSimilarElements</code> utility function to update all the elements that are having same class/id name with some value. In this case we update all the <code>#selected-color</code> elements with value <code>color</code>.</p>
</li>
<li><p>Finally, we update the the value of the opposite color picker, that is componentB's color picker <code>#color-picker-b</code>.</p>
</li>
</ul>
<p>We do the same thing for <code>componentB</code>. We create a file called <code>componentB.js</code> and update it with the following code:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> {
    setValueOfSimilarElements
} <span class="hljs-keyword">from</span> <span class="hljs-string">"./utilities"</span>;
<span class="hljs-keyword">import</span> globalStyle <span class="hljs-keyword">from</span> <span class="hljs-string">"./globalStyles"</span>;

<span class="hljs-comment">// Get respective dom elements</span>
<span class="hljs-keyword">const</span> selectedColor = <span class="hljs-built_in">document</span>.querySelectorAll(<span class="hljs-string">"#selected-color"</span>);
<span class="hljs-keyword">const</span> colorPickerA = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"color-picker-a"</span>);
<span class="hljs-keyword">const</span> colorPickerB = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"color-picker-b"</span>);

<span class="hljs-comment">/**
 * Event handler whenever a change event occurs
 */</span>
colorPickerB.onchange = <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
    <span class="hljs-comment">// set the color property of the global state with current color picker's value;</span>
    globalStyle.setPropertyValue(<span class="hljs-string">"color"</span>, event.target.value);

    <span class="hljs-keyword">const</span> color = globalStyle.getPropertyByName(<span class="hljs-string">"color"</span>);

    <span class="hljs-comment">// A function thats sets the value of all the #selection-color dom elements</span>
    setValueOfSimilarElements(selectedColor, color);

    <span class="hljs-comment">// make sure to set the component A's color picker value is set to color picker B;</span>
    <span class="hljs-comment">// this is done to make sure that both of the color picker have same value on change;</span>
    colorPickerA.value = color;
};
</code></pre>
<p>We do the same thing as of what we did inside the <code>componentA</code> file, but in this case we update the value of the color picker present inside <code>componentA</code> (that is, we update the value of element <code>#color-picker-a</code>).</p>
<p>Here is how our application will look like:</p>
<p><a target="_blank" href="https://zqbo69.csb.app/">Here is the link to the code</a>:</p>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codesandbox.io/embed/zqbo69?view=editor+%2B+preview" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="CodeSandbox embed" allow="geolocation; microphone; camera; midi; vr; accelerometer; gyroscope; payment; ambient-light-sensor; encrypted-media; usb" sandbox="allow-modals allow-forms allow-popups allow-scripts allow-same-origin" loading="lazy"></iframe></div>
<p> </p>
<h2 id="heading-pros-and-cons-of-the-singleton-design-pattern">Pros and Cons of the Singleton Design Pattern</h2>
<p>Here are some of the pros of using the Singleton design pattern:</p>
<ul>
<li><p>It makes sure that only a single instance of the class is created.</p>
</li>
<li><p>We get a single access point to the instance that can be accessed globally.</p>
</li>
</ul>
<p>Here are some cons of the Singleton design pattern:</p>
<ul>
<li><p>It violates the single responsibility principle. That is, it tries to solve two problems at the same time. It tries to solve the following problems: <em>Ensure that a class will have only one instance</em>, and <em>assigning a global access point to the singleton class instance.</em></p>
</li>
<li><p>It is difficult to write unit test cases for singleton classes. This is because the order of execution can change the value present in the global state, so the order of execution is important.</p>
</li>
<li><p>While writing unit tests, there is a risk of another component or a module might be changing the global state value/instance. In such scenarios, it becomes difficult to debug the error.</p>
</li>
</ul>
<h2 id="heading-summary">Summary</h2>
<p>The singleton design pattern can be useful in creating a global state that can be accessed by any component.</p>
<p>So to talk about singleton pattern in brief:</p>
<ul>
<li><p>It is a pattern that restricts the class to create only one instance.</p>
</li>
<li><p>Singleton pattern can be considered the basics of global state management libraries such Redux or React Context.</p>
</li>
<li><p>They can be accessed globally and acts as a single access point for accessing the global state.</p>
</li>
</ul>
<p>That's all.</p>
<p>Thank you for reading!</p>
<p>Follow me on <a target="_blank" href="https://twitter.com/keurplkar">Twitter</a>, <a target="_blank" href="https://github.com/keyurparalkar">GitHub</a>, and <a target="_blank" href="https://www.linkedin.com/in/keyur-paralkar-494415107/">LinkedIn</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use the Call, Apply, and Bind Functions in JavaScript – with Code Examples ]]>
                </title>
                <description>
                    <![CDATA[ In this article, I am going to explain how to use call, apply, and bind in JavaScript with simple examples. We will also implement an example that showcases how you can create your own map function with the apply function. Without further ado, let's ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/understand-call-apply-and-bind-in-javascript-with-examples/</link>
                <guid isPermaLink="false">66bb555a4c9d249e52882f31</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Keyur Paralkar ]]>
                </dc:creator>
                <pubDate>Mon, 20 Jun 2022 18:25:02 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/06/Screenshot-2022-06-14-at-8.53.33-PM-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this article, I am going to explain how to use call, apply, and bind in JavaScript with simple examples.</p>
<p>We will also implement an example that showcases how you can create your own map function with the apply function.</p>
<p>Without further ado, let's get started.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-definitions">Definitions</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-use-the-call-function-in-javascript">How to use the call function in JavaScript</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-use-the-apply-function-in-javascript">How to use the apply function in JavaScript</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-use-the-bind-function-in-javascript">How to use the bind function in JavaScript</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-create-your-own-map-function">How to create your own map function</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-summary">Summary</a></p>
</li>
</ul>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Here are some of the things you should understand to get the most out of this article:</p>
<ul>
<li><p><a target="_blank" href="https://www.freecodecamp.org/news/what-is-a-function-javascript-function-examples/">Functions</a></p>
</li>
<li><p><a target="_blank" href="https://www.freecodecamp.org/news/all-you-need-to-know-to-understand-javascripts-prototype-a2bff2d28f03/">Function Prototypes</a></p>
</li>
<li><p><a target="_blank" href="https://www.freecodecamp.org/news/what-is-this-in-javascript/">This keyword</a></p>
</li>
</ul>
<h2 id="heading-definitions">Definitions</h2>
<p>Let's look at the functions we'll be studying here a bit more closely to understand what they do.</p>
<p><strong>Call</strong> is a function that helps you change the context of the invoking function. In layperson's terms, it helps you replace the value of <code>this</code> inside a function with whatever value you want.</p>
<p><strong>Apply</strong> is very similar to the <code>call</code> function. The only difference is that in <code>apply</code> you can pass an array as an argument list.</p>
<p><strong>Bind</strong> is a function that helps you create another function that you can execute later with the new context of <code>this</code> that is provided.</p>
<p>Now we will look at some basic examples of the call, apply, and bind functions. Then we will look at an example were we will be constructing our own function similar to the map function.</p>
<h2 id="heading-how-to-use-the-call-function-in-javascript">How to Use the Call Function in JavaScript</h2>
<p><code>call</code> is a function that you use to change the value of <code>this</code> inside a function and execute it with the arguments provided.</p>
<p>Here is the syntax of the <code>call</code> function:</p>
<pre><code class="lang-javascript">
func.call(thisObj, args1, args2, ...)
</code></pre>
<p>Where,</p>
<ul>
<li><p><strong>func</strong> is a function that needs to be invoked with a different <code>this</code> object</p>
</li>
<li><p><strong>thisObj</strong> is an object or a value that needs to be replaced with the <code>this</code> keyword present inside the function <code>func</code></p>
</li>
<li><p><strong>args1, args2</strong> are arguments that are passed to the invoking function with the changed <code>this</code> object.</p>
</li>
</ul>
<p>Note that if you invoke a function without any <code>thisObj</code> argument, then JavaScript considers this property to be a global object.</p>
<p>Now that we have some context around what the <code>call</code> function is, let's start off by understanding it in more detail with some examples.</p>
<h3 id="heading-how-to-call-a-function-with-different-contexts-in-js">How to call a function with different contexts in JS</h3>
<p>Consider the below example. It consists of 3 classes – <code>Car</code>, <code>Brand1</code>, and <code>Brand2</code>.</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Car</span>(<span class="hljs-params">type, fuelType</span>)</span>{
    <span class="hljs-built_in">this</span>.type = type;
    <span class="hljs-built_in">this</span>.fuelType = fuelType;
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">setBrand</span>(<span class="hljs-params">brand</span>)</span>{
    Car.call(<span class="hljs-built_in">this</span>, <span class="hljs-string">"convertible"</span>, <span class="hljs-string">"petrol"</span>);
    <span class="hljs-built_in">this</span>.brand = brand;
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Car details = `</span>, <span class="hljs-built_in">this</span>);
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">definePrice</span>(<span class="hljs-params">price</span>)</span>{
    Car.call(<span class="hljs-built_in">this</span>, <span class="hljs-string">"convertible"</span>, <span class="hljs-string">"diesel"</span>);
    <span class="hljs-built_in">this</span>.price = price;
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Car details = `</span>, <span class="hljs-built_in">this</span>);
}

<span class="hljs-keyword">const</span> newBrand = <span class="hljs-keyword">new</span> setBrand(<span class="hljs-string">'Brand1'</span>);
<span class="hljs-keyword">const</span> newCarPrice = <span class="hljs-keyword">new</span> definePrice(<span class="hljs-number">100000</span>);
</code></pre>
<p>If you look carefully, you can see that we use the <code>call</code> function to invoke the <code>Car</code> function on two occasions. Firstly, in the <code>setBrand</code> and then in the <code>definePrice</code> functions.</p>
<p>In both of these functions, we invoke the <code>Car</code> function with <code>this</code> object representing to the respective functions themselves. For example, inside <code>setBrand</code>, we call the <code>Car</code> function with the <code>this</code> object belonging to its context. The case is similar for <code>definePrice</code>.</p>
<p>Here’s a short video illustrating this: <a target="_blank" href="https://www.canva.com/design/DAFD4b369JM/watch">https://www.canva.com/design/DAFD4b369JM/watch</a></p>
<h3 id="heading-how-to-call-a-function-with-no-arguments-in-js">How to call a function with no arguments in JS</h3>
<p>Consider the below example:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> newEntity = <span class="hljs-function">(<span class="hljs-params">obj</span>) =&gt;</span> <span class="hljs-built_in">console</span>.log(obj);

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">mountEntity</span>(<span class="hljs-params"></span>)</span>{
    <span class="hljs-built_in">this</span>.entity = newEntity;
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Entity <span class="hljs-subst">${<span class="hljs-built_in">this</span>.entity}</span> is mounted on <span class="hljs-subst">${<span class="hljs-built_in">this</span>}</span>`</span>);
}

mountEntity.call();
</code></pre>
<p>In this example, we invoked the function <code>mountEntity</code> with no <code>thisObj</code> argument. In such cases, JavaScript refers to the global object.</p>
<h2 id="heading-how-to-use-the-apply-function-in-javascript">How to Use the Apply Function in JavaScript</h2>
<p>The <code>Apply</code> function is very similar to the <code>Call</code> function. The only difference between <code>call</code> and <code>apply</code> is the difference in how arguments are passed.</p>
<p>In <code>apply</code>, arguments you can pass an argument as an array literal or a new array object.</p>
<p>Here is the syntax for the <code>apply</code> function:</p>
<pre><code class="lang-javascript">func.apply(thisObj, argumentsArray);
</code></pre>
<p>Where,</p>
<ul>
<li><p><strong>func</strong> is a function that needs to be invoked with a different <code>this</code> object</p>
</li>
<li><p><strong>thisObj</strong> is an object or a value that needs to be replaced with the <code>this</code> keyword present inside the function <code>func</code></p>
</li>
<li><p><strong>argumentsArray</strong> can be an array of arguments, array object, or the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments">arguments</a> keyword itself.</p>
</li>
</ul>
<p>As you can see above, the <code>apply</code> function has different types of syntaxes.</p>
<p>The first syntax is a simple one. You can pass in an array of arguments like below:</p>
<pre><code class="lang-javascript">func.apply(thisObj, [args1, args2, ...]);
</code></pre>
<p>The second syntax is where we can pass in the new array object to it:</p>
<pre><code class="lang-javascript">func.apply(thisObj, <span class="hljs-keyword">new</span> <span class="hljs-built_in">Array</span>(args1, args2));
</code></pre>
<p>The third syntax is where we can pass in the arguments keyword:</p>
<pre><code class="lang-javascript">func.apply(thisObj, <span class="hljs-built_in">arguments</span>);
</code></pre>
<p><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments">arguments</a> is a special object available inside a function. It contains values of the arguments that are passed to a function. You can use this keyword with the <code>apply</code> function to take any number of arbitrary arguments.</p>
<p>The best part about <code>apply</code> is we don’t need to take care of the number of arguments that are passed to the invoking function. Because of its dynamic and versatile nature, you can use it in complicated situations.</p>
<p>Let’s look at the same example as above, but this time we'll use the <code>apply</code> function.</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Car</span>(<span class="hljs-params">type, fuelType</span>)</span>{
    <span class="hljs-built_in">this</span>.type = type;
    <span class="hljs-built_in">this</span>.fuelType = fuelType;
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">setBrand</span>(<span class="hljs-params">brand</span>)</span>{
    Car.apply(<span class="hljs-built_in">this</span>, [<span class="hljs-string">"convertible"</span>, <span class="hljs-string">"petrol"</span>]); <span class="hljs-comment">//Syntax with array literal</span>
    <span class="hljs-built_in">this</span>.brand = brand;
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Car details = `</span>, <span class="hljs-built_in">this</span>);
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">definePrice</span>(<span class="hljs-params">price</span>)</span>{
    Car.apply(<span class="hljs-built_in">this</span>, <span class="hljs-keyword">new</span> <span class="hljs-built_in">Array</span>(<span class="hljs-string">"convertible"</span>, <span class="hljs-string">"diesel"</span>)); <span class="hljs-comment">//Syntax with array object construction</span>
    <span class="hljs-built_in">this</span>.price = price;
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Car details = `</span>, <span class="hljs-built_in">this</span>);
}

<span class="hljs-keyword">const</span> newBrand = <span class="hljs-keyword">new</span> setBrand(<span class="hljs-string">'Brand1'</span>);
<span class="hljs-keyword">const</span> newCarPrice = <span class="hljs-keyword">new</span> definePrice(<span class="hljs-number">100000</span>);
</code></pre>
<p>And here is an example that showcases how you'd use the <code>arguments</code> keyword:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">addUp</span>(<span class="hljs-params"></span>)</span>{
        <span class="hljs-comment">//Using arguments to capture the arbitrary number of inputs</span>
    <span class="hljs-keyword">const</span> args = <span class="hljs-built_in">Array</span>.from(<span class="hljs-built_in">arguments</span>); 
    <span class="hljs-built_in">this</span>.x = args.reduce(<span class="hljs-function">(<span class="hljs-params">prev, curr</span>) =&gt;</span> prev + curr, <span class="hljs-number">0</span>);
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"this.x = "</span>, <span class="hljs-built_in">this</span>.x);
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">driverFunc</span>(<span class="hljs-params"></span>)</span>{
    <span class="hljs-keyword">const</span> obj = {
        <span class="hljs-attr">inps</span>: [<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">3</span>,<span class="hljs-number">4</span>,<span class="hljs-number">5</span>,<span class="hljs-number">6</span>]
    }
    addUp.apply(obj, obj.inps);
}

driverFunc();
</code></pre>
<h2 id="heading-how-to-use-the-bind-function-in-javascript">How to Use the Bind Function in JavaScript</h2>
<p>The <code>bind</code> function creates a copy of a function with a new value to the <code>this</code> present inside the calling function.</p>
<p>Here is the syntax for the <code>bind</code> function:</p>
<pre><code class="lang-javascript">func.bind(thisObj, arg1, arg2, ..., argN);
</code></pre>
<p>Where,</p>
<ul>
<li><p><strong>func</strong> is a function that needs to be invoked with a different <code>this</code> object</p>
</li>
<li><p><strong>thisObj</strong> is an object or a value that needs to be replaced with the <code>this</code> keyword present inside the function <code>func</code></p>
</li>
<li><p><strong>arg1, arg2…argN</strong> – you can pass 1 argument to the calling function or more than that, similar to the <code>call</code> function.</p>
</li>
</ul>
<p>The <code>bind</code> function then returns a new function that consists of a new context to the <code>this</code> variable present inside the calling function:</p>
<pre><code class="lang-javascript">func(arg1, arg2);
</code></pre>
<p>Now this function <code>func</code> can be executed later with the arguments.</p>
<p>Let's look at a classic example of how to use a <code>bind</code> function with the help of a class-based React component:</p>
<pre><code class="lang-jsx"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">App</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> </span>{
  <span class="hljs-keyword">constructor</span>(props) {
    <span class="hljs-built_in">super</span>(props);
    <span class="hljs-built_in">this</span>.state = {
      <span class="hljs-attr">counter</span>: <span class="hljs-number">1</span>
    };
  }
  handleCode() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"HANDLE CODE THIS = "</span>, <span class="hljs-built_in">this</span>.state);
  }
  render() {
    <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{this.handleCode}</span>&gt;</span>Click Me<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>;
  }
}
</code></pre>
<p>Consider the above App component. It constitutes the following things:</p>
<ul>
<li><p><code>constructor</code> is a function that gets called a class and is instantiated with a <code>new</code> keyword.</p>
</li>
<li><p><code>render</code> is a function that executes/renders the JSX code.</p>
</li>
<li><p><code>handleCode</code> is a class method that logs the state of the component.</p>
</li>
</ul>
<p>If we click on the <code>Click Me</code> button then we will receive an error stating: <code>Cannot read properties of undefined (reading 'state')</code>.</p>
<p>Have you ever wondered why this issue occurs? 🤔🤔</p>
<p>You might be expecting that we should be able to access the state of the class since <code>handleCode</code> is a class method. But here is the catch:</p>
<ul>
<li><p><code>this</code> inside the <code>handleCode</code> is not same as that of the class’s <code>this</code>.</p>
</li>
<li><p>Inside a class, <code>this</code> is a regular object that has non-static class methods as its properties. But <code>this</code> inside the <code>handleCode</code> will refer to a different context.</p>
</li>
<li><p>To be honest, the value of <code>this</code> in this scenario depends on from where the functions is being called. If you see, the <code>handleCode</code> is being called on <code>onClick</code> event.</p>
</li>
<li><p>But at this stage, we will get <code>undefined</code> for the context of <code>this</code> present inside the <code>handleCode</code> function.</p>
</li>
<li><p>We're trying to call the <code>state</code> property of an undefined value. Therefore, this leads to the above error.</p>
</li>
</ul>
<p>We can fix this by providing the right context of <code>this</code> inside the <code>handleCode</code> method. You can do this with the <code>bind</code> method.</p>
<pre><code class="lang-jsx"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">App</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> </span>{
  <span class="hljs-keyword">constructor</span>(props) {
    <span class="hljs-built_in">super</span>(props);
    <span class="hljs-built_in">this</span>.state = {
      <span class="hljs-attr">counter</span>: <span class="hljs-number">1</span>
    };
   <span class="hljs-built_in">this</span>.handleCode = <span class="hljs-built_in">this</span>.handleCode.bind(<span class="hljs-built_in">this</span>); <span class="hljs-comment">//bind this function</span>
  }
  handleCode() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"HANDLE CODE THIS = "</span>, <span class="hljs-built_in">this</span>.state);
  }
  render() {
    <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{this.handleCode}</span>&gt;</span>Click Me<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>;
  }
}
</code></pre>
<p>The <code>bind</code> will create a new function and store it inside the <code>this</code> object with a new property as <code>handleCode</code>. <code>Bind</code> will make sure that the class’s <code>this</code> context gets applied to the <code>this</code> present inside the <code>handleCode</code> function.</p>
<h2 id="heading-how-to-create-your-own-map-function">How to Create Your Own <code>map</code> Function</h2>
<p>Now that we have all the necessary things, let's start off by creating our <code>own</code> map function. Let's first understand the things that we will need to build our <code>own</code> map function.</p>
<p>Here is the syntax of the <code>map</code> function:</p>
<pre><code class="lang-javascript">arr.map(func)
</code></pre>
<p>Where,</p>
<ul>
<li><p><strong>arr</strong> is an array on which the map is called.</p>
</li>
<li><p><strong>func</strong> is the function that needs to run on each element of an array.</p>
</li>
</ul>
<p>The basic functionality of a <code>map</code> function is simple:</p>
<p>It is a function that walks through each element of an array and applies the function that is passed as an argument. The return type of a map is again an array with <code>func</code> being applied on each element.</p>
<p>Now we understand the requirements, so we can move on to create our own <code>map</code> function. Here is the code of our new <code>map</code> function:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">newMap</span>(<span class="hljs-params">func</span>)</span>{
  <span class="hljs-keyword">let</span> destArr = [];
  <span class="hljs-keyword">const</span> srcArrLen = <span class="hljs-built_in">this</span>.length;
  <span class="hljs-keyword">for</span>(<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; srcArrLen; i++){
    destArr.push(func.call(<span class="hljs-built_in">this</span>, <span class="hljs-built_in">this</span>[i]));
  }

  <span class="hljs-keyword">return</span> destArr;
}
</code></pre>
<p>Let's understand the above function bit-by-bit:</p>
<ul>
<li><p>This function accepts an argument called <code>func</code>. It's nothing but a function that needs to be called on each element of an array.</p>
</li>
<li><p>The other parts of the code are pretty self explanatory. We will focus on the following line: <code>destArr.push(func.call(this, this[i]));</code></p>
</li>
<li><p>This line does two things:</p>
</li>
</ul>
<ol>
<li><p>Pushes the changes into the <code>destArr</code></p>
</li>
<li><p>Executes the <code>func</code> with the help of <code>call</code> method. Here the <code>call</code> method (as explained in the previous sections) will execute the <code>func</code> method with a new value to the <code>this</code> object present inside the <code>func</code> method.</p>
</li>
</ol>
<p>Now let's take a look at how we are going to execute our <code>newMap</code> function. The below approach of adding a new method to the existing primitive data type is not recommended but still we will do it for the sake of this article.</p>
<p><strong>NOTE:</strong> do not follow the below approach in your production code. This can cause damage to the existing code.</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">Object</span>.defineProperty(<span class="hljs-built_in">Array</span>.prototype, <span class="hljs-string">'newMap'</span>, {
  <span class="hljs-attr">value</span>: newMap
});
</code></pre>
<p><code>defineProperty</code> we create a new property inside the <code>Array.prototype</code>.</p>
<p>Once this is done, we are good to go with executing our new map function on an array.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> arr = [<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">3</span>];
<span class="hljs-keyword">const</span> newArr = arr.newMap(<span class="hljs-function"><span class="hljs-params">item</span> =&gt;</span> item + <span class="hljs-number">1</span>);
<span class="hljs-built_in">console</span>.log(newArr);
</code></pre>
<h2 id="heading-summary">Summary</h2>
<p>This article showed you what the call, apply, and bind functions can do via examples.</p>
<p>So to talk about these functions in brief:</p>
<ul>
<li><p>Call, apply, and bind are the functions that help you change the context of the <code>this</code> keyword present inside the invoking function.</p>
</li>
<li><p>We saw how each function can be called in different ways – for example, with <code>apply</code> you can execute a function with an array of arguments, and with the <code>call</code> function you can execute the same but the arguments are spread via commas.</p>
</li>
<li><p>These functions are really useful in class-based components of React.</p>
</li>
</ul>
<p>Thank you for reading!</p>
<p>Follow me on <a target="_blank" href="https://twitter.com/keurplkar">Twitter</a>, <a target="_blank" href="https://github.com/keyurparalkar">GitHub</a>, and <a target="_blank" href="https://www.linkedin.com/in/keyur-paralkar-494415107/">LinkedIn</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Lexical Scope in JavaScript – Beginner's Guide ]]>
                </title>
                <description>
                    <![CDATA[ In this article, we are going to understand what lexical scope is by going through some helpful examples.  We will also have a brief discussion about how JavaScript compiles and executes programs.  Lastly, we will have a look at how you can use lexic... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/lexical-scope-in-javascript/</link>
                <guid isPermaLink="false">66bb55524c9d249e52882f2d</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Lexical Scoping ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Keyur Paralkar ]]>
                </dc:creator>
                <pubDate>Thu, 26 May 2022 15:27:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/05/spacex--p-KCm6xB9I-unsplash-1.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this article, we are going to understand what lexical scope is by going through some helpful examples. </p>
<p>We will also have a brief discussion about how JavaScript compiles and executes programs. </p>
<p>Lastly, we will have a look at how you can use lexical scope to explain undeclared variable errors or reference errors.</p>
<p>Without further ado, let's get started.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><a class="post-section-overview" href="#heading-how-does-javascript-execute-programs">How does JavaScript execute programs?</a></li>
<li><a class="post-section-overview" href="#heading-how-javascript-parsescompiles-and-executes-code">How JavaScript Parses/Compiles and Executes Code</a></li>
<li><a class="post-section-overview" href="#heading-syntax-error">Understanding Syntax Error</a></li>
<li><a class="post-section-overview" href="#heading-variablefunction-hoisting">Understanding Variable/Function Hoisting</a></li>
<li><a class="post-section-overview" href="#heading-what-is-lexical-scope">What is lexical scope</a>?</li>
<li><a class="post-section-overview" href="#heading-understanding-lexical-scope">Understanding Lexical Scope</a></li>
<li><a class="post-section-overview" href="#heading-summary">Summary</a></li>
</ul>
<h2 id="heading-how-does-javascript-execute-programs">How Does Javascript Execute Programs?</h2>
<p>Before understanding how JavaScript executes a code/program, we will first explore the different steps that are involved in any compilation process from a compiler theory perspective.</p>
<p>For any language, the compiler performs the following operations:</p>
<h3 id="heading-tokenizinglexing">Tokenizing/Lexing</h3>
<p>In this process, the entire program is divided into keywords which are called tokens. For example, consider the following statement: <code>let temp = 10</code> – once the tokenization is applied it will divide this statement into keywords as follows: <code>let</code>, <code>temp</code>, <code>=</code>, <code>10</code>. </p>
<p>Lexing and tokenizing terms are used interchangeably, but there is a subtle difference between them. Lexing is a process of tokenization but it also checks if it needs to be considered as a distinct token. We can consider <strong>Lexing</strong> to be a smart version of tokenization.</p>
<h3 id="heading-parsing">Parsing</h3>
<p>This is a process of collecting all the tokens generated in the previous step and turning them into a nested tree structure that grammatically represents the code.</p>
<p>This tree structure is called an abstract syntax tree (AST).</p>
<h3 id="heading-code-generation">Code Generation</h3>
<p>This process converts the AST into machine-readable code.</p>
<p>So this was a brief explanation of how the compiler works and generates a machine-readable code. </p>
<p>Of course there are more steps apart from the ones that are mentioned above. But explaining the other steps/phases of the compiler is out of scope for this article.</p>
<p>The most important observation that we can make about JS execution is that to execute code, it goes through two phases:</p>
<ol>
<li>Parsing</li>
<li>Execution</li>
</ol>
<p>Before we understand lexical scope, it is important to first understand how JavaScript executes a program. In the next sections, we will dive deeper into how these two phases work.</p>
<h2 id="heading-how-javascript-parsescompiles-and-executes-code">How JavaScript Parses/Compiles and Executes Code</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/Untitled.png" alt="Image" width="600" height="400" loading="lazy">
<em>Parsing phase</em></p>
<p>Let's first talk about the parsing phase. In this phase, the JavaScript engine goes through the entire program, assigns variables to their respective scopes, and also checks for any errors. If it finds an error then the execution of the program is stopped.</p>
<p>In the next phase, the actual execution of the code takes place.</p>
<p>To understand this in more detail we will look into the following two scenarios:</p>
<ul>
<li>Syntax Error</li>
<li>Variable hoisting</li>
</ul>
<h3 id="heading-syntax-error">Syntax Error</h3>
<p>To show you how JS first parses the program and then executes it, the best and simplest way is to demonstrate the behavior of a syntax error.</p>
<p>Consider the following buggy code:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> token = <span class="hljs-string">"ABC"</span>;
<span class="hljs-built_in">console</span>.log(token);

<span class="hljs-comment">//Syntax error:</span>
<span class="hljs-keyword">const</span> newToken = %((token);
</code></pre>
<p>The above program will generate a syntax error at the last line. This is what the error will look like:</p>
<pre><code class="lang-javascript">Uncaught <span class="hljs-built_in">SyntaxError</span>: Unexpected token <span class="hljs-string">'%'</span>
</code></pre>
<p>If you look at the error, the JavaScript engines did not execute the <code>console.log</code> statement. Instead, it went through the entire program in the following manner:</p>
<ul>
<li>Line 1, found that there was a variable declaration and definition. So it stored the reference of the <code>token</code> variable in the current scope, that is global scope.</li>
<li>Line 2, JavaScript engine discovered that the <code>token</code> variable is being referenced. It first referred to the current scope to check if the <code>token</code> variable was present or not. If it’s present then it's referred to <code>token</code> variable’s declaration.</li>
<li>Line 3, the engine discovered that <code>newToken</code> variable was being declared and defined. It checked if any variable with the name <code>newToken</code> was present in the current scope or not. If yes, then throws a reference error. If no, then stores the reference of this variable in the current scope.</li>
<li>At the same line, the engine also discovered that it was trying to refer to a variable <code>%((token)</code>. But it found that it started with <code>%</code> and variable names cannot start with reserved keywords, so it threw a syntax error.</li>
</ul>
<h3 id="heading-variablefunction-hoisting">Variable/Function Hoisting</h3>
<p>Hoisting is a mechanism via which all the variables present in their respective scopes are hoisted, that is made available at the top. </p>
<p>Now let's take a look at the example below that will show you that hosting happens during the parsing phase and then execution happens:</p>
<pre><code class="lang-javascript">doSomething();

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">doSomething</span>(<span class="hljs-params"></span>)</span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"How you doing?"</span>);
}
</code></pre>
<p>In the above program, the engine goes through the program in the following manner:</p>
<ul>
<li>Line 1, JavaScript engine encountered a function called <code>doSomething</code>. It searched to see if <code>doSomething</code> was available in the current scope. If yes then it refers to the function or else it throws a reference error.</li>
<li>It turned out that during the parsing phase, the engine found the <code>function doSomething</code> line to be present in the current scope. Therefore, it added this variable’s reference in the current scope and made it available throughout the entire program.</li>
<li>Finally, the <code>doSomething</code> function printed out the string <code>How you doing?</code>.</li>
</ul>
<p>As we can see from the above explanation, the code was first parsed so as to generate some intermediary code that makes sure the variable/function (that is <code>doSomething</code>) referenced in the current scope is made available. </p>
<p>In the next phase, JavaScript knows about the function and so starts to execute.</p>
<p>From the above examples, we can safely conclude that the JavaScript engine does the following things before executing the code:</p>
<ol>
<li>Parses the code.</li>
<li>Generates the intermediary code that gives a description of the variables/functions that are available.</li>
<li>Using the above intermediary code, it then starts the execution of the program.</li>
</ol>
<h2 id="heading-what-is-lexical-scope">What is Lexical Scope?</h2>
<p>The process of determining the scopes of the variables/functions during runtime is called lexical scoping. The word <em>lexical</em> comes from the <em>lexical/tokenization phase</em> of the JS compiler steps.</p>
<p>During runtime, JavaScript does these two things: <code>parsing</code> and <code>execution</code>. As you learned in the last section, during the parsing phase the scopes of the variables/functions are defined. That is why it was important to first understand the parsing phase of the code execution since it lays down the foundation for understanding lexical scope.</p>
<p>In laymen's terms, the parsing phase of the JavaScript engine is where lexical scoping takes place.</p>
<p>Now that we know the basics of it, let's go through some of the main characteristics of lexical scope:</p>
<p>First of all, during the parsing phase, a scope is assigned/referenced to a variable where it is declared. </p>
<p>For example, consider a scenario where a variable is referenced in the inner function and its declaration is present in the global scope. In this case the inner variable is assigned with the outer scope, that is the global scope.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/ezgif.com-gif-maker--1---1-.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Scope assigned illustration</em></p>
<p>Then, while assigning scope to a variable, the JavaScript engine checks its parent scopes for the availability of the variable. </p>
<p>If the variable is present then that parent scope is applied to the variable. If a variable is not found in any of the parent scopes then a reference error is thrown.  </p>
<p>Take a look at the below illustration that demonstrates how a variable’s scope is searched.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/ezgif.com-gif-maker--3---1-.gif" alt="Image" width="600" height="400" loading="lazy">
<em>JS engine successfully finding a variable by going through each scope</em></p>
<p>Here is an illustration that represents the JS engine trying to find a variable that does not exists in any scope:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/ezgif.com-gif-maker--6---1-.gif" alt="Image" width="600" height="400" loading="lazy">
<em>JS engine throwing reference error</em></p>
<h2 id="heading-understanding-lexical-scope">Understanding Lexical Scope</h2>
<p>In the above section, we defined what lexical scope is. We also understood what characteristics it has. </p>
<p>In this section, we are going to understand lexical scope with the help of an example. As they say, it's always easier to understand difficult topics by looking at examples from real-life, day-to-day code. Let’s get started.</p>
<p>The example that we are going to use involves coloring areas of our code that have similar scopes. This may sound confusing, but let me demonstrate this with a simple illustration.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/Global-and-Functional-Scope--1---1-.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Understanding lexical scope with a coloring example</em></p>
<p>Let's take a step back and understand what is going on in this illustration.</p>
<p>We have the following things in our program:</p>
<ul>
<li><code>empData</code>: Array of objects.</li>
<li><code>allPositions</code>: Array of strings that consists of all the employee positions.</li>
<li>Lastly, we have a console statement that prints out <code>allPositions</code> variables.</li>
</ul>
<p>Now let's take a look at what happens in the parsing phase of this program:</p>
<ul>
<li>The engine starts with the first line, and it encounters a variable declaration <code>empData</code>.</li>
<li>The engine then checks if the <code>empData</code> is available in the current scope or not. Since there is no similar variable found, it checks the existence of this variable in its parent scope.</li>
<li>The engine will stop its search over here since there is no scope available and also the current scope is the global scope.</li>
<li>Next, the engine assigns an <code>undefined</code> value to the <code>empData</code> during the parsing phase so that once any nested scope tries to reference this variable, then it can be used.</li>
<li>The right-hand side of this assignment operator is evaluated during the execution phase of the program.</li>
<li>In a similar manner, the engine does the same for the <code>allPositions</code> variable and assigns it an <code>undefined</code> value.</li>
<li>But on the right-hand side, we are also referencing the <code>empData</code> variable. At this stage, the engine checks if this variable is available in the current scope. Since it is available, it refers to the same (that is, present in the global scope).</li>
<li>The engine is still on the right-hand side since it found out that there is an arrow function inside of the map function. Since the engine has encountered the function definition, it creates a new scope. In the gif, this is number 2.</li>
<li>Since this is a new scope, we are going to color code it black.</li>
<li>This arrow function has an argument of <code>data</code> and returns <code>data.position</code>. In the parsing phase, the engine hoists all the variables that are required by referencing the variables present in the current scope as well as in its parent scope. </li>
<li>Inside this function, the <code>data</code> variable is referenced so the engine checks if the current scope has this variable. Since the variable is present in the current scope, it refers to the same.</li>
<li>Once the engine encounters the <code>}</code> brace, it moves out of the functional scope.</li>
<li>Finally, at the end of the program, we have a console statement that displays <code>allPositions</code> variables. Since it is referencing the <code>allPositions</code> variable, it searches in the current scope (that is global scope). Since it is found, it refers to the same in the <code>console</code> statement.</li>
</ul>
<h2 id="heading-summary">Summary</h2>
<p>In this article, we learned about what lexical scope means, and learned how it works by looking at a simple coloring example.</p>
<p>Thank you for reading!</p>
<p>Follow me on <a target="_blank" href="https://twitter.com/keurplkar">Twitter</a>, <a target="_blank" href="https://github.com/keyurparalkar">GitHub</a>, and <a target="_blank" href="https://www.linkedin.com/in/keyur-paralkar-494415107/">LinkedIn</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Closure in JavaScript – Explained with Examples ]]>
                </title>
                <description>
                    <![CDATA[ In this article, we are going to talk about closures in JavaScript. I'll walk you through the definition of a closure, a simple day-to-day fetch utility closure example, and some of the advantages and disadvantages of using closures.  Table of Conten... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/javascript-closures-explained-with-example/</link>
                <guid isPermaLink="false">66bb554d4c9d249e52882f2b</guid>
                
                    <category>
                        <![CDATA[ closure ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Keyur Paralkar ]]>
                </dc:creator>
                <pubDate>Wed, 13 Apr 2022 18:57:03 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/04/safar-safarov-LKsHwgzyk7c-unsplash-2.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this article, we are going to talk about closures in JavaScript. I'll walk you through the definition of a closure, a simple day-to-day fetch utility closure example, and some of the advantages and disadvantages of using closures. </p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a> </li>
<li><a class="post-section-overview" href="#heading-what-are-closures">What are closures</a>?</li>
<li><a class="post-section-overview" href="#heading-use-case-of-closure-creating-a-fetch-utility-with-closures">Use case of closures</a></li>
<li><a class="post-section-overview" href="#heading-advantages-of-closures">Advantages of closures</a></li>
<li><a class="post-section-overview" href="#heading-disadvantages-of-closures">Disadvantages of closures</a></li>
<li><a class="post-section-overview" href="#heading-summary">Summary</a></li>
</ul>
<p>Without further ado, let's get started.</p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>You should have a good understanding of the following topics to understand this article:</p>
<ul>
<li>How JavaScript's <a target="_blank" href="https://www.freecodecamp.org/news/javascript-execution-context-and-hoisting/">execution context</a> works</li>
<li>What the <a target="_blank" href="https://www.freecodecamp.org/news/javascript-fetch-api-tutorial-with-js-fetch-post-and-header-examples/">Fetch API</a> is and how to use it</li>
</ul>
<h2 id="heading-what-are-closures">What are closures?</h2>
<p>Closures are functions that have access to the variables that are present in their scope chain even if the outer function ceases to exist.</p>
<p>To understand this in more detail, let's understand what a scope chain is. Scope chain refers to the fact that parent scope does not have access to the variables inside its children's scope, but the children's scope does have access to the variables present in its parent scopes. </p>
<p>Let's make this clearer by taking a look at an example below:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> buttonProps = <span class="hljs-function">(<span class="hljs-params">borderRadius</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> createVariantButtonProps = <span class="hljs-function">(<span class="hljs-params">variant, color</span>) =&gt;</span> {
        <span class="hljs-keyword">const</span> newProps = {
            borderRadius,
            variant,
            color
        };
        <span class="hljs-keyword">return</span> newProps;
    }
    <span class="hljs-keyword">return</span> createVariantButtonProps;
}
</code></pre>
<p>As you can see, we have a function called <code>buttonProps</code>. This function accepts <code>borderRadius</code> as an argument. Let's consider the <code>buttonProps</code> function as our parent function.</p>
<p>We have another function that has been defined inside the parent function, that is <code>createVariantButtonProps</code>. This function will accept <code>variant</code> and <code>color</code> as an argument and return an object that constitutes a variable <code>borderRadius</code> that is present outside its scope.</p>
<p>But a question arises as to how the inner function resolves the variables that are present in the parent scope.</p>
<p>Well, this is possible via lexical scoping. Using lexical scoping, the JS parser knows how to resolve variables present in its current scope or in fact knows how to resolve variables present in the nested functions. </p>
<p>So based on the above explanation, <code>createVariantButtonProps</code> will have access to the variables present in its outer function <code>buttonProps</code>.</p>
<p>In the above example, the inner function <code>createVariantButtonProps</code> is a closure. To understand closures in detail we will first go through the characteristics of closures which are as follows:</p>
<ul>
<li>Even if the outer function ceases to exist, a closure still has access to its parent variables.</li>
<li>Closures do not have access to their outer function’s <code>args</code> parameter.</li>
</ul>
<p>Let's get into more detail on each of these points.</p>
<h3 id="heading-even-if-the-outer-function-ceases-to-exist-it-still-has-access-to-its-parent-variables">Even if the outer function ceases to exist, it still has access to its parent variables.</h3>
<p>This is the basic functionality of any closure. This is their main life motto aka their working principle.</p>
<p>To see this in action we will now execute the above <code>buttonProps</code> function.</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> primaryButton = buttonProps(<span class="hljs-string">"1rem"</span>);
</code></pre>
<p>Calling the <code>buttonProps</code> function will return us another function that is our closure.</p>
<p>Now let's execute this closure:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> primaryButtonProps = primaryButton(<span class="hljs-string">"primary"</span>, <span class="hljs-string">"red"</span>);
</code></pre>
<p>Once the closure is executed, it returns the following object:</p>
<pre><code class="lang-js">{
   <span class="hljs-string">"borderRadius"</span>:<span class="hljs-string">"1rem"</span>,
   <span class="hljs-string">"variant"</span>:<span class="hljs-string">"primary"</span>,
   <span class="hljs-string">"color"</span>:<span class="hljs-string">"red"</span>
}
</code></pre>
<p>Here again a question arises: How does the <code>primaryButton</code> function have access to the variable <code>borderRadius</code> that was not present inside it?</p>
<p>If we go through the definition of closures, and scope chaining that we discussed earlier, it perfectly fits into that instance.</p>
<p>Let's dig deeper into why closures still have access to the variables that are defined outside their scope, even if the outer function ceases to exists – for example, <code>borderRadius</code>?  </p>
<p>The answer is simple: closures do not store static values. Instead, they store references to the variables present inside the scope chain. In this way, even if the outer function dies, the inner function, that is a closure, still has access to its parent variables.</p>
<h2 id="heading-use-case-of-closure-creating-a-fetch-utility-with-closures">Use case of closure: Creating a fetch utility with closures</h2>
<p>Now that we've learned what closures are, we will create a nice general purpose utility function. It will handle different request methods such as GET and POST with REST APIs.</p>
<p>For this use case, </p>
<ul>
<li>We will be using <a target="_blank" href="https://jsonplaceholder.typicode.com/">JSON placeholder APIs</a>. This provides us with some fake data which we can edit using REST APIs.</li>
<li>We will be using JavaScript's <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/fetch">fetch</a> API.</li>
</ul>
<p>Let's first discuss why we even need to design such a utility. There are couple of reasons:</p>
<ul>
<li>For every fetch call, we don’t want to define the base URL (or other common parameters) all the time. So we will create a mechanism that will store the base URL/parameters as a state.</li>
<li>To remove redundant code.</li>
<li>To provide modularity in the codebase.</li>
</ul>
<p>Let's dive into the details of this utility. Our fetch utility will look like below:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> fetchUtility = <span class="hljs-function">(<span class="hljs-params">baseURL, headers</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> createFetchInstance = <span class="hljs-function">(<span class="hljs-params">route, requestMethod, data</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> tempReq = <span class="hljs-keyword">new</span> Request(<span class="hljs-string">`<span class="hljs-subst">${baseURL}</span><span class="hljs-subst">${route}</span>`</span>, {
      <span class="hljs-attr">method</span>: requestMethod,
      headers,
      <span class="hljs-attr">data</span>: data || <span class="hljs-literal">null</span>
    });
    <span class="hljs-keyword">return</span> [fetch, tempReq];
  };

  <span class="hljs-keyword">return</span> createFetchInstance;
};
</code></pre>
<ul>
<li><code>fetchUtility</code> accepts two parameters that are <code>baseURL</code> and <code>headers</code>. These will be used later in the closure to construct the base URL along with the headers.</li>
<li>Then we have <code>createFetchInstance</code>, which accepts <code>route</code> <code>requestMethod</code> and <code>data</code> as parameters. </li>
<li>Next, this function creates a new request object that will construct our URL using the code: <code>${baseURL}${route}</code>. We also pass in an object which consists of the request method type, headers, and data if available.</li>
<li>Then we return the instance of a fetch API along with the request object.</li>
<li>Lastly, we return the <code>createFetchInstance</code> function.</li>
</ul>
<p>Now let's see this function in action. Call our <code>fetchUtility</code> function to initialize the <code>baseURL</code>:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> fetchInstance = fetchUtility(<span class="hljs-string">"https://jsonplaceholder.typicode.com"</span>);
</code></pre>
<ul>
<li>If we observe, the <code>fetchInstance</code> now has the value of the closure of the function <code>fetchUtility</code>.</li>
<li>Next, we pass the route and the type of the request to the closure <code>fetchInstance</code>:</li>
</ul>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> [getFunc, getReq] = fetchInstance(<span class="hljs-string">"/todos/1"</span>, <span class="hljs-string">"GET"</span>);
</code></pre>
<p>As you can see this returns us an array of fetch API instance and the request body that we configured.</p>
<p>Finally, we can make use of the <code>getFunc</code> fetch API to call the request <code>getReq</code> like below:</p>
<pre><code class="lang-javascript">getFunc(getReq)
  .then(<span class="hljs-function">(<span class="hljs-params">resp</span>) =&gt;</span> resp.json())
  .then(<span class="hljs-function">(<span class="hljs-params">data</span>) =&gt;</span> <span class="hljs-built_in">console</span>.log(data));
</code></pre>
<p>We can also create a POST request similar to the above GET request. We just need to call the <code>fetchInstance</code> again as below:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> [postFunc, postReq] = fetchInstance(
  <span class="hljs-string">"/posts"</span>,
  <span class="hljs-string">"POST"</span>,
  <span class="hljs-built_in">JSON</span>.stringify({
    <span class="hljs-attr">title</span>: <span class="hljs-string">"foo"</span>,
    <span class="hljs-attr">body</span>: <span class="hljs-string">"bar"</span>,
    <span class="hljs-attr">userId</span>: <span class="hljs-number">1</span>
  })
);
</code></pre>
<p>And to execute this post request we can do the similar operation that we did for the GET request:</p>
<pre><code class="lang-javascript">postFunc(postReq)
  .then(<span class="hljs-function">(<span class="hljs-params">resp</span>) =&gt;</span> resp.json())
  .then(<span class="hljs-function">(<span class="hljs-params">data</span>) =&gt;</span> <span class="hljs-built_in">console</span>.log(data));
</code></pre>
<p>If we closely look at the above example, we can see that the inner function <code>createFetchInstance</code> has access to the variables present in its scope chain. With the help of lexical scoping, during its definition of <code>createFetchInstance</code> it resolves the variable names. </p>
<p>In this way the closure references the variables <code>baseURL</code> and <code>headers</code> during its definition even after the outer function <code>fetchUtility</code> has ceased to exist.</p>
<p>If we think of closures from a different perspective, then closures help us to maintain a state like <code>baseURL</code> and <code>headers</code> that we can use across function calls.</p>
<h2 id="heading-advantages-of-closures">Advantages of closures</h2>
<p>Here are some advantages of closures:</p>
<ul>
<li>They allow you to attach variables to an execution context.</li>
<li>Variables in closures can help you maintain a state that you can use later.</li>
<li>They provide data encapsulation.</li>
<li>They help remove redundant code.</li>
<li>They help maintain modular code.</li>
</ul>
<h2 id="heading-disadvantages-of-closures">Disadvantages of closures</h2>
<p>There are two main disadvantages of overusing closures:</p>
<ul>
<li>The variables declared inside a closure are not garbage collected.</li>
<li>Too many closures can slow down your application. This is actually caused by duplication of code in the memory.</li>
</ul>
<h2 id="heading-summary">Summary</h2>
<p>So in this way closures can be really useful if you want to deal with or implement certain design patterns. They also help you write neat and modular code. </p>
<p>If you liked the idea of closures, then I would recommend reading further on the following topics:</p>
<ul>
<li><a target="_blank" href="https://www.patterns.dev/posts/classic-design-patterns/">Design patterns</a></li>
<li><a target="_blank" href="https://stackoverflow.com/questions/16032840/javascript-anonymous-closure">Anonymous closures</a></li>
</ul>
<p>Thank you for reading!</p>
<p>Follow me on <a target="_blank" href="https://twitter.com/keurplkar">Twitter</a>, <a target="_blank" href="https://github.com/keyurparalkar">GitHub</a>, and <a target="_blank" href="https://www.linkedin.com/in/keyur-paralkar-494415107/">LinkedIn</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build a Snake Game with React, Redux, and Redux Saga ]]>
                </title>
                <description>
                    <![CDATA[ In this article, I am going to walk you through creating a snake game using a React application. It is a simple 2d game built using TypeScript, and we won't need to use any third-party graphics libraries to build it.  This is what we'll make in this ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/build-a-snake-game-with-react-redux-and-redux-sagas/</link>
                <guid isPermaLink="false">66bb553d343f42327e719662</guid>
                
                    <category>
                        <![CDATA[ Games ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Redux ]]>
                    </category>
                
                    <category>
                        <![CDATA[ TypeScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Keyur Paralkar ]]>
                </dc:creator>
                <pubDate>Wed, 09 Feb 2022 18:03:35 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/02/pexels-pixabay-80474.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this article, I am going to walk you through creating a snake game using a React application. It is a simple 2d game built using TypeScript, and we won't need to use any third-party graphics libraries to build it. </p>
<p>This is what we'll make in this tutorial:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/02/ezgif.com-gif-maker--2-.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Snake is a fun game which you might have played on older feature phones like on Nokia 3310 models. </p>
<p>The concept behind it is simple: the snake roams around inside a box, and once it captures the fruit/object your points increase and the snake grows. If the snake hits the boundaries of the box or collides with itself then the game is over. </p>
<p>This article will provide you with all the necessary skills/steps to create your own Snake game from scratch. We'll first look at the code structures and their logic. Then I'll explain how they work when all of them are connected.</p>
<p>Without further ado, let’s get started.</p>
<h2 id="heading-table-of-contents">Table of contents</h2>
<ul>
<li><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></li>
<li><a class="post-section-overview" href="#heading-what-is-a-snake-game-what-are-we-going-to-use-in-it">What is a snake game? What are we going to use in it?</a></li>
<li><a class="post-section-overview" href="#heading-what-is-redux-why-are-we-using-it">What is redux? Why are we using this?</a></li>
<li><a class="post-section-overview" href="#heading-what-is-redux-saga-why-are-we-using-it">What is redux-saga? Why are we using this?</a></li>
<li><a class="post-section-overview" href="#heading-use-case-description">Use case description</a></li>
<li><a class="post-section-overview" href="#heading-the-application-and-data-layer-set-up">The application and data layer set up</a></li>
<li><a class="post-section-overview" href="#heading-understanding-ui-layer">Understanding UI Layer</a></li>
<li><a class="post-section-overview" href="#heading-canvas-board">Canvas Board</a></li>
<li><a class="post-section-overview" href="#heading-drawing-the-objects">Drawing the objects</a></li>
<li><a class="post-section-overview" href="#heading-moving-the-snake-across-the-board">Moving the snake across the board</a></li>
<li><a class="post-section-overview" href="#heading-drawing-the-fruit-at-a-random-position">Drawing the fruit at a random position</a></li>
<li><a class="post-section-overview" href="#heading-score-calculator">Score calculator</a></li>
<li><a class="post-section-overview" href="#heading-instruction-component">Instruction component</a></li>
<li><a class="post-section-overview" href="#heading-final-game">Final Game</a></li>
<li><a class="post-section-overview" href="#heading-summary">Summary</a></li>
</ul>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Before you start reading this article, you should have a basic understanding of the following topics:</p>
<ul>
<li>Class Diagrams: We are going to use them to showcase our example. Here are a couple of resources you can use to learn more about them:<ul>
<li><a target="_blank" href="https://drawio-app.com/uml-class-diagrams-in-draw-io/">Class diagrams</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/uml-diagrams-full-course/">UML Diagram course</a></li>
</ul>
</li>
<li><a target="_blank" href="https://www.notion.so/JS-Classes-a-boon-to-the-society-6360d1a702fe49da9b7ba98b0e03fe37">Context Diagram and Container Diagrams</a></li>
<li><a target="_blank" href="https://reactjs.org/">React</a></li>
<li>Generators:<ul>
<li><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator">Generators</a></li>
<li><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*">Function generators</a></li>
</ul>
</li>
</ul>
<h2 id="heading-what-is-a-snake-game-what-are-we-going-to-use-in-it">What is a snake game? What are we going to use in it?</h2>
<p>A snake game is an arcade game that involves a snake moving inside a box. Your score increases based on how many objects/fruit the snake eats. This will also increase the size of the snake. If it collides with itself or to the boundary of the box then the game is over. </p>
<p>You can read more about the history or the origins of the game in the Wiki <a target="_blank" href="https://en.wikipedia.org/wiki/Snake_(video_game_genre)">link</a>.</p>
<p>We are going to use the following tools to build our game:</p>
<ul>
<li>Redux: To create and manage the global state for the application.</li>
<li>Redux-saga: A redux middleware we'll use to manage async tasks.</li>
<li>Canvas HTML tag: We'll use this to draw an object like a snake and the fruit.</li>
<li>React: UI library.</li>
<li>Chakra-UI: Component library.</li>
</ul>
<h2 id="heading-what-is-redux-why-are-we-using-it">What is redux? Why are we using it?</h2>
<p>Redux is a state container that helps you create and manage global state for your application. Redux consists of some basic parts like:</p>
<ol>
<li>Global State</li>
<li>Redux store</li>
<li>Actions and action creators</li>
<li>Reducers</li>
</ol>
<p>You can learn all about the above topics and how Redux works internally from the Redux doc’s getting started <a target="_blank" href="https://redux.js.org/introduction/getting-started">section</a>.</p>
<p>We are using the state management library Redux because it will help us manage our global state in a simpler way. It will allow us to avoid prop drilling. It will also allow us to perform complex async actions via middleware. </p>
<p>You can learn more about middleware <a target="_blank" href="https://redux.js.org/understanding/history-and-design/middleware">here</a>.</p>
<h2 id="heading-what-is-redux-saga-why-are-we-using-it">What is redux-saga? Why are we using it?</h2>
<p>Redux-saga is a middleware that helps us tap in between the dispatched action and the reducer of the redux store. This allows us to perform certain side-effects between the dispatched action and the reducer such as data fetching, listening to particular actions or setting up subscriptions, spawning actions, and more.</p>
<p>Redux saga uses generators and generator functions. A typical saga would look like this:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span>* <span class="hljs-title">performAction</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">yield</span> put({
        <span class="hljs-attr">type</span>: COPY_DATA,
        <span class="hljs-attr">payload</span>: <span class="hljs-string">"Hello"</span>
    });
}
</code></pre>
<p><code>performAction</code> is a generator function. This generator function will execute the <code>put</code> function. It creates an object and returns it to the saga, telling what type of action needs to be executed with what payload. Then the <code>put</code> call returns an object descriptor saying which saga can take it up later and execute the particular action.</p>
<p><strong>NOTE:</strong> You can read more about generators and generator functions by referring to the prerequisite section.</p>
<p>Now the question arises <em>Why are we using redux-saga middleware?</em> The answer is simple:</p>
<ol>
<li>It provides a better way to write unit test cases, which will help us test the generator functions in a simpler way.</li>
<li>It can help you perform a lot of side effects and provide better control over the changes. One example is whenever you want to watch if a particular action X is executed then perform the action Y. Functions like <code>takeEvery</code>, <code>all</code>, and so on make it simple to perform these operations. We will discuss more of this in a later section.</li>
</ol>
<p>If you are not familiar with redux-saga, then I highly recommend going through the documentation <a target="_blank" href="https://redux-saga.js.org/docs/introduction/GettingStarted/">here</a>.</p>
<h2 id="heading-use-case-description">Use case description</h2>
<p><strong>NOTE:</strong> Context, Container, and Class diagrams drawn in this blog post don't accurately follow the exact conventions of these diagrams. I've approximated them here so you can understand the basic concepts.</p>
<p>Before we start, I would suggest reading up on c4models, container diagrams, and context diagrams. You can find resources about them in the prerequisites section.</p>
<p>In this article we are going to consider the following use case: <em>Create a snake game</em>.</p>
<p>The use case is pretty self-explanatory, and we have discussed what the snake game entails above. Below is the context diagram for our use case:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/02/contextDiagram.png" alt="Image" width="600" height="400" loading="lazy">
<em>Snake game context diagram</em></p>
<p>Our context diagram is pretty straightforward. The player interacts with the UI. Let's dive deeper into the container game board UI and explore what other systems are present inside it.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/02/Untitled--2-.png" alt="Image" width="600" height="400" loading="lazy">
<em>Container diagram for the snake game</em></p>
<p>As you can see from the above diagram, our Game Board UI is divided into two Layers:</p>
<ol>
<li>UI Layer</li>
<li>Data Layer</li>
</ol>
<p>The UI Layer consists of the following components:</p>
<ol>
<li><strong>Score Calculator:</strong> This is a component that will display the score whenever the snake eats the fruit.</li>
<li><strong>Canvas Board:</strong> This is a component that handles the major UI part of our game. Its basic functionality is to draw the snake on the canvas and clear the canvas. It also handles the following responsibilities:<ol>
<li>It detects if the snake has collided with itself or with the boundary walls (Collision detection).</li>
<li>Helps in moving the snake along the board with keyboard events.</li>
<li>Resets the game when the game is over.</li>
</ol>
</li>
<li><strong>Instructions:</strong> It provides the instructions for playing the game, along with the reset button.</li>
<li><strong>Utilities:</strong> These are the utility functions that we'll use throughout the application wherever needed.</li>
</ol>
<p>Let's now talk about the Data Layer. It consists of the following components:</p>
<ol>
<li><strong>Redux-saga:</strong> Set of generator functions that will perform certain actions.</li>
<li><strong>Actions and Action Creators:</strong> These are the set of constants and functions which will help in dispatching appropriate actions.</li>
<li><strong>Reducers:</strong> This will help us respond to the various actions dispatched by action creators and the sagas.</li>
</ol>
<p>We will deep dive into all of these components and see how they work collectively in the later sections. First, let's initialize our project and set up our Data layer – that is, the Redux store.</p>
<h2 id="heading-the-application-and-data-layer-set-up">The application and data layer set up</h2>
<p>Before we start understanding our game components, let's first set up our React application and the data layer. </p>
<p>The game is built with React. I highly recommend using the <a target="_blank" href="https://create-react-app.dev/">create-react-app</a> template to install all the necessary things to start your React application. </p>
<p>To create a CRA (create-react-app) project, first we need to install it. Type the below command into your terminal:</p>
<pre><code class="lang-shell">npm install -g create-react-app
</code></pre>
<p><strong>Note:</strong> Before running this command make sure you have installed Node.js in your system. Follow this <a target="_blank" href="https://nodejs.org/en/download/package-manager/">link</a> to install it.</p>
<p>Next, we will start by creating our project. Let's call it snake-game. Type the below command into your terminal to create the project:</p>
<pre><code class="lang-shell">npx create-react-app snake-game
</code></pre>
<p>This may take few minutes to complete. Once this is completed, traverse to your newly created project using the below command:</p>
<pre><code class="lang-shell">cd snake-game
</code></pre>
<p>Once inside the project, type the below command to start the project:</p>
<pre><code class="lang-shell">npm run start
</code></pre>
<p>This command will open a new tab in your browser with the React logo spinning on the page like below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/02/image-16.png" alt="Image" width="600" height="400" loading="lazy">
<em>create-react-app initial page</em></p>
<p>Now our initial project setup is complete. Let's configure our data layer (the Redux store). Our data layer requires that we install the following packages:</p>
<ul>
<li>Redux</li>
<li>Redux-saga</li>
</ul>
<p>First, let's start off by installing these packages. Before we start, make sure you are in the project directory. Type the below command in the terminal:</p>
<pre><code class="lang-shell">npm install redux react-redux redux-saga
</code></pre>
<p>Once these packages are installed then we will first configure our Redux store. To start off, let's first create a folder named <code>store</code>:</p>
<pre><code class="lang-shell">mkdir store
</code></pre>
<p>This <code>store</code> folder will consist of all the files related to Redux. We will organize our store folder in the following manner:</p>
<pre><code class="lang-shell">store/
├── actions
│   └── index.ts
├── reducers
│   └── index.ts
└── sagas
    └── index.ts
├── index.ts
</code></pre>
<p>Let's discuss what each of the files does:</p>
<ul>
<li><code>action/index.tsx</code>: This file consists of constants that represents actions that our application can perform and dispatch to the Redux store. An example of such an action constant looks like this:</li>
</ul>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> MOVE_RIGHT = <span class="hljs-string">"MOVE_RIGHT"</span>
</code></pre>
<p>We will use the same action constant to create a function which will return an object with the following properties:</p>
<ul>
<li><code>type</code>: Action type, that is action constant</li>
<li><code>payload</code>: additional data that acts as a payload.</li>
</ul>
<p>These functions which return an object with the <code>type</code> property are called action creators. We use these functions to dispatch actions to our Redux store. </p>
<p>The <code>payload</code> attribute signifies that along with the action we can also pass additional data which can be used to store or update the value inside the global state.</p>
<p><strong>NOTE</strong>: It is mandatory to have <code>type</code> property returned from the action creator. The <code>payload</code> property is optional. Also, the name of the <code>payload</code> property can be anything.</p>
<p>Let's see an example of an action creator:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">//Without payload</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> moveRight = <span class="hljs-function">() =&gt;</span> ({
    <span class="hljs-attr">type</span>: MOVE_RIGHT
});

<span class="hljs-comment">//With payload</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> moveRight = <span class="hljs-function">(<span class="hljs-params">data: string</span>) =&gt;</span> ({
    <span class="hljs-attr">type</span>: MOVE_RIGHT,
    <span class="hljs-attr">payload</span>: data
});
</code></pre>
<p>Now that we know what actions and action creators are, we can move on to configuring our next artifact which is a reducer.</p>
<p>Reducers are functions that return a new global state every time an action is dispatched. They take in the current global state and return the new state based on the action that is dispatched/called.  This new state is calculated based on the previous state. </p>
<p>We should be careful here that we do not perform any side-effects inside this function. We should not alter the global state – rather we should return the updated state as a new object itself. Therefore, the reducer function should be a pure function.</p>
<p>Now enough talking about reducers. Let's have a look at our sample reducers:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> GlobalState = {
    <span class="hljs-attr">data</span>: <span class="hljs-string">""</span>
};

<span class="hljs-keyword">const</span> gameReducer = <span class="hljs-function">(<span class="hljs-params">state = GlobalState, action</span>) =&gt;</span> {
    <span class="hljs-keyword">switch</span> (action.type) {
        <span class="hljs-keyword">case</span> <span class="hljs-string">"MOVE_RIGHT"</span>:
            <span class="hljs-comment">/**
             * Perform a certain set of operations
             */</span>
            <span class="hljs-keyword">return</span> {
                ...state, <span class="hljs-attr">data</span>: action.payload
            };

        <span class="hljs-keyword">default</span>:
            <span class="hljs-keyword">return</span> state;
    }
}
</code></pre>
<p>In this example, we have created a reducer function which is called a <code>gameReducer</code>. It takes in the state (default parameter as a global state) and an action. Whenever we have <code>action.type</code> that matches the switch case, then it performs a particular action, like returning a new state based on the action. </p>
<p>The <code>sagas/index.ts</code> file will consist of all the sagas that we will use in our application. We do have some basic understanding of the sagas which we briefly explained in the above sections. We will dive deeper into this section when we actually start our implementation of the snake game. </p>
<p>Now we have a basic understanding of the artifacts involved in making our Redux store. Let's go ahead and create <code>store/index.ts</code> like below:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> {
    createStore,
    applyMiddleware
} <span class="hljs-keyword">from</span> <span class="hljs-string">"redux"</span>;
<span class="hljs-keyword">import</span> createSagaMiddleware <span class="hljs-keyword">from</span> <span class="hljs-string">"redux-saga"</span>;
<span class="hljs-keyword">import</span> gameReducer <span class="hljs-keyword">from</span> <span class="hljs-string">"./reducers"</span>;
<span class="hljs-keyword">import</span> watcherSagas <span class="hljs-keyword">from</span> <span class="hljs-string">"./sagas"</span>;
<span class="hljs-keyword">const</span> sagaMiddleware = createSagaMiddleware();

<span class="hljs-keyword">const</span> store = createStore(gameReducer, applyMiddleware(sagaMiddleware));

sagaMiddleware.run(watcherSagas);
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> store;
</code></pre>
<p>We will first import our reducer and the saga. Next we will use the <code>createSagaMiddleware()</code> function to create a saga middleware. </p>
<p>Next, we will connect it to our store by passing it as an argument to the <code>applyMiddleware</code> function inside <code>createStore</code> which you use to create a store. We will also pass <code>gameReducer</code> to this function so that a reducer is mapped to our store.</p>
<p>Finally, we will run our sagaMiddleware using this code:</p>
<pre><code class="lang-javascript">sagaMiddleware.run(watcherSagas);
</code></pre>
<p>Our final step is to inject this <code>store</code> at the top level of our React app using the <code>Provider</code> component provided by <code>react-redux</code>. You can do this as follows:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { Provider } <span class="hljs-keyword">from</span> <span class="hljs-string">"react-redux"</span>;
<span class="hljs-keyword">import</span> store <span class="hljs-keyword">from</span> <span class="hljs-string">"./store"</span>;

<span class="hljs-keyword">const</span> App = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Provider</span> <span class="hljs-attr">store</span>=<span class="hljs-string">{store}</span>&gt;</span>
    //   Child components...
    <span class="hljs-tag">&lt;/<span class="hljs-name">Provider</span>&gt;</span></span>
  );
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<p>I have also installed chakra-UI as a UI component library for our project. To install chakra-UI, type the below command:</p>
<pre><code class="lang-shell">npm install @chakra-ui/react @emotion/react@^11 @emotion/styled@^11 framer-motion@^5
</code></pre>
<p>We also need to setup the <code>ChakraProvider</code> that will go in our <code>App.tsx</code> file. Our updated <code>App.tsx</code> file will look like this:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { ChakraProvider, Container, Heading } <span class="hljs-keyword">from</span> <span class="hljs-string">"@chakra-ui/react"</span>;
<span class="hljs-keyword">import</span> { Provider } <span class="hljs-keyword">from</span> <span class="hljs-string">"react-redux"</span>;
<span class="hljs-keyword">import</span> store <span class="hljs-keyword">from</span> <span class="hljs-string">"./store"</span>;

<span class="hljs-keyword">const</span> App = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Provider</span> <span class="hljs-attr">store</span>=<span class="hljs-string">{store}</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">ChakraProvider</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Container</span> <span class="hljs-attr">maxW</span>=<span class="hljs-string">"container.lg"</span> <span class="hljs-attr">centerContent</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Heading</span> <span class="hljs-attr">as</span>=<span class="hljs-string">"h1"</span> <span class="hljs-attr">size</span>=<span class="hljs-string">"xl"</span>&gt;</span>SNAKE GAME<span class="hljs-tag">&lt;/<span class="hljs-name">Heading</span>&gt;</span>
    //Children components
        <span class="hljs-tag">&lt;/<span class="hljs-name">Container</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">ChakraProvider</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">Provider</span>&gt;</span></span>
  );
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<h2 id="heading-understanding-ui-layer">Understanding UI layer</h2>
<p>Let's first understand the dynamics of our Snake game from the UI perspective. Before we get started, our final Snake game will look like below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/02/snake-game.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>The UI Layer consists of 3 layers: <strong>Score Calculator</strong>, <strong>Canvas Board</strong>, and <strong>Instructions</strong>. The below diagram showcases these sections:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/02/Untitled--3-.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Let's dive deeper into each of these sections to understand how our Snake game works.</p>
<h2 id="heading-canvas-board">Canvas Board</h2>
<p>We'll start off by understanding the Canvas Board:</p>
<ul>
<li>Our canvas board is going to be of dimensions <code>height: 600, width: 1000</code></li>
<li>This entire board is divided into blocks of <code>20x20</code> size. That is, every object that is drawn on this board has <code>height 20</code> and <code>width 20</code>.</li>
<li>We are using the <code>&lt;canvas&gt;</code> HTML element to draw the shapes in the canvas board component.</li>
</ul>
<p>In our project, we are writing the canvas board component inside the file <code>components/CanvasBoard.tsx</code>. Now that our basic understanding is clear about the CanvasBoard component, let's start building this component.</p>
<p>Create a simple component that returns a canvas element as below:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">export</span> interface ICanvasBoard {
  <span class="hljs-attr">height</span>: number;
  width: number;
}

<span class="hljs-keyword">const</span> CanvasBoard = <span class="hljs-function">(<span class="hljs-params">{ height, width }: ICanvasBoard</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">canvas</span>
      <span class="hljs-attr">style</span>=<span class="hljs-string">{{</span>
        <span class="hljs-attr">border:</span> "<span class="hljs-attr">3px</span> <span class="hljs-attr">solid</span> <span class="hljs-attr">black</span>",
      }}
      <span class="hljs-attr">height</span>=<span class="hljs-string">{height}</span>
      <span class="hljs-attr">width</span>=<span class="hljs-string">{width}</span>
    /&gt;</span></span>
  );
};
</code></pre>
<p>Call this component in our <code>App.tsx</code> file with width and height of 1000 and 600 as a prop like below:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { ChakraProvider, Container, Heading } <span class="hljs-keyword">from</span> <span class="hljs-string">"@chakra-ui/react"</span>;
<span class="hljs-keyword">import</span> { Provider } <span class="hljs-keyword">from</span> <span class="hljs-string">"react-redux"</span>;
<span class="hljs-keyword">import</span> CanvasBoard <span class="hljs-keyword">from</span> <span class="hljs-string">"./components/CanvasBoard"</span>;
<span class="hljs-keyword">import</span> ScoreCard <span class="hljs-keyword">from</span> <span class="hljs-string">"./components/ScoreCard"</span>;
<span class="hljs-keyword">import</span> store <span class="hljs-keyword">from</span> <span class="hljs-string">"./store"</span>;

<span class="hljs-keyword">const</span> App = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Provider</span> <span class="hljs-attr">store</span>=<span class="hljs-string">{store}</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">ChakraProvider</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Container</span> <span class="hljs-attr">maxW</span>=<span class="hljs-string">"container.lg"</span> <span class="hljs-attr">centerContent</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Heading</span> <span class="hljs-attr">as</span>=<span class="hljs-string">"h1"</span> <span class="hljs-attr">size</span>=<span class="hljs-string">"xl"</span>&gt;</span>SNAKE GAME<span class="hljs-tag">&lt;/<span class="hljs-name">Heading</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">CanvasBoard</span> <span class="hljs-attr">height</span>=<span class="hljs-string">{600}</span> <span class="hljs-attr">width</span>=<span class="hljs-string">{1000}</span> /&gt;</span> //Canvasboard component added 
        <span class="hljs-tag">&lt;/<span class="hljs-name">Container</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">ChakraProvider</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">Provider</span>&gt;</span></span>
  );
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<p>This will create a simple box of height=600 and width=1000 with a black border like below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/02/snakeCanvas1.png" alt="Image" width="600" height="400" loading="lazy">
<em>A blank canvas element with width=1000 and height=600</em></p>
<p>Now let's draw a snake at the center of this canvas. But before we can start drawing, we need to get the context of this <code>canvas</code> element. </p>
<p>The context of a canvas element provides you with all the information you need related to the canvas element. It gives you the dimensions of the canvas and also helps you draw on the canvas. </p>
<p>To get the context of our canvas element we need to call the <code>getCanvas('2d')</code> function which returns the 2d context of the canvas. The return type of this function is <code>CanvasRenderingContext2D</code> interface. </p>
<p>To do this in pure JS we would do something like below:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> canvas = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'canvas'</span>);
<span class="hljs-keyword">const</span> canvasCtx = canvas.getContext(<span class="hljs-string">'2d'</span>);
</code></pre>
<p>But to do so in React we need to create a <code>ref</code> and pass it to the canvas element so that we can address it later in different hooks. To do so in our application, create one <code>ref</code> using the <code>useRef</code> hook:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> canvasRef = useRef&lt;HTMLCanvasElement | <span class="hljs-literal">null</span>&gt;(<span class="hljs-literal">null</span>);
</code></pre>
<p>Pass the ref into our <code>canvas</code> element:</p>
<pre><code class="lang-jsx">&lt;canvas
  ref={canvasRef}
  style={{
    <span class="hljs-attr">border</span>: <span class="hljs-string">"3px solid black"</span>,
  }}
  height={height}
  width={width}
/&gt;;
</code></pre>
<p>Once the <code>canvasRef</code> is passed into the <code>canvas</code> element, we can use it inside a <code>useEffect</code> hook and store the context in a state variable. </p>
<pre><code class="lang-jsx"><span class="hljs-keyword">export</span> interface ICanvasBoard {
  <span class="hljs-attr">height</span>: number;
  width: number;
}

<span class="hljs-keyword">const</span> CanvasBoard = <span class="hljs-function">(<span class="hljs-params">{ height, width }: ICanvasBoard</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> canvasRef = (useRef &lt; HTMLCanvasElement) | (<span class="hljs-literal">null</span> &gt; <span class="hljs-literal">null</span>);
  <span class="hljs-keyword">const</span> [context, setContext] =
    (useState &lt; CanvasRenderingContext2D) | (<span class="hljs-literal">null</span> &gt; <span class="hljs-literal">null</span>);

  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-comment">//Draw on canvas each time</span>
    setContext(canvasRef.current &amp;&amp; canvasRef.current.getContext(<span class="hljs-string">"2d"</span>)); <span class="hljs-comment">//store in state variable</span>
  }, [context]);

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">canvas</span>
      <span class="hljs-attr">ref</span>=<span class="hljs-string">{canvasRef}</span>    
      <span class="hljs-attr">style</span>=<span class="hljs-string">{{</span>
        <span class="hljs-attr">border:</span> "<span class="hljs-attr">3px</span> <span class="hljs-attr">solid</span> <span class="hljs-attr">black</span>",
      }}
      <span class="hljs-attr">height</span>=<span class="hljs-string">{height}</span>
      <span class="hljs-attr">width</span>=<span class="hljs-string">{width}</span>
    /&gt;</span></span>
  );
};
</code></pre>
<h2 id="heading-drawing-the-objects">Drawing the objects</h2>
<p>After getting the context we need to do the following tasks each time a component updates:</p>
<ol>
<li>Clear the canvas</li>
<li>Draw the snake with the current position</li>
<li>Draw a fruit at a random position inside the box</li>
</ol>
<p>We are going to clear the canvas multiple times, so we will make this a utility function. So for that, let's create a folder called <code>utilities</code>:</p>
<pre><code class="lang-shell">mkdir utilities
cd utilities
touch index.tsx
</code></pre>
<p>The above command will also create an <code>index.tsx</code> file inside the utilities folder. Add the below code in the <code>utilities/index.tsx</code> file:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> clearBoard = <span class="hljs-function">(<span class="hljs-params">context: CanvasRenderingContext2D | <span class="hljs-literal">null</span></span>) =&gt;</span> {
  <span class="hljs-keyword">if</span> (context) {
    context.clearRect(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">1000</span>, <span class="hljs-number">600</span>);
  }
};
</code></pre>
<p>The <code>clearBoard</code> function is pretty straightforward. It does the following actions:</p>
<ol>
<li>It accepts the 2d canvas context objects as an argument.</li>
<li>It checks that the context is not null or undefined.</li>
<li>The <code>clearRect</code> function will clear all the pixels or objects present inside the rectangle. This function will take width and height as an argument for the rectangle to be cleared.</li>
</ol>
<p>We will use this <code>clearBoard</code> function inside our <code>CanvasBoard</code> useEffect to clear the canvas every time the component is updated. For differentiating between different <code>useEffects</code>, we will name the above useEffect as useEffect1.</p>
<p>Now let's start by drawing the snake and the fruit at a random position. Since we are going to draw the objects multiple times, we'll create a utility function called <code>drawObject</code> for it. Add the below code in the <code>utilities/index.tsx</code> file:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> interface IObjectBody {
  <span class="hljs-attr">x</span>: number;
  y: number;
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> drawObject = <span class="hljs-function">(<span class="hljs-params">
  context: CanvasRenderingContext2D | <span class="hljs-literal">null</span>,
  objectBody: IObjectBody[],
  fillColor: string,
  strokeStyle = <span class="hljs-string">"#146356"</span>
</span>) =&gt;</span> {
  <span class="hljs-keyword">if</span> (context) {
    objectBody.forEach(<span class="hljs-function">(<span class="hljs-params">object: IObjectBody</span>) =&gt;</span> {
      context.fillStyle = fillColor;
      context.strokeStyle = strokeStyle;
      context?.fillRect(object.x, object.y, <span class="hljs-number">20</span>, <span class="hljs-number">20</span>);
      context?.strokeRect(object.x, object.y, <span class="hljs-number">20</span>, <span class="hljs-number">20</span>);
    });
  }
};
</code></pre>
<p>The <code>drawObject</code> function accepts the following arguments:</p>
<ol>
<li><code>context</code> – A 2D canvas context object for drawing the object on the canvas.</li>
<li><code>objectBody</code> – This is an array of objects with each object having <code>x</code> and <code>y</code> properties, like the <code>IObjectBody</code> interface.</li>
<li><code>fillColor</code> – Color to be filled inside the object.</li>
<li><code>strokeStyle</code> – Color to be filled in the outline of the object. Defaults to <code>#146356</code>.</li>
</ol>
<p>This function will check if the context is undefined or null. Then it iterates over the <code>objectBody</code> via forEach. For each object it performs the following operations:</p>
<ol>
<li>It will assign the <code>fillStyle</code> and <code>strokeStyle</code> inside the context.</li>
<li>It will use <code>fillReact</code> to create a filled rectangle with coordinates <code>object.x</code> and <code>object.y</code> with size <code>20x20</code></li>
<li>Finally, it will use <code>strokeRect</code> to create an outlined rectangle with coordinates <code>object.x</code> and <code>object.y</code> with size <code>20x20</code> </li>
</ol>
<p>For drawing the snake we need to maintain the position of the snake. For that, we can use our global state management tool <code>redux</code>.</p>
<p>We need to update our <code>reducers/index.ts</code> file. Since we want to track the position of the snake, we will add it into our global state as follows:</p>
<pre><code class="lang-javascript">interface ISnakeCoord {
  <span class="hljs-attr">x</span>: number;
  y: number;
}

<span class="hljs-keyword">export</span> interface IGlobalState {
  <span class="hljs-attr">snake</span>: ISnakeCoord[] | [];
}

<span class="hljs-keyword">const</span> globalState: IGlobalState = {
  <span class="hljs-comment">//Postion of the entire snake</span>
  <span class="hljs-attr">snake</span>: [
    { <span class="hljs-attr">x</span>: <span class="hljs-number">580</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">300</span> },
    { <span class="hljs-attr">x</span>: <span class="hljs-number">560</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">300</span> },
    { <span class="hljs-attr">x</span>: <span class="hljs-number">540</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">300</span> },
    { <span class="hljs-attr">x</span>: <span class="hljs-number">520</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">300</span> },
    { <span class="hljs-attr">x</span>: <span class="hljs-number">500</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">300</span> },
  ],
};
</code></pre>
<p>Let's call this state in our <code>CanvasBoard</code> component. We will use the <code>useSelector</code> hook of react-redux to get the required state from the store. The following will give us the <code>snake</code>'s global state:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> snake1 = useSelector(<span class="hljs-function">(<span class="hljs-params">state: IGlobalState</span>) =&gt;</span> state.snake);
</code></pre>
<p>Let's embed this in our <code>CanvasBoard</code> component and pass it to our <code>drawObject</code> function and see the output:</p>
<pre><code class="lang-jsx"><span class="hljs-comment">//Importing necessary modules</span>
<span class="hljs-keyword">import</span> { useSelector } <span class="hljs-keyword">from</span> <span class="hljs-string">"react-redux"</span>;
<span class="hljs-keyword">import</span> { clearBoard, drawObject, generateRandomPosition } <span class="hljs-keyword">from</span> <span class="hljs-string">"../utils"</span>;

<span class="hljs-keyword">export</span> interface ICanvasBoard {
  <span class="hljs-attr">height</span>: number;
  width: number;
}

<span class="hljs-keyword">const</span> CanvasBoard = <span class="hljs-function">(<span class="hljs-params">{ height, width }: ICanvasBoard</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> canvasRef = useRef&lt;HTMLCanvasElement | <span class="hljs-literal">null</span>&gt;(<span class="hljs-literal">null</span>);
    <span class="hljs-keyword">const</span> [context, setContext] = useState&lt;CanvasRenderingContext2D | <span class="hljs-literal">null</span>&gt;(<span class="hljs-literal">null</span>);
    <span class="hljs-keyword">const</span> snake1 = useSelector(<span class="hljs-function">(<span class="hljs-params">state: IGlobalState</span>) =&gt;</span> state.snake);
    <span class="hljs-keyword">const</span> [pos, setPos] = useState&lt;IObjectBody&gt;(
        generateRandomPosition(width - <span class="hljs-number">20</span>, height - <span class="hljs-number">20</span>)
      );

    useEffect(<span class="hljs-function">() =&gt;</span> {
      <span class="hljs-comment">//Draw on canvas each time</span>
     setContext(canvasRef.current &amp;&amp; canvasRef.current.getContext(<span class="hljs-string">"2d"</span>)); <span class="hljs-comment">//store in state variable</span>
        drawObject(context, snake1, <span class="hljs-string">"#91C483"</span>); <span class="hljs-comment">//Draws snake at the required position</span>
        drawObject(context, [pos], <span class="hljs-string">"#676FA3"</span>); <span class="hljs-comment">//Draws fruit randomly</span>
    }, [context])

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">canvas</span>
      <span class="hljs-attr">style</span>=<span class="hljs-string">{{</span>
        <span class="hljs-attr">border:</span> "<span class="hljs-attr">3px</span> <span class="hljs-attr">solid</span> <span class="hljs-attr">black</span>",
      }}
      <span class="hljs-attr">height</span>=<span class="hljs-string">{height}</span>
      <span class="hljs-attr">width</span>=<span class="hljs-string">{width}</span>
    /&gt;</span></span>
  );
};
</code></pre>
<p>Let's see what the output will look like when the snake is drawn: </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/02/snake_only.png" alt="Image" width="600" height="400" loading="lazy">
<em>Drawing snake</em></p>
<h2 id="heading-moving-the-snake-across-the-board">Moving the snake across the board</h2>
<p>Now that we have our snake drawn onto the canvas, let's learn how to move the snake across the board. </p>
<p>The movement of the snake is simple. It should always follow the below points:</p>
<ol>
<li>If the snake is moving horizontally, then it can only move up, down, and in the direction it is currently moving. For example, if the snake is moving to the right then it can move up or down or continue moving to the right.</li>
<li>If the snake is moving vertically, then it can only move to the right, left or continue in the direction it's currently moving. For example, if the snake is moving up then it can move right or left (or continue up).</li>
<li>The snake cannot move in the direction opposite to that of the current direction. That is, if the snake is moving to the left then it cannot move to the right straight away. Likewise, if it's going up it cannot move down.</li>
</ol>
<p>For the smooth movement of our snake, the snake should always move in a rectangular fashion. And it needs to meet the above points to have that movement. </p>
<p>The below diagram helps summarise how the movement of the snake works in the entire application:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/02/temp.png" alt="Image" width="600" height="400" loading="lazy">
<em>Snake movement explanation</em></p>
<p><strong>NOTE:</strong> In the above diagram, the entire movement of the snake starts with the <code>CanvasBoard</code> component. </p>
<p><strong>HINT:</strong> Don't worry if you cannot follow the above diagram. Just read the later sections to get more clarity.</p>
<p>To maintain the movement of the snake, we will introduce another state variable to our global state called <code>disallowedDirection</code>. The purpose of this variable is to keep track of the opposite direction of the snake's movement. </p>
<p>For example if the snake is moving left then the <code>disallowedDirection</code> will be set to right. So to summarise, we are tracking this direction so that we can avoid the snake moving in its opposite direction.</p>
<p>Let's create this variable in our global state:</p>
<pre><code class="lang-javascript">interface ISnakeCoord {
  <span class="hljs-attr">x</span>: number;
  y: number;
}

<span class="hljs-keyword">export</span> interface IGlobalState {
  <span class="hljs-attr">snake</span>: ISnakeCoord[] | [];
  disallowedDirection: string;
}

<span class="hljs-keyword">const</span> globalState: IGlobalState = {
    <span class="hljs-comment">//Postion of the entire snake</span>
  <span class="hljs-attr">snake</span>: [
    { <span class="hljs-attr">x</span>: <span class="hljs-number">580</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">300</span> },
    { <span class="hljs-attr">x</span>: <span class="hljs-number">560</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">300</span> },
    { <span class="hljs-attr">x</span>: <span class="hljs-number">540</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">300</span> },
    { <span class="hljs-attr">x</span>: <span class="hljs-number">520</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">300</span> },
    { <span class="hljs-attr">x</span>: <span class="hljs-number">500</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">300</span> },
  ],
    <span class="hljs-attr">disallowedDirection</span>: <span class="hljs-string">""</span>
};
</code></pre>
<p>Now let's create some actions and action creators that will help us move the snake. </p>
<p>We will have two types of actions for this case:</p>
<ul>
<li>Actions for sagas<ul>
<li>These are the actions that will be dispatched from the <code>CanvasBoard</code> component. These actions will be:<ul>
<li>MOVE_RIGHT</li>
<li>MOVE_LEFT</li>
<li>MOVE_UP</li>
<li>MOVE_DOWN</li>
</ul>
</li>
</ul>
</li>
<li>Actions for reducers<ul>
<li>These are the actions that will be yielded by the saga to propagate the calls to the reducers. These actions will be:<ul>
<li>RIGHT</li>
<li>LEFT</li>
<li>UP</li>
<li>DOWN</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>We will take a closer look at these actions in the coming sections.</p>
<p>We will be creating one more action called <code>SET_DIS_DIRECTION</code> to set the <code>disallowedDirection</code> state.</p>
<p>Let's create some action creators for the movement of the snake:</p>
<ul>
<li><code>setDisDirection</code> – This action creator will be used to set the <code>disallowedDirection</code> via the <code>SET_DIS_DIRECTION</code> action. Below is the code for this action creator:</li>
</ul>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> setDisDirection = <span class="hljs-function">(<span class="hljs-params">direction: string</span>) =&gt;</span> ({
  <span class="hljs-attr">type</span>: SET_DIS_DIRECTION,
  <span class="hljs-attr">payload</span>: direction
});
</code></pre>
<ul>
<li><code>makeMove</code> – This will be used to set/update the new coordinates of the snake by updating the <code>snake</code> state variable. Below is the code for this action creator:</li>
</ul>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> makeMove = <span class="hljs-function">(<span class="hljs-params">dx: number, dy: number, move: string</span>) =&gt;</span> ({
  <span class="hljs-attr">type</span>: move,
  <span class="hljs-attr">payload</span>: [dx, dy]
});
</code></pre>
<p>The parameters <code>dx</code> and <code>dy</code> are the deltas. They tell the Redux store by how much we should increase/decrease the coordinates of each snake block to move the snake in the given direction. </p>
<p>The <code>move</code> parameter is used to specify in which direction will the snake be moving. We will have a look at these actions creators soon in the coming sections.</p>
<p>Finally, our updated <code>actions/index.ts</code> file will look something like this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> MOVE_RIGHT = <span class="hljs-string">"MOVE_RIGHT"</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> MOVE_LEFT = <span class="hljs-string">"MOVE_LEFT"</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> MOVE_UP = <span class="hljs-string">"MOVE_UP"</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> MOVE_DOWN = <span class="hljs-string">"MOVE_DOWN"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> RIGHT = <span class="hljs-string">"RIGHT"</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> LEFT = <span class="hljs-string">"LEFT"</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> UP = <span class="hljs-string">"UP"</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> DOWN = <span class="hljs-string">"DOWN"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> SET_DIS_DIRECTION = <span class="hljs-string">"SET_DIS_DIRECTION"</span>;

<span class="hljs-keyword">export</span> interface ISnakeCoord {
  <span class="hljs-attr">x</span>: number;
  y: number;
}
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> makeMove = <span class="hljs-function">(<span class="hljs-params">dx: number, dy: number, move: string</span>) =&gt;</span> ({
  <span class="hljs-attr">type</span>: move,
  <span class="hljs-attr">payload</span>: [dx, dy]
});

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> setDisDirection = <span class="hljs-function">(<span class="hljs-params">direction: string</span>) =&gt;</span> ({
  <span class="hljs-attr">type</span>: SET_DIS_DIRECTION,
  <span class="hljs-attr">payload</span>: direction
});
</code></pre>
<p>Now, let's have a look at the logic we are using to move the snake based on the above actions. All the snake movement will be tracked by the following actions:</p>
<ul>
<li>RIGHT</li>
<li>LEFT</li>
<li>UP</li>
<li>DOWN</li>
</ul>
<p>All these actions are the building blocks of the snake's movement. These actions, when dispatched, will always update the <code>snake</code>'s global state based on the logic we are describing below. And they will calculate new coordinates of the snake on each movement.</p>
<p>To calculate the new coordinates of the snake after each movement, we will use the following logic:</p>
<ol>
<li>Copy the coordinates into a new variable called <code>newSnake</code></li>
<li>Add at the start of the <code>newSnake</code> the new x and y coordinates. These x and y attributes of these coordinates are updated by adding the x and y values from the action's payload.</li>
<li>Finally, remove the last entry from the <code>newSnake</code> array.</li>
</ol>
<p>Now that we have some understanding of how the snake is moving, let's add the following cases in our <code>gameReducer</code>:</p>
<pre><code class="lang-javascript">    <span class="hljs-keyword">case</span> RIGHT:
    <span class="hljs-keyword">case</span> LEFT:
    <span class="hljs-keyword">case</span> UP:
    <span class="hljs-keyword">case</span> DOWN: {
      <span class="hljs-keyword">let</span> newSnake = [...state.snake];
      newSnake = [{
        <span class="hljs-comment">//New x and y coordinates</span>
        <span class="hljs-attr">x</span>: state.snake[<span class="hljs-number">0</span>].x + action.payload[<span class="hljs-number">0</span>],
        <span class="hljs-attr">y</span>: state.snake[<span class="hljs-number">0</span>].y + action.payload[<span class="hljs-number">1</span>],
      }, ...newSnake];
      newSnake.pop();

      <span class="hljs-keyword">return</span> {
        ...state,
        <span class="hljs-attr">snake</span>: newSnake,
      };
    }
</code></pre>
<p>For every movement of the snake, we update the new x and y coordinates which are increased by payloads <code>action.payload[0]</code> and <code>action.payload[1]</code>. We successfully completed setting up the actions, actions creators, and the reducer logic. </p>
<p>We are good to go and can now use all of this in our <code>CanvasBoard</code> component.</p>
<p>First, let's add a useEffect hook in our <code>CanvasBoard</code> component. We will use this hook to attach/add an event handler. This event handler will be attached to the event <code>keypress</code>. We are using this event because whenever we press the <code>w</code> <code>a</code> <code>s</code> <code>d</code> keys we should be able to control the movement of the snake. </p>
<p>Our useEffect will look something like below:</p>
<pre><code class="lang-javascript">useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">window</span>.addEventListener(<span class="hljs-string">"keypress"</span>, handleKeyEvents);

    <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> {
      <span class="hljs-built_in">window</span>.removeEventListener(<span class="hljs-string">"keypress"</span>, handleKeyEvents);
    };
  }, [disallowedDirection, handleKeyEvents]);
</code></pre>
<p>It works in the following manner:</p>
<ol>
<li>On the mounting of the component, the event listener with callback function <code>handleKeyEvents</code> is attached to the window object.</li>
<li>On the unmounting of the component, the event listener is removed from the window object.</li>
<li>If there is any change in the direction or <code>handleKeyEvents</code> function, we will re-run this useEffect. Therefore, we have added <code>disallowedDirection</code> and <code>handleKeyEvents</code> into the dependency array.</li>
</ol>
<p>Let's have a look at how the <code>handleKeyEvents</code> callback is created. Below is the code for the same:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> handleKeyEvents = useCallback(
    <span class="hljs-function">(<span class="hljs-params">event: KeyboardEvent</span>) =&gt;</span> {
      <span class="hljs-keyword">if</span> (disallowedDirection) {
        <span class="hljs-keyword">switch</span> (event.key) {
          <span class="hljs-keyword">case</span> <span class="hljs-string">"w"</span>:
            moveSnake(<span class="hljs-number">0</span>, <span class="hljs-number">-20</span>, disallowedDirection);
            <span class="hljs-keyword">break</span>;
          <span class="hljs-keyword">case</span> <span class="hljs-string">"s"</span>:
            moveSnake(<span class="hljs-number">0</span>, <span class="hljs-number">20</span>, disallowedDirection);
            <span class="hljs-keyword">break</span>;
          <span class="hljs-keyword">case</span> <span class="hljs-string">"a"</span>:
            moveSnake(<span class="hljs-number">-20</span>, <span class="hljs-number">0</span>, disallowedDirection);
            <span class="hljs-keyword">break</span>;
          <span class="hljs-keyword">case</span> <span class="hljs-string">"d"</span>:
            event.preventDefault();
            moveSnake(<span class="hljs-number">20</span>, <span class="hljs-number">0</span>, disallowedDirection);
            <span class="hljs-keyword">break</span>;
        }
      } <span class="hljs-keyword">else</span> {
        <span class="hljs-keyword">if</span> (
          disallowedDirection !== <span class="hljs-string">"LEFT"</span> &amp;&amp;
          disallowedDirection !== <span class="hljs-string">"UP"</span> &amp;&amp;
          disallowedDirection !== <span class="hljs-string">"DOWN"</span> &amp;&amp;
          event.key === <span class="hljs-string">"d"</span>
        )
          moveSnake(<span class="hljs-number">20</span>, <span class="hljs-number">0</span>, disallowedDirection); <span class="hljs-comment">//Move RIGHT at start</span>
      }
    },
    [disallowedDirection, moveSnake]
  );
</code></pre>
<p>We have wrapped this function with a <code>useCallback</code> hook. This is because we want the memoized version of this function which is called on every state change (that is, on the change of <code>disallowedDirection</code> and <code>moveSnake</code>).  This function is called on every key pressed on the keyboard. </p>
<p>This event handler callback function serves the following purpose:</p>
<ul>
<li>If the <code>disallowedDirection</code> is empty then we make sure that the game will start only when the user presses the <code>d</code> key. This means that the game starts only when the snake moves to the right. </li>
</ul>
<p><strong>NOTE</strong>: Initially the global state variable <code>disallowedDirection</code> value is an empty string. In this way, we know that if its value is empty then it's the start of the game.</p>
<p>Once the game starts, the <code>disallowedDirection</code> won’t be empty and then it listens to all the keyboard presses such as <code>w</code> <code>s</code> and <code>a</code>.</p>
<p>Finally, on every keypress, we are calling the function called <code>moveSnake</code>. We will take a closer look into it in the next section.</p>
<p>The <code>moveSnake</code> function is a function that dispatches an action passed to the <code>makeMove</code> action creator. This function accepts three arguments:</p>
<ol>
<li><strong>dx</strong> - <strong>Delta for x-axis</strong>. This tells by how much the snake should move along the x-axis. If <code>dx</code> is positive then it moves to the right, if it's negative it moves to the left.</li>
<li><strong>dy - Delta for the y-axis</strong>. This tells by how much the snake should move along the y-axis. If <code>dy</code> is positive then it moves down, if it's negative it moves up.</li>
<li><strong>disallowedDirection -</strong> This value tells that the snake should not move in the opposite direction. This is an action that is captured by our middleware saga.</li>
</ol>
<p>The code for the <code>moveSnake</code> function will look like this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> moveSnake = useCallback(
    <span class="hljs-function">(<span class="hljs-params">dx = <span class="hljs-number">0</span>, dy = <span class="hljs-number">0</span>, ds: string</span>) =&gt;</span> {
      <span class="hljs-keyword">if</span> (dx &gt; <span class="hljs-number">0</span> &amp;&amp; dy === <span class="hljs-number">0</span> &amp;&amp; ds !== <span class="hljs-string">"RIGHT"</span>) {
        dispatch(makeMove(dx, dy, MOVE_RIGHT));
      }

      <span class="hljs-keyword">if</span> (dx &lt; <span class="hljs-number">0</span> &amp;&amp; dy === <span class="hljs-number">0</span> &amp;&amp; ds !== <span class="hljs-string">"LEFT"</span>) {
        dispatch(makeMove(dx, dy, MOVE_LEFT));
      }

      <span class="hljs-keyword">if</span> (dx === <span class="hljs-number">0</span> &amp;&amp; dy &lt; <span class="hljs-number">0</span> &amp;&amp; ds !== <span class="hljs-string">"UP"</span>) {
        dispatch(makeMove(dx, dy, MOVE_UP));
      }

      <span class="hljs-keyword">if</span> (dx === <span class="hljs-number">0</span> &amp;&amp; dy &gt; <span class="hljs-number">0</span> &amp;&amp; ds !== <span class="hljs-string">"DOWN"</span>) {
        dispatch(makeMove(dx, dy, MOVE_DOWN));
      }
    },
    [dispatch]
  );
</code></pre>
<p>The <code>moveSnake</code> is a simple function that checks for the conditions:</p>
<ol>
<li>If dx &gt; 0, and the <code>disallowedDirection</code> is not <code>RIGHT</code>, then it can move in the RIGHT direction.</li>
<li>If dx &lt; 0, and the <code>disallowedDirection</code> is not <code>LEFT</code>, then it can move in the LEFT direction.</li>
<li>If dy &gt; 0, and the <code>disallowedDirection</code> is not <code>DOWN</code>, then it can move in the DOWN direction.</li>
<li>If dy &lt; 0, and the <code>disallowedDirection</code> is not <code>UP</code>, then it can move in the UP direction.</li>
</ol>
<p>This <code>disallowedDirection</code> value is set in our sagas which we'll talk about more in the later sections of this article. If we revisit the <code>handleKeyEvents</code> function now it makes much more sense. Let's walk through an example over here:</p>
<ul>
<li>Suppose you want to move the snake to the RIGHT. Then this function will detect that the <code>d</code> key is pressed.</li>
<li>Once this key is pressed it calls the <code>makeMove</code> function (Game start condition) with <code>dx</code> as 20 (+ve), <code>dy</code> as 0, and the previously set <code>disallowedDirection</code> previously is called over here.</li>
</ul>
<p>In this way, we make the movement of the snake in a particular direction. Now let's have a look at the <code>sagas</code> that we have used, and how they handle the movement of the snake.  </p>
<p>Let's create a file called <code>saga/index.ts</code>. This file will consist of all our sagas. This is not a rule, but in general, we create two sagas. </p>
<p>The first one is the saga which dispatches the actual actions to the store – let's call this <em>worker saga</em>. The second is the watcher saga which watches for any action that is being dispatched – let's call this <em>watcher saga</em>.</p>
<p>Now we need to create a watcher saga that will look out for the following actions: <code>MOVE_RIGHT</code>, <code>MOVE_LEFT</code>, <code>MOVE_UP</code>, <code>MOVE_DOWN</code>.</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span>* <span class="hljs-title">watcherSaga</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">yield</span> takeLatest(
      [MOVE_RIGHT, MOVE_LEFT, MOVE_UP, MOVE_DOWN],
      moveSaga
    ); 
}
</code></pre>
<p>This watcher saga will watch for the actions above and execute the <code>moveSaga</code> function which is a worker saga. </p>
<p>You will notice that we have used a new function named <code>takeLatest</code>. This function will call the worker saga and cancel any previous saga calls if any of the actions mentioned in the first argument are dispatched.</p>
<p>From the words of the redux-saga <a target="_blank" href="https://redux-saga.js.org/docs/api/#takelatestpattern-saga-args">docs</a>:</p>
<blockquote>
<p><code>takeLatest(pattern, saga, ...args)</code><a target="_blank" href="https://redux-saga.js.org/docs/api/#takelatestpattern-saga-args"></a></p>
<p>Forks a <code>saga</code> on each action dispatched to the Store that matches <code>pattern</code>. And automatically cancels any previous <code>saga</code> task started previously if it's still running.</p>
<ul>
<li>Each time an action is dispatched to the store. And if this action matches <code>pattern</code>, <code>takeLatest</code> starts a new <code>saga</code> task in the background. If a <code>saga</code> task was started previously (on the last action dispatched before the actual action), and if this task is still running, the task will be cancelled.</li>
<li><code>pattern: String | Array | Function</code> - for more information see docs for <code>[take(pattern)](https://redux-saga.js.org/docs/api/#takepattern)</code></li>
<li><code>saga: Function</code> - a Generator function</li>
<li><code>args: Array&lt;any&gt;</code> - arguments to be passed to the started task. <code>takeLatest</code> will add the incoming action to the argument list (i.e. the action will be the last argument provided to <code>saga</code>)</li>
</ul>
</blockquote>
<p>Now let's create a worker saga called <code>moveSaga</code> which will actually dispatch the actions to the Redux store:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span>* <span class="hljs-title">moveSaga</span>(<span class="hljs-params">params: {
    type: string;
    payload: ISnakeCoord;
  }</span>): <span class="hljs-title">Generator</span>&lt;
    | <span class="hljs-title">PutEffect</span>&lt;</span>{ type: string; payload: ISnakeCoord }&gt;
    | PutEffect&lt;{ <span class="hljs-attr">type</span>: string; payload: string }&gt;
    | CallEffect&lt;<span class="hljs-literal">true</span>&gt;
  &gt; {
    <span class="hljs-keyword">while</span> (<span class="hljs-literal">true</span>) {
    <span class="hljs-comment">//dispatches movement actions</span>
     <span class="hljs-keyword">yield</span> put({
           <span class="hljs-attr">type</span>: params.type.split(<span class="hljs-string">"_"</span>)[<span class="hljs-number">1</span>],
           <span class="hljs-attr">payload</span>: params.payload,
      }); 

      <span class="hljs-comment">//Dispatches SET_DIS_DIRECTION action</span>
      <span class="hljs-keyword">switch</span> (params.type.split(<span class="hljs-string">"_"</span>)[<span class="hljs-number">1</span>]) {
        <span class="hljs-keyword">case</span> RIGHT:
          <span class="hljs-keyword">yield</span> put(setDisDirection(LEFT));
          <span class="hljs-keyword">break</span>;

        <span class="hljs-keyword">case</span> LEFT:
          <span class="hljs-keyword">yield</span> put(setDisDirection(RIGHT));
          <span class="hljs-keyword">break</span>;

        <span class="hljs-keyword">case</span> UP:
          <span class="hljs-keyword">yield</span> put(setDisDirection(DOWN));
          <span class="hljs-keyword">break</span>;

        <span class="hljs-keyword">case</span> DOWN:
          <span class="hljs-keyword">yield</span> put(setDisDirection(UP));
          <span class="hljs-keyword">break</span>;
      }
      <span class="hljs-keyword">yield</span> delay(<span class="hljs-number">100</span>);
    }
  }
</code></pre>
<p>The <code>moveSaga</code> worker saga performs the following functions:</p>
<ol>
<li>It executes inside an infinite loop. </li>
<li>So once a direction is given – that is if the <code>d</code> key is pressed and <code>MOVE_RIGHT</code> action is dispatched – then it starts dispatching the same action until a new action (that is, direction) is given. This is handled by the below snippet:</li>
</ol>
<pre><code class="lang-javascript"><span class="hljs-keyword">yield</span> put({
    <span class="hljs-attr">type</span>: params.type.split(<span class="hljs-string">"_"</span>)[<span class="hljs-number">1</span>],
    <span class="hljs-attr">payload</span>: params.payload,
});
</code></pre>
<ol start="3">
<li>Once the above action is dispatched we set the disallowed direction to the opposite direction which is taken care of by the action creator <code>setDisDirection</code>.</li>
</ol>
<p>Now let's stitch these sagas into our <code>sagas/index.ts</code> file:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> {
    CallEffect,
    delay,
    put,
    PutEffect,
    takeLatest
} <span class="hljs-keyword">from</span> <span class="hljs-string">"redux-saga/effects"</span>;
<span class="hljs-keyword">import</span> {
    DOWN,
    ISnakeCoord,
    LEFT,
    MOVE_DOWN,
    MOVE_LEFT,
    MOVE_RIGHT,
    MOVE_UP, RIGHT,
    setDisDirection, UP
} <span class="hljs-keyword">from</span> <span class="hljs-string">"../actions"</span>;

  <span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span>* <span class="hljs-title">moveSaga</span>(<span class="hljs-params">params: {
    type: string;
    payload: ISnakeCoord;
  }</span>): <span class="hljs-title">Generator</span>&lt;
    | <span class="hljs-title">PutEffect</span>&lt;</span>{ type: string; payload: ISnakeCoord }&gt;
    | PutEffect&lt;{ <span class="hljs-attr">type</span>: string; payload: string }&gt;
    | CallEffect&lt;<span class="hljs-literal">true</span>&gt;
  &gt; {
    <span class="hljs-keyword">while</span> (<span class="hljs-literal">true</span>) {
      <span class="hljs-keyword">yield</span> put({
        <span class="hljs-attr">type</span>: params.type.split(<span class="hljs-string">"_"</span>)[<span class="hljs-number">1</span>],
        <span class="hljs-attr">payload</span>: params.payload,
      });
      <span class="hljs-keyword">switch</span> (params.type.split(<span class="hljs-string">"_"</span>)[<span class="hljs-number">1</span>]) {
        <span class="hljs-keyword">case</span> RIGHT:
          <span class="hljs-keyword">yield</span> put(setDisDirection(LEFT));
          <span class="hljs-keyword">break</span>;

        <span class="hljs-keyword">case</span> LEFT:
          <span class="hljs-keyword">yield</span> put(setDisDirection(RIGHT));
          <span class="hljs-keyword">break</span>;

        <span class="hljs-keyword">case</span> UP:
          <span class="hljs-keyword">yield</span> put(setDisDirection(DOWN));
          <span class="hljs-keyword">break</span>;

        <span class="hljs-keyword">case</span> DOWN:
          <span class="hljs-keyword">yield</span> put(setDisDirection(UP));
          <span class="hljs-keyword">break</span>;
      }
      <span class="hljs-keyword">yield</span> delay(<span class="hljs-number">100</span>);
    }
  }

  <span class="hljs-function"><span class="hljs-keyword">function</span>* <span class="hljs-title">watcherSagas</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">yield</span> takeLatest(
      [MOVE_RIGHT, MOVE_LEFT, MOVE_UP, MOVE_DOWN],
      moveSaga
    );
  }

  <span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> watcherSagas;
</code></pre>
<p>Now let's update our <code>CanvasBoard</code> component to incorporate these changes.</p>
<pre><code class="lang-jsx"><span class="hljs-comment">//Importing necessary modules</span>
<span class="hljs-keyword">import</span> { useSelector } <span class="hljs-keyword">from</span> <span class="hljs-string">"react-redux"</span>;
<span class="hljs-keyword">import</span> { drawObject, generateRandomPosition } <span class="hljs-keyword">from</span> <span class="hljs-string">"../utils"</span>;

<span class="hljs-keyword">export</span> interface ICanvasBoard {
    <span class="hljs-attr">height</span>: number;
    width: number;
}

<span class="hljs-keyword">const</span> CanvasBoard = <span class="hljs-function">(<span class="hljs-params">{ height, width }: ICanvasBoard</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> canvasRef = useRef &lt; HTMLCanvasElement | <span class="hljs-literal">null</span> &gt; (<span class="hljs-literal">null</span>);
    <span class="hljs-keyword">const</span> [context, setContext] = useState &lt; CanvasRenderingContext2D | <span class="hljs-literal">null</span> &gt; (<span class="hljs-literal">null</span>);
    <span class="hljs-keyword">const</span> snake1 = useSelector(<span class="hljs-function">(<span class="hljs-params">state: IGlobalState</span>) =&gt;</span> state.snake);
    <span class="hljs-keyword">const</span> [pos, setPos] = useState &lt; IObjectBody &gt; (
        generateRandomPosition(width - <span class="hljs-number">20</span>, height - <span class="hljs-number">20</span>)
    );

    <span class="hljs-keyword">const</span> moveSnake = useCallback(
        <span class="hljs-function">(<span class="hljs-params">dx = <span class="hljs-number">0</span>, dy = <span class="hljs-number">0</span>, ds: string</span>) =&gt;</span> {
            <span class="hljs-keyword">if</span> (dx &gt; <span class="hljs-number">0</span> &amp;&amp; dy === <span class="hljs-number">0</span> &amp;&amp; ds !== <span class="hljs-string">"RIGHT"</span>) {
                dispatch(makeMove(dx, dy, MOVE_RIGHT));
            }

            <span class="hljs-keyword">if</span> (dx &lt; <span class="hljs-number">0</span> &amp;&amp; dy === <span class="hljs-number">0</span> &amp;&amp; ds !== <span class="hljs-string">"LEFT"</span>) {
                dispatch(makeMove(dx, dy, MOVE_LEFT));
            }

            <span class="hljs-keyword">if</span> (dx === <span class="hljs-number">0</span> &amp;&amp; dy &lt; <span class="hljs-number">0</span> &amp;&amp; ds !== <span class="hljs-string">"UP"</span>) {
                dispatch(makeMove(dx, dy, MOVE_UP));
            }

            <span class="hljs-keyword">if</span> (dx === <span class="hljs-number">0</span> &amp;&amp; dy &gt; <span class="hljs-number">0</span> &amp;&amp; ds !== <span class="hljs-string">"DOWN"</span>) {
                dispatch(makeMove(dx, dy, MOVE_DOWN));
            }
        },
        [dispatch]
    );

    <span class="hljs-keyword">const</span> handleKeyEvents = useCallback(
        <span class="hljs-function">(<span class="hljs-params">event: KeyboardEvent</span>) =&gt;</span> {
            <span class="hljs-keyword">if</span> (disallowedDirection) {
                <span class="hljs-keyword">switch</span> (event.key) {
                    <span class="hljs-keyword">case</span> <span class="hljs-string">"w"</span>:
                        moveSnake(<span class="hljs-number">0</span>, <span class="hljs-number">-20</span>, disallowedDirection);
                        <span class="hljs-keyword">break</span>;
                    <span class="hljs-keyword">case</span> <span class="hljs-string">"s"</span>:
                        moveSnake(<span class="hljs-number">0</span>, <span class="hljs-number">20</span>, disallowedDirection);
                        <span class="hljs-keyword">break</span>;
                    <span class="hljs-keyword">case</span> <span class="hljs-string">"a"</span>:
                        moveSnake(<span class="hljs-number">-20</span>, <span class="hljs-number">0</span>, disallowedDirection);
                        <span class="hljs-keyword">break</span>;
                    <span class="hljs-keyword">case</span> <span class="hljs-string">"d"</span>:
                        event.preventDefault();
                        moveSnake(<span class="hljs-number">20</span>, <span class="hljs-number">0</span>, disallowedDirection);
                        <span class="hljs-keyword">break</span>;
                }
            } <span class="hljs-keyword">else</span> {
                <span class="hljs-keyword">if</span> (
                    disallowedDirection !== <span class="hljs-string">"LEFT"</span> &amp;&amp;
                    disallowedDirection !== <span class="hljs-string">"UP"</span> &amp;&amp;
                    disallowedDirection !== <span class="hljs-string">"DOWN"</span> &amp;&amp;
                    event.key === <span class="hljs-string">"d"</span>
                )
                    moveSnake(<span class="hljs-number">20</span>, <span class="hljs-number">0</span>, disallowedDirection); <span class="hljs-comment">//Move RIGHT at start</span>
            }
        },
        [disallowedDirection, moveSnake]
    );
    useEffect(<span class="hljs-function">() =&gt;</span> {
        <span class="hljs-comment">//Draw on canvas each time</span>
        setContext(canvasRef.current &amp;&amp; canvasRef.current.getContext(<span class="hljs-string">"2d"</span>)); <span class="hljs-comment">//store in state variable</span>
                    clearBoard(context);
        drawObject(context, snake1, <span class="hljs-string">"#91C483"</span>); <span class="hljs-comment">//Draws snake at the required position</span>
    }, [context]);

    useEffect(<span class="hljs-function">() =&gt;</span> {
        <span class="hljs-built_in">window</span>.addEventListener(<span class="hljs-string">"keypress"</span>, handleKeyEvents);

        <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> {
            <span class="hljs-built_in">window</span>.removeEventListener(<span class="hljs-string">"keypress"</span>, handleKeyEvents);
        };
    }, [disallowedDirection, handleKeyEvents]);

    <span class="hljs-keyword">return</span> (
        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">canvas</span>
            <span class="hljs-attr">style</span>=<span class="hljs-string">{{</span>
                <span class="hljs-attr">border:</span> "<span class="hljs-attr">3px</span> <span class="hljs-attr">solid</span> <span class="hljs-attr">black</span>",
            }}
            <span class="hljs-attr">height</span>=<span class="hljs-string">{height}</span>
            <span class="hljs-attr">width</span>=<span class="hljs-string">{width}</span>
        /&gt;</span></span>
    );
};
</code></pre>
<p>Once you've made these changes you can try moving the snake. And voilà! You will see the following output:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/02/ezgif.com-gif-maker--3-.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Moving snake across the board</em></p>
<h2 id="heading-drawing-the-fruit-at-a-random-position">Drawing the fruit at a random position</h2>
<p>To draw a fruit at a random position on the board we will use the <code>generateRandomPosition</code> utility function. Let's have a look at this function:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">randomNumber</span>(<span class="hljs-params">min: number, max: number</span>) </span>{
  <span class="hljs-keyword">let</span> random = <span class="hljs-built_in">Math</span>.random() * max;
  <span class="hljs-keyword">return</span> random - (random % <span class="hljs-number">20</span>);
}
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> generateRandomPosition = <span class="hljs-function">(<span class="hljs-params">width: number, height: number</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> {
    <span class="hljs-attr">x</span>: randomNumber(<span class="hljs-number">0</span>, width),
    <span class="hljs-attr">y</span>: randomNumber(<span class="hljs-number">0</span>, height),
  };
};
</code></pre>
<p>This is a function that will generate random x and y coordinates in multiples of 20. These coordinates will always be less than the width and height of the board. It accepts <code>width</code> and <code>height</code> as arguments. </p>
<p>Once we have this function we can use it to draw the fruit at a random position inside the board. </p>
<p>First, let's create a state variable <code>pos</code> that will initially consist of some random position.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> [pos, setPos] = useState&lt;IObjectBody&gt;(generateRandomPosition(width - <span class="hljs-number">20</span>, height - <span class="hljs-number">20</span>));
</code></pre>
<p>Then, we will draw the fruit via our <code>drawObject</code> function. After this we will slightly update our <code>useEffect</code> hook:</p>
<pre><code class="lang-javascript"> useEffect(<span class="hljs-function">() =&gt;</span> {
        <span class="hljs-comment">//Draw on canvas each time</span>
        setContext(canvasRef.current &amp;&amp;   canvasRef.current.getContext(<span class="hljs-string">"2d"</span>)); <span class="hljs-comment">//store in state variable</span>

        clearBoard(context);

        drawObject(context, snake1, <span class="hljs-string">"#91C483"</span>); <span class="hljs-comment">//Draws snake at the required position</span>

        drawObject(context, [pos], <span class="hljs-string">"#676FA3"</span>); <span class="hljs-comment">//Draws object randomly</span>
    }, [context]);
</code></pre>
<p>Once we have made the changes our board will look like below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/02/snake_fruit.png" alt="Image" width="600" height="400" loading="lazy">
<em>Snake and fruit drawn on the board</em></p>
<h2 id="heading-score-calculator">Score calculator</h2>
<p>The game score is calculated based on how many fruits the snake has consumed without colliding with itself or with the boundary of the box. If the snake consumes the fruit then the size of the snake increases. If it collides with the edge of the box, then the game is over.  </p>
<p>Now that we know what our criteria are for calculating the score, let's have a look on how we calculate the reward.</p>
<h3 id="heading-calculating-the-reward">Calculating the reward</h3>
<p>The reward after the snake consumes the fruit is as follows:</p>
<ol>
<li>Increase the size of the snake.</li>
<li>Increase the score.</li>
<li>Place the new fruit at a different random location.</li>
</ol>
<p>If the snake consumes the fruit, then we must increase the size of the snake. This is a really simple task, we can just append the new x and y coordinates which are less than 20 from the last element of the <code>snake</code> global state array. For example, if the snake has the following coordinates:</p>
<pre><code class="lang-javascript">{
<span class="hljs-attr">snake</span>: [
    { <span class="hljs-attr">x</span>: <span class="hljs-number">580</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">300</span> },
    { <span class="hljs-attr">x</span>: <span class="hljs-number">560</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">300</span> },
    { <span class="hljs-attr">x</span>: <span class="hljs-number">540</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">300</span> },
    { <span class="hljs-attr">x</span>: <span class="hljs-number">520</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">300</span> },
    { <span class="hljs-attr">x</span>: <span class="hljs-number">500</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">300</span> },
  ],
}
</code></pre>
<p>We should simply append the following object into the snake array: <code>{ x: 480, y: 280 }</code></p>
<p>In this way, we increase the size of the snake as well as add the new part/block at the end of it. For this to be implemented via Redux and redux-saga, we will need the following action and action creator:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> INCREMENT_SCORE = <span class="hljs-string">"INCREMENT_SCORE"</span>; <span class="hljs-comment">//action</span>

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> increaseSnake = <span class="hljs-function">() =&gt;</span> ({  <span class="hljs-comment">//action creator</span>
    <span class="hljs-attr">type</span>: INCREASE_SNAKE
  });
</code></pre>
<p>We will also update our <code>gameReducer</code> to accommodate these changes. We will add the following case:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">case</span> INCREASE_SNAKE:
      <span class="hljs-keyword">const</span> snakeLen = state.snake.length;
      <span class="hljs-keyword">return</span> {
        ...state,
        <span class="hljs-attr">snake</span>: [
          ...state.snake,
          {
            <span class="hljs-attr">x</span>: state.snake[snakeLen - <span class="hljs-number">1</span>].x - <span class="hljs-number">20</span>,
            <span class="hljs-attr">y</span>: state.snake[snakeLen - <span class="hljs-number">1</span>].y - <span class="hljs-number">20</span>,
          },
        ],
      };
</code></pre>
<p>In our <code>CanvasBoard</code> component, we will first introduce a state variable called <code>isConsumed</code>. This variable will check if the fruit is consumed or not.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> [isConsumed, setIsConsumed] = useState&lt;boolean&gt;(<span class="hljs-literal">false</span>);
</code></pre>
<p>In our <code>useEffect</code> hook where we are drawing our <code>snake</code> and the <code>fruit</code> just below that, we will add the following condition:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">//When the object is consumed</span>
    <span class="hljs-keyword">if</span> (snake1[<span class="hljs-number">0</span>].x === pos?.x &amp;&amp; snake1[<span class="hljs-number">0</span>].y === pos?.y) {
      setIsConsumed(<span class="hljs-literal">true</span>);
    }
</code></pre>
<p>The above condition will check if the head of the snake <code>snake[0]</code> is equal to the <code>pos</code>, or the position of the fruit. If it is true, then it will set the <code>isConsumed</code> state variable to true.</p>
<p>Once the fruit is consumed, we need to increase the size of the snake. We can do this easily via another <code>useEffect</code>. Let's create another <code>useEffect</code> and call the action creator <code>increaseSnake</code>:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">//useEffect2</span>
useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">if</span> (isConsumed) {
      <span class="hljs-comment">//Increase snake size when object is consumed successfully</span>
      dispatch(increaseSnake());
    }
  }, [isConsumed]);
</code></pre>
<p>Now that we have increased the size of the snake, let's take a look at how we can update the score and generate a new fruit at another random position.</p>
<p>To generate a new fruit at another random position, we update the <code>pos</code> state variable which will re-run the useEffect1 and draw the object at <code>pos</code>. We should update our useEffect1 with a new dependency of <code>pos</code> and update useEffect2 as follows:</p>
<pre><code class="lang-javascript">useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-comment">//Generate new object</span>
    <span class="hljs-keyword">if</span> (isConsumed) {
      <span class="hljs-keyword">const</span> posi = generateRandomPosition(width - <span class="hljs-number">20</span>, height - <span class="hljs-number">20</span>);
      setPos(posi);
      setIsConsumed(<span class="hljs-literal">false</span>);

      <span class="hljs-comment">//Increase snake size when object is consumed successfully</span>
      dispatch(increaseSnake());
    }
  }, [isConsumed, pos, height, width, dispatch]);
</code></pre>
<p>One last thing left to do in this reward system is to update the score each time the snake eats the fruit. To do this follow the below steps:</p>
<ol>
<li>Introduce a new global state variable called <code>score</code>. Update our global state as below in the <code>reducers/index.ts</code> file:</li>
</ol>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> interface IGlobalState {
  <span class="hljs-attr">snake</span>: ISnakeCoord[] | [];
  disallowedDirection: string;
  score: number;
}

<span class="hljs-keyword">const</span> globalState: IGlobalState = {
  <span class="hljs-attr">snake</span>: [
    { <span class="hljs-attr">x</span>: <span class="hljs-number">580</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">300</span> },
    { <span class="hljs-attr">x</span>: <span class="hljs-number">560</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">300</span> },
    { <span class="hljs-attr">x</span>: <span class="hljs-number">540</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">300</span> },
    { <span class="hljs-attr">x</span>: <span class="hljs-number">520</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">300</span> },
    { <span class="hljs-attr">x</span>: <span class="hljs-number">500</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">300</span> },
  ],
  <span class="hljs-attr">disallowedDirection</span>: <span class="hljs-string">""</span>,
  <span class="hljs-attr">score</span>: <span class="hljs-number">0</span>,
};
</code></pre>
<ol start="2">
<li>Create the following action and action creator in our <code>actions/index.ts</code> file:</li>
</ol>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> INCREMENT_SCORE = <span class="hljs-string">"INCREMENT_SCORE"</span>; <span class="hljs-comment">//action</span>

<span class="hljs-comment">//action creator:</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> scoreUpdates = <span class="hljs-function">(<span class="hljs-params">type: string</span>) =&gt;</span> ({
  type
});
</code></pre>
<ol start="3">
<li>Next, update our reducer to handle the <code>INCREMENT_SCORE</code> action. This will simply increment the global state <code>score</code> by one.</li>
</ol>
<pre><code class="lang-javascript"><span class="hljs-keyword">case</span> INCREMENT_SCORE:
      <span class="hljs-keyword">return</span> {
        ...state,
        <span class="hljs-attr">score</span>: state.score + <span class="hljs-number">1</span>,
      };
</code></pre>
<ol start="4">
<li>Then we update our score state, dispatching the <code>INCREMENT_SCORE</code> action each time snake catches the fruit. For this we can update our useEffect2 as follows:</li>
</ol>
<pre><code class="lang-javascript">useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-comment">//Generate new object</span>
    <span class="hljs-keyword">if</span> (isConsumed) {
      <span class="hljs-keyword">const</span> posi = generateRandomPosition(width - <span class="hljs-number">20</span>, height - <span class="hljs-number">20</span>);
      setPos(posi);
      setIsConsumed(<span class="hljs-literal">false</span>);

      <span class="hljs-comment">//Increase snake size when object is consumed successfully</span>
      dispatch(increaseSnake());

      <span class="hljs-comment">//Increment the score</span>
      dispatch(scoreUpdates(INCREMENT_SCORE));
    }
  }, [isConsumed, pos, height, width, dispatch]);
</code></pre>
<ol start="5">
<li>Finally, we create a component called <code>ScoreCard</code>. This will display the player’s current score. We will store this in the file <code>components/ScoreCard.tsx</code>.</li>
</ol>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { Heading } <span class="hljs-keyword">from</span> <span class="hljs-string">"@chakra-ui/react"</span>;
<span class="hljs-keyword">import</span> { useSelector } <span class="hljs-keyword">from</span> <span class="hljs-string">"react-redux"</span>;
<span class="hljs-keyword">import</span> { IGlobalState } <span class="hljs-keyword">from</span> <span class="hljs-string">"../store/reducers"</span>;

<span class="hljs-keyword">const</span> ScoreCard = <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">const</span> score = useSelector(<span class="hljs-function">(<span class="hljs-params">state: IGlobalState</span>) =&gt;</span> state.score);
    <span class="hljs-keyword">return</span> (
        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Heading</span> <span class="hljs-attr">as</span>=<span class="hljs-string">"h2"</span> <span class="hljs-attr">size</span>=<span class="hljs-string">"md"</span> <span class="hljs-attr">mt</span>=<span class="hljs-string">{5}</span> <span class="hljs-attr">mb</span>=<span class="hljs-string">{5}</span>&gt;</span>Current Score: {score}<span class="hljs-tag">&lt;/<span class="hljs-name">Heading</span>&gt;</span></span>
    );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> ScoreCard;
</code></pre>
<p>After this we should also add the <code>ScoreCard</code> component into the <code>App.tsx</code> file to display it on our page. </p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { ChakraProvider, Container, Heading } <span class="hljs-keyword">from</span> <span class="hljs-string">"@chakra-ui/react"</span>;
<span class="hljs-keyword">import</span> { Provider } <span class="hljs-keyword">from</span> <span class="hljs-string">"react-redux"</span>;
<span class="hljs-keyword">import</span> CanvasBoard <span class="hljs-keyword">from</span> <span class="hljs-string">"./components/CanvasBoard"</span>;
<span class="hljs-keyword">import</span> ScoreCard <span class="hljs-keyword">from</span> <span class="hljs-string">"./components/ScoreCard"</span>;
<span class="hljs-keyword">import</span> store <span class="hljs-keyword">from</span> <span class="hljs-string">"./store"</span>;

<span class="hljs-keyword">const</span> App = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Provider</span> <span class="hljs-attr">store</span>=<span class="hljs-string">{store}</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">ChakraProvider</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Container</span> <span class="hljs-attr">maxW</span>=<span class="hljs-string">"container.lg"</span> <span class="hljs-attr">centerContent</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Heading</span> <span class="hljs-attr">as</span>=<span class="hljs-string">"h1"</span> <span class="hljs-attr">size</span>=<span class="hljs-string">"xl"</span>&gt;</span>SNAKE GAME<span class="hljs-tag">&lt;/<span class="hljs-name">Heading</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">ScoreCard</span> /&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">CanvasBoard</span> <span class="hljs-attr">height</span>=<span class="hljs-string">{600}</span> <span class="hljs-attr">width</span>=<span class="hljs-string">{1000}</span> /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">Container</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">ChakraProvider</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">Provider</span>&gt;</span></span>
  );
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<p>Once everything is in place, our snake will have a complete reward system that increases the size of the snake to update the score.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/02/ezgif.com-gif-maker--4-.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Player playing snake with updating score and snake length.</em></p>
<h3 id="heading-collision-detection">Collision detection</h3>
<p>In this section, we are going to take a look at how we implement collision detection for our Snake game.</p>
<p>In our Snake game, if a collision is detected, then the game is over – that is, the game stops. There are two conditions for collisions to happen:</p>
<ol>
<li>Snake collides with the boundaries of the box, or</li>
<li>Snake collides with itself.</li>
</ol>
<p>Let's take a look at the first condition. Suppose the head of the snake touches the boundaries of the box. In that case we will immediately stop the game. </p>
<p>For this to be incorporated into our game we will need to do as follows:</p>
<ol>
<li>Create an action and an action creator as below:</li>
</ol>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> STOP_GAME = <span class="hljs-string">"STOP_GAME"</span>; <span class="hljs-comment">//action</span>

<span class="hljs-comment">//action creator</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> stopGame = <span class="hljs-function">() =&gt;</span> ({
  <span class="hljs-attr">type</span>: STOP_GAME
});
</code></pre>
<ol start="2">
<li>We need to update our <code>sagas/index.ts</code> file as well. We are going to make sure that saga stops dispatching actions once the <code>STOP_GAME</code> action is encountered.</li>
</ol>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span>* <span class="hljs-title">moveSaga</span>(<span class="hljs-params">params: {
  type: string;
  payload: ISnakeCoord;
}</span>): <span class="hljs-title">Generator</span>&lt;
  | <span class="hljs-title">PutEffect</span>&lt;</span>{ type: string; payload: ISnakeCoord }&gt;
  | PutEffect&lt;{ <span class="hljs-attr">type</span>: string; payload: string }&gt;
  | CallEffect&lt;<span class="hljs-literal">true</span>&gt;
&gt; {
  <span class="hljs-keyword">while</span> (params.type !== STOP_GAME) {
    <span class="hljs-keyword">yield</span> put({
      <span class="hljs-attr">type</span>: params.type.split(<span class="hljs-string">"_"</span>)[<span class="hljs-number">1</span>],
      <span class="hljs-attr">payload</span>: params.payload,
    });
    <span class="hljs-keyword">switch</span> (params.type.split(<span class="hljs-string">"_"</span>)[<span class="hljs-number">1</span>]) {
      <span class="hljs-keyword">case</span> RIGHT:
        <span class="hljs-keyword">yield</span> put(setDisDirection(LEFT));
        <span class="hljs-keyword">break</span>;

      <span class="hljs-keyword">case</span> LEFT:
        <span class="hljs-keyword">yield</span> put(setDisDirection(RIGHT));
        <span class="hljs-keyword">break</span>;

      <span class="hljs-keyword">case</span> UP:
        <span class="hljs-keyword">yield</span> put(setDisDirection(DOWN));
        <span class="hljs-keyword">break</span>;

      <span class="hljs-keyword">case</span> DOWN:
        <span class="hljs-keyword">yield</span> put(setDisDirection(UP));
        <span class="hljs-keyword">break</span>;
    }
    <span class="hljs-keyword">yield</span> delay(<span class="hljs-number">100</span>);
  }
}

<span class="hljs-function"><span class="hljs-keyword">function</span>* <span class="hljs-title">watcherSagas</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">yield</span> takeLatest(
    [MOVE_RIGHT, MOVE_LEFT, MOVE_UP, MOVE_DOWN, STOP_GAME],
    moveSaga
  );
}
</code></pre>
<ol start="3">
<li>Finally we need to update our useEffect1 by adding the following condition:</li>
</ol>
<pre><code class="lang-jsx"><span class="hljs-keyword">if</span> ( <span class="hljs-comment">//Checks if the snake head is out of the boundries of the obox</span>
      snake1[<span class="hljs-number">0</span>].x &gt;= width ||
      snake1[<span class="hljs-number">0</span>].x &lt;= <span class="hljs-number">0</span> ||
      snake1[<span class="hljs-number">0</span>].y &lt;= <span class="hljs-number">0</span> ||
      snake1[<span class="hljs-number">0</span>].y &gt;= height
    ) {
      setGameEnded(<span class="hljs-literal">true</span>);
      dispatch(stopGame());
      <span class="hljs-built_in">window</span>.removeEventListener(<span class="hljs-string">"keypress"</span>, handleKeyEvents);
    }
</code></pre>
<p>We are also removing the event listener <code>handleKeyEvents</code>. This will make sure that once the game is over the player cannot move the snake.</p>
<p>Finally, let's have a look at how we can detect the self-collision of the snake. We are going to use a utility function called <code>hasSnakeCollided</code>. It accepts two parameters: the first is the snake array, and the second is the head of the snake. If the head of the snake touches any parts of itself then it returns true or else it returns false.</p>
<p>The <code>hasSnakeCollided</code> function will look like below:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> hasSnakeCollided = <span class="hljs-function">(<span class="hljs-params">
  snake: IObjectBody[],
  currentHeadPos: IObjectBody
</span>) =&gt;</span> {
  <span class="hljs-keyword">let</span> flag = <span class="hljs-literal">false</span>;
  snake.forEach(<span class="hljs-function">(<span class="hljs-params">pos: IObjectBody, index: number</span>) =&gt;</span> {
    <span class="hljs-keyword">if</span> (
      pos.x === currentHeadPos.x &amp;&amp;
      pos.y === currentHeadPos.y &amp;&amp;
      index !== <span class="hljs-number">0</span>
    ) {
      flag = <span class="hljs-literal">true</span>;
    }
  });

  <span class="hljs-keyword">return</span> flag;
};
</code></pre>
<p>We might slightly need to update our useEffect1 by updating the collision detection condition like this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">if</span> (  
      <span class="hljs-comment">//Checks if the snake has collided with itself </span>
      hasSnakeCollided(snake1, snake1[<span class="hljs-number">0</span>]) ||

      <span class="hljs-comment">//Checks if the snake head is out of the boundries of the obox</span>
      snake1[<span class="hljs-number">0</span>].x &gt;= width ||
      snake1[<span class="hljs-number">0</span>].x &lt;= <span class="hljs-number">0</span> ||
      snake1[<span class="hljs-number">0</span>].y &lt;= <span class="hljs-number">0</span> ||
      snake1[<span class="hljs-number">0</span>].y &gt;= height
    ) {
      setGameEnded(<span class="hljs-literal">true</span>);
      dispatch(stopGame());
      <span class="hljs-built_in">window</span>.removeEventListener(<span class="hljs-string">"keypress"</span>, handleKeyEvents);
    }
</code></pre>
<p>Our useEffect1 will finally look like below:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">//useEffect1</span>
useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-comment">//Draw on canvas each time</span>
    setContext(canvasRef.current &amp;&amp; canvasRef.current.getContext(<span class="hljs-string">"2d"</span>));
    clearBoard(context);
    drawObject(context, snake1, <span class="hljs-string">"#91C483"</span>);
    drawObject(context, [pos], <span class="hljs-string">"#676FA3"</span>); <span class="hljs-comment">//Draws object randomly</span>

    <span class="hljs-comment">//When the object is consumed</span>
    <span class="hljs-keyword">if</span> (snake1[<span class="hljs-number">0</span>].x === pos?.x &amp;&amp; snake1[<span class="hljs-number">0</span>].y === pos?.y) {
      setIsConsumed(<span class="hljs-literal">true</span>);
    }

    <span class="hljs-keyword">if</span> (
      hasSnakeCollided(snake1, snake1[<span class="hljs-number">0</span>]) ||
      snake1[<span class="hljs-number">0</span>].x &gt;= width ||
      snake1[<span class="hljs-number">0</span>].x &lt;= <span class="hljs-number">0</span> ||
      snake1[<span class="hljs-number">0</span>].y &lt;= <span class="hljs-number">0</span> ||
      snake1[<span class="hljs-number">0</span>].y &gt;= height
    ) {
      setGameEnded(<span class="hljs-literal">true</span>);
      dispatch(stopGame());
      <span class="hljs-built_in">window</span>.removeEventListener(<span class="hljs-string">"keypress"</span>, handleKeyEvents);
    } <span class="hljs-keyword">else</span> setGameEnded(<span class="hljs-literal">false</span>);
  }, [context, pos, snake1, height, width, dispatch, handleKeyEvents]);
</code></pre>
<p>Our game will look like below once we add the collision detection system:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/02/ezgif.com-gif-maker--5-.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Collision detection</em></p>
<h2 id="heading-instruction-component">Instruction component</h2>
<p>We are in the end game now! Our final component will be the <code>Instruction</code> component. It will consist of instructions about the game like initial game condition, keys to use, and a reset button. </p>
<p>Let's start by creating a file called <code>components/Instructions.tsx</code>. Place the below code in this file:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { Box, Button, Flex, Heading, Kbd } <span class="hljs-keyword">from</span> <span class="hljs-string">"@chakra-ui/react"</span>;

<span class="hljs-keyword">export</span> interface IInstructionProps {
  <span class="hljs-attr">resetBoard</span>: <span class="hljs-function">() =&gt;</span> <span class="hljs-keyword">void</span>;
}
<span class="hljs-keyword">const</span> Instruction = <span class="hljs-function">(<span class="hljs-params">{ resetBoard }: IInstructionProps</span>) =&gt;</span> (
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Box</span> <span class="hljs-attr">mt</span>=<span class="hljs-string">{3}</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">Heading</span> <span class="hljs-attr">as</span>=<span class="hljs-string">"h6"</span> <span class="hljs-attr">size</span>=<span class="hljs-string">"lg"</span>&gt;</span>
      How to Play
    <span class="hljs-tag">&lt;/<span class="hljs-name">Heading</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">Heading</span> <span class="hljs-attr">as</span>=<span class="hljs-string">"h5"</span> <span class="hljs-attr">size</span>=<span class="hljs-string">"sm"</span> <span class="hljs-attr">mt</span>=<span class="hljs-string">{1}</span>&gt;</span>
    NOTE: Start the game by pressing <span class="hljs-tag">&lt;<span class="hljs-name">Kbd</span>&gt;</span>d<span class="hljs-tag">&lt;/<span class="hljs-name">Kbd</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">Heading</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">Flex</span> <span class="hljs-attr">flexDirection</span>=<span class="hljs-string">"row"</span> <span class="hljs-attr">mt</span>=<span class="hljs-string">{3}</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Flex</span> <span class="hljs-attr">flexDirection</span>=<span class="hljs-string">{</span>"<span class="hljs-attr">column</span>"}&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Kbd</span>&gt;</span>w<span class="hljs-tag">&lt;/<span class="hljs-name">Kbd</span>&gt;</span> Move Up
        <span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Kbd</span>&gt;</span>a<span class="hljs-tag">&lt;/<span class="hljs-name">Kbd</span>&gt;</span> Move Left
        <span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Kbd</span>&gt;</span>s<span class="hljs-tag">&lt;/<span class="hljs-name">Kbd</span>&gt;</span> Move Down
        <span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Kbd</span>&gt;</span>d<span class="hljs-tag">&lt;/<span class="hljs-name">Kbd</span>&gt;</span> Move Right
        <span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">Flex</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Flex</span> <span class="hljs-attr">flexDirection</span>=<span class="hljs-string">"column"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> resetBoard()}&gt;Reset game<span class="hljs-tag">&lt;/<span class="hljs-name">Button</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">Flex</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">Flex</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">Box</span>&gt;</span></span>
);

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Instruction;
</code></pre>
<p>The <code>Instruction</code> component will accept <code>resetBoard</code> as a prop which is a function that will help the user when the game is over or when they want to reset the game.</p>
<p>Before we dive into the <code>resetBoard</code> function we need to make the following updates in our Redux store and saga:</p>
<ol>
<li>Add the following action and action creator in the <code>actions/index.ts</code> file:</li>
</ol>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> RESET_SCORE = <span class="hljs-string">"RESET_SCORE"</span>; <span class="hljs-comment">//action</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> RESET = <span class="hljs-string">"RESET"</span>; <span class="hljs-comment">//action</span>

<span class="hljs-comment">//Action creator:</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> resetGame = <span class="hljs-function">() =&gt;</span> ({
  <span class="hljs-attr">type</span>: RESET
});
</code></pre>
<ol start="2">
<li>Then add the following condition into our <code>sagas/index.ts</code>. We are going to make sure that saga discontinues to dispatch actions once the <code>RESET</code> and the <code>STOP_GAME</code> actions are encountered.</li>
</ol>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span>* <span class="hljs-title">moveSaga</span>(<span class="hljs-params">params: {
  type: string;
  payload: ISnakeCoord;
}</span>): <span class="hljs-title">Generator</span>&lt;
  | <span class="hljs-title">PutEffect</span>&lt;</span>{ type: string; payload: ISnakeCoord }&gt;
  | PutEffect&lt;{ <span class="hljs-attr">type</span>: string; payload: string }&gt;
  | CallEffect&lt;<span class="hljs-literal">true</span>&gt;
&gt; {
  <span class="hljs-keyword">while</span> (params.type !== RESET &amp;&amp; params.type !== STOP_GAME) {
    <span class="hljs-keyword">yield</span> put({
      <span class="hljs-attr">type</span>: params.type.split(<span class="hljs-string">"_"</span>)[<span class="hljs-number">1</span>],
      <span class="hljs-attr">payload</span>: params.payload,
    });
    <span class="hljs-keyword">switch</span> (params.type.split(<span class="hljs-string">"_"</span>)[<span class="hljs-number">1</span>]) {
      <span class="hljs-keyword">case</span> RIGHT:
        <span class="hljs-keyword">yield</span> put(setDisDirection(LEFT));
        <span class="hljs-keyword">break</span>;

      <span class="hljs-keyword">case</span> LEFT:
        <span class="hljs-keyword">yield</span> put(setDisDirection(RIGHT));
        <span class="hljs-keyword">break</span>;

      <span class="hljs-keyword">case</span> UP:
        <span class="hljs-keyword">yield</span> put(setDisDirection(DOWN));
        <span class="hljs-keyword">break</span>;

      <span class="hljs-keyword">case</span> DOWN:
        <span class="hljs-keyword">yield</span> put(setDisDirection(UP));
        <span class="hljs-keyword">break</span>;
    }
    <span class="hljs-keyword">yield</span> delay(<span class="hljs-number">100</span>);
  }
}

<span class="hljs-function"><span class="hljs-keyword">function</span>* <span class="hljs-title">watcherSagas</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">yield</span> takeLatest(
    [MOVE_RIGHT, MOVE_LEFT, MOVE_UP, MOVE_DOWN, RESET, STOP_GAME],
    moveSaga
  );
}
</code></pre>
<ol start="3">
<li>Finally, we update our <code>reducers/index.ts</code> file for the <code>RESET_SCORE</code> case as follows:</li>
</ol>
<pre><code class="lang-javascript"><span class="hljs-keyword">case</span> RESET_SCORE:
      <span class="hljs-keyword">return</span> { ...state, <span class="hljs-attr">score</span>: <span class="hljs-number">0</span> };
</code></pre>
<p>Once our sagas and reducers are updated we can take a look at what operations the <code>resetBoard</code> callback will perform.</p>
<p>The <code>resetBoard</code> function performs the following operations:</p>
<ol>
<li>Removes the event listener <code>handleKeyEvents</code></li>
<li>dispatches the actions necessary for resetting the game.</li>
<li>Dispatches the action to reset the score.</li>
<li>Clears the canvas.</li>
<li>Draws the snake again at its initial position</li>
<li>Draws the fruit at a new random position.</li>
<li>Finally, adds the event listener <code>handleKeyEvents</code> for the <code>keypress</code> event.</li>
</ol>
<p>Below is how our <code>resetBoard</code> function will look:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> resetBoard = useCallback(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">window</span>.removeEventListener(<span class="hljs-string">"keypress"</span>, handleKeyEvents);
    dispatch(resetGame());
    dispatch(scoreUpdates(RESET_SCORE));
    clearBoard(context);
    drawObject(context, snake1, <span class="hljs-string">"#91C483"</span>);
    drawObject(
      context,
      [generateRandomPosition(width - <span class="hljs-number">20</span>, height - <span class="hljs-number">20</span>)],
      <span class="hljs-string">"#676FA3"</span>
    ); <span class="hljs-comment">//Draws object randomly</span>
    <span class="hljs-built_in">window</span>.addEventListener(<span class="hljs-string">"keypress"</span>, handleKeyEvents);
  }, [context, dispatch, handleKeyEvents, height, snake1, width]);
</code></pre>
<p>You should place this function inside the <code>CanvasBoard</code> component and pass the <code>resetBoard</code> function as a prop to the <code>Instruction</code> function as below:</p>
<pre><code class="lang-jsx">&lt;&gt;
      <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">canvas</span>
        <span class="hljs-attr">ref</span>=<span class="hljs-string">{canvasRef}</span>
        <span class="hljs-attr">style</span>=<span class="hljs-string">{{</span>
          <span class="hljs-attr">border:</span> `<span class="hljs-attr">3px</span> <span class="hljs-attr">solid</span> ${<span class="hljs-attr">gameEnded</span> ? "<span class="hljs-attr">red</span>" <span class="hljs-attr">:</span> "<span class="hljs-attr">black</span>"}`,
        }}
        <span class="hljs-attr">width</span>=<span class="hljs-string">{width}</span>
        <span class="hljs-attr">height</span>=<span class="hljs-string">{height}</span>
      /&gt;</span></span>
      <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Instruction</span> <span class="hljs-attr">resetBoard</span>=<span class="hljs-string">{resetBoard}</span> /&gt;</span></span>
    &lt;/&gt;
</code></pre>
<p>Once this is placed we will have the Instruction component set up like below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/02/image-17.png" alt="Image" width="600" height="400" loading="lazy">
<em>Instructions with reset button</em></p>
<h2 id="heading-final-game">Final Game</h2>
<p>If you have followed along up to this point, then congrats! You have successfully created a fun Snake game with React, Redux and redux-sagas. Once all of these things are connected your game will look like below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/02/ezgif.com-gif-maker--2--1.gif" alt="Image" width="600" height="400" loading="lazy">
<em>The complete snake game</em></p>
<h2 id="heading-summary">Summary</h2>
<p>So this is how you can build a Snake game from scratch. You can find the entire source code for the game in the below repository:</p>
<p><a target="_blank" href="https://github.com/keyurparalkar/snake-game">https://github.com/keyurparalkar/snake-game</a></p>
<p>If you liked the idea of building your own Snake game from scratch then you can take it up a notch by building these enhancements:</p>
<ul>
<li>Build the snake game with three.js</li>
<li>Add an online score board</li>
</ul>
<p>Thank you for reading!</p>
<p>Follow me on <a target="_blank" href="https://twitter.com/keurplkar">Twitter</a>, <a target="_blank" href="https://github.com/keyurparalkar">GitHub</a>, and <a target="_blank" href="https://www.linkedin.com/in/keyur-paralkar-494415107/">LinkedIn</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How Web Workers Work in JavaScript – With a Practical JS Example ]]>
                </title>
                <description>
                    <![CDATA[ In this article, I will walk you through an example that will show you how web workers function in JavaScript with the help of WebSockets.  I think it's helpful to work with a practical use case because it is much simpler to understand the concepts w... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-webworkers-work-in-javascript-with-example/</link>
                <guid isPermaLink="false">66bb5543f55324ca867c88d4</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ websocket ]]>
                    </category>
                
                    <category>
                        <![CDATA[ webworker ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Keyur Paralkar ]]>
                </dc:creator>
                <pubDate>Tue, 04 Jan 2022 00:31:54 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/01/christopher-burns-8KfCR12oeUM-unsplash-1.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this article, I will walk you through an example that will show you how web workers function in JavaScript with the help of WebSockets. </p>
<p>I think it's helpful to work with a practical use case because it is much simpler to understand the concepts when you can relate them to real life. </p>
<p>So in this guide, you will be learning what web workers are in JavaScript, you'll get a brief introduction to WebSockets, and you'll see how you can manage sockets in the proper way. </p>
<p>This article is quite application/hands-on oriented, so I would suggest trying the example out as you go along to get a much better understanding.</p>
<p>Let’s dive in.</p>
<h2 id="heading-table-of-contents">Table of contents</h2>
<ul>
<li><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></li>
<li><a class="post-section-overview" href="#heading-what-are-web-workers-in-javascript">What are web workers in JavaScript?</a></li>
<li><a class="post-section-overview" href="#heading-brief-introduction-to-web-sockets">Brief introduction to web sockets</a></li>
<li><a class="post-section-overview" href="#heading-use-case-description">Use case description</a></li>
<li><a class="post-section-overview" href="#heading-project-structure">Project structure</a></li>
<li><a class="post-section-overview" href="#heading-client-and-server-application">Client and Server architecture</a></li>
<li><a class="post-section-overview" href="#heading-worker-system">Worker System</a></li>
<li><a class="post-section-overview" href="#heading-communication-between-the-ui-and-the-socket-via-web-worker">Communication between the UI and the socket via web worker</a></li>
<li><a class="post-section-overview" href="#heading-summary">Summary</a></li>
</ul>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Before you start reading this article, you should have a basic understanding of the following topics:</p>
<ul>
<li>Class Diagrams: We are going to use them to showcase our example. Here are a couple resources you can use to learn more about them: <ul>
<li><a target="_blank" href="https://drawio-app.com/uml-class-diagrams-in-draw-io/">Class diagrams</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/uml-diagrams-full-course/">UML Diagram course</a></li>
</ul>
</li>
<li><a target="_blank" href="https://www.notion.so/JS-Classes-a-boon-to-the-society-6360d1a702fe49da9b7ba98b0e03fe37">Context Diagram and Container Diagrams</a></li>
<li><a target="_blank" href="https://reactjs.org/">React</a></li>
<li>Web sockets<ul>
<li><a target="_blank" href="https://javascript.info/websocket">Introduction to sockets</a></li>
<li><a target="_blank" href="https://blog.sessionstack.com/how-javascript-works-deep-dive-into-websockets-and-http-2-with-sse-how-to-pick-the-right-path-584e6b8e3bf7">How JavaScript works: Deep dive into WebSockets and HTTP/2 with SSE + how to pick the right path</a></li>
</ul>
</li>
<li><a target="_blank" href="https://blog.kevinchisholm.com/javascript/difference-between-scope-and-context/">Difference between scope and context</a></li>
<li><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Glossary/Global_object">Global objects</a></li>
</ul>
<h2 id="heading-what-are-web-workers-in-javascript">What are web workers in JavaScript?</h2>
<p>A web worker is a piece of browser functionality. It is the real OS threads that can be spawned in the background of your current page so that it can perform complex and resource-intensive tasks. </p>
<p>Imagine that you have some large data to fetch from the server, or some complex rendering needs to be done on the UI. If you do this directly on your webpage then the page might get jankier and will impact the UI. </p>
<p>To mitigate this, you can simply create a thread – that is a web worker – and let the web worker take care of the complex stuff.  </p>
<p>You can communicate with the web worker in a pretty simple manner which can be used to transfer data to and fro from the worker to the UI.</p>
<p>Common examples of web workers would be: </p>
<ul>
<li>Dashboard pages that display real-time data such as stock prices, real-time active users, and so on</li>
<li>Fetching huge files from the server</li>
<li>Autosave functionality</li>
</ul>
<p>You can create a web worker using the following syntax:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> worker = <span class="hljs-keyword">new</span> Worker(<span class="hljs-string">"&lt;worker_file&gt;.js"</span>);
</code></pre>
<p><code>Worker</code> is an API interface that lets you create a thread in the background. We need to pass a parameter, that is a <code>&lt;worker_file&gt;.js</code> file. This specifies the worker file the API needs to execute.</p>
<p><strong>NOTE</strong>: A thread is created once a <code>Worker</code> call is initiated. This thread only communicates with its creator, that is the file which created this thread.</p>
<p>A worker can be shared or used by multiple consumers/scripts. These are called shared workers. The syntax of the shared worker is very similar to that of the above mentioned workers.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> worker = <span class="hljs-keyword">new</span> SharedWorker(<span class="hljs-string">"&lt;worker_file&gt;.js"</span>);
</code></pre>
<p>You can read more about <code>SharedWorker</code>s in <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker">this guide</a>.</p>
<h3 id="heading-history-of-web-workers">History of web workers</h3>
<p>Web workers execute in a different context, that is they do not execute in a global scope such as window context. Web workers have their own dedicated worker context which is called <code>DedicatedWorkerGlobalScope</code>.</p>
<p>There are some cases where you can't use web workers, though. For example, you can't use them to manipulate the DOM or the properties of the window object. This is because the worker does not have the access to the window object. </p>
<p>Web workers can also spawn new web workers. Web workers communicate with their creator using certain methods like <code>postMessage</code>, <code>onmessage</code>, and <code>onerror</code>. We will look into these methods closely in the later sections of this article.</p>
<h2 id="heading-brief-introduction-to-web-sockets">Brief Introduction to Web Sockets</h2>
<p>A web socket is a type of communication that happens between two parties/entities using a WebSocket protocol. It actually provides a way to communicate between the two connected entities in a persistent manner. </p>
<p>You can create a simple web socket like below:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> socket = <span class="hljs-keyword">new</span> WebSocket(<span class="hljs-string">"ws://example.com"</span>);
</code></pre>
<p>Over here we have created a simple socket connection. You'll notice that we have passed a parameter to the <code>WebSocket</code> constructor. This parameter is a URL at which the connection should be established. </p>
<p>You can read more about web sockets by referring to the <strong>Websockets</strong> link in the prerequisites.</p>
<h2 id="heading-use-case-description">Use Case Description</h2>
<p><strong>NOTE:</strong> Context, Container, and Class diagrams drawn in this blog post don't accurately follow the exact conventions of these diagrams. They're approximated here so that you can understand the basic concepts.</p>
<p>Before we start, I would suggest reading up on c4models, container diagrams, and context diagrams. You can find resources about them in the prerequisites section.</p>
<p>In this article, we are going to consider the following use case: data transfer using web workers via socket protocol.</p>
<p>We are going to build a web application which will plot the data on a line chart every 1.5 seconds. The web application will receive the data from the socket connection via web workers. Below is the context diagram of our use case:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/01/c4_webworker.drawio--2-.png" alt="Image" width="600" height="400" loading="lazy">
<em>Container Diagram</em></p>
<p>As you can see from the above diagram, there are 4 main components to our use case:</p>
<ol>
<li>Person: A user who is going to use our application</li>
<li>Software system: Client App – This is the UI of our application. It consists of DOM elements and a web worker.</li>
<li>Software system: Worker system – This is a worker file that resides in the client app. It is responsible for creating a worker thread and establishing the socket connection.</li>
<li>Software system: Server application – This is a simple JavaScript file which can be executed by <code>node</code> to create a socket server. It consists of code which helps to read messages from the socket connection.</li>
</ol>
<p>Now that we understand the use case, let's dive deep into each of these modules and see how the whole application works.</p>
<h2 id="heading-project-structure"><strong>Project</strong> Structure</h2>
<p>Please follow this <a target="_blank" href="https://github.com/keyurparalkar/webworker_examples">link</a> to get the full code for the project that I developed for this article.</p>
<p>Our project is divided into two folders. First is the server folder which consists of server code. The second is the client folder, which consists of the client UI, that is a React application and the web worker code. </p>
<p>Following is the directory structure:</p>
<pre><code>├── client
│   ├── package.json
│   ├── package-lock.json
│   ├── public
│   │   ├── favicon.ico
│   │   ├── index.html
│   │   ├── logo192.png
│   │   ├── logo512.png
│   │   ├── manifest.json
│   │   └── robots.txt
│   ├── README.md
│   ├── src
│   │   ├── App.css
│   │   ├── App.jsx
│   │   ├── components
│   │   │   ├── LineChartSocket.jsx
│   │   │   └── Logger.jsx
│   │   ├── index.css
│   │   ├── index.js
│   │   ├── pages
│   │   │   └── Homepage.jsx
│   │   ├── wdyr.js
│   │   └── workers
│   │       └── main.worker.js
│   └── yarn.lock
└── server
    ├── package.json
    ├── package-lock.json
    └── server.mjs
</code></pre><p>To run the application, you first need to start the socket server. Execute the following commands one at a time to start the socket server (assuming you are in the parent directory):</p>
<pre><code class="lang-shell">cd server
node server.mjs
</code></pre>
<p>Then start the client app by running the following commands (assuming you are in the parent directory):</p>
<pre><code class="lang-shell">cd client
yarn run start
</code></pre>
<p>Open <code>http://localhost:3000</code> to start the web app.</p>
<h2 id="heading-client-and-server-application">Client and Server Application</h2>
<p>The client application is a simple React application, that is <a target="_blank" href="https://create-react-app.dev/">CRA app</a>, which consists of a Homepage. This home page consists of the following elements:</p>
<ul>
<li>Two buttons: <code>start connection</code> and <code>stop connection</code> which will help to start and stop the socket connection as required.</li>
<li>A line chart component - This component will plot the data that we receive from the socket at regular intervals.</li>
<li>Logged message - This is a simple React component that will display the connection status of our web sockets.</li>
</ul>
<p>Below is the container diagram of our client application.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/01/Untitled.png" alt="Image" width="600" height="400" loading="lazy">
<em>Container Diagram: Client Application</em></p>
<p>Below is how the UI will look:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/01/Screenshot-from-2021-12-28-08-32-06.png" alt="Image" width="600" height="400" loading="lazy">
<em>Actual UI</em></p>
<p>To check out the code for the client UI, go to the client folder. This is a regular create-react-app, except that I have removed some boilerplate code that we don't need for this project. </p>
<p><code>App.jsx</code> is actually the starter code. If you check this out, we have called the <code>&lt;Homepage /&gt;</code> component in it.</p>
<p>Now let's have a look at the <code>Homepage</code> component.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> Homepage = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">const</span> [worker, setWorker] = useState(<span class="hljs-literal">null</span>);
  <span class="hljs-keyword">const</span> [res, setRes] = useState([]);
  <span class="hljs-keyword">const</span> [log, setLog] = useState([]);
  <span class="hljs-keyword">const</span> [buttonState, setButtonState] = useState(<span class="hljs-literal">false</span>);

  <span class="hljs-keyword">const</span> hanldeStartConnection = <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-comment">// Send the message to the worker [postMessage]</span>
    worker.postMessage({
      <span class="hljs-attr">connectionStatus</span>: <span class="hljs-string">"init"</span>,
    });
  };

  <span class="hljs-keyword">const</span> handleStopConnection = <span class="hljs-function">() =&gt;</span> {
    worker.postMessage({
      <span class="hljs-attr">connectionStatus</span>: <span class="hljs-string">"stop"</span>,
    });
  };

    <span class="hljs-comment">//UseEffect1</span>
  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">const</span> myWorker = <span class="hljs-keyword">new</span> Worker(
      <span class="hljs-keyword">new</span> URL(<span class="hljs-string">"../workers/main.worker.js"</span>, <span class="hljs-keyword">import</span>.meta.url)
    ); <span class="hljs-comment">//NEW SYNTAX</span>
    setWorker(myWorker);

    <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> {
      myWorker.terminate();
    };
  }, []);

    <span class="hljs-comment">//UseEffect2</span>
  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">if</span> (worker) {
      worker.onmessage = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">e</span>) </span>{
        <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> e.data === <span class="hljs-string">"string"</span>) {
          <span class="hljs-keyword">if</span>(e.data.includes(<span class="hljs-string">"["</span>)){
            setLog(<span class="hljs-function">(<span class="hljs-params">preLogs</span>) =&gt;</span> [...preLogs, e.data]);
          } <span class="hljs-keyword">else</span> {
            setRes(<span class="hljs-function">(<span class="hljs-params">prevRes</span>) =&gt;</span> [...prevRes, { <span class="hljs-attr">stockPrice</span>: e.data }]);
          }
        }

        <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> e.data === <span class="hljs-string">"object"</span>) {
          setButtonState(e.data.disableStartButton);
        }
      };
    }
  }, [worker]);

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"stats"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"control-panel"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">h3</span>&gt;</span>WebWorker Websocket example<span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">button</span>
            <span class="hljs-attr">id</span>=<span class="hljs-string">"start-connection"</span>
            <span class="hljs-attr">onClick</span>=<span class="hljs-string">{hanldeStartConnection}</span>
            <span class="hljs-attr">disabled</span>=<span class="hljs-string">{!worker</span> || <span class="hljs-attr">buttonState</span>}
          &gt;</span>
            Start Connection
          <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
          <span class="hljs-symbol">&amp;nbsp;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">button</span>
            <span class="hljs-attr">id</span>=<span class="hljs-string">"stop-connection"</span>
            <span class="hljs-attr">onClick</span>=<span class="hljs-string">{handleStopConnection}</span>
            <span class="hljs-attr">disabled</span>=<span class="hljs-string">{!buttonState}</span>
          &gt;</span>
            Stop Connection
          <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">LineChartComponent</span> <span class="hljs-attr">data</span>=<span class="hljs-string">{res}</span> /&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Logger</span> <span class="hljs-attr">logs</span>=<span class="hljs-string">{log}/</span>&gt;</span>
    <span class="hljs-tag">&lt;/&gt;</span></span>
  );
};
</code></pre>
<p>As you can see, it's just a regular functional component that renders two buttons – a line chart, and a custom component <code>Logger</code>. </p>
<p>Now that we know how our homepage component looks, let's dive into how the web worker thread is actually created. In the above component you can see there are two <code>useEffect</code> hooks used. </p>
<p>The first one is used for creating a new worker thread. It's a simple call to the <code>Worker</code> constructor with a new operator as we have seen in the previous section of this article. </p>
<p>But there are some difference over here: we have passed an URL object to the worker constructor rather than passing the path of the worker file in the string.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> myWorker = <span class="hljs-keyword">new</span> Worker(<span class="hljs-keyword">new</span> URL(<span class="hljs-string">"../workers/main.worker.js"</span>, <span class="hljs-keyword">import</span>.meta.url));
</code></pre>
<p>You can read more about this syntax <a target="_blank" href="https://webpack.js.org/guides/web-workers/">here</a>.</p>
<p>If you try to import this web worker like below, then our create-react-app won’t be able to load/bundle it properly so you will get an error since it has not found the worker file during bundling:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> myWorker = <span class="hljs-keyword">new</span> Worker(<span class="hljs-string">"../workers/main.worker.js"</span>);
</code></pre>
<p>Next, we also don’t want our application to run the worker thread even after the refresh, or don’t want to spawn multiple threads when we refresh the page. To mitigate this, we'll return a callback in the same useEffect. We use this callback to perform cleanups when the component unmounts. In this case, we are terminating the worker thread.</p>
<p>We use the <code>useEffect2</code> to handle the messages received from the worker.</p>
<p>Web workers have a build-in property called <code>onmessage</code> which helps receive any messages sent by the worker thread. The <code>onmessage</code> is an event handler of the worker interface. It gets triggered whenever a  message event is triggered. This message event is generally triggered whenever the <code>postMessage</code> handler is executed (we will look more into this in a later section).</p>
<p>So in order for us to send a message to the worker thread, we have created two handlers. The first is <code>handleStartConnection</code> and the second is <code>handleStopConnection</code>. Both of them use the <code>postMessage</code> method of the worker interface to send the message to the worker thread. </p>
<p>We will talk about the message <code>{connectionStatus: init}</code> in our next section.</p>
<p>You can read more about the internal workings of the <code>onmessage</code> and <code>postMessage</code> in the following resources:</p>
<ul>
<li><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Worker/onmessage">Onmessage</a></li>
<li><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/DedicatedWorkerGlobalScope/postMessage">Postmessage</a></li>
</ul>
<p>Since we now have a basic understanding about how our client code is working, then let's move on to learn about the <strong>Worker System in our context diagram above.</strong></p>
<h2 id="heading-worker-system">Worker System</h2>
<p>To understand the code in this section, make sure you go through the file <code>src/workers/main.worker.js</code>.</p>
<p>To help you understand what's going on here, we will divide this code into three parts:</p>
<ol>
<li>A <code>self.onmessage</code> section</li>
<li>How the socket connection is managed using the <code>socketManagement()</code> function</li>
<li>Why we need the <code>socketInstance</code> variable at the top</li>
</ol>
<h3 id="heading-how-selfonmessage-works">How <code>self.onmessage</code> works</h3>
<p>Whenever you create a web worker application, you generally write a worker file which handles all the complex scenarios that you want the worker to perform. This all happens in the <code>main.worker.js</code> file. This file is our worker file. </p>
<p>In the above section, we saw that we established a new worker thread in the <code>useEffect</code>. Once we created the thread, we also attached the two handlers to the respective <code>start</code> and <code>stop</code> connection buttons. </p>
<p>The <code>start connection</code> button will execute the <code>postMessage</code> method with message: <code>{connectionStatus: init}</code> . This triggers the message event, and since the message event is triggered, all the message events are captured by the <code>onmessage</code> property. </p>
<p>In our <code>main.worker.js</code> file, we have attached a handler to this <code>onmessage</code> property:</p>
<pre><code class="lang-javascript">self.onmessage = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">e</span>) </span>{
  <span class="hljs-keyword">const</span> workerData = e.data;
  postMessage(<span class="hljs-string">"[WORKER] Web worker onmessage established"</span>);
  <span class="hljs-keyword">switch</span> (workerData.connectionStatus) {
    <span class="hljs-keyword">case</span> <span class="hljs-string">"init"</span>:
      socketInstance = createSocketInstance();
      socketManagement();
      <span class="hljs-keyword">break</span>;

    <span class="hljs-keyword">case</span> <span class="hljs-string">"stop"</span>:
      socketInstance.close();
      <span class="hljs-keyword">break</span>;

    <span class="hljs-keyword">default</span>:
      socketManagement();
  }
}
</code></pre>
<p>So whenever any message event is triggered in the client, it will get captured in this event handler.  </p>
<p>The message <code>{connectionStatus: init}</code> that we send from the client is received in the event <code>e</code>. Based on the value of connectionStatus we use the switch case to handle the logic. </p>
<p><strong>NOTE:</strong> We have added this switch case because we need to isolate some part of the code which we do not want to execute all the time (we will look into this in a later section).</p>
<h3 id="heading-how-the-socket-connection-is-managed-using-the-socketmanagement-function">How the socket connection is managed using the <code>socketManagement()</code> function</h3>
<p>There are some reasons why I have shifted the logic of creating and managing a socket connection into a separate function. Here is the code for a better understanding of the point I am trying to make:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">socketManagement</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">if</span> (socketInstance) {
    socketInstance.onopen = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">e</span>) </span>{
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"[open] Connection established"</span>);
      postMessage(<span class="hljs-string">"[SOCKET] Connection established"</span>);
      socketInstance.send(<span class="hljs-built_in">JSON</span>.stringify({ <span class="hljs-attr">socketStatus</span>: <span class="hljs-literal">true</span> }));
      postMessage({ <span class="hljs-attr">disableStartButton</span>: <span class="hljs-literal">true</span> });
    };

    socketInstance.onmessage = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">event</span>) </span>{
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`[message] Data received from server: <span class="hljs-subst">${event.data}</span>`</span>);
      postMessage( event.data);
    };

    socketInstance.onclose = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">event</span>) </span>{
      <span class="hljs-keyword">if</span> (event.wasClean) {
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`[close] Connection closed cleanly, code=<span class="hljs-subst">${event.code}</span>`</span>);
        postMessage(<span class="hljs-string">`[SOCKET] Connection closed cleanly, code=<span class="hljs-subst">${event.code}</span>`</span>);
      } <span class="hljs-keyword">else</span> {
        <span class="hljs-comment">// e.g. server process killed or network down</span>
        <span class="hljs-comment">// event.code is usually 1006 in this case</span>
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'[close] Connection died'</span>);
        postMessage(<span class="hljs-string">'[SOCKET] Connection died'</span>);
      }
      postMessage({ <span class="hljs-attr">disableStartButton</span>: <span class="hljs-literal">false</span> });
    };

    socketInstance.onerror = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">error</span>) </span>{
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`[error] <span class="hljs-subst">${error.message}</span>`</span>);
      postMessage(<span class="hljs-string">`[SOCKET] <span class="hljs-subst">${error.message}</span>`</span>);
      socketInstance.close();
    };
  }
}
</code></pre>
<p>This is a function that will help you manage your socket connection:</p>
<ul>
<li>For receiving the message from the socket server we have the <code>onmessage</code> property which is assigned an event handler.</li>
<li>Whenever a socket connection is opened, you can perform certain operations. To do that we have the <code>onopen</code> property which is assigned to an event handler.</li>
<li>And if any error occurs or when we are closing the connection then, we use <code>onerror</code> and <code>onclose</code> properties of the socket.</li>
</ul>
<p>For creating a socket connection there is a separate function altogether:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createSocketInstance</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">let</span> socket = <span class="hljs-keyword">new</span> WebSocket(<span class="hljs-string">"ws://localhost:8080"</span>);

  <span class="hljs-keyword">return</span> socket;
}
</code></pre>
<p>Now all of these functions are called in a switch case like below in the <code>main.worker.js</code> file:</p>
<pre><code class="lang-javascript">self.onmessage = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">e</span>) </span>{
  <span class="hljs-keyword">const</span> workerData = e.data;
  postMessage(<span class="hljs-string">"[WORKER] Web worker onmessage established"</span>);
  <span class="hljs-keyword">switch</span> (workerData.connectionStatus) {
    <span class="hljs-keyword">case</span> <span class="hljs-string">"init"</span>:
      socketInstance = createSocketInstance();
      socketManagement();
      <span class="hljs-keyword">break</span>;

    <span class="hljs-keyword">case</span> <span class="hljs-string">"stop"</span>:
      socketInstance.close();
      <span class="hljs-keyword">break</span>;

    <span class="hljs-keyword">default</span>:
      socketManagement();
  }
}
</code></pre>
<p>So based on what message the client UI sends to the worker the appropriate function will be executed. It is pretty self-explanatory on what message which particular function should be triggered, based on the above code.</p>
<p>Now consider a scenario where we placed all the code inside <code>self.onmessage</code>.</p>
<pre><code class="lang-javascript">self.onmessage = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">e</span>)</span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Worker object present "</span>, e);
    postMessage({<span class="hljs-attr">isLoading</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">data</span>: <span class="hljs-literal">null</span>});

    <span class="hljs-keyword">let</span> socket = <span class="hljs-keyword">new</span> WebSocket(<span class="hljs-string">"ws://localhost:8080"</span>);

        socket.onopen = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">e</span>) </span>{
          <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"[open] Connection established"</span>);
          <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Sending to server"</span>);
          socket.send(<span class="hljs-string">"My name is John"</span>);
        };

        socket.onmessage = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">event</span>) </span>{
          <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`[message] Data received from server: <span class="hljs-subst">${event.data}</span>`</span>);
        };

        socket.onclose = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">event</span>) </span>{
          <span class="hljs-keyword">if</span> (event.wasClean) {
            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`[close] Connection closed cleanly, code=<span class="hljs-subst">${event.code}</span> reason=<span class="hljs-subst">${event.reason}</span>`</span>);
          } <span class="hljs-keyword">else</span> {
            <span class="hljs-comment">// e.g. server process killed or network down</span>
            <span class="hljs-comment">// event.code is usually 1006 in this case</span>
            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'[close] Connection died'</span>);
          }
        };

            socket.onerror = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">error</span>) </span>{
              <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`[error] <span class="hljs-subst">${error.message}</span>`</span>);
            };
}
</code></pre>
<p>This would cause the following problems:</p>
<ol>
<li>On every <code>postMessage</code> call made by the client UI, there would have been a new socket instance.</li>
<li>It would have been difficult to close the socket connection.</li>
</ol>
<p>Because of these reasons, all the socket management code is written in a function <code>socketManagement</code> and catered using a switch case.</p>
<h3 id="heading-why-we-need-the-socketinstance-variable-at-the-top">Why we need the <code>socketInstance</code> variable at the top</h3>
<p>We do need a <code>socketInstance</code> variable at the top because this will store the socket instance which was previously created. It is a safe practice since no one can access this variable externally as <code>main.worker.js</code> is a separate module altogether.</p>
<h2 id="heading-communication-between-the-ui-and-the-socket-via-web-worker">Communication between the UI and the socket via web worker</h2>
<p>Now that we understand which part of the code is responsible for which section, we will take a look at how we establish a socket connection via webworkers. We'll also see how we respond via socket server to display a line chart on the UI.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/01/Untitled--1-.png" alt="Image" width="600" height="400" loading="lazy">
<em>End-to-end flow of the application</em></p>
<p><strong>NOTE:</strong> Some calls are purposefully not shown in the diagram since it will make the diagram cluttered. Make sure you refer to the code as well while referring to this diagram.</p>
<p>Now let's first understand what happens when you click on the <code>start connection</code> button on the UI:</p>
<ol>
<li>One thing to notice over here is that our web worker thread is created once the component is mounted, and is removed/terminated when the component is unmounted.</li>
<li>Once the <code>start connection</code> button is clicked, a <code>postMessage</code> call is made with <code>{connectionStatus: init}</code></li>
<li>The web worker’s <code>onmessage</code> event handler which is listening to all the message events comes to know that it has received <em>connectionStatus as init.</em> It matches the case, that is in the switch case of <code>main.worker.js</code>. It then calls the <code>createSocketInstance()</code> which returns a new socket connection at the URL: <code>ws://localhost:8080</code></li>
<li>After this a <code>socketManagement()</code> function is called which checks if the socket is created and then executes a couple of operations.</li>
<li>In this flow, since the socket connection is just established therefore, socketInstance’s <code>onpen</code> event handler is executed. </li>
<li>This will send a <code>{socketStatus: true}</code> message to the socket server. This will also send a message back to the client UI via <code>postMessage({ disableStartButton: true})</code> which tells the client UI to disable the start button.</li>
<li>Whenever the socket connection is established, then the server socket’s <code>on('connection', ()=&gt;{})</code> is invoked. So in step 3, this function is invoked at the server end.</li>
<li>Socket’s <code>on('message', () =&gt; {})</code> is invoked whenever a message is sent to the socket. So at step 6, this function is invoked at the server end. This will check if the <code>socketStatus</code> is true, and then it will start sending a random integer every 1.5 seconds to the client UI via web workers.</li>
</ol>
<p>Now that we understood how the connection is established, let's move on to understand how the socket server sends the data to the client UI:</p>
<ol>
<li>As discussed above, socket server received the message to send the data, that is a random number every 1.5 second.</li>
<li>This data is recieved on the web worker’s end using the <code>onmessage</code> handler. </li>
<li>This handler then calls the <code>postMessage</code> function and sends this data to the UI.</li>
<li>After receiving the data it appends it to an array as a <code>stockPrice</code> object. </li>
<li>This acts as a data source for our line chart component and gets updated every 1.5 seconds.</li>
</ol>
<p>Now that we understand how the connection is established, let's move on to understand how the socket server sends the data to the client UI:</p>
<ol>
<li>As discussed above, socket server recieved the message to send the data, that is a random number, every 1.5 seconds.</li>
<li>This data is recieved on the web worker’s end using the socket's <code>onmessage</code> handler. </li>
<li>This handler then calls the <code>postMessage</code> function of the web worker and sends this data to the UI.</li>
<li>After receiving the data via <code>useEffect2</code> it appends it to an array as a <code>stockPrice</code> object. </li>
<li>This acts as a data source for our line chart component and gets updated every 1.5 seconds.</li>
</ol>
<p><strong>NOTE:</strong> We are using recharts for plotting the line chart. You can find more information about it at <a target="_blank" href="https://recharts.org/en-US/">the official docs</a>.</p>
<p>Here is how our application will look in action:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/01/ezgif.com-gif-maker.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Working Example</em></p>
<h2 id="heading-summary">Summary</h2>
<p>So this was a quick introduction to what web workers are and how you can use them to solve complex problems and create better UIs. You can use web workers in your projects to handle complex UI scenarios. </p>
<p>If you want to optimize your workers, read up on the below libraries:</p>
<ul>
<li><a target="_blank" href="https://www.npmjs.com/package/comlink">comlink</a></li>
<li><a target="_blank" href="https://threads.js.org/">thread.js</a></li>
</ul>
<p>Thank you for reading!</p>
<p>Follow me on <a target="_blank" href="https://twitter.com/keurplkar">twitter</a>, <a target="_blank" href="http://github.com/keyurparalkar">github</a>, and <a target="_blank" href="https://www.linkedin.com/in/keyur-paralkar-494415107/">linkedIn</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ JavaScript Classes – How They Work with Use Case Example ]]>
                </title>
                <description>
                    <![CDATA[ In this blog post I'll walk you through a real life example which uses the concept of classes in JavaScript.  I think it's helpful to work with a practical use case because it is much simpler to understand the concepts when you can relate them to rea... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/javascript-classes-how-they-work-with-use-case/</link>
                <guid isPermaLink="false">66bb5549e326dc37a9d68ee3</guid>
                
                    <category>
                        <![CDATA[ classes ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Object Oriented Programming ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Keyur Paralkar ]]>
                </dc:creator>
                <pubDate>Mon, 13 Dec 2021 19:24:50 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/12/feliphe-schiarolli-hes6nUC1MVc-unsplash-1.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this blog post I'll walk you through a real life example which uses the concept of classes in JavaScript. </p>
<p>I think it's helpful to work with a practical use case because it is much simpler to understand the concepts when you can relate them to real life. </p>
<p>So in this guide, you will learn about classes in JavaScript, inheritance, abstract functions, how to use keywords such as <code>super</code> and <code>extend</code>s, static keywords, and private members of classes.</p>
<p>Let's dive in.</p>
<h2 id="heading-table-of-contents">Table of contents</h2>
<ul>
<li><a class="post-section-overview" href="#Prerequisites">Prerequisites</a></li>
<li><a class="post-section-overview" href="#heading-what-are-classes-in-javascript">What Are Classes in JavaScript?</a></li>
<li><a class="post-section-overview" href="#heading-use-case-description">Use Case Description</a></li>
<li><a class="post-section-overview" href="#heading-abstract-functions-and-inheritance-in-chair-management-system">Abstract Functions and Inheritance in Chair Management System</a></li>
<li><a class="post-section-overview" href="#heading-static-keyword-in-javascript">Static Keyword in JavaScript</a></li>
<li><a class="post-section-overview" href="#heading-private-members-of-classes-in-javascript">Private members in JavaScript</a></li>
</ul>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Before you start reading this blog post you should have a basic understanding of the following topics:</p>
<ul>
<li><a target="_blank" href="https://drawio-app.com/uml-class-diagrams-in-draw-io/">Class Diagrams: We are going to use them to showcase our example</a></li>
<li><a target="_blank" href="https://en.wikipedia.org/wiki/System_context_diagram">Context Diagram and Container Diagrams</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/object-oriented-programming-javascript/">Knowledge of OOPs</a></li>
<li><a target="_blank" href="https://dev.to/lawrence_eagles/understanding-prototypal-inheritance-in-javascript-4f31#chp-2">Introduction to Prototypal Inheritance, and Prototype chaining</a> </li>
<li><a target="_blank" href="https://dev.to/lawrence_eagles/an-easy-guide-to-understanding-constructors-in-javascript-2mf6">Introduction to constructor functions in JS</a></li>
</ul>
<h2 id="heading-what-are-classes-in-javascript">What are classes in JavaScript?</h2>
<p>Classes were introduced in <a target="_blank" href="https://262.ecma-international.org/6.0/">EcmaScript 2015</a> (ES6) to provide a cleaner way to follow object-oriented programming patterns. </p>
<p>JavaScript still follows a prototype-based inheritance model. Classes in JavaScript are syntactic sugar over the prototype-based inheritance model which we use to implement OOP concepts. </p>
<p>Thus the introduction of classes in JS made it easier for developers to build software around OOP concepts. It also brought in similarities to different OOP-based programming languages such as C++ and Java. </p>
<p>Before classes, we used constructor functions to do OOP in JavaScript. Have a look at the example below:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Pen</span>(<span class="hljs-params">name, color, price</span>) </span>{
    <span class="hljs-built_in">this</span>.name = name;
    <span class="hljs-built_in">this</span>.color = color;
    <span class="hljs-built_in">this</span>.price = price;
}

<span class="hljs-keyword">const</span> pen1 = <span class="hljs-keyword">new</span> Pen(<span class="hljs-string">"Marker"</span>, <span class="hljs-string">"Blue"</span>, <span class="hljs-string">"$3"</span>);
<span class="hljs-built_in">console</span>.log(pen1);
</code></pre>
<p>The above code shows a <code>Pen</code> constructor function that has name, color, and price properties. We are using the <code>new</code> keyword with the <code>Pen</code> constructor to create an object <code>pen1</code>.  </p>
<p>Now let's say we want to add a new function to the <code>Pen</code> constructor. To do this we need to add the function into the prototype property of <code>Pen</code>. Have a look at the <code>showPrice</code> function below:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Pen</span>(<span class="hljs-params">name, color, price</span>) </span>{
    <span class="hljs-built_in">this</span>.name = name;
    <span class="hljs-built_in">this</span>.color = color;
    <span class="hljs-built_in">this</span>.price = price;
}

<span class="hljs-keyword">const</span> pen1 = <span class="hljs-keyword">new</span> Pen(<span class="hljs-string">"Marker"</span>, <span class="hljs-string">"Blue"</span>, <span class="hljs-string">"$3"</span>);

Pen.prototype.showPrice = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Price of <span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span> is <span class="hljs-subst">${<span class="hljs-built_in">this</span>.price}</span>`</span>);
}

pen1.showPrice();
</code></pre>
<p>If these concepts aren't making sense to you, then I would recommend brushing up on your JS/background knowledge through the articles mentioned in the Prerequisites section. In particular, check out the article about Prototype and Constructor functions.</p>
<p>Looking at the above code, we can say that we have done what we wanted to do – that is, add a <code>showPrice</code> function to the constructor <code>Pen</code>. But you can see that it's not that readable compared to OOP concepts we implement in C++ or Java.</p>
<p>We can re-create the above example with the help of the <code>class</code> keyword. Have a look at the below code:</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Pen</span> </span>{
    <span class="hljs-keyword">constructor</span>(name, color, price){
        <span class="hljs-built_in">this</span>.name = name;
        <span class="hljs-built_in">this</span>.color = color; 
        <span class="hljs-built_in">this</span>.price = price;
    }

    showPrice(){
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Price of <span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span> is <span class="hljs-subst">${<span class="hljs-built_in">this</span>.price}</span>`</span>);
    }
}

<span class="hljs-keyword">const</span> pen1 = <span class="hljs-keyword">new</span> Pen(<span class="hljs-string">"Marker"</span>, <span class="hljs-string">"Blue"</span>, <span class="hljs-string">"$3"</span>);
pen1.showPrice();
</code></pre>
<p>Noticed the difference! We have achieved the same results but with much cleaner syntax. The addition of a new member function like <code>showPrice</code> is much easier as compared to adding a function directly into the constructor's prototype.</p>
<p>Let's dive into classes in JS a bit deeper using an example use case. With this use case, we are going to see how these concepts can be useful to solve some real-life problems.</p>
<h2 id="heading-use-case-description">Use Case Description</h2>
<p><strong>Just a quick note</strong>: the Context, Container, and Classes diagrams drawn in this blog post don't exactly follow the conventions of the above diagrams. I've approximated the diagrams to help you understand the concepts in general.</p>
<p>Before we start, I would suggest reading up on c4models, container diagrams, and context diagrams if you need a refresher. You can find them in the prerequisites section.</p>
<p>We are going to solve the following problem: helping a shopkeeper classify the chairs in their inventory and display them on the screen.</p>
<p>The use case is simple and pretty self-explanatory. Have a look at the diagram below which showcases the overall proposed system:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/js_classes_tut_context.drawio--1-.png" alt="Image" width="600" height="400" loading="lazy">
<em>Context Diagram for the Chair Management System</em></p>
<p>As you can see from the above diagram, there are 3 main components to it:</p>
<ol>
<li><strong>Person:</strong> The shopkeeper is going to interact with our system.</li>
<li><strong>Software System: Stock Interface Portal</strong> - This is an interface that allows the shopkeeper to view or modify the chair information present in the inventory.</li>
<li><strong>Software System: Chair Management System</strong> - This system will allow the interface to fetch or modify the required details requested by the shopkeeper.</li>
</ol>
<p>Now that we understand the use case, let's start with the target system that we are going to focus on in this blog post. It is the <strong>Chair Management System.</strong> </p>
<p>We'll start off by creating some major components in our Chair Management System. Our components in this system are just different classes which will help facilitate the different needs of the shopkeeper.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/chairModel.drawio--2--1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Chair component of Chair Management System</em></p>
<p>Let's add one component called <strong><code>Chair</code></strong>. Since it is a class, it will have its own attributes (properties) and behavior (methods). </p>
<p>Have a look at the above diagram. We can see that:</p>
<ul>
<li>The second row contains attributes of the chair class, for example color, seatHeight, recliningAngle, and so on. </li>
<li>The third row corresponds to the methods that tell us what functions the chair can perform, for example adjustSeatHeight, adjustAngle, moveChair, and so on.</li>
</ul>
<p>We'll follow the above representation for all the components that we'll create throughout this article.</p>
<p>The <code>Chair</code> component will be our base component. This means that all the other types of chairs such as office chairs, dining chairs, and so on will come under this class/component. </p>
<p>Let's start off by creating our base chair class in JS. Have a look at the below code:</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Chair</span> </span>{
    <span class="hljs-keyword">constructor</span>(color, seatHeight, recliningAngle, backSupport, headSupport, padding, armRests, seatSize, isHeightAdjustable, isMovable){
        <span class="hljs-built_in">this</span>.color = color;
        <span class="hljs-built_in">this</span>.seatHeight = seatHeight;
        <span class="hljs-built_in">this</span>.recliningAngle = recliningAngle;
        <span class="hljs-built_in">this</span>.backSupport = backSupport;
        <span class="hljs-built_in">this</span>.headSupport = headSupport;
        <span class="hljs-built_in">this</span>.padding = padding;
        <span class="hljs-built_in">this</span>.armRests = armRests;
        <span class="hljs-built_in">this</span>.seatSize = seatSize;
        <span class="hljs-built_in">this</span>.isHeightAdjustable = isHeightAdjustable;
        <span class="hljs-built_in">this</span>.isMovable = isMovable;
    }

    adjustableHeight() {};
    adjustAngle(){};
    moveChair(){};    
}

<span class="hljs-keyword">const</span> newChair = <span class="hljs-keyword">new</span> Chair(<span class="hljs-string">"Blue"</span>,<span class="hljs-string">"25 inch"</span>,<span class="hljs-string">"20 deg"</span>,<span class="hljs-literal">true</span>,<span class="hljs-literal">false</span>,<span class="hljs-string">"3 inch"</span>,<span class="hljs-literal">true</span>,<span class="hljs-string">"16 inch"</span>,<span class="hljs-literal">false</span>,<span class="hljs-literal">false</span>);

<span class="hljs-built_in">console</span>.dir(<span class="hljs-string">"Chair Prototype"</span>, Chair);
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Chair Object"</span>, newChair);
</code></pre>
<p>The chair class has the following members: </p>
<ul>
<li><strong>Attributes</strong>: These will define the attributes of the chair such as color, seat height, backSupport, and so on.</li>
<li><strong>Functions</strong>: These define the behavior of the chair. For example, if the chair has <code>isHeightAdjustable</code> set to true then it can use the function <code>adjustableHeight</code>. You can see that all the functions are declared in the <code>Chair</code> class. These are the abstract functions. We will talk more about these functions later in this article.</li>
</ul>
<p>At the bottom of the code, we have two console log statements. The first one will print out the definition of the class <code>Chair</code> . The second object will print the <code>newChair</code> instance. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Screenshot-from-2021-12-11-11-58-14.png" alt="Image" width="600" height="400" loading="lazy">
<em>First console.dir output</em></p>
<p>If you look at the first output, it prints out the <code>Chair</code> class. Let's have a look at the contents of it: </p>
<ul>
<li>It consists of a property <code>prototype</code>. This is the prototype that all the instances of class Chair will have.</li>
<li>The <code>name</code> property is the name of the object.</li>
<li>Lastly, we have the <code>__proto__</code>  or <code>[[Prototype]]</code> property. This is the actual prototype of the class <code>Chair</code>.</li>
</ul>
<pre><code class="lang-json">{
    <span class="hljs-attr">"color"</span>: <span class="hljs-string">"Blue"</span>,
    <span class="hljs-attr">"seatHeight"</span>: <span class="hljs-string">"25 inch"</span>,
    <span class="hljs-attr">"recliningAngle"</span>: <span class="hljs-string">"20 deg"</span>,
    <span class="hljs-attr">"backSupport"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">"headSupport"</span>: <span class="hljs-literal">false</span>,
    <span class="hljs-attr">"padding"</span>: <span class="hljs-string">"3 inch"</span>,
    <span class="hljs-attr">"armRests"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">"seatSize"</span>: <span class="hljs-string">"16 inch"</span>,
    <span class="hljs-attr">"isHeightAdjustable"</span>: <span class="hljs-literal">false</span>,
    <span class="hljs-attr">"isMovable"</span>: <span class="hljs-literal">false</span>,
    [[Prototype]]: {
        adjustAngle: ƒ adjustAngle()
        adjustableHeight: ƒ adjustableHeight()
        constructor: class Chair
        moveChair: ƒ moveChair()
        [[Prototype]]: Object
    }
}
</code></pre>
<p>The second log statement prints out the information of the chair object instance. It will consist of all of the Chair class attributes. If you notice closely you can see that the prototype of this instance is similar to that of the <code>prototype</code> property of the chair class. This happens because of prototypical inheritance.</p>
<p>Now let's see how we can use this concept by adding a new component/class into our <strong>Chair Management System.</strong></p>
<h2 id="heading-abstract-functions-and-inheritance-in-chair-management-system">Abstract Functions and Inheritance in Chair Management System</h2>
<p>The abstract function is just a function signature in a class without any implementation. It helps us generalize the code so that the subclasses can use them and add their own implementation to it. </p>
<p>To demonstrate this in our use case, let's add one more component to our <strong>Chair Management System.</strong> </p>
<p>I have modified the chair class so that it now consists of defaults. These defaults will be used by all the instances. Later the subclass can modify it. We will see shortly how we can achieve this. Have a look at the new <code>Chair</code> class below:</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Chair</span> </span>{
    <span class="hljs-keyword">constructor</span>(color, seatHeight, recliningAngle, backSupport, headSupport, padding, armRests, seatSize, isHeightAdjustable, isMovable){
        <span class="hljs-comment">//Defaults which can be changed by the subclass class.</span>
        <span class="hljs-built_in">this</span>.color = color;
        <span class="hljs-built_in">this</span>.seatHeight = seatHeight;
        <span class="hljs-built_in">this</span>.recliningAngle = recliningAngle;
        <span class="hljs-built_in">this</span>.backSupport = <span class="hljs-literal">true</span>;
        <span class="hljs-built_in">this</span>.headSupport = <span class="hljs-literal">false</span>;
        <span class="hljs-built_in">this</span>.padding = <span class="hljs-string">"3 inch"</span>;
        <span class="hljs-built_in">this</span>.armRests = <span class="hljs-literal">true</span>;
        <span class="hljs-built_in">this</span>.seatSize = <span class="hljs-string">"16 inch"</span>;
        <span class="hljs-built_in">this</span>.isHeightAdjustable = <span class="hljs-literal">false</span>;
        <span class="hljs-built_in">this</span>.isMovable = <span class="hljs-literal">false</span>;
        <span class="hljs-built_in">this</span>.type = <span class="hljs-string">"Chair"</span>;
    }

    adjustableHeight() {};
    adjustAngle(){};
    moveChair(){};    
}

<span class="hljs-keyword">const</span> newChair = <span class="hljs-keyword">new</span> Chair();

newChair;
</code></pre>
<p>Now let's add a new component/class called <strong><code>OfficeChair</code></strong>. This will inherit the attributes and methods from the <code>Chair</code> class. The new modified class diagram will look like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/chairModel.drawio--1---1-.png" alt="Image" width="600" height="400" loading="lazy">
<em>Class diagram</em></p>
<p>Notice that the new class <code>OfficeChair</code> consists of only the methods and not the attributes. We assume here that all the attributes will be inherited from the <code>Chair</code> class.  </p>
<p>For the <code>OfficeChair</code> class, we have implemented the abstract methods present in the <code>Chair</code> class. </p>
<p>Have a look at the below code for the <code>OfficeChair</code> class:</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">OfficeChair</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Chair</span></span>{
    <span class="hljs-keyword">constructor</span>(color, isHeightAdjustable, seatHeight, recliningAngle){
        <span class="hljs-built_in">super</span>();
        <span class="hljs-built_in">this</span>.type = <span class="hljs-string">"Office Chair"</span>;
        <span class="hljs-built_in">this</span>.color = color;
        <span class="hljs-built_in">this</span>.isHeightAdjustable = isHeightAdjustable;
        <span class="hljs-built_in">this</span>.seatHeight = seatHeight;
        <span class="hljs-built_in">this</span>.recliningAngle = recliningAngle;
        <span class="hljs-built_in">this</span>.isMovable = <span class="hljs-literal">true</span>;
    }

    adjustableHeight(height){
        <span class="hljs-keyword">if</span>(height &gt; <span class="hljs-built_in">this</span>.seatHeight){
            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Chair height changed to <span class="hljs-subst">${height}</span>`</span>);        
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Height cannot be decreased more than the seat height <span class="hljs-subst">${<span class="hljs-built_in">this</span>.seatHeight}</span>`</span>);
        }
    }

    adjustAngle(angle){
        <span class="hljs-keyword">if</span>(angle &gt;= <span class="hljs-built_in">this</span>.recliningAngle){
            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Chair angle changed to <span class="hljs-subst">${angle}</span>`</span>);        
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Angle cannot be decreased more than the min reclining angle <span class="hljs-subst">${<span class="hljs-built_in">this</span>.recliningAngle}</span>`</span>);
        }
    }

    moveChair(x,y){
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Chair moved to co-ordinates = (<span class="hljs-subst">${x}</span>, <span class="hljs-subst">${y}</span>)`</span>);
    }
}

<span class="hljs-keyword">const</span> newOfficeChair = <span class="hljs-keyword">new</span> OfficeChair(<span class="hljs-string">"Red"</span>, <span class="hljs-literal">true</span>, <span class="hljs-number">30</span>, <span class="hljs-number">30</span>);

<span class="hljs-built_in">console</span>.log(newOfficeChair.adjustableHeight(<span class="hljs-number">31</span>));
<span class="hljs-built_in">console</span>.log(newOfficeChair.adjustAngle(<span class="hljs-number">40</span>));
<span class="hljs-built_in">console</span>.log(newOfficeChair.moveChair(<span class="hljs-number">10</span>,<span class="hljs-number">20</span>));
</code></pre>
<p>This is a class that inherits the functions and attributes from the superclass <code>chair</code>. It uses the <code>extends</code> keyword to allow the <code>OfficeChair</code> class to perform inheritance. </p>
<p>The <code>extends</code> keyword has the following syntax:</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ChildClass</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">ParentClass</span></span>{...}
</code></pre>
<p>Next, we have a constructor function and the implementation of some of the functions from the superclass. Notice that we are using the <code>super</code> keyword in the constructor.</p>
<p>We use the <code>super</code> keyword to call the constructor of the parent class. We can also use it to call functions and properties of the parent class. </p>
<p>A word of caution when you're using the <code>super</code> keyword:</p>
<ul>
<li>Make sure you call the <code>super</code> function at the start of the constructor. If you don't, and you try to access the parent class's properties before you use <code>super</code> in the child class constructor, it will throw an error. </li>
<li>Once the <code>super</code> function is called, then you can access all the attributes and functions of the parent class. </li>
<li>Super is not just related to the classes – you can also use it to call functions on the object's parent. </li>
</ul>
<p>You can read more about <code>super</code> in the MDN <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/super">docs</a>.</p>
<p>Lastly, if you notice, we have added the implementation for the abstract functions. The functions are as follows:</p>
<ul>
<li><code>adjustableHeight</code>: This function will check if the input height is greater than the minimum height of the chair. If yes, we can change the height or else display the error message. A person can also increase or decrease the height of the chair. Note that <code>this.seatHeight</code> is the minimum height of the chair from the ground below which the person cannot lower the height.</li>
<li><code>adjustAngle</code>: This function will check if the input angle is greater than the default value <code>this.recliningAngle</code>. If the input angle is greater than the default angle, then the angle will change or else an error message will be displayed.</li>
<li><code>moveChair</code>: Any chair whose <code>isMovable</code> property is true then the corresponding class will have an implementation of the <code>moveChair</code> function. It simply helps to move the chair based on the input x and y coordinates.</li>
</ul>
<p>Note that we have also reinitialized some of the attributes of the <code>Chair</code> class such as <code>type</code>. We will be explicitly defining the <code>type</code> attribute for each subclass. This will help us classify the chairs present in the inventory by assigning these classes to each of them.</p>
<p>You should now have an idea of what abstract functions are and how useful they can be. Some advantages of having abstract functions:</p>
<ul>
<li>Reduces redundancy in the codebase.</li>
<li>Provides a proper way of generalizing classes.</li>
<li>Allows flexibility for subclasses to implement whichever abstract function they need.</li>
</ul>
<h2 id="heading-static-keyword-in-javascript">Static Keyword in Javascript</h2>
<p>The <code>static</code> keyword in JavaScript helps you define functions and properties in the class that cannot be called by the instance of the object. They can only be called by the class itself which consists of these static functions and properties.</p>
<p>Generally, we use <code>static</code> methods in the classes for utility purposes such as printing out all the properties of the class, creating a new object, clearing other objects of the classes, and so on.  </p>
<p>The advantage of using <code>static</code> functions or properties in a class is that:</p>
<ul>
<li>They can be used to create functions/properties which need not be present in the instances. This helps to maintain some isolation in the codebase.</li>
<li>They reduce code redundancy in some cases.</li>
</ul>
<p>Now let's have a look at how we can implement this concept in our <code>Chair</code> class. We will also take a look at some use cases where we can use the <code>static</code> keyword.</p>
<p>Here are the scenarios where you can use the <code>static</code> keyword:</p>
<ul>
<li>Usage in classes</li>
<li>Static within static</li>
<li>Calling static from a constructor</li>
<li>Class static initialization blocks</li>
</ul>
<p>For more information on the above scenarios, please visit the MDN <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/static">docs</a>.</p>
<p>We are going to see all the variants of the <code>Chair</code> class via these scenarios:</p>
<h3 id="heading-how-to-use-the-static-keyword-in-classes">How to use the <code>static</code> keyword in classes</h3>
<p>Like any other programming language, this is one of the most beginner-friendly ways to use the static keyword. Let's define some methods and properties of the classes as <code>static</code> and observe the behavior. </p>
<p>Have a look at the below code:</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Chair</span> </span>{
<span class="hljs-comment">//Defaults that will be common for all the instances:</span>
    <span class="hljs-keyword">static</span> backSupport = <span class="hljs-literal">true</span>;
    <span class="hljs-keyword">static</span> armRests = <span class="hljs-literal">true</span>;

    <span class="hljs-keyword">constructor</span>(color, seatHeight, recliningAngle, headSupport, padding, seatSize, isHeightAdjustable, isMovable){
        <span class="hljs-comment">//Defaults which can be changed by the subclass class.</span>
        <span class="hljs-built_in">this</span>.color = color;
        <span class="hljs-built_in">this</span>.seatHeight = seatHeight;
        <span class="hljs-built_in">this</span>.recliningAngle = recliningAngle;
        <span class="hljs-built_in">this</span>.headSupport = <span class="hljs-literal">false</span>;
        <span class="hljs-built_in">this</span>.padding = <span class="hljs-string">"3 inch"</span>;
        <span class="hljs-built_in">this</span>.seatSize = <span class="hljs-string">"16 inch"</span>;
        <span class="hljs-built_in">this</span>.isHeightAdjustable = <span class="hljs-literal">false</span>;
        <span class="hljs-built_in">this</span>.isMovable = <span class="hljs-literal">false</span>;
        <span class="hljs-built_in">this</span>.type = <span class="hljs-string">"Chair"</span>;
    } 

    <span class="hljs-keyword">static</span> logObjectProps(){
        <span class="hljs-built_in">console</span>.dir(<span class="hljs-built_in">this</span>);
    }

    adjustableHeight() {};
    adjustAngle(){};
    moveChair(){};    
}
</code></pre>
<p>Below is the output of the above code:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Screenshot-from-2021-12-01-11-05-15.png" alt="Image" width="600" height="400" loading="lazy">
<em>Static variables</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Screenshot-from-2021-12-01-11-06-35.png" alt="Image" width="600" height="400" loading="lazy">
<em>The output of the static function</em></p>
<p>As you can see above, the static methods are only accessible via the class itself. It cannot be accessed by instances of the <code>Chair</code> class. Instances of the class do not have the static attributes present:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Screenshot-from-2021-12-01-11-09-20.png" alt="Image" width="600" height="400" loading="lazy">
<em>No static members in instances</em></p>
<p>As you can see above, the instance <code>x</code> of the <code>Chair</code> class does not have the static method or properties present in its definitions. </p>
<p>If you try to access a static method or a property using a class instance then it will throw a reference error or simply return undefined.</p>
<h3 id="heading-how-to-use-the-static-keyword-within-another-static-function">How to use the <code>static</code> keyword within another static function</h3>
<p>There can be a situation where you might need to use the static properties or function inside another static function. You can do this by referring to your other property/function using this keyword inside the static function. </p>
<p>Let's modify our <code>Chair</code> class to show how this works:</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Chair</span> </span>{
<span class="hljs-comment">//Defaults that will be common for all the instances:</span>
    <span class="hljs-keyword">static</span> backSupport = <span class="hljs-literal">true</span>;
    <span class="hljs-keyword">static</span> armRests = <span class="hljs-literal">true</span>;

    <span class="hljs-keyword">constructor</span>(color, seatHeight, recliningAngle, headSupport, padding, seatSize, isHeightAdjustable, isMovable){
        <span class="hljs-comment">//Defaults which can be changed by the subclass class.</span>
        <span class="hljs-built_in">this</span>.color = color;
        <span class="hljs-built_in">this</span>.seatHeight = seatHeight;
        <span class="hljs-built_in">this</span>.recliningAngle = recliningAngle;
        <span class="hljs-built_in">this</span>.headSupport = <span class="hljs-literal">false</span>;
        <span class="hljs-built_in">this</span>.padding = <span class="hljs-string">"3 inch"</span>;
        <span class="hljs-built_in">this</span>.seatSize = <span class="hljs-string">"16 inch"</span>;
        <span class="hljs-built_in">this</span>.isHeightAdjustable = <span class="hljs-literal">false</span>;
        <span class="hljs-built_in">this</span>.isMovable = <span class="hljs-literal">false</span>;
        <span class="hljs-built_in">this</span>.type = <span class="hljs-string">"Chair"</span>;
    } 

    <span class="hljs-keyword">static</span> logObjectProps(){
        <span class="hljs-built_in">console</span>.dir(<span class="hljs-built_in">this</span>);
    }

        <span class="hljs-comment">//Static within static usage</span>
        <span class="hljs-keyword">static</span> printDefaultProps(){
                <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Chair Back Support = <span class="hljs-subst">${<span class="hljs-built_in">this</span>.backSupport}</span>`</span>);
                <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Arm rests support = <span class="hljs-subst">${<span class="hljs-built_in">this</span>.armRests}</span>`</span>);
        }

    adjustableHeight() {};
    adjustAngle(){};
    moveChair(){};    
}
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Screenshot-from-2021-12-05-16-49-12.png" alt="Image" width="600" height="400" loading="lazy">
<em>Output of the above code</em></p>
<p>As you can see the <code>printDefaultProps</code> function has access to the static properties <code>backSupport</code> and <code>armRests</code>.</p>
<h3 id="heading-how-to-call-static-propertiesfunctions-from-a-constructor">How to call static properties/functions from a constructor</h3>
<p>Similar to what we saw above, you can also access these static properties/functions in a constructor. To do this, things are a bit different over here.</p>
<p>Within a constructor to call a static property/function you need to use the <code>&lt;classname&gt;.property</code> or <code>&lt;classname&gt;.functionName()</code>. This happens because the <code>this</code> keyword does not have direct access to the static members. This is not only true for constructors but any non-static functions.</p>
<p>Let's try to understand this by modifying the <code>Chair</code> class.</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Chair</span> </span>{
<span class="hljs-comment">//Defaults that will be common for all the instances:</span>
    <span class="hljs-keyword">static</span> backSupport = <span class="hljs-literal">true</span>;
    <span class="hljs-keyword">static</span> armRests = <span class="hljs-literal">true</span>;

    <span class="hljs-keyword">constructor</span>(color, seatHeight, recliningAngle, headSupport, padding, seatSize, isHeightAdjustable, isMovable){
        <span class="hljs-comment">//Defaults which can be changed by the subclass class.</span>
        <span class="hljs-built_in">this</span>.color = color;
        <span class="hljs-built_in">this</span>.seatHeight = seatHeight;
        <span class="hljs-built_in">this</span>.recliningAngle = recliningAngle;
        <span class="hljs-built_in">this</span>.headSupport = <span class="hljs-literal">false</span>;
        <span class="hljs-built_in">this</span>.padding = <span class="hljs-string">"3 inch"</span>;
        <span class="hljs-built_in">this</span>.seatSize = <span class="hljs-string">"16 inch"</span>;
        <span class="hljs-built_in">this</span>.isHeightAdjustable = <span class="hljs-literal">false</span>;
        <span class="hljs-built_in">this</span>.isMovable = <span class="hljs-literal">false</span>;
        <span class="hljs-built_in">this</span>.type = <span class="hljs-string">"Chair"</span>;
        <span class="hljs-built_in">console</span>.log(Chair.printDefaultProps()); <span class="hljs-comment">//Usage of static method inside constructor</span>
    } 

    <span class="hljs-keyword">static</span> logObjectProps(){
        <span class="hljs-built_in">console</span>.dir(<span class="hljs-built_in">this</span>);
    }

        <span class="hljs-comment">//Static within static usage</span>
        <span class="hljs-keyword">static</span> printDefaultProps(){
                <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Chair Back Support = <span class="hljs-subst">${<span class="hljs-built_in">this</span>.backSupport}</span>`</span>);
                <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Arm rests support = <span class="hljs-subst">${<span class="hljs-built_in">this</span>.armRests}</span>`</span>);
        }

    adjustableHeight() {};
    adjustAngle(){};
    moveChair(){};    
}
</code></pre>
<p>In the above code, the last line <code>console.log(Chair.printDefaultProps());</code> showcases how we can use a static method inside a constructor.</p>
<h2 id="heading-private-members-of-classes-in-javascript">Private members of classes in Javascript</h2>
<p>Private members are members of the class which can only be used internally by the class itself. They cannot be accessed outside the class. Even the instances of the class cannot access these private members. </p>
<p>All private members are declared using <code>#&lt;propertName&gt;</code> syntax. They are generally called <em>hash names</em>. </p>
<p>Let's have a look at an example based on our use case. </p>
<p>We'll define some new properties inside the <code>OfficeChair</code> class. Suppose we want to add default billing information for all the office chairs. We also want these to be only accessible to the <code>OfficeChair</code> class so that the other utility functions can use these variables. </p>
<p>We don't want other classes to interfere with the billing information of other classes. To handle this we can use private fields.</p>
<p>Consider the addition of the following fields:</p>
<ul>
<li>Price</li>
<li>Maximum Discount</li>
<li>Seller Address</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/chairModel2.drawio--1-.png" alt="Image" width="600" height="400" loading="lazy">
<em>Updated Class Diagram</em></p>
<p>Note that we can represent private fields in a class diagram using a dash, like this: <code>-</code>.</p>
<p>Have a look at the code below which demonstrates how we have added these fields into the class <code>OfficeChair</code>:</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">OfficeChair</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Chair</span> </span>{
    <span class="hljs-comment">//Newly Added Properties</span>
    #basePrice;
    #maxDiscount;
    #sellerAddress;

    <span class="hljs-keyword">constructor</span>(type, color, isHeightAdjustable, seatHeight, recliningAngle) {
        <span class="hljs-built_in">super</span>();
        <span class="hljs-built_in">this</span>.type = type;
        <span class="hljs-built_in">this</span>.color = color;
        <span class="hljs-built_in">this</span>.isHeightAdjustable = isHeightAdjustable;
        <span class="hljs-built_in">this</span>.seatHeight = seatHeight;
        <span class="hljs-built_in">this</span>.recliningAngle = recliningAngle;
        <span class="hljs-built_in">this</span>.isMovable = <span class="hljs-literal">true</span>;
        <span class="hljs-built_in">this</span>.#basePrice = <span class="hljs-number">1000</span>;
        <span class="hljs-built_in">this</span>.#maxDiscount = <span class="hljs-number">5</span>; <span class="hljs-comment">//In percentage</span>
        <span class="hljs-built_in">this</span>.#sellerAddress = <span class="hljs-string">"XYZ, street"</span>;
    }

    adjustableHeight(height) {
        <span class="hljs-keyword">if</span> (height &gt; <span class="hljs-built_in">this</span>.seatHeight) {
            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Chair height changed to <span class="hljs-subst">${height}</span>`</span>);
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Height cannot be decreased more than the seat height <span class="hljs-subst">${<span class="hljs-built_in">this</span>.seatHeight}</span>`</span>);
        }
    }

    adjustAngle(angle) {
        <span class="hljs-keyword">if</span> (angle &gt;= <span class="hljs-built_in">this</span>.recliningAngle) {
            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Chair angle changed to <span class="hljs-subst">${angle}</span>`</span>);
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Angle cannot be decreased more than the min reclining angle <span class="hljs-subst">${<span class="hljs-built_in">this</span>.recliningAngle}</span>`</span>);
        }
    }

    moveChair(x, y) {
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Chair moved to co-ordinates = (<span class="hljs-subst">${x}</span>, <span class="hljs-subst">${y}</span>)`</span>);
    }

    <span class="hljs-comment">//Newly Added function</span>
    #getChairAmount(taxCharge) {
        <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.#basePrice + (<span class="hljs-built_in">this</span>.#basePrice - <span class="hljs-built_in">this</span>.#basePrice * <span class="hljs-built_in">this</span>.#maxDiscount / <span class="hljs-number">100</span>) + taxCharge;
    }

    <span class="hljs-comment">//Newly Added function</span>
    generateBill() {
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"**** BILLING INFORMATION ****"</span>);
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Chair Price = <span class="hljs-subst">${<span class="hljs-built_in">this</span>.#getChairAmount(<span class="hljs-number">20</span>)}</span>`</span>);
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Seller Address = <span class="hljs-subst">${<span class="hljs-built_in">this</span>.#sellerAddress}</span>`</span>);
    }
}
</code></pre>
<p>When you run the above code in the console, you should see the following output:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Screenshot-from-2021-12-05-17-03-53.png" alt="Image" width="600" height="400" loading="lazy">
<em>Output of private members</em></p>
<p>As you can see from the above output, we have executed the <code>generateBill</code> function. This function accesses the private fields and function within the class to generate the billing information. </p>
<p>These private variables will only be accessible within the class itself. If you try to reference any of the private members of the class then it will throw a syntax error like below:</p>
<pre><code class="lang-javascript">Uncaught <span class="hljs-built_in">SyntaxError</span>: Private field <span class="hljs-string">'#basePrice'</span> must be declared <span class="hljs-keyword">in</span> an enclosing <span class="hljs-class"><span class="hljs-keyword">class</span></span>
</code></pre>
<p>Let me demonstrate how it will look if a subclass tries to access the private variables of the base class:</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DinningChair</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">OfficeChair</span></span>{}

<span class="hljs-keyword">let</span> dineChair = <span class="hljs-keyword">new</span> DinningChair();
dineChair.#basePrice(); <span class="hljs-comment">//Throws syntax error</span>
</code></pre>
<p>The above code will throw a syntax error since you are trying to access the private property of another class.</p>
<p>Static private variables are out of the scope of this blog post, so we won't discuss them further. But you can read about them <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Private_class_fields">here</a>.</p>
<h2 id="heading-summary">Summary</h2>
<p>These are some of the ways we can leverage classes in JavaScript to implement object-oriented programming concepts in a real-world example. </p>
<p>You can read more about advanced object-oriented concepts below:</p>
<ul>
<li><a target="_blank" href="https://en.wikipedia.org/wiki/Polymorphism_(computer_science)">Polymorphism</a></li>
<li><a target="_blank" href="https://en.wikipedia.org/wiki/Inheritance_(object-oriented_programming)">Types of inheritance</a></li>
</ul>
<p>Thank you for reading!</p>
<p>Follow me on <a target="_blank" href="https://twitter.com/keurplkar">Twitter</a>, <a target="_blank" href="http://github.com/keyurparalkar">GitHub</a>, and <a target="_blank" href="https://www.linkedin.com/in/keyur-paralkar-494415107/">LinkedIn</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
