<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Austin Labador</title>
    <description>The latest articles on Forem by Austin Labador (@alabador).</description>
    <link>https://forem.com/alabador</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F869861%2Fbfd748c9-979a-47a5-b659-e9a871b399ba.jpg</url>
      <title>Forem: Austin Labador</title>
      <link>https://forem.com/alabador</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/alabador"/>
    <language>en</language>
    <item>
      <title>Taking a Bite out of Hamburger Menus in React</title>
      <dc:creator>Austin Labador</dc:creator>
      <pubDate>Tue, 27 Jun 2023 03:56:19 +0000</pubDate>
      <link>https://forem.com/alabador/taking-a-bite-out-of-hamburger-menus-in-react-1hm2</link>
      <guid>https://forem.com/alabador/taking-a-bite-out-of-hamburger-menus-in-react-1hm2</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Hamburger menus are a common yet important part of an application's user interface that helps with navigation. They make navigation cleaner, provide top-level access, and are a very familiar icon to many users. In this article, I explore my process in creating a hamburger menu, and the hiccups along the way.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;I wanted to create a nav menu that shows when you click on a hamburger menu icon. When the menu shows, you should be able to click on those links and navigate to those menus, with the nav menu closing automatically. Additionally, you should be able to exit out of the menu when you click outside of it. &lt;/p&gt;

&lt;h2&gt;
  
  
  The Process
&lt;/h2&gt;

&lt;p&gt;I started off with just an onClick. So you can open up a menu, but you can only close the menu when clicking the hamburger icon again. If you click outside, the menu stays there. This is fine, but not the greatest for UX.&lt;/p&gt;

&lt;p&gt;I did some research and these were some of the resources that helped me most.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://stackoverflow.com/questions/72739930/how-to-focus-on-dynamically-added-input-field-in-react"&gt;Focusing on Dynamically Added Element&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ibaslogic.com/how-to-add-hamburger-menu-in-react/"&gt;Adding Hamburger Menu&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.carlrippon.com/react-forwardref-typescript/"&gt;ForwardRef&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;This was what I found worked the best for me. &lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Click on nav button, handleClick to change state.&lt;/li&gt;
&lt;li&gt;I set up a useEffect hook that runs every time the value of toggleNav(state) is changed.&lt;/li&gt;
&lt;li&gt;Create a useRef hook to reference child component with forwardRef, which will be focused.&lt;/li&gt;
&lt;li&gt;Since nav menu is conditionally rendered (when hamburger is clicked), setTimeout to focus on the newly rendered menu (child component).&lt;/li&gt;
&lt;li&gt;Set up an event listener to &lt;/li&gt;
&lt;li&gt;check if nav menu (toggleNav) is true, &lt;/li&gt;
&lt;li&gt;if useRef current has a value, &lt;/li&gt;
&lt;li&gt;and if the value of the currently clicked target (e.target), taken from the event listener, is not equal to useRef current. &lt;/li&gt;
&lt;li&gt;If all the above conditions are fulfilled, then setToggleNav to false. This will make the nav bar close when you click anywhere that is outside of the ref. &lt;/li&gt;
&lt;li&gt;Then remove the side effect (event listener) at the end of useEffect. &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Resolving Final Issues
&lt;/h2&gt;

&lt;p&gt;After trying a few different combinations of things, I was finally able to get my navbar to work. When I clicked outside of the menu, it would close. But now, when I clicked on the hamburger menu, it would stay open, or rather reopen!&lt;/p&gt;

&lt;p&gt;At first I tried changing the conditions to the event listener, but that didn't give any good results. I ended up going with a CSS solution, preventing the user from clicking the hamburger menu icon again by hiding it. &lt;/p&gt;

&lt;p&gt;Now that gave a different result, because the menu was a child component of the hamburger menu. So I added a class that would reduce the height and width of the component to 0 on click. This was what worked the best.&lt;/p&gt;




&lt;p&gt;What I thought would be a simple task turned out to be a little more complicated. But, I was able to learn and get practice with useRef, a hook I was not very familiar with!&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>learning</category>
    </item>
    <item>
      <title>Upgrading my Portfolio - Process (HTML, CSS, JS to ASTRO.js )</title>
      <dc:creator>Austin Labador</dc:creator>
      <pubDate>Sun, 18 Jun 2023 22:54:21 +0000</pubDate>
      <link>https://forem.com/alabador/upgrading-my-portfolio-process-html-css-js-to-astrojs--3j7a</link>
      <guid>https://forem.com/alabador/upgrading-my-portfolio-process-html-css-js-to-astrojs--3j7a</guid>
      <description>&lt;p&gt;A portfolio is something developers use to tell people who they are, and what they can do. It’s a showcase of our best work. &lt;/p&gt;

&lt;p&gt;When I started off creating my portfolio, I was eager to show off all the projects I created. However, I didn’t consider maintainability. My files grew larger, it took longer to scroll through a single file to make changes to multiple copies of the same element, and it was eventually just a pain to change things around. I started looking into component-based solutions, and eventually found one that balanced speed and dev experience, which for me -- was Astro. &lt;/p&gt;

&lt;h2&gt;
  
  
  Old Portfolio
&lt;/h2&gt;

