<?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>DEV Community: Matheus Vieira do Nascimento</title>
    <description>The latest articles on DEV Community by Matheus Vieira do Nascimento (@matheusmcz).</description>
    <link>https://dev.to/matheusmcz</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%2F1939676%2Fdf003c6c-d7aa-412d-a0b4-2682d0c7bcd2.jpeg</url>
      <title>DEV Community: Matheus Vieira do Nascimento</title>
      <link>https://dev.to/matheusmcz</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/matheusmcz"/>
    <language>en</language>
    <item>
      <title>Context API: simple, but dangerous?</title>
      <dc:creator>Matheus Vieira do Nascimento</dc:creator>
      <pubDate>Mon, 08 Sep 2025 15:04:51 +0000</pubDate>
      <link>https://dev.to/matheusmcz/context-api-simple-but-dangerous-51e4</link>
      <guid>https://dev.to/matheusmcz/context-api-simple-but-dangerous-51e4</guid>
      <description>&lt;p&gt;Continuing the conversation on state management and optimizations, in a recent post, I discussed using multiple useState hook versus useReducer, and how the false sense of organization can hurt performance and maintainability in React components.&lt;/p&gt;

&lt;p&gt;Today, let’s go a step further and talk about another silent performance killer: overusing Context API for dynamic state.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;The common and maybe problematic use of Context&lt;/strong&gt;&lt;br&gt;
You’ve probably seen or written something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqfnxv9ob9agwhha9bylc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqfnxv9ob9agwhha9bylc.png" alt=" " width="800" height="640"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;On the surface, this looks good. You’re sharing state globally. But this pattern, while common, comes with hidden costs.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;The invisible problem&lt;/strong&gt;&lt;br&gt;
React’s Context was designed for static or rarely changing data, like theme, language, or authentication info.&lt;/p&gt;

&lt;p&gt;When used for highly dynamic values like loading states, modals, form flags, or local UI logic, every single change to the .Provider's value causes all consuming components to re-render, even if they don’t use the updated part of the state.&lt;/p&gt;

&lt;p&gt;In the example above, toggling isModalVisible will cause a re-render in every component consuming ModalContext.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;But what about memo? Doesn’t that help?&lt;/strong&gt;&lt;br&gt;
Yes, React.memo can help avoid unnecessary re-renders if used correctly, and in combination with useMemo and useCallback to preserve reference stability.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7d4g7ago3oqifiz5lvlf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7d4g7ago3oqifiz5lvlf.png" alt=" " width="736" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Also, the component consuming the context needs to be memoized with React.memo, and its props must maintain stable references too.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Here’s the catch: this requires deeper technical knowledge and discipline from the developer. While possible, it's easy to overlook small things like an inline function or a value that changes on every render that silently break the optimization.&lt;/p&gt;

&lt;p&gt;So yes, the issue can be avoided, but it demands a higher level of attention and care. That’s not inherently bad, but it's risky and easy to get wrong leading to performance bottlenecks that are hard to trace.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;When is Context a good fit?&lt;/strong&gt;&lt;br&gt;
In my opinion Context works great when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The shared value changes rarely (e.g., theme, locale, authenticated user)&lt;/li&gt;
&lt;li&gt;Performance isn't critical&lt;/li&gt;
&lt;li&gt;The tree of consuming components is small&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;More efficient alternatives&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Zustand (or other lightweight state managers) One of the best modern solutions. Global scope, granular reactivity, simple APIs, and great performance.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fafmj1uitkvr0aituni7t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fafmj1uitkvr0aituni7t.png" alt=" " width="800" height="569"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdplfernxy45s4fr3e62o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdplfernxy45s4fr3e62o.png" alt=" " width="800" height="251"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Now, only components that depend on isModalVisible re-render. Nothing else.&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;useReducer + Context Separating state from dispatch, and using useReducer inside a context provider gives you more precise control over updates.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Lift state locally Sometimes the best alternative is simply to lift state to a common parent and pass it via props. No need for Context at all.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;&lt;strong&gt;Final thoughts&lt;/strong&gt;&lt;br&gt;
React’s Context API is powerful, but it's often misused. Overusing it for dynamic state causes a flood of re-renders that impact performance and make debugging harder.&lt;/p&gt;

&lt;p&gt;If you're using Context to manage frequently changing values, take a step back and reconsider. Tools like Zustand, useReducer, or simply lifting state locally are often more performant, scalable, and safer.&lt;/p&gt;

