<?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" version="2.0"><channel><title><![CDATA[Adnan Reza's Blog]]></title><description><![CDATA[Adnan Reza is a software engineer and educator based in Canada.]]></description><link>https://blog.adnanreza.com</link><generator>RSS for Node</generator><lastBuildDate>Thu, 07 May 2026 08:32:09 GMT</lastBuildDate><atom:link href="https://blog.adnanreza.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[React Search Filter using Hooks, Context API, and RegEx]]></title><description><![CDATA[In this article, we will implement a search filter to filter blog posts in React from scratch. Along the way, you will learn how to set up and use the  Context API to manage global state in your React App. We will also learn about actions, reducers, ...]]></description><link>https://blog.adnanreza.com/react-search-filter-using-hooks-context-api-and-regex</link><guid isPermaLink="true">https://blog.adnanreza.com/react-search-filter-using-hooks-context-api-and-regex</guid><category><![CDATA[React]]></category><category><![CDATA[ReactHooks]]></category><dc:creator><![CDATA[Adnan Reza]]></dc:creator><pubDate>Fri, 11 Jun 2021 17:16:42 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1623368611969/MKDCLRxFN.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this article, we will implement a <strong>search filter</strong> to filter blog posts in React from scratch. Along the way, you will learn how to set up and use the <em> <a target="_blank" href="https://reactjs.org/docs/context.html">Context API</a></em> to manage global state in your React App. We will also learn about <em>actions</em>, <em>reducers</em>, <em>regular expressions</em> and how they all fit into the search filter we will build. </p>
<p><iframe src="https://giphy.com/embed/8wm7kdqhkdq4RQGyz7" width="480" height="264" class="giphy-embed"></iframe></p><p></p>
<p>While we will go through the process of building this feature from scratch, you can also choose to add this to an existing project.</p>
<h2 id="step-0-create-a-new-react-app-and-directory-structure">Step 0: Create a new react app and directory structure</h2>
<p>Let's start by setting up our React app using create-react-app.</p>
<p><code>npx create-react-app react-search-filter</code></p>
<p>Once we have our app set up, we are going to install Material UI to make things look a bit nicer.</p>
<p><code>npm install @material-ui/core</code> or  <code>yarn add @material-ui/core</code></p>
<h3 id="directory-structure">Directory Structure:</h3>
<p>We are going to create two directories inside the <code>src</code> folder: <code>context</code> and <code>components</code>.</p>
<p>Inside the <code>context</code> directory, let's create three files:</p>
<ul>
<li><code>blogContext.js</code></li>
<li><code>BlogState.js</code></li>
<li><code>blogReducer.js</code></li>
</ul>
<p>Inside the <code>components</code> directory, let's create three files:</p>
<ul>
<li><code>Blog.js</code>- represents each individual blog item.</li>
<li><code>Blogs.js</code> - component that displays blog items.</li>
<li><code>BlogFilter.js</code> - component responsible for filtering blogs based on search term.</li>
<li><code>types.js</code> - action types we use to connect our actions, state, and reducer.</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1623366836958/Yt5DX66qK.png" alt="directory-structure.PNG" /></p>
<h2 id="step-1-create-blog-context-state-and-reducer">Step 1: Create blog Context, State and Reducer</h2>
<p>Let's start by declaring and exporting the constants we are going to use throughout the app in <code>types.js</code>:</p>
<pre><code><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> FILTER_BLOGS = <span class="hljs-string">'FILTER_BLOGS'</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> <span class="hljs-built_in">CLEAR_FILTER</span> = <span class="hljs-string">'CLEAR_FILTER'</span>;
</code></pre><p>Now let's move on to <code>blogContext.js</code>. We will create the blogContext and export it.</p>
<pre><code><span class="hljs-keyword">import</span> { createContext } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-keyword">const</span> blogContext = createContext();

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> blogContext;
</code></pre><p>With the blogContext created, we can implmenet our <code>BlogState</code> component. This is where we set up our initial state which contains an array of blogs. While we use a hardcoded array of objects here, feel free to replace this with a <code>GET</code> request to an API endpoint of your choice to fetch data that you want to filter.</p>
<p>Below the initialState, we use the useReducer() hook to connect our initial state to the reducer function. The useReducer() hook is an alternative to the useState() hook (more on this later).</p>
<p>The next step is to declare actions to filter blog items:<code>filterBlogs(text)</code> and clear the filter: <code>clearFilter()</code></p>
<p>Finally, we return a <code>&lt;BlogContext.Provider&gt;</code> with a <code>value</code> prop set to an object containing the blogs array, filtered array, and action functions we declared above.</p>
<pre><code><span class="hljs-keyword">import</span> React, { useReducer } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> BlogContext <span class="hljs-keyword">from</span> <span class="hljs-string">'./blogContext'</span>;
<span class="hljs-keyword">import</span> blogReducer <span class="hljs-keyword">from</span> <span class="hljs-string">'./blogReducer'</span>;
<span class="hljs-keyword">import</span> {
  FILTER_BLOGS,
  CLEAR_FILTER,
} <span class="hljs-keyword">from</span> <span class="hljs-string">'./types'</span>;

