<?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: Glover</title>
    <description>The latest articles on DEV Community by Glover (@_itsglover).</description>
    <link>https://dev.to/_itsglover</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%2F329780%2F26f7f4be-c58a-478c-9f35-6f428aee6249.JPG</url>
      <title>DEV Community: Glover</title>
      <link>https://dev.to/_itsglover</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/_itsglover"/>
    <language>en</language>
    <item>
      <title>I Built a Mac App That Does One Thing: Let You Clean Your Keyboard</title>
      <dc:creator>Glover</dc:creator>
      <pubDate>Sun, 29 Mar 2026 10:36:00 +0000</pubDate>
      <link>https://dev.to/_itsglover/i-built-a-mac-app-that-does-one-thing-let-you-clean-your-keyboard-181g</link>
      <guid>https://dev.to/_itsglover/i-built-a-mac-app-that-does-one-thing-let-you-clean-your-keyboard-181g</guid>
      <description>&lt;p&gt;Every MacBook owner knows this moment. You grab a cloth to wipe your keyboard, and the second you touch a key, Spotlight opens. You brush the trackpad, the cursor flies across the screen. You wipe the function row and your volume changes, your brightness drops, your music skips. You're trying to &lt;em&gt;clean&lt;/em&gt; the machine, and the machine keeps interpreting your cleaning as commands.&lt;/p&gt;

&lt;p&gt;It sounds trivial. It's not.&lt;/p&gt;

&lt;p&gt;This small frustration is the reason I built Mac Pause. And the process of building it taught me a lot about how macOS actually works under the surface.&lt;/p&gt;

&lt;h2&gt;
  
  
  There's No "Cleaning Mode" for Your Mac
&lt;/h2&gt;

&lt;p&gt;Think about it. Your Mac has Do Not Disturb, Focus modes, screen savers, sleep timers, and a dozen other states it can enter. But there's no mode that says: "Hey, I'm wiping my keyboard right now. Please ignore everything for the next thirty seconds."&lt;/p&gt;

&lt;p&gt;The workarounds all have problems. You can shut down completely, but that's overkill for a quick wipe. You can lock the screen, but keys and controls still register in ways you don't expect. You can try to be careful, but "carefully cleaning a keyboard" kind of defeats the purpose.&lt;/p&gt;

&lt;p&gt;What was missing was simple: a temporary, safe way to suspend all input on macOS so you can touch any surface without consequences.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Concept Was Tiny on Purpose
&lt;/h2&gt;

&lt;p&gt;Mac Pause was designed to be small. Not small as in "MVP I'll expand later." Small as in: this is the entire product.&lt;/p&gt;

&lt;p&gt;The idea was a menu bar utility with one job. Start a cleaning session. Block keyboard and pointer input. Exit only when the user deliberately unlocks it. Include a failsafe timeout in case anything goes wrong.&lt;/p&gt;

&lt;p&gt;That's it. No settings panels with forty options. No subscription. No system tweaker ambitions. One sentence should explain what the app does. If it can't, the scope is wrong.&lt;/p&gt;

&lt;p&gt;I believed (and still do) that the best utilities are the ones that feel obvious once they exist. "Of course there should be a cleaning mode for your Mac." That's the reaction I was going for.&lt;/p&gt;

&lt;h2&gt;
  
  
  Then I Started Building It, and macOS Had Other Plans
&lt;/h2&gt;

&lt;p&gt;The concept was straightforward. The implementation was not. macOS is a sophisticated operating system with deep security layers, and building an app that suppresses input touches several of them at once.&lt;/p&gt;

&lt;h3&gt;
  
  
  Permissions Are the First Wall
&lt;/h3&gt;

&lt;p&gt;An app that wants to intercept and block keyboard and mouse input can't just start doing it. macOS requires explicit user permission, specifically Accessibility and Input Monitoring access.&lt;/p&gt;

&lt;p&gt;That's entirely reasonable from a security standpoint. But from a product standpoint, it creates immediate friction. Your brand-new utility that does "one simple thing" now needs the user to open System Settings, find the right section, toggle the right switch, and potentially restart the app.&lt;/p&gt;

&lt;p&gt;Permission handling isn't a side feature. It's a core part of the user experience. I learned this early. If the permission flow is confusing or feels aggressive, people won't trust your app enough to grant access.&lt;/p&gt;

&lt;h3&gt;
  
  
  "Block Input" Isn't Actually One Operation
&lt;/h3&gt;

&lt;p&gt;At first glance, "pause keyboard and mouse" sounds like flipping a switch. On macOS, it's more like intercepting a river at multiple points.&lt;/p&gt;

&lt;p&gt;For a regular (non-kernel) app, the practical approach is event suppression: you intercept input events and prevent them from reaching the rest of the system. That means the app has to catch the right categories of events, suppress them consistently, and still preserve a reliable unlock path.&lt;/p&gt;

&lt;p&gt;That last part was non-negotiable. A utility that blocks all input and then gets stuck has turned your laptop into a brick. Mac Pause needed both an intentional unlock mechanism and a hard timeout that would always restore control, no matter what.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Function Row Didn't Play by the Rules
&lt;/h3&gt;

&lt;p&gt;Here's where it got interesting. I had regular key blocking working. Mouse input was blocked. Everything seemed fine. Then I wiped the function row during a test and the volume changed.&lt;/p&gt;

&lt;p&gt;Turns out, function keys on macOS (brightness, volume, media controls) don't always travel through the same event pipeline as regular keyboard input. Some of them arrive as legacy system-defined events, which is a different path entirely. So "keyboard blocked" didn't actually mean "all keyboard-looking input blocked."&lt;/p&gt;

&lt;p&gt;This is the kind of thing that makes system utilities tricky. The first 90% of the problem is solvable in a weekend. The last 10% is where your assumptions get tested by how the OS actually works.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Do You Unlock Something That Blocks All Input?
&lt;/h3&gt;

&lt;p&gt;This was a subtle design problem. The obvious answer is "press Escape to exit." But if you're cleaning your keyboard, you probably want to wipe the Escape key too. A single-key exit means there's one key you can never touch during cleaning.&lt;/p&gt;

&lt;p&gt;I landed on a hold-based chord: Right Shift + Escape. You hold both keys for a short duration to unlock.&lt;/p&gt;

