<?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[Alanna Codes]]></title><description><![CDATA[I'm a software engineer who makes it a priority to deep-dive into the fundamentals of web development and software engineering.]]></description><link>https://blog.ruthmatieu.com</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1770327274625/dc727134-7827-46f1-a3fa-38cd1631b98a.png</url><title>Alanna Codes</title><link>https://blog.ruthmatieu.com</link></image><generator>RSS for Node</generator><lastBuildDate>Tue, 21 Apr 2026 14:01:25 GMT</lastBuildDate><atom:link href="https://blog.ruthmatieu.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Lessons Learned Migrating a Large Production Codebase from Zod v3 to v4]]></title><description><![CDATA[The Problem: Inconsistent Email Validation Across the Codebase
A frontend spike revealed that email validation logic between the backend and frontend was not consistent. The backend depended on a large Mailman regex with additional length checks, whi...]]></description><link>https://blog.ruthmatieu.com/lessons-learned-migrating-a-large-production-codebase-from-zod-v3-to-v4-1</link><guid isPermaLink="true">https://blog.ruthmatieu.com/lessons-learned-migrating-a-large-production-codebase-from-zod-v3-to-v4-1</guid><category><![CDATA[React]]></category><category><![CDATA[react-hook-form]]></category><category><![CDATA[zod]]></category><category><![CDATA[schema]]></category><category><![CDATA[form validation]]></category><dc:creator><![CDATA[Alanna M.]]></dc:creator><pubDate>Sat, 14 Feb 2026 21:55:58 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/_yMciiStJyY/upload/55f39cdb7aa6a47d4e27e12bdc1343ff.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-the-problem-inconsistent-email-validation-across-the-codebase"><strong>The Problem: Inconsistent Email Validation Across the Codebase</strong></h2>
<p>A frontend spike revealed that email validation logic between the backend and frontend was not consistent. The backend depended on a large Mailman regex with additional length checks, while the frontend validation was less restrictive.</p>
<h2 id="heading-why-we-chose-to-upgrade-to-zod-v4"><strong>Why We Chose to Upgrade to Zod v4</strong></h2>
<p>As part of improving consistency, maintainability, and centralizing validation logic across the repo, Zod v4 presented a strong opportunity to modernize how validation is handled across the repository.</p>
<p>The goal was to align frontend validation rules with backend requirements while also reducing technical debt. Migrating to standardized Zod-based validation allowed us to:</p>
<ul>
<li><p>Prevent email addresses accepted on the frontend but rejected by the backend</p>
</li>
<li><p>Update the email validation regex on the frontend to match backend validation</p>
</li>
<li><p>Maintain consistent validation behavior across the app</p>
</li>
<li><p>Reduce manual regex maintenance and duplication</p>
</li>
<li><p>Centralize email address validation into a reusable shared schema</p>
</li>
</ul>
<p>While the migration was initially motivated by email validation, it quickly became clear that upgrading Zod would provide long-term improvements in developer experience, type safety, and validation reliability.</p>
<h2 id="heading-unseen-prerequisites-that-blocked-the-migration"><strong>Unseen Prerequisites That Blocked the Migration</strong></h2>
<p>Like many large-scale dependency upgrades, the Zod migration uncovered several prerequisite upgrades that needed to happen first.</p>
<p>When I initially took on on the the project, I discovered our TypeScript version was still on v4.9 while Zod v4 required TypeScript v5.5 or higher. This meant the migration could not happen without first upgrading TypeScript across the repository.</p>
<p>After upgrading TypeScript, additional compatibility issues surfaced with React Hook Form (RHF) and @hookform/resolvers, both required upgrades to support the newer ecosystem.</p>
<p>Adding a bit more complication, our Design System team maintained shared form components that depended on RHF. Their components were running on an older version than what Zod v4 needed to work with, which created a dependency mismatch that prevented a straightforward upgrade.</p>
<p>To resolve this, I collaborated with the Design System team by outlining:</p>
<ul>
<li><p>Why upgrading RHF was necessary for Zod v4 compatibility</p>
</li>
<li><p>How mismatch impacted validation and form integrations</p>
</li>
<li><p>The importance of modernizing our ecosystem</p>
</li>
</ul>
<p>Because these shared components were consumed across multiple applications, the upgrade required careful coordination and testing, which extended the migration timeline.</p>
<p>Once the Design System updates were completed and deployed, I was able to successfully install and integrate Zod v4 without additional compatibility issues.</p>
<h2 id="heading-migration-challenges-inside-the-codebase"><strong>Migration Challenges Inside the Codebase</strong></h2>
<p>Once Zod v4 was installed, I quickly realized how loosely validated Zod v3 was compared to v4. Running TypeScript after the upgrade surfaced 80+ type errors across the codebase. While this initially felt overwhelming, a few of the errors highlighted areas where validation logic had been loosely defined or relied on deprecated APIs that included simple updates such as:</p>
<ul>
<li><p>Replacing <code>message</code> with <code>error</code></p>
</li>
<li><p>Replacing <code>invalid_type_error</code> and <code>required_error</code> with <code>error</code></p>
</li>
<li><p>Replacing <code>import { schema } from “zod”</code> from <code>import { z } from “zod”</code></p>
</li>
</ul>
<h3 id="heading-zod-v4-runs-a-stricter-program"><strong>Zod v4 Runs a Stricter Program</strong></h3>
<p>Beyond syntax updates, Zod v4 introduced noticeably stricter type enforcement. In several files, schemas that compiled successfully now failed due to mismatches between expected and actual data shapes. The stricter checks surfaced validation issues such as:</p>
<ul>
<li><p>Optional values being treated as required</p>
</li>
<li><p>Inconsistent handling of nullable vs optional fields</p>
</li>
<li><p>Incorrect union definitions</p>
</li>
<li><p>Even found a case where a value was spelled incorrectly but still passed in v3!</p>
</li>
</ul>
<p>Zod v4 also refined how schemas are composed and extended. Several chained validation patterns that worked in v3 required restructuring to align with the new composition behavior.</p>
<p>In particular, complex validation scenarios involving:</p>
<ul>
<li><p><code>.refine()</code></p>
</li>
<li><p><code>.superRefine()</code></p>
</li>
<li><p>Schema merging and extension</p>
</li>
<li><p><code>transform</code> and <code>coerce</code> changed to type <code>unknown</code></p>
</li>
</ul>
<h3 id="heading-resolver-and-form-integration-updates"><strong>Resolver and Form Integration Updates</strong></h3>
<p>Because Zod was tightly integrated with React Hook Form, upgrading Zod required verifying compatibility with the latest resolver versions. Schema changes occasionally affected how form errors were mapped and surfaced in UI components.</p>
<p>In some cases, validation behavior subtly changed due to stricter typing or updated resolver expectations, requiring regression testing across form-heavy workflows.</p>
<h2 id="heading-key-lesson"><strong>Key Lesson</strong></h2>
<p>Large dependency migrations rarely fail because of the library upgrade itself. They expose inconsistencies, technical debt, and architectural drift that accumulate over time.</p>
<p>Zod v4 did exactly that for our codebase. While the migration required significant effort, it resulted in stronger type guarantees, more consistent validation behavior, and a cleaner foundation for future development.</p>
]]></content:encoded></item><item><title><![CDATA[Diving into Singly Linked Lists]]></title><description><![CDATA[Linked lists are a linear data structure consisting of nodes that are not stored contiguously (right next to each other) in memory.
Each node of the linked list consists of data and a next pointer. Since (unlike the array) a linked list is not stored...]]></description><link>https://blog.ruthmatieu.com/diving-into-singly-linked-lists</link><guid isPermaLink="true">https://blog.ruthmatieu.com/diving-into-singly-linked-lists</guid><category><![CDATA[data structures]]></category><dc:creator><![CDATA[Alanna M.]]></dc:creator><pubDate>Tue, 15 Feb 2022 17:32:26 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1649344676388/ZCRcFimID.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Linked lists are a linear data structure consisting of nodes that are not stored contiguously (right next to each other) in memory.</p>
<p>Each node of the linked list consists of data and a next pointer. Since (unlike the array) a linked list is not stored contiguously, the purpose of the next pointer is to provide a reference or link to the next node in the sequence. Hence the term "linked" list.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1649344676388/ZCRcFimID.png" alt="1_iiEWrP2IznA6HbmuIdK0lQ.png" /></p>
<p>As seen in the image above, the last node's next pointer always points to null. This is how we know we've reached the end of the list. </p>
<p><strong>Head</strong> is the name given to the <em>first</em> node in the list
<strong>Tail</strong> is the name given to the <em>last</em> node in the list</p>
<p><strong>Pros of linked list</strong></p>
<ul>
<li>insertion and deletion are done in O(1)</li>
<li>not stored contiguously in memory</li>
<li>dynamic (linked lists grow/shrink at runtime depending on its size)</li>
</ul>
<p><strong>Cons of linked list</strong></p>
<ul>
<li>uses more memory than an array</li>
<li>traversal is more time consuming compared to an array since there is no direct (index) access</li>
<li>in a SLL, reverse traversing is not possible</li>
<li>random access is not possible because there are no indices</li>
</ul>
<p>Stepping away from linked lists for a while, when we think of the array in JavaScript, there are methods that allow us to interact and modify the array. Think, <code>push()</code>, <code>shift()</code>, etc. Similarly, there are linked list methods allowing us the ability to interact with and modify it. The only difference is that they're not built-in; we have to create them ourselves.</p>
<p><strong>These methods include</strong></p>
<ul>
<li>addToEnd() or push(): adds a node to the end of the list</li>
<li>addToStart() or unshift(): adds a node to the start of the list</li>
<li>deleteFromEnd() or pop(): deletes a node from the end of the list</li>
<li>deleteFromStart() or shift(): deletes a node from start of the list</li>
<li>length(): returns the length of the linked list</li>
<li></li>
</ul>
<p>Implementing a linked list node:</p>
<p>Remember, a node consists of data (val) and a next pointer which is initialized to null since the linked list will be empty when we start.</p>
<pre><code>class Node {
  <span class="hljs-function"><span class="hljs-keyword">constructor</span>(<span class="hljs-params">val</span>) </span>{
    <span class="hljs-built_in">this</span>.<span class="hljs-built_in">value</span> <span class="hljs-operator">=</span> val;
    <span class="hljs-built_in">this</span>.next <span class="hljs-operator">=</span> null;
  }
}
</code></pre><p>Implementing a linked list:</p>
<p>Remember, the first node is called the head and the last node is called the tail. We have instant access to the first and last node which is why insertion and deletion is O(1). Also, the linked list will be empty initially, so both head and tail are initialized with null.</p>
<pre><code>class LinkedList {
  <span class="hljs-function"><span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>)</span>{
    <span class="hljs-built_in">this</span>.head <span class="hljs-operator">=</span> null
    <span class="hljs-built_in">this</span>.tail <span class="hljs-operator">=</span> null
    <span class="hljs-built_in">this</span>.<span class="hljs-built_in">length</span> <span class="hljs-operator">=</span> <span class="hljs-number">0</span>;
  }

  addToEnd(val) {
    let node <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> Node(val)
    <span class="hljs-keyword">if</span>(<span class="hljs-operator">!</span><span class="hljs-built_in">this</span>.head) {
      <span class="hljs-built_in">this</span>.head <span class="hljs-operator">=</span> node
      <span class="hljs-built_in">this</span>.tail <span class="hljs-operator">=</span> node
    }
    <span class="hljs-built_in">this</span>.tail.next <span class="hljs-operator">=</span> node
    <span class="hljs-built_in">this</span>.tail <span class="hljs-operator">=</span> node

    <span class="hljs-built_in">this</span>.<span class="hljs-built_in">length</span>+<span class="hljs-operator">+</span>
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>;
  }

  deleteFromEnd() {
    <span class="hljs-keyword">if</span>(<span class="hljs-operator">!</span><span class="hljs-built_in">this</span>.head) <span class="hljs-keyword">return</span> undefined
    let curr <span class="hljs-operator">=</span> <span class="hljs-built_in">this</span>.head
    let newTail <span class="hljs-operator">=</span> curr

    <span class="hljs-keyword">while</span>(curr.next) {
      newTail <span class="hljs-operator">=</span> curr
      curr <span class="hljs-operator">=</span> curr.next
    }
    newTail.next <span class="hljs-operator">=</span> null
    <span class="hljs-built_in">this</span>.tail <span class="hljs-operator">=</span> newTail

    <span class="hljs-built_in">this</span>.<span class="hljs-built_in">length</span>-<span class="hljs-operator">-</span>

    <span class="hljs-keyword">if</span>(<span class="hljs-built_in">this</span>.<span class="hljs-built_in">length</span> <span class="hljs-operator">=</span><span class="hljs-operator">=</span><span class="hljs-operator">=</span> <span class="hljs-number">0</span>) {
      <span class="hljs-built_in">this</span>.head <span class="hljs-operator">=</span> null;
      <span class="hljs-built_in">this</span>.tail <span class="hljs-operator">=</span> null
    }
    <span class="hljs-keyword">return</span> curr;
  }

  addToStart(val) {
    let node <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> Node(val)

    <span class="hljs-keyword">if</span>(<span class="hljs-operator">!</span><span class="hljs-built_in">this</span>.head) {
      <span class="hljs-built_in">this</span>.head <span class="hljs-operator">=</span> node
      <span class="hljs-built_in">this</span>.tail <span class="hljs-operator">=</span> node
    }
    node.next <span class="hljs-operator">=</span> <span class="hljs-built_in">this</span>.head
    <span class="hljs-built_in">this</span>.head <span class="hljs-operator">=</span> node

    <span class="hljs-built_in">this</span>.<span class="hljs-built_in">length</span>+<span class="hljs-operator">+</span>

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

  deleteFromStart() {
    <span class="hljs-keyword">if</span>(<span class="hljs-operator">!</span><span class="hljs-built_in">this</span>.head) <span class="hljs-keyword">return</span> undefined

    let curr <span class="hljs-operator">=</span> <span class="hljs-built_in">this</span>.head
    <span class="hljs-built_in">this</span>.head <span class="hljs-operator">=</span> curr.next

    <span class="hljs-built_in">this</span>.<span class="hljs-built_in">length</span>-<span class="hljs-operator">-</span>

    <span class="hljs-keyword">if</span>(<span class="hljs-built_in">this</span>.<span class="hljs-built_in">length</span> <span class="hljs-operator">=</span><span class="hljs-operator">=</span><span class="hljs-operator">=</span> <span class="hljs-number">0</span>) {
      <span class="hljs-built_in">this</span>.head <span class="hljs-operator">=</span> null
      <span class="hljs-built_in">this</span>.tail <span class="hljs-operator">=</span> null
    }
    <span class="hljs-keyword">return</span> null
  }

}
<span class="hljs-comment">// creating a new instantiation of our linked list class called list.</span>