<span class="hljs-keyword">const</span> BlogState = <span class="hljs-function">(<span class="hljs-params">props</span>) =&gt;</span> {

    <span class="hljs-keyword">const</span> initialState = {
    <span class="hljs-attr">blogs</span>: [
      {
        <span class="hljs-attr">id</span>: <span class="hljs-number">1</span>,
        <span class="hljs-attr">title</span>: <span class="hljs-string">"Server Side Rendering for the win!"</span>,
        <span class="hljs-attr">description</span>: <span class="hljs-string">"NextJS is an awesome React framework"</span>
      },
      {
        <span class="hljs-attr">id</span>: <span class="hljs-number">2</span>,
        <span class="hljs-attr">title</span>: <span class="hljs-string">"React - The future is bright!"</span>,
        <span class="hljs-attr">description</span>: <span class="hljs-string">"React is picking up steam!"</span>
      },
      {
        <span class="hljs-attr">id</span>: <span class="hljs-number">3</span>,
        <span class="hljs-attr">title</span>: <span class="hljs-string">"NodeJS - Server-side JS"</span>,
        <span class="hljs-attr">description</span>: <span class="hljs-string">"Write JavaScript on the server"</span>
      },
    ],
    <span class="hljs-attr">filtered</span>: <span class="hljs-literal">null</span>,
  };

  <span class="hljs-keyword">const</span> [state, dispatch] = useReducer(blogReducer, initialState);

  <span class="hljs-comment">// Filter Blogs</span>
  <span class="hljs-keyword">const</span> filterBlogs = <span class="hljs-function">(<span class="hljs-params">text</span>) =&gt;</span> {
    dispatch({ <span class="hljs-attr">type</span>: FILTER_BLOGS, <span class="hljs-attr">payload</span>: text });
  };

  <span class="hljs-comment">// Clear filter</span>
  <span class="hljs-keyword">const</span> clearFilter = <span class="hljs-function">() =&gt;</span> {
    dispatch({ <span class="hljs-attr">type</span>: CLEAR_FILTER });
  };

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">BlogContext.Provider</span>
      <span class="hljs-attr">value</span>=<span class="hljs-string">{{</span>
        <span class="hljs-attr">blogs:</span> <span class="hljs-attr">state.blogs</span>,
        <span class="hljs-attr">filtered:</span> <span class="hljs-attr">state.filtered</span>,
        <span class="hljs-attr">filterBlogs</span>,
        <span class="hljs-attr">clearFilter</span>,
      }}
    &gt;</span>
      {props.children}
    <span class="hljs-tag">&lt;/<span class="hljs-name">BlogContext.Provider</span>&gt;</span></span>
  );
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> BlogState;
</code></pre><p>A  <a target="_blank" href="https://reactjs.org/docs/hooks-reference.html#usereducer">reducer</a>  is a function that takes in the current state and an action, and based on the action type, updates the state. It is an alternative to the <code>useState()</code> hook and is usually preferable when you have complex state logic involving multiples sub-values or when the next state depends on the previous one.</p>
<p>The <code>blogReducer</code> is relatively simple since we only have two cases <code>FILTER_BLOGS</code> and <code>CLEAR_FILTER</code>,</p>
<ul>
<li>Case 1: <code>FILTER_BLOGS</code> We modify the <code>filtered</code> array in state by using a regular expression to match the search term with the title or description of the blog post.</li>
<li>Case 2: <code>CLEAR_FILTER</code> We return the existing state with the <code>filtered</code> array set to <code>null</code>.</li>
<li>Case 3: <code>default</code> We return the existing state</li>
</ul>
<pre><code><span class="hljs-keyword">import</span> {
    FILTER_BLOGS,
    CLEAR_FILTER,
  } <span class="hljs-keyword">from</span> <span class="hljs-string">'./types'</span>;

  <span class="hljs-keyword">const</span> blogReducer = <span class="hljs-function">(<span class="hljs-params">state, action</span>) =&gt;</span> {
      <span class="hljs-keyword">switch</span>(action.type) {
          <span class="hljs-keyword">case</span> FILTER_BLOGS:
              <span class="hljs-keyword">return</span> {
                  ...state,
                  filtered: state.blogs.filter(<span class="hljs-function"><span class="hljs-params">blog</span> =&gt;</span> {
                      <span class="hljs-keyword">const</span> regex = <span class="hljs-keyword">new</span> <span class="hljs-built_in">RegExp</span>(<span class="hljs-string">`<span class="hljs-subst">${action.payload}</span>`</span>, <span class="hljs-string">'ig'</span>);
                      <span class="hljs-keyword">return</span>(
                          blog.title.match(regex) || blog.description.match(regex)
                      );
                  })
              }

          <span class="hljs-keyword">case</span> CLEAR_FILTER:
              <span class="hljs-keyword">return</span> {
                  ...state,
                  filtered: <span class="hljs-literal">null</span>
              }

          <span class="hljs-keyword">default</span>:
              <span class="hljs-keyword">return</span> state;
      }
  }

  <span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> blogReducer;