&lt;p&gt;That solved several problems at once. It was unlikely to trigger accidentally during cleaning. It let users clean the Escape key by itself (just don't hold Right Shift at the same time). And the hold requirement made the action feel intentional, which matters for something safety-related.&lt;/p&gt;

&lt;p&gt;A tap would have been too risky. People brush keys while cleaning. A deliberate hold is a different kind of input, and that distinction is the whole point.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Setup Screen Almost Became the Problem
&lt;/h3&gt;

&lt;p&gt;One of the more ironic bugs I hit wasn't in the input blocker at all. It was in the permission setup flow.&lt;/p&gt;

&lt;p&gt;At one point, the permission prompt behaved too much like a system-level overlay. It filled the screen. It was hard to dismiss. The very app designed to prevent your Mac from feeling "trapped" was trapping people during setup.&lt;/p&gt;

&lt;p&gt;I rebuilt the setup flow into something calmer: a smaller utility window, clear guidance about what permissions were needed and where to find them, and honest messaging when macOS didn't behave consistently (because sometimes the system doesn't deep-link to the exact settings page you'd expect).&lt;/p&gt;

&lt;p&gt;That redesign ended up improving the whole app. Honesty about system quirks turned out to be better UX than pretending everything would work perfectly every time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Packaging Was the Invisible Make-or-Break
&lt;/h3&gt;

&lt;p&gt;Here's something that surprised me. macOS privacy permissions are sensitive to &lt;em&gt;how your app is packaged and identified&lt;/em&gt;. Running a raw executable during development is not the same as running a properly bundled &lt;code&gt;.app&lt;/code&gt; with a stable bundle identifier.&lt;/p&gt;

&lt;p&gt;During development, I hit a confusing state where permissions appeared granted in System Settings, but the app still couldn't suppress input correctly. The fix wasn't a code change. The fix was proper packaging: a real &lt;code&gt;.app&lt;/code&gt; bundle, a stable bundle ID, an app icon, and a clean zip for distribution.&lt;/p&gt;

&lt;p&gt;It's the kind of work nobody ever sees, but it's the difference between a utility that works reliably and one that works "most of the time."&lt;/p&gt;

&lt;h2&gt;
  
  
  What Came Out the Other Side
&lt;/h2&gt;

&lt;p&gt;The final product is a small menu bar utility with a short, predictable flow:&lt;/p&gt;

&lt;p&gt;Start a cleaning session. Wait through an arming countdown (so you have time to put down the mouse). Clean while everything is blocked. Exit by holding Right Shift + Escape, or let the automatic timeout handle it.&lt;/p&gt;

&lt;p&gt;I also added a few things that turned out to matter more than expected. Partial lock modes (keyboard only, or pointer only) for people who just want to clean one surface. Solid backdrop modes for screen cleaning. Launch-at-login support. A visible overlay so you always know the app is active.&lt;/p&gt;

&lt;p&gt;The app is distributed as a direct download, outside the App Store. That was a deliberate choice. For a small, focused utility, the App Store's review process and sandboxing restrictions add friction without adding much value.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Lesson That Keeps Repeating
&lt;/h2&gt;

&lt;p&gt;Building Mac Pause reinforced something I've seen over and over with macOS utilities.&lt;/p&gt;

&lt;p&gt;The headline feature is rarely the hard part. "Block input" took a fraction of the total effort. The real work was everything around it: permission flows, edge cases with function keys, unlock safety, packaging, and making the whole experience feel trustworthy enough that someone would grant an app control over their keyboard and mouse.&lt;/p&gt;

&lt;p&gt;Small tools demand a level of polish that bigger apps can sometimes get away with skipping. When your entire product is one interaction, every rough edge is visible.&lt;/p&gt;

&lt;p&gt;Mac Pause is the kind of app that should feel almost unnecessary once you've used it. &lt;em&gt;Of course&lt;/em&gt; your Mac should have a cleaning mode. The fact that it didn't was the gap, and filling it turned out to be a lot more interesting than I expected.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;Mac Pause is open source. The full code is on GitHub: &lt;a href="https://github.com/gloverola/macPause" rel="noopener noreferrer"&gt;github.com/gloverola/macPause&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you find it useful, I'd really appreciate a star on the repo. It helps more people discover the project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Installing from a release
&lt;/h3&gt;

&lt;p&gt;Download the latest &lt;code&gt;MacPause-&amp;lt;version&amp;gt;.zip&lt;/code&gt; from the releases page, then:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Unzip the file.&lt;/li&gt;
&lt;li&gt;Open &lt;code&gt;Mac Pause.app&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Drag it into &lt;code&gt;/Applications&lt;/code&gt; if you want to keep it installed.&lt;/li&gt;
&lt;li&gt;If macOS warns that the developer cannot be verified, right-click the app and choose &lt;strong&gt;Open&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Grant &lt;strong&gt;Accessibility&lt;/strong&gt; and &lt;strong&gt;Input Monitoring&lt;/strong&gt; when prompted (you'll find these under &lt;code&gt;System Settings &amp;gt; Privacy &amp;amp; Security&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Quit and reopen once after enabling Input Monitoring. macOS often needs a restart of the app before it recognizes that permission correctly.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If Gatekeeper still blocks the app after download, you can remove the quarantine flag in Terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;xattr &lt;span class="nt"&gt;-dr&lt;/span&gt; com.apple.quarantine &lt;span class="s2"&gt;"/Applications/Mac Pause.app"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Building from source
&lt;/h3&gt;

&lt;p&gt;If you'd rather build it yourself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./Scripts/build_app_bundle.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then run the bundled app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./Scripts/run_bundled_app.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mac Pause requires macOS 13 or later.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>showdev</category>
      <category>sideprojects</category>
      <category>swift</category>
    </item>
    <item>
      <title>AI Writes the Code Now. So What Are You?</title>
      <dc:creator>Glover</dc:creator>
      <pubDate>Mon, 09 Mar 2026 07:03:45 +0000</pubDate>
      <link>https://dev.to/_itsglover/ai-writes-the-code-now-so-what-are-you-3b7i</link>
      <guid>https://dev.to/_itsglover/ai-writes-the-code-now-so-what-are-you-3b7i</guid>
      <description>&lt;h2&gt;
  
  
  &lt;em&gt;The hardest part of this transition isn't learning new tools. It's letting go of the identity you built around writing code, and figuring out what replaces it.&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;Last week, Alexey Grigorev, the founder of DataTalks.Club (a platform that teaches data engineering to over 100,000 students), let Claude Code run a Terraform command. Within seconds, it wiped out his entire production infrastructure. The course platform, 2.5 years of student submissions, homework, projects, leaderboard entries, every automated database snapshot he'd counted on as backups. All of it, gone.&lt;/p&gt;

&lt;p&gt;Here's how it happened. Grigorev was migrating a side project to AWS and wanted it to share infrastructure with DataTalks.Club to save a few dollars a month. Claude actually &lt;em&gt;advised against this&lt;/em&gt;. It suggested keeping the setups separate. He overrode the recommendation. Then he ran &lt;code&gt;terraform plan&lt;/code&gt; from a new computer without the state file, which is the critical document that tells Terraform what infrastructure already exists. Without it, Terraform thought nothing existed. Duplicate resources got created. When the state file was finally uploaded, Claude did what Terraform's logic dictated: it ran &lt;code&gt;terraform destroy&lt;/code&gt; to bring everything into alignment. Since the state file described &lt;em&gt;both&lt;/em&gt; sites, everything was obliterated.&lt;/p&gt;

&lt;p&gt;It took 24 hours and an emergency AWS Business Support upgrade to recover the data. Nearly two million rows, restored from a hidden snapshot that wasn't even visible in the AWS console.&lt;/p&gt;

&lt;p&gt;In his &lt;a href="https://x.com/al_grigor/status/2029889772181934425?s=46" rel="noopener noreferrer"&gt;post-mortem&lt;/a&gt;, Grigorev was remarkably honest. He didn't blame the AI. He wrote: "I over-relied on the AI agent to run Terraform commands." His fixes? Enable deletion protection, move state files to S3, and most importantly, &lt;em&gt;manually review every plan before executing destructive actions&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I keep thinking about this story. Not because it's about a careless developer (Grigorev is clearly not that), but because it captures exactly where we are right now. An experienced engineer, using a powerful AI tool, making reasonable decisions at each step, and still watching 2.5 years of work disappear. The AI did exactly what it was told. The problem was that nobody was doing the &lt;em&gt;thinking&lt;/em&gt; about what it should have been told.&lt;/p&gt;

&lt;p&gt;That gap between what AI can execute and what a human needs to judge? That's the entire story of the developer career transition we're living through.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Numbers Behind the Anxiety
&lt;/h2&gt;

&lt;p&gt;If you've been writing code for any amount of time, you've felt it. Every week brings a new tool (Cursor, Copilot, Claude Code, Devin, v0) and with it, a fresh wave of "developers are done" takes on Twitter.&lt;/p&gt;

&lt;p&gt;The adoption numbers are staggering. GitHub Copilot now has over 20 million users. AI generates roughly 46% of all code written by active Copilot users. According to the 2025 Stack Overflow Developer Survey, 84% of developers now use or plan to use AI tools in their workflow, up from 76% the year before. Over half of professional developers use AI tools daily.&lt;/p&gt;

&lt;p&gt;But here's the number everyone overlooks: in that same survey, positive sentiment toward AI tools dropped from over 70% to just 60%. A full 46% of developers actively &lt;em&gt;distrust&lt;/em&gt; AI output. The top frustration, cited by 66% of respondents? AI solutions that are "almost right, but not quite." Close enough to be tempting, wrong enough to be dangerous.&lt;/p&gt;

&lt;p&gt;Sound familiar? Grigorev's Terraform plan looked reasonable at each step. The AI wasn't hallucinating. It was following a coherent logic chain. The problem was contextual, the kind of "almost right" that only a human who understood the full picture could catch.&lt;/p&gt;

&lt;p&gt;Your career isn't ending. But it is changing shape. And the developers who recognize that shift early will have a massive advantage over those who either panic or pretend nothing's different.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Honest Assessment: What AI Actually Replaced
&lt;/h2&gt;

&lt;p&gt;Let's get the uncomfortable part out of the way.&lt;/p&gt;

&lt;p&gt;AI coding tools have reduced the need for certain kinds of work. If your entire value proposition is "I can write a CRUD endpoint" or "I can convert this Figma design into pixel-perfect CSS," you're now competing directly with tools that do this faster and for a fraction of the cost. As one engineer put it: "Why hire a junior for $90K when GitHub Copilot costs $10 a month?"&lt;/p&gt;

&lt;p&gt;But what the doom commentary misses is that those tasks were &lt;em&gt;already&lt;/em&gt; being commoditized. Frameworks, low-code platforms, and template ecosystems had been compressing the value of raw code output for years. AI just hit the accelerator on an existing trend.&lt;/p&gt;

&lt;p&gt;What AI has &lt;em&gt;not&lt;/em&gt; replaced, and likely won't for a long time, is the messy, contextual, deeply human work of building software that actually solves problems. Understanding what a non-technical stakeholder actually needs (not what they say they need). Making architectural decisions that account for team capacity, company runway, and the debt you'll inherit. Debugging production systems where the issue spans three services, a race condition, and a misconfigured environment variable. Deciding what &lt;em&gt;not&lt;/em&gt; to build, or in Grigorev's case, deciding that Claude's advice to keep infrastructure separate was worth listening to.&lt;/p&gt;

&lt;p&gt;That Stack Overflow survey asked developers where they'd still want human help even in a future where AI handles most coding. The top answer, at 75%, was: "When I don't trust AI's answers." The human developer isn't going away. They're becoming the final quality gate.&lt;/p&gt;




&lt;h2&gt;
  
  
  If You're a Junior Developer, Read This
&lt;/h2&gt;

&lt;p&gt;I'm not going to sugarcoat it. The entry-level landscape is brutal right now.&lt;/p&gt;

&lt;p&gt;Entry-level hiring at the 15 largest tech firms fell 25% between 2023 and 2024. Salesforce announced zero engineering hires for 2025, citing AI agents. CS graduates now face a 6.1% unemployment rate, nearly double the national average. A Harvard study tracking 62 million workers across 285,000 U.S. firms found that junior employment at AI-adopting companies dropped 9 to 10% within six quarters of AI implementation. The decline wasn't from layoffs. Companies simply stopped posting junior roles.&lt;/p&gt;

&lt;p&gt;This is real, and it's worth being honest about. The traditional path of "learn to code, land a junior role, learn on the job, move up" has fractured.&lt;/p&gt;

&lt;p&gt;But here's the counter-narrative nobody's platforming enough: every senior engineer was once a junior. If companies stop hiring juniors today, they're creating a senior talent crisis in five to seven years. AWS CEO Matt Garman called the idea of replacing junior developers with AI "one of the dumbest things I've ever heard." The pipeline &lt;em&gt;has&lt;/em&gt; to be rebuilt. The question is what "junior" looks like now.&lt;/p&gt;

&lt;p&gt;If you're early in your career, the bar has risen. The junior of 2026 needs something closer to the system-design fluency of a mid-level engineer from 2020. But here's how you meet that bar:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ship real things, not tutorials.&lt;/strong&gt; Deploy end-to-end applications. React frontend, Node backend, a database, CI/CD pipeline. A to-do list app means nothing when AI can generate one in 60 seconds. An app that integrates an LLM to solve a real problem, handles edge cases, and runs in production? That proves something.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Get absurdly good at reviewing AI output.&lt;/strong&gt; The developers getting hired right now aren't the ones who generate the most code with AI. They're the ones who can look at AI-generated code and immediately spot what's wrong. Think of yourself as a code auditor, not a code writer. If Grigorev's story teaches us anything, it's that the ability to pause, read the plan, and say "wait, this doesn't look right" is the skill that saves entire platforms.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Build in public and contribute to open source.&lt;/strong&gt; When the market is flooded with applicants, a visible track record of shipped work and meaningful contributions is worth more than a polished resume. Three to five real pull requests on established projects will set you apart.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Target industries that are actually hiring.&lt;/strong&gt; Consumer tech is contracting, but "boring" sectors are aggressive buyers. AI-related job postings in insurance jumped 74% in 2025, with similar surges in finance, logistics, and healthcare. These industries don't need someone to build pretty landing pages. They need engineers who can automate internal workflows and build the infrastructure that controls them.&lt;/p&gt;




&lt;h2&gt;
  
  
  The New Developer Skill Stack
&lt;/h2&gt;

&lt;p&gt;Here's what developers who are thriving right now have deliberately built up.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. System Thinking Over Syntax Fluency
&lt;/h3&gt;

&lt;p&gt;The ability to hold a complex system in your head, to understand how a change in the payment service cascades through the event pipeline to the notification layer, is becoming more valuable, not less. AI can generate any individual component. It cannot reason reliably about the emergent behavior of interconnected systems.&lt;/p&gt;

&lt;p&gt;This is exactly what made Grigorev's incident so instructive. Claude Code executed each individual command correctly. The Terraform syntax was valid. The AWS CLI calls worked. But the &lt;em&gt;system-level&lt;/em&gt; understanding, that this state file described production infrastructure for a live platform with 100,000+ users, that was the human's job. And at the critical moment, the human had delegated too much of that thinking to the machine.&lt;/p&gt;

&lt;p&gt;U.S. Bureau of Labor Statistics data tells the same story at a macro level: overall programmer employment fell 27.5% between 2023 and 2025, but employment for software &lt;em&gt;developers&lt;/em&gt;, a more design- and architecture-oriented role, fell only 0.3%. The market isn't punishing people who build systems. It's punishing people who only write code.&lt;/p&gt;

&lt;p&gt;If you've been meaning to go deeper into distributed systems, event-driven architecture, or observability, now is the time. These are force-multiplier skills.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. AI Fluency as a Real Development Skill
&lt;/h3&gt;

&lt;p&gt;I know "prompt engineering" sounds like a buzzword. But the productivity gap between developers who use AI tools well and those who don't is enormous, and measurable. Research involving 4,800 developers showed those using Copilot completed tasks 55% faster, with pull request turnaround dropping from 9.6 days to 2.4 days.&lt;/p&gt;

&lt;p&gt;The gap isn't magic. It's discipline. Break problems into well-scoped, testable chunks before involving AI. Provide sufficient context upfront: project constraints, coding conventions, known edge cases. Review AI output with the same rigor you'd apply to a junior developer's PR. And know when to stop prompting and just write the code yourself.&lt;/p&gt;

&lt;p&gt;That last point matters more than people admit. In the Stack Overflow survey, 45% of developers said debugging AI-generated code takes &lt;em&gt;longer&lt;/em&gt; than writing it themselves. The skill isn't "use AI for everything." It's knowing exactly when AI accelerates you and when it slows you down.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Taste and Product Sense
&lt;/h3&gt;

&lt;p&gt;This one surprises people, but it might be the most important shift. When the cost of producing code approaches zero, the bottleneck moves to &lt;em&gt;deciding what code should exist&lt;/em&gt;. Developers with strong product sense, the ones who can look at a feature request and say "this won't move the metric we care about, here's what will," become disproportionately valuable.&lt;/p&gt;

&lt;p&gt;Build this by getting closer to your users. Read support tickets. Sit in on sales calls. Look at your analytics dashboards. The developer who understands the business will always out-earn the one who only understands the framework.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. The "Glue Work" That AI Can't Do
&lt;/h3&gt;

&lt;p&gt;Every successful software project runs on a substrate of almost-invisible work. Facilitating technical decisions across teams, writing clear RFC documents, mentoring junior developers, translating between engineering and product language, building consensus around tradeoffs.&lt;/p&gt;

&lt;p&gt;This work has historically been undervalued. In an AI-augmented world, it becomes the differentiator. And there's a growing concern that as companies cut juniors, seniors are losing the ability to delegate lower-risk tasks entirely, creating a "delegation vacuum" where they shoulder both the high-level architecture &lt;em&gt;and&lt;/em&gt; the grunt work with no pressure valve. If you're the person who helps a team function, lean in hard.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Not to Do
&lt;/h2&gt;

&lt;p&gt;Before the playbook, a few traps I keep seeing developers fall into:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don't let AI touch production without guardrails.&lt;/strong&gt; This is the Grigorev lesson, distilled. He's now requiring manual review of every Terraform plan, enabling deletion protection on all critical resources, and storing state files in S3 instead of locally. These aren't complex changes. They're the kind of boring, five-minute safeguards that separate professionals from people who move fast and break things. AI can draft the infrastructure code. A human should hold the keys to &lt;code&gt;destroy&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don't chase every new AI tool.&lt;/strong&gt; A new coding assistant drops every week. If you're constantly switching between Cursor, Copilot, Claude Code, Windsurf, and whatever launched yesterday, you're optimizing for novelty instead of depth. Pick one or two tools. Master them. Depth beats breadth.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don't over-rely on AI without reviewing output.&lt;/strong&gt; This is the most common mistake I see. AI-generated code often &lt;em&gt;looks&lt;/em&gt; correct, passes a quick scan, and then fails in production on edge cases the model couldn't anticipate. 72% of developers say "vibe coding," meaning generating software from prompts without deeply understanding what's produced, is &lt;em&gt;not&lt;/em&gt; part of their professional work. There's a reason for that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don't panic-pivot into management because you think engineering is dead.&lt;/strong&gt; If you love building, stay building. The demand for engineers who can think at the system level is actually &lt;em&gt;increasing&lt;/em&gt;. Switching to management out of fear rather than genuine interest is a recipe for misery.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don't ignore the fundamentals.&lt;/strong&gt; When AI handles the surface-level implementation, your understanding of data structures, networking, concurrency, and system design becomes &lt;em&gt;more&lt;/em&gt; important, not less. AI is a layer on top of fundamentals, not a replacement for them. As Satya Nadella put it: "Having the ability to think computationally matters a lot."&lt;/p&gt;




&lt;h2&gt;
  
  
  A Practical Playbook for the Next 12 Months
&lt;/h2&gt;

&lt;p&gt;Theory is nice. Here's what I'd actually do.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Month 1 to 3: Integrate AI deeply into your workflow.&lt;/strong&gt; Don't just dabble. Use an AI coding tool as your default pair programmer for a full month. Build muscle memory. The goal isn't to use AI for everything. It's to develop an instinct for when to reach for it. &lt;em&gt;What "done" looks like:&lt;/em&gt; You can estimate, before starting a task, whether AI will speed it up or slow it down, and you're right 80% of the time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Month 4 to 6: Go deep in one area AI struggles with.&lt;/strong&gt; Pick a domain that requires judgment, context, and systems-level thinking. Performance engineering. Security architecture. Data modeling for complex domains. Infrastructure design. Become genuinely excellent at one of these. &lt;em&gt;What "done" looks like:&lt;/em&gt; You can explain to a non-technical PM why your system handles 10x traffic spikes without falling over, and they believe you.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Month 7 to 9: Build something end-to-end with AI as your co-pilot.&lt;/strong&gt; Ship a side project, contribute to open source, or take on an ambitious work project. Document the process. Not just the wins, but the moments where AI led you astray. Where did you override it? Where did you wish you had? Grigorev's post-mortem is a masterclass in this kind of reflective practice. &lt;em&gt;What "done" looks like:&lt;/em&gt; You have a shipped project and a written reflection (blog post, internal doc, even a detailed README) that someone else could learn from.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Month 10 to 12: Teach what you've learned.&lt;/strong&gt; Write about your experience. Give a talk at a meetup. Mentor someone more junior. Teaching forces you to crystallize your understanding, and it positions you publicly as someone navigating this transition with intention. &lt;em&gt;What "done" looks like:&lt;/em&gt; You've published at least one piece of content or given one talk that generated real feedback or conversation.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Mindset Shift That Matters Most
&lt;/h2&gt;

&lt;p&gt;I want to close with something less tactical and more fundamental.&lt;/p&gt;

&lt;p&gt;The developers struggling most with this transition aren't the ones with weaker technical skills. They're the ones whose professional identity is built on &lt;em&gt;being the person who writes the code&lt;/em&gt;. When AI can write the code, that identity feels threatened.&lt;/p&gt;

&lt;p&gt;The developers who are thriving? They see themselves as &lt;em&gt;problem solvers who happen to use code as their primary tool&lt;/em&gt;. For them, AI is just another tool in the kit, like when they adopted a new framework or learned a new language. It changes how they work, not who they are.&lt;/p&gt;

&lt;p&gt;Grigorev's story lands differently when you see it through this lens. He didn't write a post about how AI is dangerous and should be avoided. He wrote a post about what &lt;em&gt;he&lt;/em&gt; could do differently. What guardrails to add, what processes to change, what judgment calls to stop delegating. His identity as an engineer didn't break. It evolved. He's still building. He's just building with clearer boundaries now.&lt;/p&gt;

&lt;p&gt;That's the model.&lt;/p&gt;

&lt;p&gt;The software industry has always been defined by waves of abstraction. Assembly to C. C to Python. Manual deployment to CI/CD. Every wave eliminated certain jobs and created others that were previously unimaginable. We're in another one of those waves.&lt;/p&gt;

&lt;p&gt;But this one has a wrinkle. It's not just changing the tools. It's changing who gets to enter the profession and what the first few years of a career look like. That's worth taking seriously, both as individuals adapting our own paths and as an industry deciding whether to invest in the next generation or abandon them.&lt;/p&gt;

&lt;p&gt;The developers who adapt won't just survive. They'll look back in five years and realize this was the inflection point that made their careers.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;If this resonated, I'd love to hear how you're adapting your own workflow. Or if you're early career, what the job search actually looks like right now.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>career</category>
    </item>
    <item>
      <title>Why React Developers Can Finally Delete Half Their Performance Code</title>
      <dc:creator>Glover</dc:creator>
      <pubDate>Mon, 02 Mar 2026 14:44:30 +0000</pubDate>
      <link>https://dev.to/_itsglover/why-react-developers-can-finally-delete-half-their-performance-code-1oh9</link>
      <guid>https://dev.to/_itsglover/why-react-developers-can-finally-delete-half-their-performance-code-1oh9</guid>
      <description>&lt;p&gt;Every React developer has felt the creeping dread: you're building a feature, it works, and then you remember you need to wrap this in &lt;code&gt;useMemo&lt;/code&gt;. And that callback needs &lt;code&gt;useCallback&lt;/code&gt;. And the child component needs &lt;code&gt;React.memo&lt;/code&gt;. What started as a simple button is now buried under three layers of optimization boilerplate.&lt;/p&gt;

&lt;p&gt;React 19's compiler makes all of it obsolete.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The problem wasn't that optimization was hard. The problem was that React forced you to do the compiler's job.&lt;/strong&gt; You had to manually tell React what not to re-render, what not to recalculate, what references to preserve. The new compiler handles this automatically not as a convenience feature, but as a fundamental architectural shift in how React processes your code.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Tax You've Been Paying
&lt;/h2&gt;

&lt;p&gt;React's rendering model created a specific headache: when a parent component's state changed, every child re-rendered. Even if those children displayed static text. Even if nothing about them changed.&lt;/p&gt;

&lt;p&gt;Developers fought this with three tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;React.memo&lt;/code&gt;&lt;/strong&gt; told React to skip re-rendering a child unless its props actually changed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;useMemo&lt;/code&gt;&lt;/strong&gt; cached expensive calculations so they wouldn't rerun on every render.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;useCallback&lt;/code&gt;&lt;/strong&gt; preserved function references, because React compares props by reference, a recreated function looked like a new prop, triggering unnecessary re-renders.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The tax wasn't just in writing this code. It was in debugging dependency arrays, weighing whether optimization was worth the complexity, and watching your clean component logic disappear under wrapper functions.&lt;/p&gt;

&lt;p&gt;Here's what that looked like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useMemo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useCallback&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;memo&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ChildComponent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;memo&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Increment&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleIncrement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useCallback&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt; 

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;expensivePrimeNumbers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useMemo&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;calculatePrimes&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; 
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Count: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ChildComponent&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleIncrement&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three hooks. One wrapper. All to render a counter with a button.&lt;/p&gt;




&lt;h2&gt;
  
  
  What the Compiler Actually Does
&lt;/h2&gt;

&lt;p&gt;The React Compiler converts your components into optimized JavaScript and memoizes automatically. It tracks when inputs change and when they don't, it skips the work.&lt;/p&gt;

&lt;p&gt;No wrappers. No hooks. No dependency arrays to manage.&lt;/p&gt;

&lt;p&gt;The same component now looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ChildComponent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Increment&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleIncrement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;expensivePrimeNumbers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;calculatePrimes&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Count: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ChildComponent&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleIncrement&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This isn't a simplified example for documentation. This is production code. The compiler handles what you used to handle manually.&lt;/p&gt;

&lt;p&gt;Adoption requires no code changes, just enabling the compiler. If a component violates React's rules, the compiler skips that component and optimizes the rest. An ESLint plugin flags violations so you can fix them incrementally.&lt;/p&gt;




&lt;h2&gt;
  
  
  Three More Cuts to Your Codebase
&lt;/h2&gt;

&lt;p&gt;The compiler dominates the headline, but React 19 trims boilerplate elsewhere too.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Refs without &lt;code&gt;forwardRef&lt;/code&gt;.&lt;/strong&gt; Passing a reference to a child component used to require wrapping the entire child in &lt;code&gt;forwardRef&lt;/code&gt;. Now &lt;code&gt;ref&lt;/code&gt; works like any other prop.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The &lt;code&gt;use&lt;/code&gt; hook.&lt;/strong&gt; A single hook that resolves promises and context. It replaces &lt;code&gt;useContext&lt;/code&gt; and offers a cleaner alternative to &lt;code&gt;useEffect&lt;/code&gt; for data fetching. Combined with Suspense, async loading states become declarative instead of manually tracked.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Form actions.&lt;/strong&gt; Pass functions directly to a form's &lt;code&gt;action&lt;/code&gt; prop—client-side or server-side. New hooks like &lt;code&gt;useFormStatus&lt;/code&gt; disable buttons during submission, and &lt;code&gt;useOptimistic&lt;/code&gt; updates the UI instantly while waiting for the server.&lt;/p&gt;




&lt;h2&gt;
  
  
  What This Actually Means
&lt;/h2&gt;

&lt;p&gt;React 19 isn't adding features you need to learn. It's removing problems you've been solving manually.&lt;/p&gt;

&lt;p&gt;The code you delete is code you never have to debug. The patterns you unlearn are patterns that were always workarounds. For the first time in years, React is getting simpler not because it's doing less, but because you are.&lt;/p&gt;

</description>
      <category>react</category>
      <category>compiling</category>
    </item>
    <item>
      <title>Getting the Deck in Order: Custom Types and Methods in Go!</title>
      <dc:creator>Glover</dc:creator>
      <pubDate>Fri, 01 Nov 2024 06:53:50 +0000</pubDate>
      <link>https://dev.to/_itsglover/getting-the-deck-in-order-custom-types-and-methods-in-go-40a9</link>
      <guid>https://dev.to/_itsglover/getting-the-deck-in-order-custom-types-and-methods-in-go-40a9</guid>
      <description>&lt;p&gt;Hello Gophers! Today we are going to familiarize ourselves with this great world of custom types and methods in Go. Sounds a bit overwhelming? Don't worry, by the end of this article you are going to be able to do it with eyes closed and one hand tied behind your back. So go ahead, pick up your favorite beverage, take a seat and lets dive in.&lt;/p&gt;

&lt;p&gt;Go's Type Magic&lt;br&gt;
Suppose at some point, one day, one wanted to conjure a deck of cards; he would do so in Go by first introducing what is called a custom type. Instead of saying "I want a list of strings", which is kind of a bore, he gets to name it something cool, like deck! Naming makes it easier to use and keeps the code nice and neat, just like a perfectly stacked deck of cards.&lt;/p&gt;

&lt;p&gt;Here's the abracadabra that does the trick:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;deck&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Boom!&lt;/strong&gt; You now have a new type called &lt;code&gt;deck&lt;/code&gt;, and all it really is, under the hood, is a slice of strings (&lt;code&gt;[]string&lt;/code&gt;). You’ve just made Go a little more readable and fun!&lt;/p&gt;

&lt;h3&gt;
  
  
  Making &lt;code&gt;deck&lt;/code&gt; Do Tricks - Adding Methods
&lt;/h3&gt;

&lt;p&gt;But a deck of cards by itself is kind of boring, right? What’s a magician without a few card tricks? That's where &lt;strong&gt;methods&lt;/strong&gt; come into play! In Go, you can attach &lt;strong&gt;methods&lt;/strong&gt; to your custom types, making them do all sorts of cool things.&lt;/p&gt;

&lt;p&gt;Let’s start by adding a &lt;code&gt;print()&lt;/code&gt; method to our &lt;code&gt;deck&lt;/code&gt; type so it can list out all the cards in the deck. Here's how you do it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="n"&gt;deck&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;card&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;card&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hold up—what just happened? Let me break it down for you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;func (d deck) print()&lt;/code&gt;&lt;/strong&gt;: This is a &lt;strong&gt;method&lt;/strong&gt; called &lt;code&gt;print()&lt;/code&gt; that belongs to our &lt;code&gt;deck&lt;/code&gt; type. The &lt;code&gt;(d deck)&lt;/code&gt; part is called a &lt;strong&gt;receiver&lt;/strong&gt;. You can think of it like saying, “Hey &lt;code&gt;deck&lt;/code&gt;, here’s what I want you to do when I call &lt;code&gt;print()&lt;/code&gt; on you.”&lt;/li&gt;
&lt;li&gt;Inside &lt;code&gt;print()&lt;/code&gt;, we’re looping through each card in the deck and printing out its &lt;strong&gt;index&lt;/strong&gt; (&lt;code&gt;i&lt;/code&gt;) and its &lt;strong&gt;value&lt;/strong&gt; (&lt;code&gt;card&lt;/code&gt;). Simple, yet powerful!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's the full picture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"fmt"&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;deck&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="n"&gt;deck&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;card&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;card&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;cards&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;deck&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"Ace of Spades"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Two of Hearts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Three of Diamonds"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;cards&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run this, and you’ll get something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0 Ace of Spades
1 Two of Hearts
2 Three of Diamonds
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look at that! Your deck knows how to introduce itself. You've made a talking deck—how cool is that?&lt;/p&gt;

&lt;h3&gt;
  
  
  Not Just Cards: Real-Life Use Cases
&lt;/h3&gt;

&lt;p&gt;So you’ve learned to make a deck of cards, but what else can you do with custom types and methods in Go? Glad you asked—because the possibilities are endless. Let’s walk through a few fun examples that go beyond just cards.&lt;/p&gt;

&lt;h4&gt;
  
  
  1. &lt;strong&gt;Managing Students Like a Boss&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Imagine you’re a teacher with a list of students. Instead of using a boring old slice, why not create a new type called &lt;code&gt;students&lt;/code&gt;?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;students&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="n"&gt;students&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;student&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;students&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"Alice"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Bob"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Charlie"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, when you need to list all the students, you just call &lt;code&gt;class.print()&lt;/code&gt;. It’s like having your own roll call assistant!&lt;/p&gt;

&lt;h4&gt;
  
  
  2. &lt;strong&gt;Shopping Cart for an E-Commerce App&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Running an online store? You’ll probably want a &lt;code&gt;cart&lt;/code&gt; type to manage the items customers add to their shopping cart.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;cart&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="n"&gt;cart&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;printItems&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%d: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;shoppingCart&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;cart&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"Laptop"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Mouse"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Keyboard"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;shoppingCart&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;printItems&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is super handy for quickly listing everything in the cart without any extra effort. You could even add methods like &lt;code&gt;addItem()&lt;/code&gt; or &lt;code&gt;removeItem()&lt;/code&gt; to make it more powerful.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. &lt;strong&gt;Bank Account Transactions&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;How about keeping track of bank transactions? You could create a &lt;code&gt;transactions&lt;/code&gt; type and add methods for printing and calculating balances.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;transactions&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;float64&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="n"&gt;transactions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;printHistory&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;transaction&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Transaction %d: $%.2f&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;transaction&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;account&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;transactions&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="m"&gt;100.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="m"&gt;50.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;25.5&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;printHistory&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This way, you can quickly see every deposit and withdrawal and easily manage your bank history—without even needing an app!&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Custom Types Are Awesome
&lt;/h3&gt;

&lt;p&gt;Custom types and methods are all about &lt;strong&gt;making your life easier&lt;/strong&gt;. By grouping related data and functionality together, you make your code more readable, reusable, and much more manageable. Instead of juggling random slices and utility functions all over the place, you have something that makes &lt;strong&gt;sense&lt;/strong&gt; to your project.&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;deck&lt;/code&gt; knows how to print itself. A &lt;code&gt;cart&lt;/code&gt; knows what’s inside it. A &lt;code&gt;students&lt;/code&gt; type knows how to call roll. It’s all about attaching &lt;strong&gt;meaning&lt;/strong&gt; to your data and giving it &lt;strong&gt;superpowers&lt;/strong&gt; to do useful things.&lt;/p&gt;

&lt;h3&gt;
  
  
  Your Next Magic Trick?
&lt;/h3&gt;

&lt;p&gt;Why not give it a shot yourself? Try creating a new type for something you work with—maybe a list of favorite movies or tasks for your to-do app—and add a method or two that makes it useful.&lt;/p&gt;

&lt;p&gt;And there you have it—you’ve learned how to create &lt;strong&gt;custom types&lt;/strong&gt; and &lt;strong&gt;add methods&lt;/strong&gt; to them in Go, making your code more expressive and powerful. Now, it’s your turn to be the magician! Who knows, maybe your next trick will be the best one yet.&lt;/p&gt;

&lt;p&gt;Happy Go coding, my friend!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Tackling Complexity: Practical Principles for Scaling Frontend Applications</title>
      <dc:creator>Glover</dc:creator>
      <pubDate>Wed, 09 Oct 2024 21:36:06 +0000</pubDate>
      <link>https://dev.to/_itsglover/tackling-complexity-practical-principles-for-scaling-frontend-applications-3949</link>
      <guid>https://dev.to/_itsglover/tackling-complexity-practical-principles-for-scaling-frontend-applications-3949</guid>
      <description>&lt;p&gt;As frontend applications grow, so does their complexity. Adding more features often brings challenges that can slow your team's productivity and introduce hidden bugs. Scaling a frontend isn't about building bigger; it's about building smarter.&lt;/p&gt;

&lt;p&gt;This article explores core principles to keep complexity manageable as your frontend scales. We'll focus on actionable steps that can help you navigate growing codebases without losing sight of performance, maintainability, and simplicity. Some ideas here draw from an insightful piece on complexity by &lt;a href="https://frontendatscale.com/" rel="noopener noreferrer"&gt;Frontend at Scale&lt;/a&gt;, and the lessons learned are applicable to anyone building large applications.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;1. Keep Components Small&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Components are the building blocks of any frontend. But as the codebase scales, it's easy for these building blocks to grow into unwieldy giants. The solution? Keep components small and focused.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Single Responsibility&lt;/strong&gt;: Each component should do one thing well.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Avoid Long Files&lt;/strong&gt;: Break larger components into smaller, reusable pieces.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Smaller components are easier to reason about, test, and modify. You can isolate complexity by delegating responsibilities across multiple smaller parts instead of one large, confusing unit.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;2. Embrace Reusable Patterns&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Reusable patterns help eliminate duplicated logic and make development faster. Think about utilities, hooks, and helper functions that can be reused across multiple components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hooks&lt;/strong&gt; (if using React) allow stateful logic to be reused easily.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Utility Functions&lt;/strong&gt; reduce redundancy in common data transformations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Don't fall into the trap of copying code blocks from one component to another. Abstracting common logic into reusable functions avoids a "copy-paste" mess that can grow uncontrollably.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;3. Split by Domains, Not by File Type&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;A lot of teams organize projects by file type components in one folder, styles in another, utilities in a third. But as the project grows, this approach can get hard to manage.&lt;/p&gt;

&lt;p&gt;Instead, split by &lt;strong&gt;domain&lt;/strong&gt;. Group everything related to a specific feature—components, styles, tests, etc.—in one place. This structure keeps related files together, making it easier to scale features and maintain a clear understanding of your application.&lt;/p&gt;

&lt;p&gt;Example folder structure for a feature:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Features/
  - UserProfile/
    - UserProfile.tsx
    - UserProfile.styles.ts
    - UserProfile.test.ts
    - hooks/
    - utils/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When scaling, you want to understand a feature in its entirety without jumping across folders. Domain-driven file organization helps to achieve that.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;4. Apply State Management Wisely&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Managing state is often one of the biggest sources of complexity in a frontend application. Introducing the wrong state management pattern too early or over-using a global state can lead to unnecessary headaches.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Local vs. Global State&lt;/strong&gt;: Keep state as local as possible. If multiple components don’t need access to a particular piece of state, avoid moving it to a global store.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Split State into Layers&lt;/strong&gt;: Use context, global state libraries (Redux, Zustand), or query libraries (React Query) depending on the state’s purpose. A data-fetching state doesn't need to live alongside UI state.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Global state management adds overhead. Assess if it’s necessary before reaching for complex solutions. Start simple and evolve as the needs of your application change.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;5. Document Early, Document Often&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Documentation tends to be an afterthought, but as your frontend scales, poor documentation can significantly increase onboarding time and slow down development.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Add Inline Comments&lt;/strong&gt;: Avoid assuming code is self-explanatory.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Create Component Documentation&lt;/strong&gt;: Make it easy for new developers to understand how each component works, what props it expects, and the outcomes it provides.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even lightweight documentation can make a difference in maintaining clarity in a growing codebase.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;6. Performance-First Mindset&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Complexity isn’t just about code—it also shows up in how your app performs.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Code Splitting&lt;/strong&gt;: Split bundles to keep load times short.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lazy Loading&lt;/strong&gt;: Load components and resources only when they're needed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Performance issues multiply as features add up. Keeping performance considerations at the forefront will make sure that your app remains responsive at scale.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;7. Embrace Automation&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Manual processes introduce delays and increase the risk of human error.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Code Quality&lt;/strong&gt;: Use linters, formatters, and type checkers like ESLint and Prettier to maintain consistent quality.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Testing&lt;/strong&gt;: Write automated tests to catch breaking changes. As complexity grows, having a reliable test suite saves significant debugging time.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Final Thoughts&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Scaling frontend applications is less about adding more features and more about managing the complexity that comes with them. As you add new capabilities, remember to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep things modular.&lt;/li&gt;
&lt;li&gt;Reuse as much as possible.&lt;/li&gt;
&lt;li&gt;Document clearly.&lt;/li&gt;
&lt;li&gt;Manage state effectively.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These practices keep growth in control, letting your app scale smoothly rather than turning into a tangled mess.&lt;/p&gt;

&lt;p&gt;Many ideas here were inspired by &lt;a href="https://frontendatscale.com/" rel="noopener noreferrer"&gt;Frontend at Scale&lt;/a&gt;. It's a highly recommended read for anyone building complex systems.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>frontend</category>
      <category>react</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Deploying a React App on DigitalOcean App Platform Using GitHub Actions</title>
      <dc:creator>Glover</dc:creator>
      <pubDate>Thu, 01 Jun 2023 11:39:20 +0000</pubDate>
      <link>https://dev.to/_itsglover/deploying-a-react-app-on-digitalocean-app-platform-using-github-actions-38jj</link>
      <guid>https://dev.to/_itsglover/deploying-a-react-app-on-digitalocean-app-platform-using-github-actions-38jj</guid>
      <description>&lt;p&gt;Deploying a React app on the DigitalOcean App Platform can be streamlined using GitHub Actions. In this article, we'll go through the process of setting up a deployment workflow and automating the deployment using a GitHub Actions workflow file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites:&lt;/strong&gt;&lt;br&gt;
Before we begin, make sure you have a DigitalOcean Personal Access Token. If you don't have one, follow the instructions provided by DigitalOcean to &lt;a href="https://docs.digitalocean.com/reference/api/create-personal-access-token/" rel="noopener noreferrer"&gt;create a token&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Setting Up the Personal Access Token:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Access your GitHub repository and navigate to the repository's Secrets settings.&lt;/li&gt;
&lt;li&gt;Declare a new secret called DIGITALOCEAN_ACCESS_TOKEN and set its value to your DigitalOcean Personal Access Token. This token will be securely stored and used in the deployment process.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Creating the GitHub Action Workflow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a new GitHub Action workflow file or modify an existing one in your repository.&lt;/li&gt;
&lt;li&gt;Add the following workflow configuration to the file:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy app&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;build_and_deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout main branch&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Use Node.js&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v1&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;16.x'&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install dependencies&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yarn install&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Test application&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yarn test&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy to DigitalOcean&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;digitalocean/app_action@main&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;app_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;my_react_app&lt;/span&gt;
          &lt;span class="na"&gt;token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Let's go through the different steps in the workflow:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Checking out the main branch:&lt;/strong&gt; This step ensures that the workflow operates on the main branch of your repository.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Setting up Node.js:&lt;/strong&gt; This step sets up the required Node.js environment for the deployment process. We specify the desired Node.js version (in this case, 16.x).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Installing dependencies:&lt;/strong&gt; This step installs the project dependencies using the yarn install command. Make sure to customize it if you're using a different package manager.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Testing the application:&lt;/strong&gt; This step runs the tests for your React app using the yarn test command. Adjust this step if you have different testing requirements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deploying to DigitalOcean:&lt;/strong&gt; The final step utilizes the &lt;a href="https://github.com/marketplace/actions/digitalocean-app-platform-deployment" rel="noopener noreferrer"&gt;digitalocean/app_action&lt;/a&gt; action to trigger the deployment to the DigitalOcean App Platform. Set the app_name parameter to the name of your React app on DigitalOcean. The token parameter fetches the previously set DIGITALOCEAN_ACCESS_TOKEN secret securely.&lt;/p&gt;

&lt;p&gt;By following the steps outlined in this article and using the provided GitHub Actions workflow file, you can automate the deployment of your React app on the DigitalOcean App Platform. This streamlined process allows you to focus on developing your app while ensuring efficient and reliable deployments&lt;/p&gt;

</description>
      <category>deployment</category>
      <category>react</category>
      <category>githubactions</category>
      <category>digitalocean</category>
    </item>
    <item>
      <title>Understanding the Impact of React.StrictMode on Application Performance</title>
      <dc:creator>Glover</dc:creator>
      <pubDate>Thu, 22 Dec 2022 06:36:12 +0000</pubDate>
      <link>https://dev.to/_itsglover/understanding-the-impact-of-reactstrictmode-on-application-performance-1ide</link>
      <guid>https://dev.to/_itsglover/understanding-the-impact-of-reactstrictmode-on-application-performance-1ide</guid>
      <description>&lt;p&gt;React.StrictMode is a tool introduced in React 16.3 that helps identify potential problems in an application. It activates additional checks and warnings for components within its scope, which helps improve the performance and correctness of an application.&lt;/p&gt;

&lt;p&gt;One of the key features of React.StrictMode is its ability to detect unexpected side effects in components. In React, side effects refer to any operations that mutate state or trigger other changes outside the component, such as network requests or manually modifying the DOM. By default, these side effects are allowed to happen asynchronously, which can lead to unexpected behavior and performance issues.&lt;/p&gt;

&lt;p&gt;React.StrictMode wraps its children in a fragile and isolated environment, where any side effects are detected and reported. This allows developers to find and fix potential problems before they become severe. For example, consider the following component that triggers a side effect by updating the document title:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;MyComponent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;My page&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Hello&lt;/span&gt; &lt;span class="nx"&gt;world&lt;/span&gt;&lt;span class="o"&gt;!&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without React.StrictMode, this component would silently update the document title without any warnings. However, when wrapped in React.StrictMode, it would produce a warning in the console:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// MyComponent.js:5&lt;/span&gt;
&lt;span class="c1"&gt;//   React has detected a legacy lifecycle event in a strict-mode component.&lt;/span&gt;
&lt;span class="c1"&gt;//   As a precaution, React will freeze this component...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This warning indicates that the useEffect hook, which is used to manage side effects, has been called in a strict mode component. In the future, this hook will be frozen and can no longer be used, which means that the component will need to be updated to avoid the side effect.&lt;/p&gt;

&lt;p&gt;In addition to detecting side effects, React.StrictMode also enables additional checks and warnings for other potential problems. For instance, it can detect deprecated APIs and component patterns that will be removed in future versions of React. It can also help improve the performance of an application by highlighting unnecessary rendering and outdated styles.&lt;/p&gt;

&lt;p&gt;Here is an example of how React.StrictMode can detect deprecated APIs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;MyComponent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;useLegacyContextAPI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;MyContext&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Hello&lt;/span&gt; &lt;span class="nx"&gt;world&lt;/span&gt;&lt;span class="o"&gt;!&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// MyComponent.js:3&lt;/span&gt;
&lt;span class="c1"&gt;//   React has detected a legacy context API being used...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, the useLegacyContextAPI hook is deprecated and will be removed in a future version of React. When used in a strict mode component, it produces a warning that advises developers to update their code to the new context API.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Strict mode checks are run in development mode only; they do not impact the production build.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Overall, React.StrictMode is a valuable tool for improving the performance and correctness of a React application. By detecting unexpected side effects and other potential problems, it helps developers catch and fix issues before they become severe. While it may require some additional work to update components to avoid the warnings it produces, the long-term benefits of using React.StrictMode are well worth the effort.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Next.js in Production: Best Practices and Common Pitfalls</title>
      <dc:creator>Glover</dc:creator>
      <pubDate>Wed, 14 Dec 2022 12:57:02 +0000</pubDate>
      <link>https://dev.to/_itsglover/nextjs-in-production-best-practices-and-common-pitfalls-3ind</link>
      <guid>https://dev.to/_itsglover/nextjs-in-production-best-practices-and-common-pitfalls-3ind</guid>
      <description>&lt;p&gt;Next.js is a popular framework for building server-rendered React applications. It offers a rich set of features and tools for building fast and scalable web applications, including automatic code splitting, optimized performance, and seamless integration with popular serverless technologies.&lt;/p&gt;

&lt;p&gt;However, as with any technology, there are some best practices and common pitfalls to be aware of when using Next.js in production. In this article, we will discuss some of these best practices and pitfalls, and provide some tips and guidance for building successful and reliable Next.js applications.&lt;/p&gt;

&lt;p&gt;First, let's discuss some of the best practices for using Next.js in production. One of the key advantages of Next.js is its ability to automatically optimize the performance of your applications. This includes features such as code splitting, lazy loading, and server-side rendering, which can help improve the loading speed and user experience of your applications.&lt;/p&gt;

&lt;p&gt;However, to take full advantage of these features, it is important to properly configure and optimize your Next.js applications. This includes setting up the proper build and deployment processes, as well as implementing caching and other performance-enhancing techniques.&lt;/p&gt;

&lt;p&gt;Another best practice for using Next.js in production is to properly handle errors and exceptions. Next.js provides a built-in error-handling mechanism, which can be used to catch and handle errors in your application. However, it is important to also implement robust logging and monitoring systems to ensure that errors and exceptions are properly detected and addressed.&lt;/p&gt;

&lt;p&gt;Now, let's discuss some of the common pitfalls to avoid when using Next.js in production. One of the biggest challenges with server-rendered applications is the management of application state. Next.js provides a built-in mechanism for managing application state, but it can be difficult to manage and maintain, especially in larger and more complex applications.&lt;/p&gt;

&lt;p&gt;To avoid this pitfall, it is important to implement a robust state management solution, such as Redux or MobX, to ensure that your application state is properly managed and maintained. This will help improve the maintainability and scalability of your applications, and reduce the risk of errors and inconsistencies.&lt;/p&gt;

&lt;p&gt;Another common pitfall when using Next.js in production is the difficulty of debugging and testing applications. Because Next.js applications are server-rendered, it can be difficult to debug and test them using traditional client-side tools and techniques. To avoid this pitfall, it is important to implement robust testing and debugging processes, such as unit and integration testing, to ensure the reliability and quality of your applications.&lt;/p&gt;

&lt;p&gt;In conclusion, Next.js is a powerful and flexible framework for building server-rendered React applications. However, like any technology, it has its own best practices and common pitfalls that developers should be aware of. By following these best practices and avoiding these pitfalls, you can build successful and reliable Next.js applications that deliver a seamless and engaging user experience.&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>womenintech</category>
    </item>
    <item>
      <title>Reducing the Size of Your React Applications with Tree Shaking and Code Splitting</title>
      <dc:creator>Glover</dc:creator>
      <pubDate>Sun, 11 Dec 2022 10:37:09 +0000</pubDate>
      <link>https://dev.to/_itsglover/reducing-the-size-of-your-react-applications-with-tree-shaking-and-code-splitting-1650</link>
      <guid>https://dev.to/_itsglover/reducing-the-size-of-your-react-applications-with-tree-shaking-and-code-splitting-1650</guid>
      <description>&lt;p&gt;As React applications grow in size and complexity, it becomes increasingly important to optimise their performance and reduce their footprint. Two powerful techniques for achieving this are tree shaking and code splitting, which can help to eliminate unused code and split large applications into smaller, more manageable chunks.&lt;/p&gt;

&lt;p&gt;Tree shaking is a term used to describe the process of removing unused exports from a module. This is typically done during the bundling process, using a tool such as Webpack or Rollup. By removing unused code, the resulting bundle can be significantly smaller and more efficient, improving the performance and loading time of an application.&lt;/p&gt;

&lt;p&gt;To enable tree shaking in a React application, developers can use the import and export syntax provided by ECMAScript modules. For example, instead of importing a module using the require function, developers can use the import keyword, along with the specific exports they want to use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { MyComponent } from './MyModule';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This syntax allows the bundler to determine which exports are actually used in the application, and to eliminate the unused ones.&lt;/p&gt;

&lt;p&gt;Code splitting is another technique for optimising the size and performance of React applications. Instead of bundling all of the application code into a single file, code splitting allows developers to split their applications into multiple chunks, which can be loaded on demand as needed.&lt;/p&gt;

&lt;p&gt;For example, instead of importing a large module at the top level of an application, developers can use the dynamic import syntax provided by ECMAScript, which allows the module to be loaded asynchronously:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const MyModule = React.lazy(() =&amp;gt; import('./MyModule'));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This syntax allows the module to be loaded only when it is needed, improving the initial loading time of the application and reducing its overall size.&lt;/p&gt;

&lt;p&gt;By using tree shaking and code splitting together, developers can create smaller, faster, and more efficient React applications. These techniques can help to eliminate unused code and split large applications into manageable chunks, improving the performance and user experience of an application.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>codesplitting</category>
      <category>optimisation</category>
    </item>
    <item>
      <title>Introduction to CSS Positioning.</title>
      <dc:creator>Glover</dc:creator>
      <pubDate>Thu, 03 Dec 2020 21:56:41 +0000</pubDate>
      <link>https://dev.to/_itsglover/introduction-to-css-positioning-45k6</link>
      <guid>https://dev.to/_itsglover/introduction-to-css-positioning-45k6</guid>
      <description>&lt;p&gt;Positioning defines where an item stands in relation to others, as simple as that may sound CSS positioning can be a bit tricky to deal with. Taking elements out of their normal document flow by making them sit on top of one another or always remaining in the same place inside the browser viewport is known as CSS positioning. In this article, we will explore the different position properties and how to use them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites:&lt;/strong&gt; &lt;em&gt;Basic HTML and CSS knowledge&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The main aim of the positioning is to override the default behavior of elements in the document flow as described above. In instances where we want to alter the position of elements, create UI elements that float or sits in the same place inside the browser window no matter how much the page is scrolled.&lt;/p&gt;

&lt;p&gt;There are a number of positioning properties we can put into effect, to make a specific type of positioning active on an element, we use the &lt;code&gt;position&lt;/code&gt; property.&lt;/p&gt;

&lt;h2&gt;
  
  
  Static Positioning.
&lt;/h2&gt;

&lt;p&gt;This is the default position every element gets. Elements remain stacked in their normal position in the document layout flow, using this property in our CSS won't alter the position of the element. to demonstrate this, we create a div element with a class of "box-1".&lt;br&gt;
&lt;code&gt;&amp;lt;div class="box-1"&amp;gt;Static&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;br&gt;
Now we can add the following CSS properties by referencing the class attribute attached to our div above.&lt;/p&gt;

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

.box-1 {
background-color: #edfcae;
height: 50px;
width: 50px;
}


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

&lt;/div&gt;

&lt;p&gt;If we peep into our browser, we will see our element sitting pretty at the top left corner like this:&lt;br&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%2Fi%2F9nh1m118um5la0wdi6wn.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%2Fi%2F9nh1m118um5la0wdi6wn.png" alt="Screenshot 2020-12-03 at 12.05.34"&gt;&lt;/a&gt;.&lt;br&gt;
Now let's add the static position property to our element below.&lt;/p&gt;

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

.box-1 {
  position: static;
}


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

&lt;/div&gt;

&lt;p&gt;If we preview our element in the browser we notice no changes at all, This is cool, as we said before, static positioning is the default behavior!&lt;/p&gt;

&lt;h2&gt;
  
  
  Relative Positioning.
&lt;/h2&gt;

&lt;p&gt;This is a bit similar to static positioning, except that we can also modify the final position of our element once it has taken its place in the normal layout flow, including allowing elements to overlap one another on our page layout.&lt;/p&gt;

&lt;p&gt;Let's go ahead and create another box below&lt;br&gt;
&lt;code&gt;&amp;lt;div class="box-2"&amp;gt;Relative&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/p&gt;

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

.box-2 {
    background-color: #f5ab57;
    color: #000;
    text-align: center;
    height: 50px;
    width: 50px;
    position: relative;
}


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

&lt;/div&gt;

&lt;p&gt;If we preview our browser we can see it's stacked perfectly below our "static" box like this,&lt;br&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%2Fi%2Fbi3s2y2bhr3x4jq6skd9.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%2Fi%2Fbi3s2y2bhr3x4jq6skd9.png" alt="Screenshot 2020-12-03 at 12.29.08"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;so how do we modify the position of our element?. This is where we introduce the &lt;code&gt;top&lt;/code&gt;, &lt;code&gt;bottom&lt;/code&gt;, &lt;code&gt;left&lt;/code&gt; and &lt;code&gt;right&lt;/code&gt; properties.&lt;/p&gt;

&lt;h3&gt;
  
  
  top, bottom, left, and right.
&lt;/h3&gt;

&lt;p&gt;These properties are used alongside &lt;code&gt;position&lt;/code&gt; to specify exactly where we want to move the positioned element. &lt;br&gt;
now let's update our CSS below&lt;/p&gt;

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

.box-2 {
    background-color: #f5ab57;
    color: #000;
    text-align: center;
    height: 50px;
    width: 50px;
    position: relative;
    top: 30px;
    left: 100px;
}


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

&lt;/div&gt;

&lt;p&gt;The values of these properties can take any available CSS units e.g pixels, rem, em, % e.t.c.&lt;br&gt;
Now if we preview our browser we notice some changes like this&lt;br&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%2Fi%2Foekzneanmi9w1v1ldx61.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%2Fi%2Foekzneanmi9w1v1ldx61.png" alt="Screenshot 2020-12-03 at 12.29.27"&gt;&lt;/a&gt;&lt;br&gt;
interesting right?. Yeah, by assigning the top and left property to our element we've simply moved our element &lt;code&gt;30px&lt;/code&gt; from the top of its default position and 100px from the left of its default position. &lt;/p&gt;

&lt;h2&gt;
  
  
  Absolute Positioning.
&lt;/h2&gt;

&lt;p&gt;Absolute positioning gives us a different result entirely, let's try creating another box with position property set to absolute.&lt;br&gt;
&lt;code&gt;&amp;lt;div class="box-3"&amp;gt;Absolute&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/p&gt;

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

.box-3 {
    background-color: #59b1da;
    color: #fff;
    text-align: center;
    height: 50px;
    width: 120px;
    position: absolute;
}


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

&lt;/div&gt;

&lt;p&gt;If we save and refresh, we should notice something like this:&lt;br&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%2Fi%2Fwkviktp8a5e3qd5g96u5.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%2Fi%2Fwkviktp8a5e3qd5g96u5.png" alt="Screenshot 2020-12-03 at 17.00.22"&gt;&lt;/a&gt;&lt;br&gt;
First, we should notice that that the "absolute" box is overlapping the "relative" box, the remaining elements on our web page act as if the absolute box no longer exist, well, in a way this is true. An absolutely positioned element no longer exists in the normal document layout flow. By assigning absolute to the position property of an element it means that we can create isolated UI features that don't interfere with the layout of other elements on our web page, e.g popup information like alerts and prompt e.t.c.&lt;br&gt;
The &lt;code&gt;top&lt;/code&gt;, &lt;code&gt;bottom&lt;/code&gt;, &lt;code&gt;left&lt;/code&gt; and &lt;code&gt;right&lt;/code&gt; properties behave in a different way with absolute positioning. Rather than positioning the element based on its relative position within the normal document flow, they specify the distance the element should be from each of the containing element's sides.&lt;/p&gt;

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

.box-3 {
    background-color: #59b1da;
    color: #fff;
    text-align: center;
    height: 50px;
    width: 120px;
    position: absolute;
    top: 40px;
    left: 50px;
}


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

&lt;/div&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%2Fi%2F425l3iq9tiekuvb5550l.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%2Fi%2F425l3iq9tiekuvb5550l.png" alt="Screenshot 2020-12-03 at 17.39.42"&gt;&lt;/a&gt;&lt;br&gt;
In this case, we are saying that the absolutely positioned element should sit &lt;code&gt;40px&lt;/code&gt; from the top of the containing element and &lt;code&gt;50px&lt;/code&gt; from the left. &lt;/p&gt;

&lt;h2&gt;
  
  
  Z-Index
&lt;/h2&gt;

&lt;p&gt;Absolute positioning is great, but there is another thing we haven't considered yet when elements start to overlap, what determines which elements appear on top of which other elements? In the example we've seen so far, we only have one positioned element in the positioning context, and it appears on the top since positioned elements win over non-positioned elements. What about when we have more than one?.&lt;br&gt;
Can we change the stacking order of an element?. Absolutely!, the &lt;code&gt;z-index&lt;/code&gt; property allows us to do so. "z-index" is a reference to the z-axis. Web pages also have z-axis, &lt;code&gt;z-index&lt;/code&gt; values affect where positioned elements sit on that axis. Positive "z-index" values will move them higher up the stack and negative values move them lower down the stack. By default, positioned elements all have a &lt;code&gt;z-index&lt;/code&gt; of &lt;code&gt;auto&lt;/code&gt; which is effectively 0.&lt;/p&gt;

&lt;p&gt;let's try bringing the "relative" box higher up the stack, by adding the z-index property.&lt;/p&gt;

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

.box-2 {
    background-color: #f5ab57;
    color: #000;
    text-align: center;
    height: 50px;
    width: 50px;
    position: relative;
    top: 30px;
    left: 100px;
    z-index: 1;
}


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

&lt;/div&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%2Fi%2F3ublclqzhv3th5pe82fx.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%2Fi%2F3ublclqzhv3th5pe82fx.png" alt="Screenshot 2020-12-03 at 18.09.06"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Excellent!, we now have our relative box higher up the stack. We should note that "z-index" only accepts unitless values, you can't specify that you want an element to be 20 pixels up the z-axis, it doesn't work that way. Using 1 and 2 would give the same effect as 100 and 2000.&lt;/p&gt;

&lt;p&gt;In our next episode, we will discuss the fixed and sticky positioning.&lt;br&gt;
Note: You can see the example at this point &lt;a href="https://github.com/copdev/Blog-codes/tree/main/CSS/Positioning" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>css</category>
      <category>html</category>
    </item>
  </channel>
</rss>