let list <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> LinkedList();
list.addToEnd(<span class="hljs-number">21</span>)
list.addToEnd(<span class="hljs-number">24</span>)
list.addToEnd(<span class="hljs-number">35</span>)
list.addToStart(<span class="hljs-number">99</span>)
list.deleteFromEnd()
console.log(list)
</code></pre>]]></content:encoded></item><item><title><![CDATA[Complexity Analysis + Big O Notation]]></title><description><![CDATA[To start off our computer science fundamentals series, we will cover complexity analysis and Big O. Prior to understanding data structures and algorithms, it's important to understand how code is analyzed for efficiency in software engineering. This ...]]></description><link>https://blog.ruthmatieu.com/complexity-analysis-big-o-notation</link><guid isPermaLink="true">https://blog.ruthmatieu.com/complexity-analysis-big-o-notation</guid><category><![CDATA[Computer Science]]></category><category><![CDATA[data structures]]></category><category><![CDATA[time]]></category><category><![CDATA[Software Engineering]]></category><category><![CDATA[algorithms]]></category><dc:creator><![CDATA[Alanna M.]]></dc:creator><pubDate>Tue, 18 Jan 2022 01:25:39 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/unsplash/oMpAz-DN-9I/upload/v1642555261787/I5KR2BKfG.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>To start off our computer science fundamentals series, we will cover complexity analysis and Big O. Prior to understanding data structures and algorithms, it's important to understand how code is analyzed for efficiency in software engineering. This will come in handy later in deciding which data structure and algorithm is best to solve a problem.</p>
<h3 id="heading-what-is-complexity-analysis">What is complexity analysis</h3>
<p>Prior to diving into computer science, I used to think all code weighed the same, meaning, all code completed the same task within the same timeframe. Lo and behold, complexity analysis has proven this is not the case! Although two different programs given the same number of inputs provide the same output, one typically gets the job done more efficiently. So, to put it simply, complexity analysis is the method by which we measure this efficiency. </p>
<h3 id="heading-what-makes-code-efficient">What makes code efficient</h3>
<p>Now, what exactly is efficiency? Efficiency is broken down between time and space. Key things to understand:</p>
<p><strong>Time complexity</strong>: measures the amount of time it takes a program to complete. The faster your code, the better.</p>
<p><strong>Space complexity</strong>: measures the amount of space (memory) a program takes up as it completes. The less space your code consumes, the better.</p>
<p>Both are important but we are generally more concerned with time complexity.</p>
<h3 id="heading-big-o-analysis">Big O analysis</h3>
<p>If complexity analysis is the method by which we measure the efficiency of code, we can then think of Big O as the unit by which we do this measuring. Big O analysis is used to rank an algorithm's performance in relation to the growth of input size. In other words, as our input size gets closer to an infinite number (obviously very large), how efficient does our algorithm remain?</p>
<h3 id="heading-big-o-notation">Big O notation</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1642554586033/tQ6GaejsT.png" alt="Screen Shot 2022-01-18 at 8.09.23 PM.png" /></p>
<p>Note: n represents input size</p>
<p><strong>O(1) - Constant:</strong>
No matter the size of n, our algorithm will take the same amount of time to execute.</p>
<p><strong>O(log n) - Logarithmic:</strong>
Time goes up linearly, while n goes up exponentially. Meaning, if it takes 1 second to compute 10 elements, it will take 2 seconds to compute 100 elements, etc. </p>
<p><strong>O(n) - Linear:</strong>
Our algorithm's performance will grow in direct proportion as our input. For example, if it takes 1 second to compute 1 element, it will take 2 seconds to compute 2 elements, 5 seconds to compute 5 elements, and so on.</p>
<p><strong>O(n log n) - Loglinear:</strong>
Algorithms that repeatedly divide a set of data in half, and then process those halves independently.</p>
<p><strong>O(n²) - Quadratic:</strong>
As the size of n increases, our algorithm's time to complete will increase exponentially. </p>
<p>We won't cover the others in the chart because as you can see, they're no better than the ones we've already covered anyway so if you ever find yourself in red, it's better to find a better solution to the problem at hand.</p>
<h3 id="heading-calculating-big-o">Calculating Big O</h3>
<p>Let's calculate the Big O solution to Two Sum. Given an array, we must find the two numbers that add up to a given target. Our result should return their index, if there is no sum, return an empty array.</p>
<p>This solution utilizes a brute force approach.</p>
<pre><code><span class="hljs-number">1.</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">twoSum</span>(<span class="hljs-params">arr, target</span>)</span>{
<span class="hljs-number">2.</span>     <span class="hljs-keyword">for</span>(let i<span class="hljs-operator">=</span><span class="hljs-number">0</span>; i <span class="hljs-operator">&lt;</span> arr.<span class="hljs-built_in">length</span>; i<span class="hljs-operator">+</span><span class="hljs-operator">+</span>) {
<span class="hljs-number">3.</span>         <span class="hljs-keyword">for</span>(let j<span class="hljs-operator">=</span>i<span class="hljs-operator">+</span><span class="hljs-number">1</span>; j <span class="hljs-operator">&lt;</span> arr.<span class="hljs-built_in">length</span>; j<span class="hljs-operator">+</span><span class="hljs-operator">+</span>) {
<span class="hljs-number">4.</span>             <span class="hljs-keyword">if</span>(arr[i] <span class="hljs-operator">+</span> arr[j] <span class="hljs-operator">=</span><span class="hljs-operator">=</span><span class="hljs-operator">=</span> target) <span class="hljs-keyword">return</span> [arr[i],arr[j]]
<span class="hljs-number">5.</span>         }
<span class="hljs-number">6.</span>     }
<span class="hljs-number">7.</span>     <span class="hljs-keyword">return</span> []
<span class="hljs-number">8.</span> }
</code></pre><p>Line 2: This for loop traverses our <code>arr</code> array. Since it loops n times for each n element in our array, this line runs in O(n).</p>
<p>Line 3: This second for loop will always run one index ahead of the first loop. This way it's able to sum the numbers of index 1 and index 2 to check if they add to our <code>target</code>.  So, for every item in the array, the second loop will traverse that one item n times in order to compare all numbers to that one number before moving to the second index and doing the same all over again. In other words, these two loops are executed in n x n resulting in O(n^2).</p>
<p>Line 4: This line will take the same time to execute no matter our input size. It's O(1).</p>
<p>Line 7: This is a simple statement not relying on n. It also runs in O(1).</p>
<p><strong>Final verdict: Time: O(n^2) | Space: O(1)</strong>
O(n^2) dominates all other runtimes when it comes to the worst-case scenario, therefore this solution runs in O(n^2).</p>
<p>This next solution utilizes the two-pointers technique.</p>
<pre><code><span class="hljs-number">1.</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">twoSum</span>(<span class="hljs-params">arr, target</span>) </span>{
<span class="hljs-number">2.</span>     arr.sort((a,b) <span class="hljs-operator">=</span><span class="hljs-operator">&gt;</span> a<span class="hljs-operator">-</span>b)
<span class="hljs-number">3.</span>     let start <span class="hljs-operator">=</span> <span class="hljs-number">0</span>;
<span class="hljs-number">4.</span>     let end <span class="hljs-operator">=</span> arr.<span class="hljs-built_in">length</span>-<span class="hljs-number">1</span>
<span class="hljs-number">5.</span>    
<span class="hljs-number">6.</span>     <span class="hljs-keyword">while</span>(start <span class="hljs-operator">&lt;</span> end) {
<span class="hljs-number">7.</span>         <span class="hljs-keyword">if</span> (arr[start] <span class="hljs-operator">+</span> arr[end] <span class="hljs-operator">=</span><span class="hljs-operator">=</span><span class="hljs-operator">=</span> target) <span class="hljs-keyword">return</span> [arr[start],arr[end]]
<span class="hljs-number">8.</span>         <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> ((arr[start] <span class="hljs-operator">+</span> arr[end]) <span class="hljs-operator">&lt;</span> target) start<span class="hljs-operator">+</span><span class="hljs-operator">+</span>;
<span class="hljs-number">9.</span>         <span class="hljs-keyword">else</span> end<span class="hljs-operator">-</span><span class="hljs-operator">-</span>;
<span class="hljs-number">10.</span>     }
<span class="hljs-number">11.</span>    <span class="hljs-keyword">return</span> []
<span class="hljs-number">12.</span> }
</code></pre><p>line 2: The sort function traverses the array in order to sort it in increasing order. This line runs in O(n).</p>
<p>line 3: Initiating the <code>start</code> variable runs in O(1).</p>
<p>line 4. Initiating the <code>end</code> variable runs in O(1).</p>
<p>line 6. This while loop runs as long as <code>start</code> is less than <code>end</code>. For each loop, we will traverse the array checking to see if our loop statement is still truthy. This line runs in O(n).</p>
<p>line 7-8: These statements run in O(1).</p>
<p><strong>Final verdict: Time: O(n) | Space: O(1)</strong></p>
<p>O(n) dominates all other runtimes in this solution when it comes to the worst-case scenario, therefore this solution runs in O(n). This solution is obviously far superior to the first because it is more efficient. </p>
<h3 id="heading-summary">Summary</h3>
<ol>
<li><p>Time complexity + space complexity = code efficiency</p>
</li>
<li><p>Time complexity measures the amount of time a program takes to complete. The faster your code, the better.</p>
</li>
<li><p>Space complexity measures the amount of space (memory) a program takes up as it completes. The less space, the better.</p>
</li>
<li><p>Big O is used to rank an algorithm's performance in relation to the growth of input size. As our input gets larger, how efficient does our code remain?</p>
</li>
<li><p>Study your big O notations.</p>
</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[Class Components Vs. Functional Components in React]]></title><description><![CDATA[When I started my React journey back in 2019, hooks had just been introduced a couple of months earlier in February of that year. After coming across multiple sources vouching for the ease and simplicity of functional components compared to class-bas...]]></description><link>https://blog.ruthmatieu.com/class-components-vs-functional-components-in-reactjs</link><guid isPermaLink="true">https://blog.ruthmatieu.com/class-components-vs-functional-components-in-reactjs</guid><category><![CDATA[React]]></category><category><![CDATA[ReactHooks]]></category><category><![CDATA[create-react-app]]></category><dc:creator><![CDATA[Alanna M.]]></dc:creator><pubDate>Tue, 08 Dec 2020 22:37:03 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/unsplash/1HCb2gPk3ik/upload/v1642372675510/1NIwzoMa8.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>When I started my React journey back in 2019, hooks had just been introduced a couple of months earlier in February of that year. After coming across multiple sources vouching for the ease and simplicity of functional components compared to class-based components, I was sold. Right then and there, I decided functional components were the way to go and that I never needed to learn anything about class components. It wasn’t long before I realized that while I was ready to dive into hooks, not everyone was willing to transition so quickly.</p>
<p>At the time, I’d estimate that about 95% of the code snippets I found online (StackOverflow, YouTube tutorials, CodeSandbox, etc.) to help me learn React were written using class components. That presented a dilemma.</p>
<p>In the end, I decided it would be beneficial to learn both. And so I did.</p>
<h2 id="heading-what-are-class-components">What Are Class Components?</h2>
<p>Before React v16.8, class components were the primary way React managed state in applications. State is defined as any piece of data capable of changing (via user actions or interactions), causing the UI to re-render with updated data.</p>
<p>In class components, state is typically initialized inside the <code>constructor</code>, as shown in the snippet below. The <code>constructor()</code> is a method that is automatically called when a class instance is created. Additionally, because we are extending the React class (<code>React.Component</code>), <code>super()</code> must be called. This invokes the constructor of the parent class and allows the subclass to function properly.</p>
<p>In short:</p>
<ul>
<li><p>Use <code>constructor()</code> when creating your own classes.</p>
</li>
<li><p>When extending an existing class, always call <code>super()</code> inside the constructor.</p>
</li>
</ul>
<p>The <code>this</code> keyword refers to the current class instance. Inside the constructor, <code>this</code> refers to the component instance being created. Inside methods like <code>handleNameChange</code> and <code>handleSubmit</code>, <code>this</code> still refers to the component instance. Because arrow functions do not create their own <code>this</code> context, they safely allow access to component state using <code>this.setState()</code>.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <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">tempName</span>: <span class="hljs-string">""</span>,
      <span class="hljs-attr">name</span>: <span class="hljs-string">"Jane Doe"</span>,
    };
  }

  handleNameChange = <span class="hljs-function">(<span class="hljs-params">e</span>) =&gt;</span> {
    <span class="hljs-built_in">this</span>.setState({ <span class="hljs-attr">tempName</span>: e.target.value });
  };

  handleSubmit = <span class="hljs-function">(<span class="hljs-params">e</span>) =&gt;</span> {
    e.preventDefault();
    <span class="hljs-built_in">this</span>.setState({ <span class="hljs-attr">name</span>: <span class="hljs-built_in">this</span>.state.tempName, <span class="hljs-attr">tempName</span>: <span class="hljs-string">""</span> });
  };

  render() {
    <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">"App"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Hello, {this.state.name}!<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>If you want to change your name, enter it below.<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
          <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span>
          <span class="hljs-attr">name</span>=<span class="hljs-string">"name"</span>
          <span class="hljs-attr">value</span>=<span class="hljs-string">{this.state.tempName}</span>
          <span class="hljs-attr">onChange</span>=<span class="hljs-string">{this.handleNameChange}</span>
        /&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{this.handleSubmit}</span>&gt;</span>
          Submit
        <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>
    );
  }
}
</code></pre>
<h2 id="heading-what-are-functional-components">What Are Functional Components?</h2>
<p>Originally, functional components were used for simple, stateless presentational components because they lacked the ability to manage state like class components. With the release of React v16.8, Hooks were introduced, allowing functional components to manage state and side effects.</p>
<p>Hooks are functions that allow developers to use state and lifecycle features inside function components. A common convention is that Hooks start with the prefix <code>use</code>.</p>
<p>To convert the class component above into a stateful functional component, we can use the <code>useState</code> Hook. Similar to how the constructor holds state in class components, <code>useState</code> manages state inside functional components.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React, { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</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">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [name, setName] = useState(<span class="hljs-string">"Jane Doe"</span>);
  <span class="hljs-keyword">const</span> [tempName, setTempName] = useState(<span class="hljs-string">""</span>);

  <span class="hljs-keyword">const</span> handleNameChange = <span class="hljs-function">(<span class="hljs-params">e</span>) =&gt;</span> {
    setTempName(e.target.value);
  };

  <span class="hljs-keyword">const</span> handleSubmit = <span class="hljs-function">(<span class="hljs-params">e</span>) =&gt;</span> {
    e.preventDefault();
    setName(tempName);
    setTempName(<span class="hljs-string">""</span>);
  };

  <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">"App"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Hello, {name}!<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>If you want to change your name, enter it below.<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
        <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span>
        <span class="hljs-attr">name</span>=<span class="hljs-string">"name"</span>
        <span class="hljs-attr">value</span>=<span class="hljs-string">{tempName}</span>
        <span class="hljs-attr">onChange</span>=<span class="hljs-string">{handleNameChange}</span>
      /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{handleSubmit}</span>&gt;</span>
        Submit
      <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>
  );
}
</code></pre>
<p>In this article, I've used just one hook for simplicity. Check out the first article in the React Hooks series: <a target="_blank" href="https://blog.ruthmatieu.com/react-hooks-pt-i-usestate">React Hooks Pt. I - useState</a>.</p>
<p>Numerous times, I found myself discouraged when I couldn’t complete certain projects because I struggled to understand how to convert class components into functional ones. So aside from the obvious syntax differences, what truly distinguishes these two component types?</p>
<p>In short: not much.</p>
<p>Functional components have always been a core part of React. However, before version 16.8, they could not manage state. Developers were required to use class components for state management. With the introduction of Hooks in React v16.8, functional components gained the ability to manage state and lifecycle behavior. This innovation removed the need to rely exclusively on class components.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Both functional and class components ultimately produce the same results. The choice between them largely depends on your project requirements and team preferences. That said, functional components with Hooks have become the modern standard due to their simplicity, readability, and flexibility.</p>
]]></content:encoded></item></channel></rss>