</code></pre><h2 id="step-2-creating-the-lessbloggreater-and-lessblogfiltergreater-component">Step 2: Creating the <code>&lt;Blog/&gt;</code> and <code>&lt;BlogFilter/&gt;</code> component</h2>
<p>Now that we have our global state, actions, and reducer setup using the Context API, we can move onto creating the components that will be displayed:</p>
<p>The <code>Blog</code> component represents a single blog post item. We destructure a blog post object and return its <code>title</code> and <code>description</code>.</p>
<pre><code><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>

<span class="hljs-keyword">const</span> Blog = <span class="hljs-function">(<span class="hljs-params">{ blog }</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> { title, description } = blog;

    <span class="hljs-keyword">return</span> (
        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'blog'</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>{title}<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{description}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
    )
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Blog
</code></pre><p>We can add some simple styling to each blog item. </p>
<pre><code><span class="hljs-selector-class">.blog</span> {
  <span class="hljs-attribute">margin</span>: <span class="hljs-number">1rem</span> <span class="hljs-number">0</span>;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">1rem</span>;
  <span class="hljs-attribute">border</span>: <span class="hljs-number">1px</span> solid;
}
</code></pre><p>Alternatively, you could use a <code>&lt;Card/&gt;</code> from Material UI.</p>
<p>The <code>BlogFilter</code> component contains a critical part of this app: the search bar. We have a <strong>useState()</strong> hook to keep track of what the user is typing in as a search term. The <code>&lt;Input/&gt;</code> also has a onChange() handler that updates the search value based on what the user types in, and invokes the <code>filterBlogs()</code> method if there is a search term. Otherwise, it clears the filter by invoking the <code>clearFilter()</code> function.</p>
<pre><code><span class="hljs-keyword">import</span> React, { useContext, useState } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>
<span class="hljs-keyword">import</span> { FormControl, Input } <span class="hljs-keyword">from</span> <span class="hljs-string">'@material-ui/core'</span>
<span class="hljs-keyword">import</span> BlogContext <span class="hljs-keyword">from</span> <span class="hljs-string">'../context/blogContext'</span>;

<span class="hljs-keyword">const</span> BlogFilter = <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">const</span> blogContext = useContext(BlogContext);
    <span class="hljs-keyword">const</span> { filterBlogs, clearFilter } = blogContext;

    <span class="hljs-keyword">const</span> [searchValue, setSearchValue] = useState(<span class="hljs-string">''</span>);

    <span class="hljs-keyword">const</span> handleChange = <span class="hljs-function">(<span class="hljs-params">e</span>) =&gt;</span> {
        setSearchValue(e.target.value);
        <span class="hljs-keyword">if</span>(searchValue !== <span class="hljs-string">''</span>) {
            filterBlogs(searchValue);
        } <span class="hljs-keyword">else</span> {
            clearFilter();
        }
    }

    <span class="hljs-keyword">return</span> (
        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">FormControl</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">Input</span>
                <span class="hljs-attr">value</span>=<span class="hljs-string">{searchValue}</span>
                <span class="hljs-attr">type</span>=<span class="hljs-string">'text'</span>
                <span class="hljs-attr">placeholder</span>=<span class="hljs-string">'Filter Blogs'</span>
                <span class="hljs-attr">onChange</span>=<span class="hljs-string">{handleChange}</span>
            /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">FormControl</span>&gt;</span></span>
    )
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> BlogFilter
</code></pre><h2 id="step-3-creating-the-lessblogsgreater-component">Step 3: Creating the <code>&lt;Blogs/&gt;</code> component</h2>
<p>Finally, we can create the <code>Blogs</code> component which displays the list of blogs based on two cases:</p>
<ul>
<li>If the <code>filtered</code> array is <strong>not</strong> empty, that means we have something typed in the search bar. So we map through the array and return a  component for each blog in the <code>filtered</code> array</li>
<li>Otherwise, we don't have anything typed in the search bar; we map through the <code>blogs</code> array and return a  component for each blog.</li>
</ul>
<pre><code><span class="hljs-keyword">import</span> React, {useContext} <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>
<span class="hljs-keyword">import</span> Blog <span class="hljs-keyword">from</span> <span class="hljs-string">'./Blog'</span>
<span class="hljs-keyword">import</span> BlogContext <span class="hljs-keyword">from</span> <span class="hljs-string">'../context/blogContext'</span>

<span class="hljs-keyword">const</span> Blogs = <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-comment">//Initialize context</span>
    <span class="hljs-keyword">const</span> blogContext = useContext(BlogContext);
    <span class="hljs-keyword">const</span> { blogs, filtered } = blogContext;

    <span class="hljs-keyword">return</span> (
        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
            {
                filtered !== null
                ? (
                    filtered.map(blog =&gt; <span class="hljs-tag">&lt;<span class="hljs-name">Blog</span> <span class="hljs-attr">blog</span>=<span class="hljs-string">{blog}</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{blog.id}</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">Blog</span>&gt;</span>)
                ) :
                (
                    blogs.map(blog =&gt; <span class="hljs-tag">&lt;<span class="hljs-name">Blog</span> <span class="hljs-attr">blog</span>=<span class="hljs-string">{blog}</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{blog.id}</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">Blog</span>&gt;</span>)
                )
            }
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
    )
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Blogs
</code></pre><h2 id="step-4-restructuring-the-lessappgreater-component">Step 4: Restructuring the <code>&lt;App/&gt;</code> component</h2>
<p>The final step involves importing all our components into our  component and making calls to them in our return statement.</p>
<pre><code><span class="hljs-keyword">import</span> <span class="hljs-string">'./App.css'</span>;
<span class="hljs-keyword">import</span> Blogs <span class="hljs-keyword">from</span> <span class="hljs-string">'./components/Blogs'</span>
<span class="hljs-keyword">import</span> BlogState <span class="hljs-keyword">from</span> <span class="hljs-string">'./context/BlogState'</span>;
<span class="hljs-keyword">import</span> BlogFilter <span class="hljs-keyword">from</span> <span class="hljs-string">'./components/BlogFilter'</span>;
<span class="hljs-keyword">import</span> { Container } <span class="hljs-keyword">from</span> <span class="hljs-string">'@material-ui/core'</span>

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">BlogState</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">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">BlogFilter</span>/&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Blogs</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">Container</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">BlogState</span>&gt;</span></span>
  );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre><h2 id="summary">Summary</h2>
<p>This brings us to the end of the tutorial. Let's finish by recapping some of the things we’ve learned.</p>
<ul>
<li><strong>Context</strong> provides a way to pass data (for instance data regarding blogs) through the component tree without having to pass props down manually at every level.</li>
<li><strong>Actions</strong> (eg. <code>filter(searchTerm)</code> and <code>clearFilter()</code>) are <strong>dispatched</strong> based on user interactions with the UI.</li>
<li>Based on the action type, the <strong>reducer</strong> function updates the store (the <code>filtered</code> array is modified). This triggers a change in the UI which now displays the new data (a filtered list).</li>
<li>If you prefer to code along while watching me build this from scratch, you can watch my  <a target="_blank" href="https://www.youtube.com/watch?v=2yA2BO9c4c8&amp;t=1442s">YouTube video</a>.</li>
</ul>
<p><a target="_blank" href="https://app.netlify.com/sites/admiring-booth-1a322a/deploys"><img src="https://api.netlify.com/api/v1/badges/68ae10d5-dc55-4568-8a6c-f13e9472aa1c/deploy-status" alt="Netlify Status" /></a></p>
<h3 id="deployed-url-httpswwwreactsearchfilterwebdev4allcom">Deployed URL: <code>https://www.reactsearchfilter.webdev4all.com/</code></h3>
<h3 id="youtube-video-httpswwwyoutubecomwatchv2ya2bo9c4c8">YouTube Video: <code>https://www.youtube.com/watch?v=2yA2BO9c4c8</code></h3>
<h3 id="github-httpsgithubcomadnanrezareact-search-filter">Github: <code>https://github.com/adnanreza/react-search-filter</code></h3>
]]></content:encoded></item><item><title><![CDATA[VS Code Extensions to optimize your React workflow]]></title><description><![CDATA[1. ES7 React/Redux/GraphQL/React-Native Snippets Extension
Creating React applications involves repeating code multiple times. For instance, every time you create a new component we have to go through the same process and write boilerplate code. Let'...]]></description><link>https://blog.adnanreza.com/vs-code-extensions-to-optimize-your-react-workflow</link><guid isPermaLink="true">https://blog.adnanreza.com/vs-code-extensions-to-optimize-your-react-workflow</guid><category><![CDATA[Visual Studio Code]]></category><category><![CDATA[vscode extensions]]></category><category><![CDATA[React]]></category><category><![CDATA[Productivity]]></category><category><![CDATA[Web Development]]></category><dc:creator><![CDATA[Adnan Reza]]></dc:creator><pubDate>Sat, 05 Jun 2021 21:00:54 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1622926441978/O2bFaQG1B.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="1-es7-reactreduxgraphqlreact-native-snippets-extensionhttpsmarketplacevisualstudiocomitemsitemnamedsznajderes7-react-js-snippets">1. <a target="_blank" href="https://marketplace.visualstudio.com/items?itemName=dsznajder.es7-react-js-snippets">ES7 React/Redux/GraphQL/React-Native Snippets Extension</a></h2>
<p>Creating React applications involves repeating code multiple times. For instance, every time you create a new component we have to go through the same process and write boilerplate code. Let's look at a couple of common use cases to speed up your workflow:</p>
<ul>
<li><code>rcc</code> | Creating a class-based component</li>
</ul>
<iframe src="https://giphy.com/embed/iPazNi9cfnCgkZbSTN" width="480" height="262" class="giphy-embed"></iframe>


<ul>
<li><code>rafc</code> | Creating a functional component</li>
</ul>
<iframe src="https://giphy.com/embed/56nFZlrEiMaReBAvn5" width="480" height="262" class="giphy-embed"></iframe>

<p>You can find the entire list of snippets on the  <a target="_blank" href="https://marketplace.visualstudio.com/items?itemName=dsznajder.es7-react-js-snippets">official page</a>.</p>
<h2 id="2-auto-rename-taghttpsmarketplacevisualstudiocomitemsitemnameformulahendryauto-rename-tag">2. <a target="_blank" href="https://marketplace.visualstudio.com/items?itemName=formulahendry.auto-rename-tag">Auto Rename Tag</a></h2>
<p>As the name suggests, this handy extension automatically renames your closing tag when you rename your opening tag and vice versa. For instance, if you decide to change an <code>&lt;h1&gt;</code> to <code>&lt;h2&gt;</code>, the closing tag will be automatically renamed from an <code>&lt;/h1&gt;</code> to <code>&lt;/h2&gt;</code>.</p>
<iframe src="https://giphy.com/embed/gzIi2b4U7ss0lMIm3W" width="480" height="262" class="giphy-embed"></iframe>


<h2 id="3-bracket-pair-colorizerhttpsmarketplacevisualstudiocomitemsitemnamecoenraadsbracket-pair-colorizer">3. <a target="_blank" href="https://marketplace.visualstudio.com/items?itemName=CoenraadS.bracket-pair-colorizer">Bracket Pair Colorizer</a></h2>
<p>Do you ever find it difficult to match bracket pairs, especially when there are multiple nested levels? Bracket Pair Colorizer identifies matching brackets with colors.</p>
<iframe src="https://giphy.com/embed/wHW07aJdL9IW19denF" width="480" height="262" class="giphy-embed"></iframe>

<p>Thanks for reading! Let me know in the comments if there are any others that have helped you out.</p>
]]></content:encoded></item></channel></rss>