&lt;p&gt;In my last post, I talked about how useReducer can replace multiple useState hooks with more clarity and control. That same mindset applies here to look beyond the “organized” look of your code and prioritize scalable architecture and real world performance.&lt;/p&gt;




&lt;p&gt;*&lt;em&gt;#ReactJS #ReactHooks #ContextAPI #Zustand #CleanCode #Performance #FrontendTips #StateManagement #CodeQuality #JavaScript #Scalability&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
Liked the article? Let me know your thoghts in the comments&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Demystifying Git Flow: 'Clean Room' Mode</title>
      <dc:creator>Matheus Vieira do Nascimento</dc:creator>
      <pubDate>Thu, 04 Sep 2025 13:30:59 +0000</pubDate>
      <link>https://dev.to/matheusmcz/demystifying-git-flow-clean-room-mode-3j3n</link>
      <guid>https://dev.to/matheusmcz/demystifying-git-flow-clean-room-mode-3j3n</guid>
      <description>&lt;p&gt;After several years in the world of software development, code management has always been a cornerstone of productivity and quality. However, who has never found themselves trapped in a tangle of merge conflicts, having to resolve them two or three times a week just to get a piece of code into a testing environment? It's a question that, curiously, often leads to silence, and no one dares to throw the first stone.&lt;/p&gt;

&lt;p&gt;The malleability of Git Flow, if not carefully managed, can frequently lead to disorganized or unproductive Git flows. This situation isn't just a technical inconvenience; it represents a significant drain on team productivity and morale, confirming that merge conflicts are a frequent obstacle in development environments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But why do our Git flows get tangled?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The frequency of conflicts and disorganized Git flows are often symptoms of deeper problems in the branching strategy itself. One of the most common pitfalls is the existence of long-lived branches that diverge significantly from the main branch (develop or main). This substantial divergence makes merge operations progressively more complex and conflict-prone.&lt;/p&gt;

&lt;p&gt;Another significant challenge, especially in traditional Git Flow implementations, lies in unwanted dependencies between features. When feature branches are created from develop, and one of them (say, Feature A) is integrated into develop, any subsequent feature branch (Feature B) that updates its base from develop will end up inheriting the changes from Feature A, including potential bugs or unfinished work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rethinking Our Git Workflow:&lt;/strong&gt;&lt;br&gt;
The other day, I was reading some complaints on Slack from colleagues who had to review PRs with nearly 100 changes (and that wasn't even the biggest I've seen), and I started to analyze some recent experiences to gather ideas and build a model to be followed that would bring more peace of mind to the daily grind. That's what I'm going to show you, hoping to help you, whether by following it to the letter or adapting it to your reality. The important thing is that you leave here feeling lighter, with the peace of mind that your Git flow will be better. hehehe&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsyjlayrpcbdfzdwaheii.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsyjlayrpcbdfzdwaheii.png" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The central philosophy of this adapted Git Flow methodology is based on three pillars: granularity, isolation, and controlled integration. The goal is to break down large tasks, isolate changes, and introduce multiple controlled review points to ensure quality and minimize the impact of conflicts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Every new branch must start from main (or master)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The first and fundamental change from traditional Git Flow is that every new branch must start from main. Unlike the classic model where feature branches usually originate from develop, here, each new feature is started from the stable, released production branch. This directly addresses the problem of unwanted dependencies, where updating a feature branch from develop could inadvertently inherit bugs or incomplete work from other features. This strategy ensures that each feature is completely independent and can only be integrated when it is ready, validating the importance of isolating feature branches for superior control.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Fractional PRs/MRs for features – Breaking down cards into smaller subtasks&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of a single, large Pull Request (PR) or Merge Request (MR) for an entire feature, the approach is to break down cards (representing features or epics) into smaller, atomic parts. This practice is a direct application of the best practices of keeping commits small and focused and making frequent, small commits. Smaller changes are inherently easier to review, understand, and, crucially, less likely to generate severe merge conflicts. This facilitates review and conflict resolution, and smaller commits make it easier to identify and resolve conflicts incrementally&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: chore branches for subtasks and PR to feature for Code Review&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Each of these smaller subtasks gets its own dedicated branch, typically named as chore. Once a chore branch is completed, a PR is opened pointing to its parent feature branch to undergo a code review. This introduces a layer of early and granular code review, ensuring that even within a single functionality, changes are meticulously verified before they are integrated. This step is in perfect alignment with the emphasis on Pull Requests (PRs) and Code Review as essential practices for evaluating changes and reducing the risk of errors.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: feature to develop only after all subtasks are reviewed&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Only after all subtasks of a feature have been completed and individually reviewed (via PRs from chore branches to the feature branch) is the feature branch ready to be integrated into the develop branch (the main integration branch). This ensures that develop receives only code that has already gone through a comprehensive, multi-stage review process. This approach significantly reduces the risk of introducing incomplete, buggy, or unreviewed code into the primary development line, contributing to a more stable develop branch. This echoes the principle of ensuring that only reviewed and approved changes are added.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5: Dedicated feature-dev branch for conflict resolution&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is a highly innovative and practical aspect of the workflow. In cases of conflict between the feature and develop branches, instead of the common (and often problematic) practice of pulling develop into the feature branch to resolve conflicts (which can pollute the feature branch with unwanted changes), a new dedicated branch, feature-dev, is created. This branch serves as a temporary staging area specifically for resolving conflicts between the feature and develop. Once the conflicts are resolved in feature-dev, this branch is then integrated into develop.&lt;/p&gt;