&lt;p&gt;For my first iteration of my portfolio, I started off in pure vanilla HTML, CSS, and JS, eventually adopting Tailwind CSS. I figured since it was mostly a static site, it would be good to practice the fundamentals.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QLomyYsV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nsd740f2b9of4iguc1aa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QLomyYsV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nsd740f2b9of4iguc1aa.png" alt="Old version of portfolio" width="800" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, as I continued to develop the site, it began to be hard to maintain as the content and site grew. For a landing page style portfolio on a single page, the file ended up having around &lt;strong&gt;600 lines&lt;/strong&gt; of code. I added Tailwind CSS as well, making the HTML tags even longer to read through.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;article class="py-6 flex flex-col"&amp;gt;
  &amp;lt;img src="./img/wewatch.jpeg" alt="wewatch website" class="rounded-lg object-cover object-top h-48 lg:h-64"&amp;gt;

  &amp;lt;h1 class="text-3xl py-4"&amp;gt;WeWatch&amp;lt;/h1&amp;gt;

  &amp;lt;div class="flex py-2 flex-wrap gap-1"&amp;gt;
    &amp;lt;p class="inline-block px-2 py-1 text-xs font-semibold rounded-xl bg-blue-400 text-gray-900"&amp;gt;
      Node.js
    &amp;lt;/p&amp;gt;
    &amp;lt;p class="inline-block px-2 py-1 text-xs font-semibold rounded-xl bg-blue-400 text-gray-900"&amp;gt;
      Express.js
    &amp;lt;/p&amp;gt;
    &amp;lt;p class="inline-block px-2 py-1 text-xs font-semibold rounded-xl bg-blue-400 text-gray-900"&amp;gt;
      MongoDB/Mongoose
    &amp;lt;/p&amp;gt;
    &amp;lt;p class="inline-block px-2 py-1 text-xs font-semibold rounded-xl bg-blue-400 text-gray-900"&amp;gt;
      EJS
    &amp;lt;/p&amp;gt;
    &amp;lt;p class="inline-block px-2 py-1 text-xs font-semibold rounded-xl bg-blue-400 text-gray-900"&amp;gt;                                
      API
    &amp;lt;/p&amp;gt;
    &amp;lt;p class="inline-block px-2 py-1 text-xs font-semibold rounded-xl bg-blue-400 text-gray-900"&amp;gt;
      MVC Pattern
    &amp;lt;/p&amp;gt;
    &amp;lt;p class="inline-block px-2 py-1 text-xs font-semibold rounded-xl bg-blue-400 text-gray-900"&amp;gt;
      Passport.js/Auth
    &amp;lt;/p&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;p class="font-light text-gray-300 text-base py-2"&amp;gt;
                            A shared show watch list using Mongoose + MongoDB, Express.js, Node.js and EJS.
  &amp;lt;/p&amp;gt;
  &amp;lt;div class="flex gap-2 pt-2 items-center mt-auto justify-self-end"&amp;gt;                            
    &amp;lt;a                           
      href="https://wewatch.cyclic.app/"
      target="_blank"
      class="pr-2 text-xl hover:text-orange-400 dark:hover:text-orange-400"
    &amp;gt;
     &amp;lt;i class="fa-solid fa-link"&amp;gt;&amp;lt;/i&amp;gt;
    &amp;lt;/a&amp;gt;                             
    &amp;lt;a href="https://github.com/alabador/wewatch"
       target="_blank"
       class="pr-2 text-xl hover:text-orange-400 dark:hover:text-orange-400"
    &amp;gt;&amp;lt;i class="fa-brands fa-github"&amp;gt;&amp;lt;/i
                            &amp;gt;&amp;lt;/a&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/article&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now keep in mind, this code above was formatted for the purpose of readability on the blog. But on the actual codebase before...the formatting was much worse. (in hindsight I should have used a code formatter like Prettier though). &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Here's the link to my old branch of my portfolio. The live site is down for it, but the code is all still  &lt;a href="https://github.com/alabador/portfolio/tree/oldVanilla"&gt;there&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Component-Like Client-based JS
&lt;/h2&gt;

&lt;p&gt;So at the time of development, I didn't have too much experience with React and other component-based libraries. I was still fairly new to web development, so I used what was in my toolset. &lt;/p&gt;

&lt;p&gt;During the process, I knew there had to be an easier way than hardcoding HTML into my website. I tried using JS to declutter the HTML, creating functions that would dynamically create elements then append to the DOM. Essentially doing something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function addElement() {
  const projects = document.querySelector('.projects');
  const newProject = document.createElement("article");
  projects.appendChild(newProject);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I skipped a few details, but I also created a JS object that held the information of my projects, then added that for each project within another function.&lt;/p&gt;

&lt;h2&gt;
  
  
  Moving to React/Astro
&lt;/h2&gt;

&lt;p&gt;Doing things this way was fine for a while. Fast forward a few months, and as I started to grow as a developer, I picked up more experience with React. My portfolio looked like it needed a revamp considering the new things I learned. I started looking towards more component based tech, and considered React and Next.js. &lt;/p&gt;

&lt;p&gt;However, these seemed to be too much overhead for a simple mostly-static site. I discovered Astro, and I fell in love with how easy it was to use, how fast it was, and it's ability to have partial hydration. So my site could still be static, and only the parts I needed React on (if I wanted to implement React) would have client-side JS.&lt;/p&gt;

&lt;p&gt;Here's the link to the Github for my portfolio if you want to keep up with the progress: &lt;a href="https://github.com/alabador/portfolio"&gt;Portfolio Link - Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vC2Nlwso--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ttbxstew8ae65ptq1mm8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vC2Nlwso--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ttbxstew8ae65ptq1mm8.png" alt="New version of the portfolio" width="800" height="491"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>astro</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