&lt;p&gt;This strategy keeps the original feature branch untouched and focused on its core functionality, ensuring that the branch destined for main (production) remains clean and free of merge commits or conflict resolution artifacts. The concept of a dedicated branch for conflict resolution is directly validated by the idea of using conflict resolution branches instead of polluting feature branches.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 6: Corrections for QA Testing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When corrections are needed after QA testing, the developer should make these changes in the original feature branch. These corrections should then be pulled into the feature-dev branch. This practice keeps both branches up-to-date and ensures peace of mind regarding the release flow. If corrections for QA testing were made directly in the feature-dev branch, it would be necessary to cherry-pick these changes later to update the original feature branch, which is essential for a secure deployment and to avoid inconsistencies in the code history.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Okay, but what's next?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After that, it's just about being happy. The feature-dev branch moves to other environments that may exist in your work context, such as QA, HML, etc. But at the end of the process, the release starts from main (or master) and receives the original feature branch, clean and free of any suspicion (lol).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why This Approach Works:&lt;/strong&gt;&lt;br&gt;
Introducing the feature-dev branch for conflict resolution is a simple but effective application of conflict resolution and a key workflow design element. This approach embodies the principle that prevention is key and that preventing Git conflicts is always better than resolving them. By isolating conflict resolution, you ensure that the feature branch remains clean and focused, mitigating the risk of problems when merging to main for production. (And let's be honest, reviewing 43 altered files at once?! No amount of coffee can get a cowboy excited).&lt;/p&gt;

&lt;p&gt;So, have you ever had bad experiences because of a poorly done Git flow?&lt;/p&gt;

&lt;p&gt;Have you ever made a slip-up in Git? Me? I've made several, but the important thing is to learn from your mistakes and move forward.&lt;/p&gt;

&lt;p&gt;Tell me about your experience and if you liked this concept in the comments!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;#GitFlow #VersionControl #SoftwareDevelopment #DevOps #MergeConflicts #Productivity #TechTips #GoodCodingPractices&lt;/strong&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Pseudo-organization with useState vs using useReducer</title>
      <dc:creator>Matheus Vieira do Nascimento</dc:creator>
      <pubDate>Mon, 12 May 2025 21:17:20 +0000</pubDate>
      <link>https://dev.to/matheusmcz/pseudo-organization-with-usestate-vs-using-usereducer-3pg8</link>
      <guid>https://dev.to/matheusmcz/pseudo-organization-with-usestate-vs-using-usereducer-3pg8</guid>
      <description>&lt;p&gt;&lt;em&gt;Posted first on my linkedIn&lt;/em&gt;&lt;br&gt;
&lt;strong&gt;Recently, I’ve seen many discussions about the so-called “mess” caused by multiple useState calls in React components.&lt;br&gt;
The criticism often comes with a proposed "improvement": grouping all states into a single useState with an object, aiming to reduce lines of code and make the component appear more "organized."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz1tsdxwvtk8ti9gvz5z8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz1tsdxwvtk8ti9gvz5z8.png" alt="Image description" width="800" height="715"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At first glance, this idea might seem elegant, after all, who doesn't want cleaner-looking code?But behind this pseudo-organization lie serious issues with performance, readability, and scalability.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;The trap of useState with an object:&lt;/strong&gt;&lt;br&gt;
When you use a single useState with an object containing multiple state flags (like loading indicators), you're essentially linking all those flags to a single memory reference.&lt;/p&gt;

&lt;p&gt;In practice:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Every time you update any key in the object, the entire object is recreated.&lt;/li&gt;
&lt;li&gt;Even if you use immutable updates (setState({ ...state, changedKey: value })), React sees this as a new full state because the reference has changed.&lt;/li&gt;
&lt;li&gt;This causes &lt;strong&gt;unnecessary re-renders&lt;/strong&gt;, even when other properties haven’t changed.&lt;/li&gt;
&lt;li&gt;It affects &lt;strong&gt;performance directly&lt;/strong&gt;, especially in components with heavy rendering or many states.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There’s also a &lt;strong&gt;readability issue&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You lose individual setters like setIsLoading(true), now you must manually manipulate a shared object.&lt;/li&gt;
&lt;li&gt;You lose the semantic clarity of each individual state, hiding them inside a structure that’s harder to reason about.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;The illusion of “cleaner code”:&lt;/strong&gt;&lt;br&gt;
The main reason for adopting the object approach is to make the file look organized and reduce line count. But visual organization ≠ good architecture.&lt;/p&gt;

&lt;p&gt;Just because "they're all states" doesn't mean they belong together.&lt;/p&gt;

&lt;p&gt;This approach makes the state harder to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Debug&lt;/li&gt;
&lt;li&gt;Test&lt;/li&gt;
&lt;li&gt;Maintain&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What truly matters in code organization is &lt;strong&gt;making the logic explicit and resilient&lt;/strong&gt;, not saving a few lines.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;The road with useReducer:&lt;/strong&gt;&lt;br&gt;
When you start managing several related states, especially booleans like loading flags, form validations, request statuses, useReducer becomes a powerful alternative.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It allows you to group related states logically while keeping updates isolated.&lt;/li&gt;
&lt;li&gt;A well-structured reducer makes state transitions explicit, predictable, and traceable.&lt;/li&gt;
&lt;li&gt;dispatch and type bring a Redux-like structure, but lighter and scoped locally.&lt;/li&gt;
&lt;li&gt;Independent updates won’t trigger unnecessary renders because state reactivity remains granular.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;**But, how to use it?&lt;/p&gt;

&lt;p&gt;Step 1: Define actions and initial state**&lt;/p&gt;

&lt;p&gt;We create the &lt;strong&gt;available actions&lt;/strong&gt; and the &lt;strong&gt;initial state&lt;/strong&gt;, which contains two boolean flags: isLoading and isSubmitting.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9oaa4o2rvpyhb0eb3sck.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9oaa4o2rvpyhb0eb3sck.png" alt="Image description" width="523" height="548"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Create the reducer function&lt;/strong&gt;&lt;br&gt;
The reducer function takes the current state and an action, then returns the &lt;strong&gt;updated state&lt;/strong&gt; based on the action type.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1t2sal8tcmphq3doreea.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1t2sal8tcmphq3doreea.png" alt="Image description" width="630" height="589"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Create the MiniLoader component using useReducer&lt;/strong&gt;&lt;br&gt;
Inside the component, we use useReducer by passing the reducer and initialState. We define two functions that simulate asynchronous operations and update the corresponding loading states.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9ma3wqai2wpgwx6v6le4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9ma3wqai2wpgwx6v6le4.png" alt="Image description" width="666" height="589"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;To Infinity, And Beyond!&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reducers can be unit tested in isolation.&lt;/li&gt;
&lt;li&gt;It’s easier to scale the state logic as your component grows.&lt;/li&gt;
&lt;li&gt;You can add new actions without disrupting existing flow.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;"In the crack of the eggs":&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Visual organization ≠ good architecture.&lt;/strong&gt; Replacing multiple useStates with a single object feels like an optimization, but it’s a dangerous abstraction that harms maintainability, performance, and clarity.&lt;/p&gt;

&lt;p&gt;On the other hand, useReducer scales better, offers better control, and gives you a more predictable and reliable component structure.&lt;/p&gt;

&lt;p&gt;If your component is juggling multiple flags or tightly related states, stop fighting useStates, embrace the power of useReducer.&lt;/p&gt;

&lt;p&gt;It’s a small change that brings big benefits: &lt;strong&gt;cleaner, scalable, and more robust code.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;#ReactJS #useState #useReducer #ReactHooks #CleanCode #FrontendTips #WebPerformance #CodeQuality #ReactBestPractices #JavaScript #DevTips #FrontendArchitecture #ScalableCode #MaintainableCode&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>typescript</category>
      <category>node</category>
      <category>javascript</category>
    </item>
    <item>
      <title>New React 19 Hook: use()</title>
      <dc:creator>Matheus Vieira do Nascimento</dc:creator>
      <pubDate>Mon, 06 Jan 2025 19:27:15 +0000</pubDate>
      <link>https://dev.to/matheusmcz/new-react-19-hook-use-55m6</link>
      <guid>https://dev.to/matheusmcz/new-react-19-hook-use-55m6</guid>
      <description>&lt;p&gt;With use(), the way we handle asynchronous data in React components has been drastically simplified.&lt;/p&gt;

&lt;p&gt;💡 Before vs. Now: Comparison with Examples&lt;/p&gt;

&lt;p&gt;Before React 19&lt;br&gt;
Handling asynchronous data required the use of useEffect and useState, leading to more verbose code:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnvysbwzw6nog4a2t6bnh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnvysbwzw6nog4a2t6bnh.png" alt="Image description" width="800" height="1206"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With React 19 and the use() Hook&lt;br&gt;
Now it's possible to handle Promises directly in the component body in a more declarative way:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvggnpe36litoyfqz3nwh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvggnpe36litoyfqz3nwh.png" alt="Image description" width="800" height="957"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By using use(), React pauses the component rendering until the Promise is resolved, directly integrating with the loading management of the Suspense API.&lt;/p&gt;

</description>
      <category>react</category>
      <category>typescript</category>
      <category>frontend</category>
      <category>webdev</category>
    </item>
    <item>
      <title>My Experience with AsyncThunk in Redux Toolkit</title>
      <dc:creator>Matheus Vieira do Nascimento</dc:creator>
      <pubDate>Wed, 20 Nov 2024 04:29:09 +0000</pubDate>
      <link>https://dev.to/matheusmcz/my-experience-with-asyncthunk-in-redux-toolkit-in4</link>
      <guid>https://dev.to/matheusmcz/my-experience-with-asyncthunk-in-redux-toolkit-in4</guid>
      <description>&lt;p&gt;Hey devs! I wanted to share something I’ve been using a lot at work that has made managing async calls in Redux much easier: the createAsyncThunk.&lt;/p&gt;

&lt;p&gt;If, like me, you’ve struggled to keep async calls organized in Redux, here’s some good news: AsyncThunk simplifies it all in a super clean way.&lt;/p&gt;

&lt;p&gt;Here’s a real example I used to fetch data with GraphQL:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftkzxhbjp6dy3tyq74bbg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftkzxhbjp6dy3tyq74bbg.png" alt="Image description" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2fb91yt4bt9u9j868hbb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2fb91yt4bt9u9j868hbb.png" alt="Image description" width="800" height="928"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Why do I love it?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Clean and organized: You can track the status of an async request (loading, success, or error) directly in the slice.&lt;/li&gt;
&lt;li&gt;Less boilerplate: No need to manually write actions and reducers for async logic—it’s all handled automatically.&lt;/li&gt;
&lt;li&gt;Easy maintenance: Everything lives in one place, making it simple to read and update when needed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Since I started using createAsyncThunk, async calls in Redux have been so much smoother. If you haven’t tried it yet, I highly recommend it.&lt;/p&gt;

</description>
      <category>reduxtoolkit</category>
      <category>asyncthunk</category>
      <category>frontend</category>
      <category>graphql</category>
    </item>
    <item>
      <title>📢 Why I Use Git UIs in My Daily Work and What You Should Know About Them</title>
      <dc:creator>Matheus Vieira do Nascimento</dc:creator>
      <pubDate>Fri, 01 Nov 2024 14:07:42 +0000</pubDate>
      <link>https://dev.to/matheusmcz/why-i-use-git-uis-in-my-daily-work-and-what-you-should-know-about-them-5ah3</link>
      <guid>https://dev.to/matheusmcz/why-i-use-git-uis-in-my-daily-work-and-what-you-should-know-about-them-5ah3</guid>
      <description>&lt;p&gt;When it comes to development tools, version control is a crucial part of any project. Git, one of the most widely used tools for this, can be a bit intimidating at first. So many developers, especially with the daily rush, end up using graphical interfaces (Git UIs) to make the process easier.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;💡Git Graph on VS Code:&lt;/strong&gt;&lt;br&gt;
For those of us using Visual Studio Code, the &lt;strong&gt;Git Graph&lt;/strong&gt; extension is one of my favorites. It offers functionalities that greatly simplify working with Git repositories, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Tree view visualization:&lt;/strong&gt; You can clearly see all commits, branches, and merges on a graphical timeline, which is super helpful when trying to understand the change history in larger projects.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Quick branch control:&lt;/strong&gt; With Git Graph, it’s easy to switch between branches, create new ones, merge, and view everything without leaving the editor.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Commit comparison:&lt;/strong&gt; You can compare differences between specific commits, making it faster to understand changes between versions. This feature is a huge help for anyone who frequently reviews code.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using tools like Git Graph significantly reduces the time and effort needed for common Git tasks. However, &lt;strong&gt;I don't recommend using Git UIs for those who are just starting to learn Git&lt;/strong&gt;. Why? Simply because using the terminal is essential for a deep understanding of how Git works. Writing and executing commands manually in the terminal helps you grasp Git's functionality, version control concepts, and the processes behind each action.&lt;/p&gt;

&lt;p&gt;I know it may feel harder at first, but the learning is much more solid. What I suggest is: practice with the terminal, learn the flow of commits, branches, merges, rebases, etc. Only after you build that foundation will a graphical interface make sense and truly be a helpful tool for your daily workflow—not just a crutch.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhvlhlitd6yvrmkek8wu0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhvlhlitd6yvrmkek8wu0.png" alt="Imagem da extensão git graph no vscode" width="800" height="509"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In summary, &lt;strong&gt;Git UIs can absolutely speed up your workflow&lt;/strong&gt;, and Git Graph is one of the best options on VS Code. But if you're just starting out, my tip is: start with the terminal!&lt;/p&gt;

</description>
      <category>git</category>
      <category>frontend</category>
      <category>react</category>
      <category>node</category>
    </item>
    <item>
      <title>maxLength input type=number</title>
      <dc:creator>Matheus Vieira do Nascimento</dc:creator>
      <pubDate>Fri, 16 Aug 2024 20:23:37 +0000</pubDate>
      <link>https://dev.to/matheusmcz/maxlength-input-typenumber-4npl</link>
      <guid>https://dev.to/matheusmcz/maxlength-input-typenumber-4npl</guid>
      <description>&lt;p&gt;Have you ever needed to use a numeric input but couldn't limit the maximum number of characters?! I faced this recently and I'm sharing what helped me!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔐 Developing a Custom OTP Input Component 🔐&lt;/strong&gt;&lt;br&gt;
Recently, I needed to create an OTP input component for a project where users had to enter a verification code sent via SMS or email. The challenge was to ensure that the input accepted only numbers and that each field allowed only a single digit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;&lt;br&gt;
The &lt;code&gt;&amp;lt;input type="number"/&amp;gt;&lt;/code&gt; ignores the HTML "maxLength" property, making it necessary to use JavaScript to achieve this behavior. When we create an input of this type, the element automatically converts all non-numeric values into empty strings! After some research and experimentation, I came up with a solution that combines simplicity and efficiency.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📋Input code:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

&amp;lt;input
  type="number"
  maxLength={1}
  inputMode="numeric" //Opens numeric keyboard on mobile
  onInput={(e) =&amp;gt; {
    const target = e.target as HTMLInputElement;

    // Removes non-numeric characters
    target.value = target.value.replace(/\D/g, "");

    // Limits to one digit
    if (target.value.length &amp;gt; target.maxLength) {
      target.value = target.value.slice(0, target.maxLength);
    }
  }}
/&amp;gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;💡How it works:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;replace(/\D/g, ""): Removes any non-numeric characters, ensuring that only numbers are entered.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;maxLength={1} e slice(0, target.maxLength): Limit the input to a single digit.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This solution was essential to create a clean and intuitive user experience, focusing on simplicity and efficiency in entering the OTP code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But why handle non-numeric characters if the input type is number?&lt;/strong&gt;&lt;br&gt;
Surprisingly, the letter "e" is interpreted as a number, meaning if the user somehow entered "e", it would be accepted. So, even with type=number, it was necessary to add this regex.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;😊 BONUS&lt;/strong&gt;&lt;br&gt;
If you've ever used a numeric input, you've probably encountered those annoying little arrows:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1ld55hm3ywd79jslnccj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1ld55hm3ywd79jslnccj.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's the CSS to hide them:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

input {
  &amp;amp;::-webkit-outer-spin-button,
  &amp;amp;::-webkit-inner-spin-button {
      -webkit-appearance: none;
      margin: 0;
  }
  -moz-appearance: textfield;
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;I'm always looking for new ways to optimize the user experience in a simple yet effective way. What do you think of this approach? Any suggestions or alternatives that you've used? Let's discuss! 💬&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>html</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
