<?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: Corbin Crutchley</title>
    <description>The latest articles on DEV Community by Corbin Crutchley (@crutchcorn).</description>
    <link>https://dev.to/crutchcorn</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%2F563791%2F6cf9e1b0-caa1-4e7f-8fc7-cc1cf1f201df.jpg</url>
      <title>DEV Community: Corbin Crutchley</title>
      <link>https://dev.to/crutchcorn</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/crutchcorn"/>
    <language>en</language>
    <item>
      <title>Merging the "This Is" Community into "Playful Programming"</title>
      <dc:creator>Corbin Crutchley</dc:creator>
      <pubDate>Mon, 09 Feb 2026 11:50:04 +0000</pubDate>
      <link>https://dev.to/playfulprogramming/merging-the-this-is-community-into-playful-programming-1nfi</link>
      <guid>https://dev.to/playfulprogramming/merging-the-this-is-community-into-playful-programming-1nfi</guid>
      <description>&lt;p&gt;Today marks a major milestone for open-source education: &lt;strong&gt;&lt;a href="https://x.com/Thisis_Learning" rel="noopener noreferrer"&gt;"This is Learning"&lt;/a&gt; and &lt;a href="https://playfulprogramming.com" rel="noopener noreferrer"&gt;"Playful Programming"&lt;/a&gt; are joining forces.&lt;/strong&gt; We are bringing two communities together to reinforce our shared goal of transparent, accessible developer education.&lt;/p&gt;

&lt;p&gt;Let's introduce each community and explain what this means for both communities.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing "This is Learning" (TiL)
&lt;/h2&gt;

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

&lt;p&gt;"This is Learning" (TiL) was originally created in 2020 by &lt;a href="https://www.santoshyadav.dev/" rel="noopener noreferrer"&gt;Santosh Yadav&lt;/a&gt; and &lt;a href="https://github.com/layzeedk" rel="noopener noreferrer"&gt;Lars Gyrup Brink Nielsen&lt;/a&gt; to bring together authors and share software development knowledge.&lt;/p&gt;

&lt;p&gt;Santosh and Lars are both highly accomplished engineers and community leaders. Both receiving multi-year awards from prestigious organizations like GitHub, Microsoft, Google, and Nx for their efforts on "This is" as well as many other open-source projects.&lt;/p&gt;

&lt;p&gt;It's no wonder, then, that since they started their project they've:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://dev.to/this-is-learning"&gt;Facilitated the release of over 1480 articles on their Dev.to community by over 175 authors&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/this-is-angular"&gt;This includes 650 articles specifically about Angular in their "This is Angular" sub-brand&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href="https://www.youtube.com/c/ThisisTechTalks" rel="noopener noreferrer"&gt;Created 100 videos on their YouTube channel&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href="https://til-conf.netlify.app/" rel="noopener noreferrer"&gt;Ran a successful virtual conference in 2024&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Created two courses for &lt;a href="https://this-is-angular.github.io/ngrx-essentials-course/" rel="noopener noreferrer"&gt;NgRx&lt;/a&gt; and &lt;a href="https://this-is-learning.github.io/rxjs-fundamentals-course/" rel="noopener noreferrer"&gt;RxJS&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href="https://thisislearning.substack.com/archive" rel="noopener noreferrer"&gt;Sent out 50+ issues of their newsletter&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;As we migrate these resources to "Playful Programming" branding and our main website, these links may break over time. We will leave them as-is for historical context.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Throughout it all, they always remained strictly "not for profit" and encouraged cross-posting, self-controlled content ownership, and community wellbeing over all else.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing "Playful Programming" (PFP)
&lt;/h2&gt;

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

&lt;p&gt;"Playful Programming" (PFP) was started by &lt;a href="http://jfenn.me/" rel="noopener noreferrer"&gt;James Fenn&lt;/a&gt;, &lt;a href="https://playfulprogramming.com/people/evelynhathaway" rel="noopener noreferrer"&gt;Evelyn Hathaway&lt;/a&gt;, and &lt;a href="https://github.com/crutchcorn" rel="noopener noreferrer"&gt;myself (Corbin Crutchley)&lt;/a&gt; in &lt;a href="https://playfulprogramming.com/posts/uttering-hello-introduction-post/" rel="noopener noreferrer"&gt;2019&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Playful Programming (originally called &lt;a href="https://playfulprogramming.com/posts/rebrand-to-playful-programming/" rel="noopener noreferrer"&gt;"Unicorn Utterances"&lt;/a&gt;) started as an alternative to a bootcamp that I worked in that I felt was acting predatory to the students in my area. Knowing that James and Evelyn were all-star engineers, I asked for their help to propel our mission — of teaching others in a transparent and helpful way — forward. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;More history:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Want to learn more about Playful Programming's origins? &lt;a href="https://playfulprogramming.com/posts/a-complete-history-of-uu/" rel="noopener noreferrer"&gt;When we rebranded from "Unicorn Utterances" we wrote a historical article on our project that you can read on our site.&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Since then, we as a community have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://playfulprogramming.com/search/?q=*" rel="noopener noreferrer"&gt;Had over 230 articles released on our site from over 60 contributors&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://discord.gg/FMcvc6T" rel="noopener noreferrer"&gt;Ran a Discord community with 2700 members&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://playfulprogramming.com" rel="noopener noreferrer"&gt;Made a bespoke highly performant and accessible website&lt;/a&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/playfulprogramming/playfulprogramming" rel="noopener noreferrer"&gt;The site was built along the timeline of 7000+ commits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/playfulprogramming/hoof" rel="noopener noreferrer"&gt;Begun to introduce a dedicated backend and complex deployment infrastructure to make our site more scalable in the long-run&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.figma.com/design/Ul8KB1Sc6etCNTRCRSc27z/Playful-Programming---Website?m=auto&amp;amp;t=jtN97SD9KIA9GZ09-6" rel="noopener noreferrer"&gt;Created a robust design system with hundreds of design components and 300+ variables alone&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href="https://mailinglist.playfulprogramming.com/" rel="noopener noreferrer"&gt;Had a mailing list with over 1500 subscribers&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href="https://playfulprogramming.com/events/sacramento-bootcamp/" rel="noopener noreferrer"&gt;Started a &lt;strong&gt;free&lt;/strong&gt; 12-week coding bootcamp teaching web development using our resources&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href="https://playfulprogramming.com/posts/playful-programming-non-profit/" rel="noopener noreferrer"&gt;Became a California non-profit&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;That last item is one I'm particularly proud of. It continually reminds (and enforces) our goals to keep our content accessible and driven towards the community; not towards profits.&lt;/p&gt;

&lt;h2&gt;
  
  
  Details about the merger
&lt;/h2&gt;

&lt;p&gt;As both organizations have scaled, we've faced different challenges:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;For TiL, they've remained focused on the content. This has meant that they have a strong repertoire of content, but have focused less on other avenues of growth.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Contrarily, PFP has developed a powerful brand, a "uniquely ours" website, and a larger community in our Discord. We're proud of what we've put out, but it does mean that our content catalog is comparatively weak.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After some discussion between Lars, Santosh, and myself, we realized that we'd be able to grow a substantially healthier community with a joint effort.&lt;/p&gt;

&lt;p&gt;As such, &lt;strong&gt;we will be doing the following&lt;/strong&gt; going forward:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Retain Playful Programming's name, branding, and structure&lt;/li&gt;
&lt;li&gt;Keeping our board of directors as-is&lt;/li&gt;
&lt;li&gt;Rename This is Learning's Dev.to blog to "Playful Programming" and their Angular specific blog to "Playful Programming Angular"&lt;/li&gt;
&lt;li&gt;Continuing to run the "This is Tech Talks" podcast under Playful Programming&lt;/li&gt;
&lt;li&gt;Reposting authors of This is Learning's existing content to opt-into reposting their content to the Playful Programming website&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Again, it's that last point that we've spent a considerable amount of time enabling. Twenty TiL authors agreed for us to port hundreds of their posts to our site. This required us to develop many new features for our site, but has resulted in &lt;strong&gt;our site having 750+ articles present today!&lt;/strong&gt;&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A note for TiL contributors:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;While we've done our best to reach out to all existing contributors to TiL, we acknowledge that it's tough to keep up-to-date with every community we find ourselves in.&lt;/p&gt;

&lt;p&gt;As such, if you'd like to have your contents on our site or have feedback regarding this change, reach out to me on &lt;a href="https://crutchcorn.dev" rel="noopener noreferrer"&gt;any of my social media channels&lt;/a&gt; and I'll help migrate your content or address concerns you might have.&lt;/p&gt;

&lt;p&gt;Regardless of if you'd like your content reposted onto our site, your Dev.to content will remain fully in-tact and all links to existing content should redirect on Dev.to's site.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Our future
&lt;/h2&gt;

&lt;p&gt;But this isn't all we have planned! We also intend on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Migrating TiL's RxJS and NgRx courses into Playful Programming's collections feature&lt;/li&gt;
&lt;li&gt;Creating topic-specific pages to explore content of (like "This is Angular" provided for the broader "This is Learning" community)&lt;/li&gt;
&lt;li&gt;Building out integrations with social media feeds to automatically promote authors' works&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;With this influx of new content and authors, we want to improve the writing experience. One concern we've heard from authors is challenges with posting to Playful's site. Today, &lt;a href="https://github.com/playfulprogramming/playfulprogramming/blob/main/CONTRIBUTING.md" rel="noopener noreferrer"&gt;writing a post for our site includes making a pull request to our GitHub repo&lt;/a&gt;. While we've tried to reduce friction with that process as much as we can, we know that writing for Dev.to using a GUI is much easier to navigate.&lt;/p&gt;

&lt;p&gt;As such, we're working incredibly hard on building out a custom CMS for our site. Here's a small mockup preview of such:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8kw7vtld9u3cd33i9clz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8kw7vtld9u3cd33i9clz.png" alt="A mockup of a post creation screen with fake images and tags" width="800" height="655"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why build out a custom CMS?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;While there's &lt;a href="https://github.com/playfulprogramming/playfulprogramming/pull/1297" rel="noopener noreferrer"&gt;a long and well-researched answer to that question&lt;/a&gt;, the long-story short is that we haven't found a CMS that allows our content to be stored in a Git repository with the features we want to support in the long run.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why do you want to store content in Git?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The biggest reason for wanting to store authors' contents in Git is that it's a systemic answer to our goals of remaining maximally transparent. If our values are ever mismatched from authors', we want an easy way for authors to take their whole dataset with them without needing to access an account or API token.&lt;/p&gt;

&lt;p&gt;And while radical transparency is our primary motivator, creating our own CMS allows us to add features in the future like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cross-posting to Dev.to instantly&lt;/li&gt;
&lt;li&gt;Social media feed promotion of our authors' material&lt;/li&gt;
&lt;li&gt;Additional components that markdown doesn't provide out-of-the-box&lt;/li&gt;
&lt;li&gt;Revision history from the editor itself&lt;/li&gt;
&lt;li&gt;Multi-player editing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And much more.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Join us:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sound like a project you might want to help build? &lt;a href="https://playfulprogramming.com/join-us/" rel="noopener noreferrer"&gt;Come join us and help us build it out!&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Thank you
&lt;/h2&gt;

&lt;p&gt;Neither "This is Learning" nor "Playful Programming" would be where we are today without you; the readers.&lt;/p&gt;

&lt;p&gt;We're excited by our next chapter as we continue to serve the community with learning materials. There's still a great deal of work for us to accomplish, but we're driven by the northern star of those that we're able to serve.&lt;/p&gt;

&lt;p&gt;We appreciate your continued support and hope to see you in our community.&lt;/p&gt;

&lt;p&gt;Until next time,&lt;/p&gt;

&lt;p&gt;- Corbin Crutchley, Executive Director of Playful Programming  &lt;/p&gt;

</description>
      <category>community</category>
      <category>opensource</category>
      <category>news</category>
    </item>
    <item>
      <title>Challenges in writing a programming book</title>
      <dc:creator>Corbin Crutchley</dc:creator>
      <pubDate>Mon, 29 Jul 2024 15:00:00 +0000</pubDate>
      <link>https://dev.to/playfulprogramming/challenges-in-writing-a-programming-book-4dh9</link>
      <guid>https://dev.to/playfulprogramming/challenges-in-writing-a-programming-book-4dh9</guid>
      <description>&lt;p&gt;Have you ever thought about writing a book about software engineering?&lt;/p&gt;

&lt;p&gt;I have. I thought about this idea of &lt;a href="https://framework.guide" rel="noopener noreferrer"&gt;a book that would teach you React, Angular, and Vue all at once&lt;/a&gt; for years and years.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://framework.guide" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyw3o3vj6rw93i28chuw7.png" alt="" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The idea started as a simple blog post series and, as I learned more about each respective framework, I realized that wouldn't cut it.&lt;/p&gt;

&lt;p&gt;Finally something cracked. I had been writing blog posts both professionally and not for a while. I had amassed 50 blog posts in my repertoire and thought "How hard could it be?"&lt;/p&gt;

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

&lt;p&gt;This started my journey to write &lt;a href="https://framework.guide" rel="noopener noreferrer"&gt;"The Framework Field Guide"&lt;/a&gt;, a trilogy of programming books that I'm making free for the general public. &lt;/p&gt;

&lt;p&gt;While I've only finished one of the books thus far, I want to share with you my learnings around this time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Writing a book is hard
&lt;/h2&gt;

&lt;p&gt;It took me a little over two years to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Start writing a book&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Realize it was getting too long, even in rough sketches of headings&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Re-organize existing content and outline enough rough content to fill a trilogy of books&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Develop a &lt;a href="https://framework.guide" rel="noopener noreferrer"&gt;high-performance custom-designed marketing site&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4sm309gugmkf2mxybzam.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4sm309gugmkf2mxybzam.png" alt="The landing page for my book series that has an illustration of a man hiking" width="800" height="784"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Redesign and rewrite &lt;a href="https://unicorn-utterances.com" rel="noopener noreferrer"&gt;an entire blogging platform&lt;/a&gt; to host the book's contents on&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F73t4n8l8sk441a44norb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F73t4n8l8sk441a44norb.png" alt="A landing page with many articles on it covered in programming stickers" width="800" height="573"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Write the first book&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;95K words&lt;/li&gt;
&lt;li&gt;16 chapters&lt;/li&gt;
&lt;/ul&gt;

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


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Create code samples &amp;amp; embeds for every code block in the book&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;25K lines of code&lt;/li&gt;
&lt;/ul&gt;

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


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Do grammar and spelling edits to the book's contents&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;All while maintaining my day job's duties of leading a software engineering team.&lt;/p&gt;

&lt;p&gt;What's more; book sales are rough. While I'm not charging for my content, I've regularly heard from other authors that writing content is challenging to break even with your time spent. Consider your salary, now consider how much time it'd take to do everything I just listed. Are you willing to take home (potentially) a lot less than you might by doing consulting?&lt;/p&gt;

&lt;p&gt;Moreover, how are you going to price things? Price too low (like I have) and people tend to devalue your work (even subconsciously). Price too high and your work is inaccessible to many.&lt;/p&gt;

&lt;p&gt;All-in-all, you have to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Be willing to write for yourself&lt;/li&gt;
&lt;li&gt;Stay resilient and know that the outcome will be immensely rewarding&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Developers glance, not read
&lt;/h2&gt;

&lt;p&gt;This article is going to lose a lot of readers. Why? Well, during my past five years writing for developers I've learned that the content that has the best engagement has:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A shorter in length&lt;/li&gt;
&lt;li&gt;Content broken up by images&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bolded&lt;/strong&gt; and &lt;em&gt;italicized&lt;/em&gt; formatting&lt;/li&gt;
&lt;li&gt;Lists to break up formatting even further&lt;/li&gt;
&lt;li&gt;The article filled with code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You generally want your article to more like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faxjykjxothtywmvhmz5z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faxjykjxothtywmvhmz5z.png" alt="A well formatted article that includes links, lists, images, and code embeds" width="800" height="1232"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And less like this:&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;Notice how boring this screenshot looks? Nobody's reading all of that. Break it up with formatting, images, emoji - anything to spice it up!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Keep your headings clearly named
&lt;/h2&gt;

&lt;p&gt;As I mentioned previously, most developers will only glance at your articles. If your headings aren't representative of what they'll be learning underneath them, they'll likely gloss over their content.&lt;/p&gt;

&lt;p&gt;It may be tempting to have fun headings like this:&lt;/p&gt;

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

&lt;p&gt;Try instead to be more explicit with what's being talked about:&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Code will be copy+pasted
&lt;/h2&gt;

&lt;p&gt;Assume your article or book includes JavaScript code that demonstrates some broken code like so:&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;const&lt;/span&gt; &lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This might be an obvious error to us, it might not be so clear for a newcomer developer.&lt;/p&gt;

&lt;p&gt;Instead of this code block on its own, try to annotate it using comments &lt;strong&gt;inside the code block itself&lt;/strong&gt;:&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;// This is broken code, remove the second `=` to fix it&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lean into copy+pasted code; it's how many developers will learn. Force them to tweak code themselves to see the results they want - it encourages learning and interactivity!&lt;/p&gt;

&lt;h2&gt;
  
  
  Developers seem to prefer video content
&lt;/h2&gt;

&lt;p&gt;You might ask yourself on your journey if a pre-recorded video content is worthwhile making. While editing can be lengthy and recording can be intimidating, the return on investment (ROI) for video content appears to be higher for developers in my experience.&lt;/p&gt;

&lt;p&gt;Compare and contrast a reasonably successful article of mine:&lt;/p&gt;

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

&lt;p&gt;To the meteoric rise of, say, &lt;a href="https://www.youtube.com/@t3dotgg/" rel="noopener noreferrer"&gt;Theo over on YouTube&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fawgrd9utnyqgfid9sip3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fawgrd9utnyqgfid9sip3.png" alt="A video by Theo has 158K views in 12 days" width="560" height="402"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For what it's worth, &lt;a href="https://dev.to/crutchcorn/advice-for-new-twitch-streamers-1lhg"&gt;I don't recommend investing very heavily in live-streaming on Twitch or YouTube. I've written about this before, but my 1K+ hours on the platform has yielded minimal ROI.&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Making content of any kind can be a grueling task. If you choose to write a book about software engineering, you can expect to pour hours and hours into the writing process.&lt;/p&gt;

&lt;p&gt;But if you pull it off, you'll have an improved resume, bragging rights, and have likely helped someone along the way learn valuable skills in their career.&lt;/p&gt;

&lt;p&gt;There's more to share, which I'll include in a future series, but that's all for now.&lt;/p&gt;

&lt;p&gt;And hey, if you wouldn't mind - I'd love you to take a look and share my book, "The Framework Field Guide":&lt;/p&gt;

&lt;p&gt;&lt;a href="https://fundamentals.framework.guide" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa616gtfex50wnvgqag91.png" alt="The Framework Field Guide cover" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's free and teaches multiple frameworks at once. Thanks a bunch!&lt;/p&gt;

</description>
      <category>writing</category>
      <category>programming</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Advice for New Twitch Streamers</title>
      <dc:creator>Corbin Crutchley</dc:creator>
      <pubDate>Tue, 23 Jul 2024 09:48:35 +0000</pubDate>
      <link>https://dev.to/crutchcorn/advice-for-new-twitch-streamers-1lhg</link>
      <guid>https://dev.to/crutchcorn/advice-for-new-twitch-streamers-1lhg</guid>
      <description>&lt;p&gt;You've spent hours in your favorite streamer's chat. You've gotten to see all the critical moments of their streams live, joined in on community jokes, and even memorized their emote names.&lt;/p&gt;

&lt;p&gt;One day, it hits you; If you're having this much fun in someone &lt;em&gt;else&lt;/em&gt;'s stream, maybe you should give Twitch streaming a shot.&lt;/p&gt;

&lt;p&gt;What do you need to know to get started? If only someone could give you advice on what you need to know to make the most of your streaming time.&lt;/p&gt;

&lt;p&gt;My name's Corbin and I go by &lt;a href="https://twitch.tv/crutchcorn/" rel="noopener noreferrer"&gt;&lt;code&gt;@crutchcorn&lt;/code&gt; on Twitch&lt;/a&gt;, and I've been there too. After over 1,000 hours of streaming, I've learned a few things that I wish I knew when I first started. Here are a few of the key takeaways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Streaming Strategy&lt;/li&gt;
&lt;li&gt;Essential Equipment&lt;/li&gt;
&lt;li&gt;Culminating Community&lt;/li&gt;
&lt;li&gt;Managing Moderation&lt;/li&gt;
&lt;li&gt;Generating Growth&lt;/li&gt;
&lt;li&gt;Branded Broadcasts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's go through these items one-by-one and create a solid strategy for our future streams.&lt;/p&gt;

&lt;h1&gt;
  
  
  Streaming Strategy
&lt;/h1&gt;

&lt;p&gt;Streaming is unlike any other content creation medium. Unlike blog posting, it's multi-faceted and has audio and video. Unlike a YouTube video, it's live. Unlike live TV, it's interactive.&lt;/p&gt;

&lt;p&gt;It's these differences that require a different approach to streaming than other content mediums. Here's a few things to keep in mind:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Be yourself; you're not at a job interview.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Livestreaming is meant to be more natural and personal than prerecorded videos or even a live presentation/talk. You can be a bit (or a lot, depending on your comfort level) more casual than you might otherwise. Similarly, verbal slip-ups and hiccups are 10000% expected, especially early on. Just like any other skill, you will improve. ✨&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Interact with chat! People watch live content in particular &lt;em&gt;because&lt;/em&gt; it's live.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;They want to hear your thoughts and opinions on things, they want to have a two-way conversation and have real-time interaction with a person/personality. Remember, most people watch a streamer for their personality - they can't see much of that personality if you're not interacting with your viewers.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Be honest with yourself and your chat - they will be understanding.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you're streaming programming content, but aren't yet a master at the language you're writing in - tell chat! It's okay to be a &lt;em&gt;bit&lt;/em&gt; vulnerable in that way. By being up front with your community, you're able to set the tone of supportiveness and kindness that you'll want to culminate as you grow. Similarly, if you're speed-running a game but aren't towards the top of the leaderboard, maybe show your P.B. on screen so your community can celebrate new P.Bs with you!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Set your boundaries with your community.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;While a &lt;em&gt;bit&lt;/em&gt; of vulnerability can go a long way to making a safe community, there will always be trolls. However, remember that you have the center stage, not chat; Utilize this to flow your community towards the tone/attitude you want to see in them. Don't want advice on the puzzle game you're playing - make "no back-seating" part of your channel rules and enforce them with your mods. Everyone will want to establish their communities differently - follow your goals.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Ask your friends to tune into early streams!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It's fun, gives you someone to chat with early on when you might otherwise have few/no other viewers, and encourages you to practice how to engage the broader community.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Essential Equipment
&lt;/h1&gt;

&lt;p&gt;While it's always fun to buy new toys for a new hobby, I have some guidance that pertains specifically to streaming:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Don't worry about gear early on.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You don't need a DSLR, green screen, or fancy audio equipment to make good content early on. Start with a cheap microphone, see if you enjoy it, then move on to better gear. If you &lt;em&gt;do&lt;/em&gt; want to get better gear, start with audio equipment; it tends to pay the best dividends and is a less messy world than live video quality improvements.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Don't force a facecam.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you enjoy having a facecam and think it adds production quality you yearn for, add it! But don't feel it's an obligation; you're able to get by perfectly fine without facecam. Even big content creators can go without (see also: &lt;a href="https://www.youtube.com/user/gamegrumps" rel="noopener noreferrer"&gt;GameGrumps&lt;/a&gt;, &lt;a href="https://www.youtube.com/channel/UCFNTq9XKHDNy_1-2lL0kqCg" rel="noopener noreferrer"&gt;Corpse Husband&lt;/a&gt;, and others). &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Create a unique and relevant set of branding.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Whether it be overlay customization, Twitch panel graphics, sound effects, emotes, or anything in between - make it yours and make it consistent. Starting out? Don't just use a default unmodified theme. Take a pre-made asset pack and hodgepodge it until it's unique to your brand. Growing and ready to level-up? Hire artists to make something expressly yours - there's hoards of talented creatives that want to work with you.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Avoid spending too much time on your branding.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;While we just touched on how unique branding can be a boon to your channel, it can also be a massive time sink. While meta-stream customization (updating your overlay while live) can be loads of fun, they don't tend to have good viewer retension. &lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;In particular, if you're a programmer I generally advise not working on your own overlay unless you have &lt;strong&gt;really&lt;/strong&gt; cool and unique integration ideas. Even if you do, see if they can't be accomplished with &lt;a href="https://streamelements.com/" rel="noopener noreferrer"&gt;StreamElements&lt;/a&gt; or custom OBS plugins instead of hand-rolling your own systems from scratch.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Culminating Community
&lt;/h1&gt;

&lt;p&gt;When streaming on Twitch, you're likely to run into unfamiliar terminology that is helpful to know when on the platform. Here are just a few:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Raids&lt;/strong&gt;: When someone is done with their stream, they can keep the party train going onto someone else's stream.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They're able to "raid" another channel and move all of their live viewers to another channel. They can be as small as 1 viewer to a huge stream with dozens, or even hundreds of viewers.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Bits&lt;/strong&gt;: A small-sized donation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bits are a way to donate to a streamer. Usually, 1 bit is ~$0.10 USD. They can be redeemed to send a highlighted message that your overlay can do special things with (if configured).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Subscriptions&lt;/strong&gt;: A larger donation with more rewards.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A subscription (or "sub") is a way for someone to donate to your channel every month. There are three different types of subs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Tier 1: ~$5 USD&lt;/em&gt; - Unlock the first set of streamer-specific emotes&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Tier 2: ~$10 USD&lt;/em&gt; - Unlock the second set of streamer-specific emotes&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Tier 3: ~$15 USD&lt;/em&gt; - Unlock the third set of streamer-specific emotes&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Keep in mind, while you can be raided before becoming an affiliate - you can only get donations through bits and subs by becoming &lt;a href="https://help.twitch.tv/s/article/joining-the-affiliate-program?language=en_US" rel="noopener noreferrer"&gt;an official affiliate of Twitch. You become an affiliate by reaching certain viewership goals.&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;Similarly, there are a few global Twitch Emotes that you may want to know ahead of time:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Emote&lt;/th&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwc6z7g2t8d0zxkq0q8pz.png" alt="A snake with its mouth wide open looking excited" width="112" height="112"&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PogChamp&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;OMG I can't believe you've managed to pull that off! (Chat is excited)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgybxv5y95x6p1ptczpzp.png" alt="A man laughing with his hand to his chin" width="112" height="112"&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;LUL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A laughing face to express just how funny that "Why did the chicken cross the road" joke was.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faf5s0dom8um3a6770s0m.png" alt="A smug looking face in black and white" width="128" height="128"&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Kappa&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;An emote meant to represent sarcasm or a joke of some kind.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo19x550663be04xuao0l.png" alt="A man with hands in his hair, distressed" width="112" height="112"&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;NotLikeThis&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;I can't believe this has happened. (Chat is jokingly upset by something going on)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs3bbnefjncpqm57e0pv8.png" alt="A nervous looking girl waving hello" width="112" height="112"&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;HeyGuys&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A way to say "Hi" to chat for the first time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fejfiltmfv3jyp6bssh6d.png" alt="A man with his mouth open in an orgasmic way" width="128" height="128"&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Kreygasm&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;That feeling when you get a 360 no-scope (Chat found something satisfying)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fptervkmwr1i5b2uy68oe.png" alt="A face of disgust" width="112" height="112"&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;WutFace&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;What did you just say?! (Chat is confused or upset by what you said)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fly9b8abr88wooe41its0.png" alt="A hammer with a smiley face on it" width="112" height="112"&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;BOP&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A hammer to bonk you with for being silly. (or some other emotion...)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Famdmozavsyqai1l1sfr8.png" alt="A red face crying" width="128" height="128"&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;BibleThump&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The face says it all; what you said was sad.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6im6x0n4rbfenu8qrsz8.png" alt="Bob ross with his hand to his face like he's hearing a cool story" width="112" height="112"&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;CoolStoryBob&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Cool story, can you tell it again? (chat doesn't believe you)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;In case this isn't enough &lt;a href="https://www.twitch.tv/creatorcamp/en/paths/getting-started-on-twitch/emotes/" rel="noopener noreferrer"&gt;here are a few other emotes, introduced by Twitch themselves.&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Managing Moderation
&lt;/h1&gt;

&lt;p&gt;While streaming can be fun and relaxing at times, there are potential downsides as well. Just like any other platform, Twitch has its fair share of trolls that need to be cut from the stream when they engage.&lt;/p&gt;

&lt;p&gt;To help solve this, here's a few tips to follow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Establish a mod team of friends or frequent chatters that you can trust early on.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;They're not only a lifesaver for the instances where you need moderation, but also greatly help with your moral to keep streaming and can encourage chat to stay in the boundaries you've set, even in subtle ways.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Prepare for potential hate raids or follow-botting.&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While Twitch has gotten &lt;em&gt;better&lt;/em&gt; at filtering out these kinds of negative interactions, it never hurts to be familiar with what tools you have at your disposal ahead-of-time. Just to name a few, &lt;a href="https://safety.twitch.tv/s/article/Protect-your-channel-with-Shield-Mode?language=en_US" rel="noopener noreferrer"&gt;Twitch has its built in "Shield" functionality&lt;/a&gt;, but there are community efforts like &lt;a href="https://serycodes.carrd.co/" rel="noopener noreferrer"&gt;Sery_Bot&lt;/a&gt; as well.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Be on guard for your digital security.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Remember, there are bad actors all over the internet. While most links shared with you might be authentic, don't click on any unfamiliar links coming from your chat. This helps prevent hacking or phishing attempts.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Manage your on-stream privacy to avoid accidental self-doxing.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Doxing is when someone shares personal information about another person. However, there are times when you might accidentally dox &lt;em&gt;yourself&lt;/em&gt;. To prevent this, use a separate browser from your daily-driver so that you don't accidentally share DMs, location, or other information about yourself. Further, if you're streaming on Windows, make your non-streaming monitor your "primary" monitor, so that new windows, dialog boxes, and notifications don't automatically show on-screen accidentally.&lt;/p&gt;

&lt;h1&gt;
  
  
  Generating Growth
&lt;/h1&gt;

&lt;p&gt;While not top of mind for everyone, some streamers want to grow their streams to have as many viewers as possible. To help grow your brand, consider:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Schedule consistency is key.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Especially early on in your streams, keep a schedule that you follow &lt;em&gt;religiously&lt;/em&gt;. For example, you might try streaming on "Tuesdays and Thursdays at 4PM PST". This will help propel your audience's ability to keep up and catch your content regularly.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Stay on brand with your categories.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While a &lt;em&gt;bit&lt;/em&gt; of variety &lt;em&gt;can&lt;/em&gt; be good for some streamers, it's generally advised to stay away from multi-focusing your channel's categories. Variety streamers have a much more challenging time trying to garner their foothold. Not only is it harder to make connections in a niche (both with other streamers and viewers alike), but the recommendation algorithm seems to punish you harshly for jumping categories frequently.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Network with fellow streamers&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Like other parts of brand growth, networking is absolutely critical in streamer brand growth. I'd say that 30-40% of your time on Twitch should be as a viewer of other people in your niche. Get to know them; follow them on other social media and make friends. Raids grow the channel &lt;strong&gt;significantly&lt;/strong&gt; faster than organic growth.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Set your expectations realistically.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Becoming a Twitch affiliate is feasible within the first couple of months or first year of streaming, but becoming a Twitch Partner is &lt;strong&gt;exceedingly&lt;/strong&gt; challenging to reach. Especially if your niche is small like mine; in the programming category there are &lt;em&gt;maybe&lt;/em&gt; 20-30 partners in the entire category across all languages and regions. Even big brands with a specific investment in Twitch have a hard time breaking into partner.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Recognize the relevant metrics&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While followers are nice to have as a vanity metric, they seldomly represent the health of a channel. I know some partner channels with low thousand followers while some channels have over 10,000 followers and aren't even close to partner. &lt;em&gt;The most relevant metric to see a channel's size is average viewership.&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;"A body in motion stays in motion."&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're on an upswing of viewership, add gas to the fire by streaming more regularly/often immediately following. The Twitch recommendation algorithm is a fickle beast, but in my experience absolutely rewards those that are already doing well. Similarly, if you let your viewership drop for a short time, it may take some time growing it back to baseline.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Diversify your audience.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While having a primary audience on Twitch is great, Twitch's notification system may fail to inform your users when you go live. Furthermore, being able to culminate a community outside of Twitch allows your viewers to become more personable with you, which may keep their interest in the channel for longer. Try promoting a Discord or a personal Twitter account to help others stay up-to-date and keep the conversation going with you.&lt;/p&gt;

&lt;h1&gt;
  
  
  Branded Broadcasts
&lt;/h1&gt;

&lt;p&gt;While this guide has primarily been geared towards individuals looking to become Twitch streamers, I've also had some experience trying to break into the streaming world as a cooperate brand.&lt;/p&gt;

&lt;p&gt;Here are my learnings from this time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;I generally do not recommend streaming to &lt;em&gt;almost&lt;/em&gt; anyone looking to grow their corporate brand/audience.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The first ~600 hours of personal streaming were exceedingly tough to grow. Not only are you getting used to this awkward new environment, but you have very little traffic to your branded site or content and those that &lt;em&gt;do&lt;/em&gt; show up can be a bit dismissive of a brand in a personality-driven environment.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Streaming has among the lowest ROI of any content-creation adjacent activities I've ever done.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Keep in mind that streaming is a huge time investment where your first major hurdle is to grow an audience. From my experience, I found it easier to grow the company's ROI by blogging, attending meetups, or otherwise pre-recording video.&lt;/p&gt;

&lt;p&gt;If you get into streaming - I'd generally advice it be seen as an extremely long-term investment and/or an easy content generation method while multi-tasking and doing other things; don't make it your core KPI to grow on streaming platforms.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;While I could continue this guide for almost forever, this is a good stopping point for the guidance I'm hoping to provide for others looking to get into streaming.&lt;/p&gt;

&lt;p&gt;Hopefully this has been an insightful look into how Twitch streamers can grow and improve their own streams.&lt;/p&gt;

&lt;p&gt;Until next time, I hope your streaming career goes well!&lt;/p&gt;

</description>
      <category>devrel</category>
      <category>content</category>
      <category>beginners</category>
      <category>livestream</category>
    </item>
    <item>
      <title>How Binary and Hexadecimal Work: An introduction to non-decimal number systems</title>
      <dc:creator>Corbin Crutchley</dc:creator>
      <pubDate>Sat, 16 Mar 2024 15:00:00 +0000</pubDate>
      <link>https://dev.to/playfulprogramming/how-binary-and-hexadecimal-work-an-introduction-to-non-decimal-number-systems-145c</link>
      <guid>https://dev.to/playfulprogramming/how-binary-and-hexadecimal-work-an-introduction-to-non-decimal-number-systems-145c</guid>
      <description>&lt;p&gt;Computers, on a very low level, are built upon binary (ones and zeros). Think about that — all of the text you're reading on your screen started life as either a one or a zero in some form. That's incredible! How can it turn something so simple into a sprawling sheet of characters that you can read on your device? Let's find out together!&lt;/p&gt;

&lt;h1&gt;
  
  
  Decimal
&lt;/h1&gt;

&lt;p&gt;When you or I count, we typically use 10 numbers in some variation of combination to do so: &lt;code&gt;0&lt;/code&gt;, &lt;code&gt;1&lt;/code&gt;, &lt;code&gt;2&lt;/code&gt;, &lt;code&gt;3&lt;/code&gt;, &lt;code&gt;4&lt;/code&gt;, &lt;code&gt;5&lt;/code&gt;, &lt;code&gt;6&lt;/code&gt;, &lt;code&gt;7&lt;/code&gt;, &lt;code&gt;8&lt;/code&gt;, and &lt;code&gt;9&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;When you count to &lt;code&gt;10&lt;/code&gt;, you're really using a combination of &lt;code&gt;1&lt;/code&gt; and &lt;code&gt;0&lt;/code&gt; in order to construct a larger number that we cognizantly recognize. The number &lt;code&gt;10&lt;/code&gt; persists in our minds even when we have it written out; &lt;strong&gt;ten&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzjo5zfxvp6d1oiehjhng.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzjo5zfxvp6d1oiehjhng.png" alt="An image showcasing the symbols for decimal with one and zero highlighted to make up the number " width="239" height="212"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Knowing that we can separate the number from our thoughts allows us to further categorize the number, mentally breaking it down into smaller groupings. For example, the number &lt;code&gt;34&lt;/code&gt; can be broken down into three groups: the &lt;em&gt;ones&lt;/em&gt;, the &lt;em&gt;tens&lt;/em&gt;, and the &lt;em&gt;hundreds&lt;/em&gt;.&lt;/p&gt;

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

&lt;p&gt;For the number &lt;code&gt;34&lt;/code&gt;, we break it down into: &lt;code&gt;0&lt;/code&gt; &lt;em&gt;hundreds&lt;/em&gt;, &lt;code&gt;3&lt;/code&gt; &lt;em&gt;tens&lt;/em&gt;, and &lt;code&gt;4&lt;/code&gt; &lt;em&gt;ones&lt;/em&gt;. We can then multiply the higher number with the lower number (the column they're in) to get the numbers &lt;strong&gt;&lt;code&gt;30&lt;/code&gt;&lt;/strong&gt; (&lt;code&gt;3&lt;/code&gt; &lt;em&gt;tens&lt;/em&gt;) and &lt;strong&gt;&lt;code&gt;4&lt;/code&gt;&lt;/strong&gt; (&lt;code&gt;4&lt;/code&gt; &lt;em&gt;ones&lt;/em&gt;). Finally, we add them all together to make the number we all know and love: &lt;strong&gt;&lt;code&gt;34&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This breakdown showcases a limitation with having 10 symbols to represent numbers; with only a single column, the highest number we can represent is &lt;em&gt;&lt;code&gt;9&lt;/code&gt;&lt;/em&gt;.&lt;br&gt;
Remember that the number &lt;strong&gt;&lt;code&gt;10&lt;/code&gt;&lt;/strong&gt; is a combination of &lt;strong&gt;&lt;code&gt;1&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;0&lt;/code&gt;&lt;/strong&gt;? That's due to this limitation. Likewise - with two columns - the highest number we can represent is &lt;em&gt;&lt;code&gt;99&lt;/code&gt;&lt;/em&gt;.&lt;/p&gt;

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

&lt;h1&gt;
  
  
  Binary
&lt;/h1&gt;

&lt;p&gt;Now this may seem rather simplistic, but it's an important distinction to be made to understand binary. Our typical decimal numeral system is known as the &lt;em&gt;base 10&lt;/em&gt; system. &lt;strong&gt;It's called as such because there are 10 symbols used to construct all other numbers&lt;/strong&gt; (once again, that's: &lt;code&gt;0&lt;/code&gt;, &lt;code&gt;1&lt;/code&gt;, &lt;code&gt;2&lt;/code&gt;, &lt;code&gt;3&lt;/code&gt;, &lt;code&gt;4&lt;/code&gt;, &lt;code&gt;5&lt;/code&gt;, &lt;code&gt;6&lt;/code&gt;, &lt;code&gt;7&lt;/code&gt;, &lt;code&gt;8&lt;/code&gt;, and &lt;code&gt;9&lt;/code&gt;).&lt;br&gt;
Binary, on the other hand, is &lt;em&gt;base two&lt;/em&gt;. &lt;strong&gt;This means that there are only two symbols that exist in this numeral system.&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For the Latin enthusiasts, binary comes from "binarius" meaning "two together". &lt;em&gt;Deca&lt;/em&gt;, meaning 10, is where "decimal" comes from.&lt;br&gt;
Additionally, the term "radix" is sometimes used instead of "base" when describing numeral systems, especially in programming.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instead of using numbers, which can get very confusing very quickly while learning for the first time, let's use &lt;strong&gt;&lt;code&gt;X&lt;/code&gt;&lt;/strong&gt;'s and &lt;strong&gt;&lt;code&gt;O&lt;/code&gt;&lt;/strong&gt;'s as our two symbols for our first few examples. &lt;em&gt;An &lt;strong&gt;&lt;code&gt;X&lt;/code&gt;&lt;/strong&gt; represents if a number is present and that we should add it to the final sum; an &lt;strong&gt;&lt;code&gt;O&lt;/code&gt;&lt;/strong&gt; means that the number is not present and that we should not add it&lt;/em&gt;.&lt;br&gt;
Take the following example:&lt;/p&gt;

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

&lt;p&gt;In this example, both &lt;code&gt;1&lt;/code&gt; and &lt;code&gt;2&lt;/code&gt; are present, so we add them together to make &lt;strong&gt;&lt;code&gt;3&lt;/code&gt;&lt;/strong&gt;. You'll see that since we can only have a value present or not present — because we only have two symbols in binary — this conversion has fewer steps than using decimal. For example, if you only wanted the number two, you could simply mark the &lt;code&gt;1&lt;/code&gt; as "not present" using the &lt;strong&gt;&lt;code&gt;O&lt;/code&gt;&lt;/strong&gt;:&lt;/p&gt;

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

&lt;p&gt;You can even replace the two symbols with &lt;code&gt;1&lt;/code&gt; and &lt;code&gt;0&lt;/code&gt; to get the actual binary number of &lt;code&gt;10&lt;/code&gt; in order to represent &lt;code&gt;2&lt;/code&gt;:&lt;/p&gt;

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

&lt;p&gt;So, how does this play out when trying to represent the number &lt;strong&gt;&lt;code&gt;50&lt;/code&gt;&lt;/strong&gt; in binary?&lt;/p&gt;

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

&lt;p&gt;As you can see, we create columns that are powers of &lt;code&gt;2&lt;/code&gt; for similar reasons as using powers of &lt;code&gt;10&lt;/code&gt; in decimal; you can't represent &lt;code&gt;4&lt;/code&gt;, &lt;code&gt;8&lt;/code&gt;, &lt;code&gt;16&lt;/code&gt;, or &lt;code&gt;32&lt;/code&gt; without creating a new column otherwise.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Remember, in this system, a number can only be present or not; there is no &lt;em&gt;&lt;code&gt;2&lt;/code&gt;&lt;/em&gt;. This means that only the symbols &lt;code&gt;1&lt;/code&gt; and &lt;code&gt;0&lt;/code&gt; are present. Keeping this in mind, it then means that we can only have &lt;code&gt;11&lt;/code&gt; as the highest represented number without another column. &lt;strong&gt;&lt;code&gt;11&lt;/code&gt;&lt;/strong&gt; in binary is &lt;strong&gt;&lt;code&gt;3&lt;/code&gt;&lt;/strong&gt; in decimal. &lt;em&gt;This shows that with only 2 binary digits, only the decimal numbers that can be represented are: &lt;code&gt;0&lt;/code&gt;, &lt;code&gt;1&lt;/code&gt;, &lt;code&gt;2&lt;/code&gt;, and &lt;code&gt;3&lt;/code&gt;&lt;/em&gt;. As a result, we need to add a &lt;em&gt;&lt;code&gt;4&lt;/code&gt;&lt;/em&gt; column in order to represent that number in binary.&lt;/p&gt;

&lt;p&gt;Continuing on with this pattern: without an &lt;strong&gt;&lt;code&gt;8&lt;/code&gt;&lt;/strong&gt; column, you can only have a &lt;code&gt;4&lt;/code&gt;, &lt;code&gt;2&lt;/code&gt;, and &lt;code&gt;1&lt;/code&gt; which would yield a maximum value of &lt;strong&gt;&lt;code&gt;7&lt;/code&gt;&lt;/strong&gt;. It's important to note that these values are always one less than a power of 2.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Once each of these powers is laid out, we can start adding &lt;code&gt;1&lt;/code&gt;s where we have the minimum amount of each value. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is &lt;code&gt;64&lt;/code&gt; less than or equal to &lt;code&gt;50&lt;/code&gt;? No. That's a &lt;strong&gt;&lt;code&gt;0&lt;/code&gt;&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Is &lt;code&gt;32 &amp;lt;= 50&lt;/code&gt;? Yes, therefore that's a &lt;strong&gt;&lt;code&gt;1&lt;/code&gt;&lt;/strong&gt;.

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;50 - 32 = 18&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Moving down the list, is &lt;code&gt;16 &amp;lt;= 18&lt;/code&gt;? Yes, that's a &lt;strong&gt;&lt;code&gt;1&lt;/code&gt;&lt;/strong&gt;.
-&lt;code&gt;18 - 16 = 2&lt;/code&gt;
&lt;/li&gt;

&lt;li&gt;Is &lt;code&gt;8 &amp;lt;= 2&lt;/code&gt;? No, that's a &lt;strong&gt;&lt;code&gt;0&lt;/code&gt;&lt;/strong&gt;.&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;4 &amp;lt;= 2&lt;/code&gt;? No, that's a &lt;strong&gt;&lt;code&gt;0&lt;/code&gt;&lt;/strong&gt; as well.&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;2 &amp;lt;= 2&lt;/code&gt;? Yes, that's a &lt;strong&gt;&lt;code&gt;1&lt;/code&gt;&lt;/strong&gt;.

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;2 - 2 = 0&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Now that we're left with &lt;code&gt;0&lt;/code&gt;, we know that the rest of the digits will be &lt;code&gt;0&lt;/code&gt;.&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Add up all those numbers:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Column&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;64&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;0&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;32&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;1&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;16&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;1&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;8&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;0&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;4&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;0&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;1&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;0&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;And voilà, you have the binary representation of &lt;code&gt;50&lt;/code&gt;: &lt;strong&gt;&lt;code&gt;0110010&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Author's note:&lt;/p&gt;

&lt;p&gt;While there are plenty of ways to find the binary representation of a decimal number, this example uses a "greedy" algorithm. I find this algorithm to flow the best with learning the binary number system, but it's not the only way (or even the best way, oftentimes).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Hexadecimal
&lt;/h1&gt;

&lt;p&gt;Binary isn't the only non-decimal system. You're able to use any number as your base as long as you have enough symbols to represent the digits. Let's look at another example of a non-decimal system: &lt;em&gt;hexadecimal&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Hexadecimal is the base 16 number system.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Hexa&lt;/em&gt; means "six" in Latin, and &lt;em&gt;deca&lt;/em&gt; means "ten", so these are combined to form "sixteen".&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now you may wonder how you can count to 16 in a single column when we only use 10 symbols to represent numbers. The answer, to many developers, is to fill the remaining last 6 with other symbols: alphabetical letters.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;0&lt;/code&gt;, &lt;code&gt;1&lt;/code&gt;, &lt;code&gt;2&lt;/code&gt;, &lt;code&gt;3&lt;/code&gt;, &lt;code&gt;4&lt;/code&gt;, &lt;code&gt;5&lt;/code&gt;, &lt;code&gt;6&lt;/code&gt;, &lt;code&gt;7&lt;/code&gt;, &lt;code&gt;8&lt;/code&gt;, &lt;code&gt;9&lt;/code&gt;, &lt;code&gt;A&lt;/code&gt;, &lt;code&gt;B&lt;/code&gt;, &lt;code&gt;C&lt;/code&gt;, &lt;code&gt;D&lt;/code&gt;, &lt;code&gt;E&lt;/code&gt;, &lt;code&gt;F&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;These are the symbols that make up the hexadecimal numeral system for many developers. &lt;em&gt;&lt;code&gt;A&lt;/code&gt;&lt;/em&gt;, in this case, represents the number &lt;strong&gt;&lt;code&gt;10&lt;/code&gt;&lt;/strong&gt;; &lt;em&gt;&lt;code&gt;F&lt;/code&gt;&lt;/em&gt; represents the number &lt;strong&gt;&lt;code&gt;15&lt;/code&gt;&lt;/strong&gt;. In this numeral system, there are the &lt;em&gt;sixteens&lt;/em&gt;, the &lt;em&gt;two-hundred fifty sixes&lt;/em&gt; (gathered by multiplying 16 by itself — 16&lt;sup&gt;2&lt;/sup&gt;), and other powers of 16.&lt;/p&gt;

&lt;p&gt;Given this information, how would we represent the number &lt;strong&gt;&lt;code&gt;50&lt;/code&gt;&lt;/strong&gt;?&lt;/p&gt;

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

&lt;p&gt;Assuming we have a &lt;em&gt;ones&lt;/em&gt; column, a &lt;em&gt;sixteens&lt;/em&gt; column, and a &lt;em&gt;two-hundred fifty sixes&lt;/em&gt; column, we can calculate the number in a similar way to the binary example earlier:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is &lt;code&gt;256&lt;/code&gt; less than or equal to &lt;code&gt;50&lt;/code&gt;? No. That's a &lt;strong&gt;&lt;code&gt;0&lt;/code&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Is &lt;code&gt;16 &amp;lt;= 50&lt;/code&gt;? Yes. So we know it's &lt;em&gt;at least &lt;code&gt;1&lt;/code&gt;&lt;/em&gt;.

&lt;ul&gt;
&lt;li&gt;Now, how many times can you put &lt;code&gt;16&lt;/code&gt; in &lt;code&gt;50&lt;/code&gt;?

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;16 * 2 = 32&lt;/code&gt; and &lt;code&gt;32 &amp;lt;= 50&lt;/code&gt;, so it's &lt;em&gt;at least&lt;/em&gt; &lt;em&gt;&lt;code&gt;2&lt;/code&gt;&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;16 * 3 = 48&lt;/code&gt; and &lt;code&gt;48 &amp;lt;= 50&lt;/code&gt; so it's &lt;em&gt;at least&lt;/em&gt; &lt;em&gt;&lt;code&gt;3&lt;/code&gt;&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;16 * 4 = 64&lt;/code&gt;. However, &lt;code&gt;64 &amp;gt; 50&lt;/code&gt;, therefor the &lt;em&gt;sixteenth&lt;/em&gt; place cannot be &lt;em&gt;&lt;code&gt;4&lt;/code&gt;&lt;/em&gt;, therefore it must be &lt;strong&gt;&lt;code&gt;3&lt;/code&gt;&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Now that we know the most we can have in the &lt;em&gt;sixteenth&lt;/em&gt; place, we can subtract the sum (&lt;code&gt;48&lt;/code&gt;) from our result (&lt;code&gt;50&lt;/code&gt;).

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;50 - 48 = 2&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;Now onto the &lt;em&gt;ones&lt;/em&gt; place: how many &lt;em&gt;ones&lt;/em&gt; can fit into &lt;em&gt;&lt;code&gt;2&lt;/code&gt;&lt;/em&gt;?

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;1 * 1 = 1&lt;/code&gt; and &lt;code&gt;1 &amp;lt;= 2&lt;/code&gt;, so it's &lt;em&gt;at least&lt;/em&gt; &lt;em&gt;&lt;code&gt;1&lt;/code&gt;&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;1 * 2 = 2&lt;/code&gt; and &lt;code&gt;2 &amp;lt;= 2&lt;/code&gt; and because these numbers are equal, we know that there must be &lt;strong&gt;&lt;code&gt;2&lt;/code&gt;&lt;/strong&gt; &lt;em&gt;twos&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Now if we add up these numbers:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Column&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;256&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;0&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;16&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;3&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;2&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Why &lt;code&gt;256&lt;/code&gt;?
&lt;/h2&gt;

&lt;p&gt;While reading through this, you may wonder, "Where did the &lt;code&gt;256&lt;/code&gt; come from?". Let's take a step back to analyze this question.&lt;/p&gt;

&lt;p&gt;If you recall, we use these 15 symbols to represent digits in hexadecimal:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;0&lt;/code&gt;, &lt;code&gt;1&lt;/code&gt;, &lt;code&gt;2&lt;/code&gt;, &lt;code&gt;3&lt;/code&gt;, &lt;code&gt;4&lt;/code&gt;, &lt;code&gt;5&lt;/code&gt;, &lt;code&gt;6&lt;/code&gt;, &lt;code&gt;7&lt;/code&gt;, &lt;code&gt;8&lt;/code&gt;, &lt;code&gt;9&lt;/code&gt;, &lt;code&gt;A&lt;/code&gt;, &lt;code&gt;B&lt;/code&gt;, &lt;code&gt;C&lt;/code&gt;, &lt;code&gt;D&lt;/code&gt;, &lt;code&gt;E&lt;/code&gt;, &lt;code&gt;F&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Using just a single digit (or, phrased in another way: A single number column), the biggest number we can represent is &lt;code&gt;F&lt;/code&gt;, or &lt;code&gt;15&lt;/code&gt; in decimal.&lt;/p&gt;

&lt;p&gt;This is similar to how the biggest number we can represent with a single digit in decimal is &lt;code&gt;9&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In order to add a number larger than &lt;code&gt;15&lt;/code&gt; in the hexadecimal system, we need to add another digit/column. This column would represent the &lt;em&gt;sixteens&lt;/em&gt; place. Having &lt;code&gt;F&lt;/code&gt; in both this column and the &lt;em&gt;ones&lt;/em&gt; column, the highest number we can represent would be &lt;code&gt;FF&lt;/code&gt;, or &lt;code&gt;255&lt;/code&gt; in decimal. As a result, we need to add a &lt;em&gt;two-hundred-fifty-six&lt;/em&gt; column to represent any numbers higher.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For those that have experience in algebra, you'll notice that these are all powers of 16.&lt;/p&gt;

&lt;p&gt;Just as &lt;em&gt;&lt;code&gt;100&lt;/code&gt;&lt;/em&gt; is 10&lt;sup&gt;2&lt;/sup&gt; for the decimal system, &lt;code&gt;256&lt;/code&gt; is 16&lt;sup&gt;2&lt;/sup&gt;. We can follow this pattern to the next number in the hexadecimal column: &lt;code&gt;4096&lt;/code&gt;, which is 16&lt;sup&gt;3&lt;/sup&gt;. You can even apply it to &lt;code&gt;1&lt;/code&gt; which is 16&lt;sup&gt;0&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;Binary works in the same manner. The first 5 columns/digits of binary are: &lt;code&gt;1&lt;/code&gt;, &lt;code&gt;2&lt;/code&gt;, &lt;code&gt;4&lt;/code&gt;, &lt;code&gt;8&lt;/code&gt;, &lt;code&gt;16&lt;/code&gt;. These numbers align respectively to their binary exponents: 2&lt;sup&gt;0&lt;/sup&gt;, 2&lt;sup&gt;1&lt;/sup&gt;, 2&lt;sup&gt;2&lt;/sup&gt;, 2&lt;sup&gt;3&lt;/sup&gt;, 2&lt;sup&gt;4&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;It's also worth noting that decimal numbers can be written out the same way. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;code&gt;732&lt;/code&gt;&lt;/em&gt; for example, in base 10, can be written as (7 × 10&lt;sup&gt;2&lt;/sup&gt;) + (3 × 10&lt;sup&gt;1&lt;/sup&gt;) + (2 × 10&lt;sup&gt;0&lt;/sup&gt;).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  To Binary
&lt;/h2&gt;

&lt;p&gt;Remember that at the end of the day, hexadecimal is just another way to represent a value using a specific set of symbols. Just as we're able to convert from binary to decimal, we can convert from hexadecimal to binary and vice versa. &lt;br&gt;
In binary, the set of symbols is much smaller than in hexadecimal, and as a result, the symbolic representation is longer.&lt;/p&gt;

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

&lt;p&gt;After all, they're just reflections of the numbers that we represent using a specific set of symbols. In binary, those symbols are more restrictive than in hexadecimal, and therefore the symbolic representation is longer.&lt;/p&gt;

&lt;h1&gt;
  
  
  Applications
&lt;/h1&gt;

&lt;h2&gt;
  
  
  CSS Colors
&lt;/h2&gt;

&lt;p&gt;Funnily enough, if you've used a "hex" value in HTML and CSS, you may already be loosely familiar with a similar scenario to what we walked through with the hexadecimal section.&lt;/p&gt;

&lt;p&gt;For example, take the color &lt;code&gt;#F33BC6&lt;/code&gt; (a pinkish color). This color is a combination of &lt;code&gt;3&lt;/code&gt; two-column hexadecimal numbers back-to-back. These numbers are:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;F3&lt;/code&gt;, &lt;code&gt;3B&lt;/code&gt;, &lt;code&gt;C6&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;They reflect the amount of red, green, and blue (respectively) in that color.&lt;/em&gt; Because these numbers are two-digit hexadecimal numbers, &lt;em&gt;the highest a number can be to reflect one of these colors is &lt;code&gt;255&lt;/code&gt;&lt;/em&gt; (which is &lt;strong&gt;FF&lt;/strong&gt; in hexadecimal).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you're unfamiliar with how red, green, and blue can combine to make the colors we're familiar with (such as yellow, orange, purple, and much more), it might be worth taking a look at some of the color theory behind it. &lt;a href="https://en.wikipedia.org/wiki/RGB_color_model" rel="noopener noreferrer"&gt;You can find resources on the topic on Wikipedia&lt;/a&gt; and elsewhere.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;These numbers, in decimal, are as follows:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Hex&lt;/th&gt;
&lt;th&gt;Decimal&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;F3&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;243&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;3B&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;59&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;C6&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;196&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;And construct the amount of &lt;code&gt;Red&lt;/code&gt;, &lt;code&gt;Green&lt;/code&gt;, and &lt;code&gt;Blue&lt;/code&gt; used to construct that color&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Represents&lt;/th&gt;
&lt;th&gt;Hex&lt;/th&gt;
&lt;th&gt;Decimal&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Red&lt;/td&gt;
&lt;td&gt;&lt;code&gt;F3&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;243&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Green&lt;/td&gt;
&lt;td&gt;&lt;code&gt;3B&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;59&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Blue&lt;/td&gt;
&lt;td&gt;&lt;code&gt;C6&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;196&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Even without seeing a visual representation, you can tell that this color likely has a purple hue - since it has a high percentage of red and blue.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftnf6ttnfz3c7aizmy6ou.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftnf6ttnfz3c7aizmy6ou.png" alt="A visual representation of the color above, including a color slider to show where it falls in the ROYGBIV spectrum" width="736" height="458"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Text Encoding
&lt;/h2&gt;

&lt;p&gt;Although hexadecimal has a much more immediately noticeable application with colors, we started this post off with a question: "How does your computer know what letters to display on the screen from only binary?"&lt;/p&gt;

&lt;p&gt;The answer to that question is quite complex, but let's answer it in a very simple manner (despite missing a lot of puzzle pieces in a very &lt;a href="https://knowyourmeme.com/memes/how-to-draw-an-owl" rel="noopener noreferrer"&gt;"draw the owl"&lt;/a&gt; kind of way).&lt;/p&gt;

&lt;p&gt;Let's take a real way that computers used to (and still do, to some extent) represent letters internally: &lt;a href="https://en.wikipedia.org/wiki/ASCII" rel="noopener noreferrer"&gt;ASCII&lt;/a&gt;. ASCII is an older standard for representing each textual character as a different number inside your computer. Take the following (simplified) chart:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fenpg3pu1yppns8hx4wi9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fenpg3pu1yppns8hx4wi9.png" alt="An ASCII chart that maps the numbers 64 which is capital A through to 90 which is capital Z and 97 which is lowercase a to 122 which is capital z" width="800" height="564"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When the user types &lt;em&gt;"This"&lt;/em&gt;, what the computer interprets (using ASCII) is &lt;code&gt;84&lt;/code&gt;, &lt;code&gt;104&lt;/code&gt;, &lt;code&gt;105&lt;/code&gt;, and &lt;code&gt;115&lt;/code&gt; for &lt;code&gt;T&lt;/code&gt;, &lt;code&gt;h&lt;/code&gt;, &lt;code&gt;i&lt;/code&gt;, and &lt;code&gt;s&lt;/code&gt;, respectively.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You might be wondering, "Why are there a bunch of missing numbers"?&lt;/p&gt;

&lt;p&gt;I've removed them to keep the examples simple, but many of them are for symbols (EG: &lt;code&gt;#&lt;/code&gt;, &lt;code&gt;/&lt;/code&gt;, and more), and some of them are for internal key commands that were used for terminal computing long ago that your computer now does without you noticing.&lt;/p&gt;

&lt;p&gt;It's also worth mentioning that ASCII (which does have more characters than what's presented here) was eventually replaced in various applications by &lt;a href="https://en.wikipedia.org/wiki/Unicode" rel="noopener noreferrer"&gt;Unicode&lt;/a&gt; and other text encoding formats as it lacks various functionality we expect of our machines today, such as emoji and non-latin symbols (like Kanji). ASCII still sticks around to some extent though, as the first 255 characters in Unicode are the same as they originally were in ASCII.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;While I've used the above chart to reflect &lt;em&gt;A&lt;/em&gt; as &lt;code&gt;65&lt;/code&gt;, it'd be more accurate to say that your computer interprets the symbol as &lt;code&gt;01000001&lt;/code&gt; internally. This is again due to the fact that your computer must interpret every number and letter as binary.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;While this has been only a high-level overview of how your computer interprets these non-decimal numbers (and some of their applications), it can provide some basic insights to what your computer is doing every time you make a keystroke or see a color on screen. Under the hood, everything is binary, and now you understand the introduction to how to convert binary to numbers you and I may understand better: to decimal!&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>programming</category>
      <category>math</category>
      <category>learning</category>
    </item>
    <item>
      <title>TypeScript Intermediates - Type Generics</title>
      <dc:creator>Corbin Crutchley</dc:creator>
      <pubDate>Thu, 14 Mar 2024 15:00:00 +0000</pubDate>
      <link>https://dev.to/playfulprogramming/typescript-intermediates-type-generics-b84</link>
      <guid>https://dev.to/playfulprogramming/typescript-intermediates-type-generics-b84</guid>
      <description>&lt;p&gt;While working in various projects, you may come across a weird looking syntax in the codebase: &lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt;. No no, not JSX, we're of course talking about type generics. They'll appear next to function calls (&lt;code&gt;callFn&amp;lt;T&amp;gt;()&lt;/code&gt;), TypeScript types (&lt;code&gt;Array&amp;lt;any&amp;gt;&lt;/code&gt;), and more.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Type generics are a way to handle abstract types in your function.&lt;/em&gt; &lt;strong&gt;They act as a variable for types in that they contain information about the way your types will function.&lt;/strong&gt; They're very powerful in their own right, and their usage is not just restricted to TypeScript. You'll see many of these concepts applied under very similar terminologies in various languages. Enough on that, however. Let's dive into how to use them! 🏊‍&lt;/p&gt;

&lt;h1&gt;
  
  
  The Problem
&lt;/h1&gt;

&lt;p&gt;Type generics — on the highest level — &lt;em&gt;allow you to accept arbitrary data instead of strict typing, making it possible to broaden a type's scope&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;For example, what if you wanted to make a function that took an argument of &lt;code&gt;returnProp&lt;/code&gt; and returned the &lt;code&gt;returnProp&lt;/code&gt; value itself (&lt;a href="https://en.wikipedia.org/wiki/Identity_function" rel="noopener noreferrer"&gt;the formal name for a function like this is an &lt;strong&gt;identity function&lt;/strong&gt;&lt;/a&gt;)? Without type generics, providing a typing for a function like this could be difficult.&lt;/p&gt;

&lt;p&gt;Take the following implementation and consider its limitations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;returnProp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;returnProp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;returnProp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;returnProp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// ✅ This is fine&lt;/span&gt;
&lt;span class="nf"&gt;returnProp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// ❌ This would fail as `4` is not a string&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, we want to make sure that every possible input type is available for the prop type. Let's take a look at a few potential solutions, with their various pros and cons, and see if we can find a solution that fits the requirements for providing typing for a function like this.&lt;/p&gt;

&lt;h2&gt;
  
  
  Potential Solution 1: Unions
&lt;/h2&gt;

&lt;p&gt;One potential solution to this problem might be TypeScript unions. &lt;em&gt;Unions allow us to define an &lt;code&gt;or&lt;/code&gt; condition of sorts for our types&lt;/em&gt;. As we want to allow various types for inputs and outputs, perhaps that can help us here!&lt;/p&gt;

&lt;p&gt;Using this method, if we wanted to accept numbers, we could add that as a union:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;returnProp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;returnProp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;returnProp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;returnProp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// ✅ This is fine&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;shouldBeNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;returnProp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// ✅ This won't show errors now&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, unions have some limitations. You'll find that this doesn't give the example you might want:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ❌ This will yield an error&lt;/span&gt;
&lt;span class="c1"&gt;// &amp;gt; Operator '+' cannot be applied to types '4' and 'string | number'.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;shouldBeNumber&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The reason that the operation &lt;code&gt;shouldBeNumber + 4&lt;/code&gt; yields this error is because you've told TypeScript that &lt;code&gt;shouldBeNumber&lt;/code&gt; is either a number &lt;strong&gt;or&lt;/strong&gt; a string by making the output explicitly typed as a union. As a result, TypeScript is unable to do addition between a number and a string (which is one of the potential values) and therefore throws an error.&lt;/p&gt;

&lt;h3&gt;
  
  
  Potential Solutions Disclaimer
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Author's note:&lt;/p&gt;

&lt;p&gt;If you were using unions in your property definitions and left your return type blank, TypeScript would be able to infer what the return type should be just fine.&lt;/p&gt;

&lt;p&gt;That said, we're trying to build on concepts, so we're trying to provide some examples of where this might be used and what it does. There are also instances, such as type definition files, where this inference might not be available to an author of typings, as well as other limitations with this method that we'll see later.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Potential Solution 2: Function Overloading
&lt;/h2&gt;

&lt;p&gt;In order to get around the issues with explicitly returning a union, you &lt;em&gt;COULD&lt;/em&gt; utilize function overloading to provide the proper return typings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;returnProp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;returnProp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;returnProp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;returnProp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// While this seems repetitive, TS requires it.&lt;/span&gt;
&lt;span class="c1"&gt;// Otherwise, it will complain:&lt;/span&gt;
&lt;span class="c1"&gt;// This overload signature is not compatible with its implementation signature.&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;returnProp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;returnProp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;returnProp&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;That said, in addition to having some obnoxious duplicated type information, this method also has its limitations.&lt;/p&gt;

&lt;p&gt;For example, if we wanted to pass in an object of some kind (such as &lt;code&gt;{}&lt;/code&gt;, a simple empty object), it would be invalid:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;returnProp&lt;/span&gt;&lt;span class="p"&gt;({})&lt;/span&gt; &lt;span class="c1"&gt;// Argument of type '{}' is not assignable to parameter of type 'string'.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This may seem obvious from the typings, but &lt;em&gt;we ideally want &lt;code&gt;returnProp&lt;/code&gt; to accept ANY type because &lt;strong&gt;we aren't using any operations that require knowing the type&lt;/strong&gt;.&lt;/em&gt; (no addition or subtraction, requiring a number; no string concatenation that might restrict an object from being passed).&lt;/p&gt;

&lt;h2&gt;
  
  
  Potential Solution 3: Any
&lt;/h2&gt;

&lt;p&gt;Of course, we could use the &lt;code&gt;any&lt;/code&gt; type to force any input and return type. (Goodness knows I've had my fair share of typing frustrations that ended with a few &lt;code&gt;any&lt;/code&gt;s in my codebase!)&lt;/p&gt;

&lt;p&gt;Although this would allow any input type, we'd also be losing any type information between the input and output. As a result our types would be too loose on the return type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;returnSelf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;returnProp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;returnProp&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;returnedObject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;returnSelf&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;objProperty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt; &lt;span class="c1"&gt;// This now works! 🎉&lt;/span&gt;

&lt;span class="nx"&gt;returnedObject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// This will not return an error but should 🙁&lt;/span&gt;
&lt;span class="nx"&gt;returnedObject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;objProperty&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// This will also (correctly) not throw an error, but TS won't know it's a number ☹️&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  The Real Solution
&lt;/h1&gt;

&lt;p&gt;So what's the answer? How can we get preserved type data on both the input and the output??&lt;/p&gt;

&lt;p&gt;The solution is... Well, you've read the title I'm sure.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Type generics allow us to store loose type data in a &lt;strong&gt;type variable&lt;/strong&gt;&lt;/em&gt;. A type variable is &lt;em&gt;a unique kind of variable that's not exposed to JavaScript but is instead handled by TypeScript to provide expected typing data&lt;/em&gt;. For example, the above example could be rewritten as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;returnSelf&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;returnProp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;returnProp&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;In this example, we're defining a type variable &lt;code&gt;T&lt;/code&gt;, then telling TS that both the property and the return type should be the same type.&lt;/p&gt;

&lt;p&gt;This means that you can use the function like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;numberVar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;returnSelf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// T in this instance is `2`, so it's similar to writing `const numberVal: 2 = 2;`&lt;/span&gt;

&lt;span class="c1"&gt;// Likewise, this object is now returned as if it was just placed on the const&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;returnedObject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;returnSelf&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;objProperty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// This will fail, as expected&lt;/span&gt;
&lt;span class="nx"&gt;returnedObject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// This will exist, and TS will know it as a number&lt;/span&gt;
&lt;span class="nx"&gt;returnedObject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;objProperty&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Author's note:&lt;/p&gt;

&lt;p&gt;The type variable does not need to be called &lt;code&gt;T&lt;/code&gt;. In fact, while it seems to be commonplace for the community to use single-letter type variable names (often due to the length and complexity of the typings), there are many reasons why more explicit type names should be used.&lt;/p&gt;

&lt;p&gt;Remember, type variables are like other variables in that you need to maintain them and understand what they're doing in your code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Okay, but Why?
&lt;/h1&gt;

&lt;p&gt;Why might we want to do this? Returning an item as itself in an identity function is cool, but it's not very useful in its current state. That said, there &lt;strong&gt;are&lt;/strong&gt; many, many uses for generics in real-world codebases.&lt;/p&gt;

&lt;p&gt;For example, let's say that we had the following JavaScript code that we wanted to use as a logger:&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;const&lt;/span&gt; &lt;span class="nx"&gt;util&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;util&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Have the `writeFile` return a promise instead of having to use a callback&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;writeFileAsync&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;util&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;promisify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;writeFile&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Async functions allows us to use `await` on promises in the function body, try/catch them, and
 * will return their own promise wrapped around the `return` value
 */&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;logTheValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&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;jsonString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Attempt to write a new log file. If this fails, save the error to the `err` variable&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;writeFileAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`/logs/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;jsonString&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// Catch any errors and keep them as the `e` variable to assign to `err` later&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&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="na"&gt;loggedValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;jsonString&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;original&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="c1"&gt;// If there was no error, return `undefined` here&lt;/span&gt;
        &lt;span class="na"&gt;err&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;err&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;If we wanted to type the &lt;code&gt;logTheValue&lt;/code&gt; function, we'd want to make sure to use a type generic for the input parameter &lt;code&gt;item&lt;/code&gt;. By doing so, we could use that same generic for the return prop of &lt;code&gt;loggedValue&lt;/code&gt; to ensure they both have the same typing. To do this, we could do so inline:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Because this is an `async` function, we want to wrap the returned type value in a Promise&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;logTheValue&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ItemT&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ItemT&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;loggedValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;original&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ItemT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;err&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&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="c1"&gt;// ... Function body here&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alternatively, we could utilize another feature of generics — the ability to pass the type value of the generic manually — and make an interface with a generic and do so there:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;LogTheValueReturnType&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;originalT&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;loggedValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;original&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;originalT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;err&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Notice how we're even wrapping that interface in a built-in type with a generic argument for `Promise`!&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;logTheValue&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ItemT&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ItemT&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;LogTheValueReturnType&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ItemT&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ... Function body here&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With these few features, we're able to utilize much of the functionality of generics. &lt;/p&gt;

&lt;p&gt;However, I know I haven't answered what the &lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt; really is for. Well, much like type variables, there's also the ability to pass types as "type arguments" when generics are applied to a function.&lt;/p&gt;

&lt;p&gt;An example of this would be a syntax like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;logTheValue&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Non-Function Generics
&lt;/h1&gt;

&lt;p&gt;As you saw before with the &lt;code&gt;LogTheValueReturnType&lt;/code&gt; interface — functions aren't the only ones with generics. In addition to using them within functions and interfaces, you can also use them in classes. &lt;/p&gt;

&lt;p&gt;Classes with generics can be particularly helpful for data structures like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// DataType might want to be a base64 encoded string, a buffer, or an IntArray&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ImageType&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;DataType&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DataType&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DataType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleImageBuffer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ImageType&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Buffer&lt;/span&gt;&lt;span class="o"&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;Type generics in classes can be used as method argument and property types alike.&lt;/p&gt;

&lt;p&gt;There's also the ability to use generics within &lt;code&gt;type&lt;/code&gt; definitions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;ImageType&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;DataType&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DataType&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;ImageConvertMethods&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;DataType&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// This is the typing of a method. It will take a prop of the generic type and return the generic type&lt;/span&gt;
    &lt;span class="na"&gt;toPNG&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DataType&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;DataType&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;toJPG&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DataType&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;DataType&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ImageTypeWithConvertMethods&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;DataType&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ImageType&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;DataType&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;ImageConvertMethods&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;DataType&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Okay, but why-&lt;em&gt;er&lt;/em&gt;?
&lt;/h1&gt;

&lt;p&gt;My my, you don't seem to take my word for it when I tell you that type generics are useful. That's alright, I suppose; After all, doubt while learning can lead to some great questions! 😉&lt;/p&gt;

&lt;p&gt;Type generics enable us to do things like provide typings for &lt;strong&gt;polymorphic functions&lt;/strong&gt;. &lt;em&gt;Polymorphic functions are functions that can accept a myriad of different types and handle them differently.&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Polymorphic functions are not unique to TypeScript; the things learned here about polymorphic functions can be applied to other languages as well. They also provide some real-world insight into the usages of generics and when they could be used.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For example, let's take a look at the code for the &lt;code&gt;toPNG&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;toPNG&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DataType&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;DataType&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isBuffer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&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="nf"&gt;convertBufferToPNG&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&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;imgBuffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&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;pngBuffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;convertBufferToPNG&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;imgBuffer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;        
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pngBuffer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// base64 encoded string&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;imgBuffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getBufferFromBaseStr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&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;pngBuffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;convertBufferToPNG&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;imgBuffer&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;bufferToBase64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pngBuffer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;toPNG only accepts arrays, buffers, or strings&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even though this function accepts various data types, it handles them differently under the hood! Functions that have this type of "accept many, handle each slightly differently" behavior are called &lt;strong&gt;Polymorphic Functions&lt;/strong&gt;. They're particularly useful in utility libraries.&lt;/p&gt;

&lt;h1&gt;
  
  
  Restricting The Types
&lt;/h1&gt;

&lt;p&gt;Unfortunately, there's a problem with the above code: we don't know what type &lt;code&gt;DataType&lt;/code&gt; is. Why does that matter? Well, if it's not a string, a Buffer, or an Array-like, it will throw an error! That's certainly not behavior to run into at runtime.&lt;/p&gt;

&lt;p&gt;Let's fix that typing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;toPNG&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;DataType&lt;/span&gt; &lt;span class="nf"&gt;extends &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;Buffer&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="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DataType&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;DataType&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example &lt;em&gt;we're using the &lt;code&gt;extends&lt;/code&gt; keyword to enforce some level of type restriction in the otherwise broad definition of a type generic&lt;/em&gt;. We're using a TypeScript union to say that it can be any one of those types, and we're still able to set the value to the type variable &lt;code&gt;DataType&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Broaden Your Horizons
&lt;/h2&gt;

&lt;p&gt;We're also able to keep that type restriction broad within itself. Let's say we had a function that only cared if an object had a specific property on it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;TimestampReturn&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;isPast&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;isFuture&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&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;checkTimeStamp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;time&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&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="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;TimestampReturn&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;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="kd"&gt;let&lt;/span&gt; &lt;span class="na"&gt;returnVal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TimestampReturn&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;isPast&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;isFuture&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;obj&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;returnVal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isPast&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;returnVal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isFuture&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&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="nx"&gt;returnVal&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;In this case, we can rely on implicit type casting to ensure that we're able to pass &lt;code&gt;{time: new Date()}&lt;/code&gt; but not &lt;code&gt;{}&lt;/code&gt; as values for &lt;code&gt;obj&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;And that's all I have for generics! Their usages are far and wide, and now you're able to apply your knowledge in code! We're hoping to have more posts on TypeScript soon - both more introductory and advanced. &lt;/p&gt;

&lt;p&gt;Questions? Feedback? Sound off in the comments below; we'd love to hear from you!&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Introduction to TypeScript — What is TypeScript?</title>
      <dc:creator>Corbin Crutchley</dc:creator>
      <pubDate>Tue, 12 Mar 2024 10:10:03 +0000</pubDate>
      <link>https://dev.to/playfulprogramming/introduction-to-typescript-what-is-typescript-48j4</link>
      <guid>https://dev.to/playfulprogramming/introduction-to-typescript-what-is-typescript-48j4</guid>
      <description>&lt;p&gt;TypeScript's popularity cannot be understated. Either you likely know someone who works with it, you've heard of it, or possibly you've been using it. As the language continues to grow and evolve, it can be helpful to jump into the language and play with it. Other times, however, having a reference for what the language is, what the language is not, and how it can be helpful can be of great resource. We're hoping that this page can be a good starting point for that resource.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you're more of an auditory learner, there's also a podcast episode that was done on this exact subject matter with the author of this post.&lt;/p&gt;

&lt;p&gt;This podcast episode &lt;a href="https://www.thepolyglotdeveloper.com/2019/10/tpdp-e32-getting-familiar-typescript-development/" rel="noopener noreferrer"&gt;can be found on the Polyglot Developer Podcast's page&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  What is TypeScript?
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;TypeScript is a superset of JavaScript&lt;/strong&gt;, meaning that &lt;em&gt;all valid JavaScript is valid TypeScript, but not all TypeScript is valid JavaScript&lt;/em&gt;. Think of it as JavaScript plus some goodies. These goodies &lt;em&gt;allow developers to add type information to their code that is enforced during a TypeScript to JavaScript compilation step&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;These goodies are enabled by the TypeScript compiler, which takes your TypeScript source code and output JavaScript source code, capable of running in any JavaScript environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Doesn't JavaScript Have Types Already?
&lt;/h2&gt;

&lt;p&gt;While JavaScript &lt;em&gt;does&lt;/em&gt; have a loose understanding of types, they're not strictly enforced.&lt;/p&gt;

&lt;p&gt;Take the following example:&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;let&lt;/span&gt; &lt;span class="nx"&gt;numberHere&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;numberHere&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Test&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;newNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;numberHere&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, we're expecting &lt;code&gt;10 - 0&lt;/code&gt; but have accidentally thrown in a new line during a copy + paste session (this always happens to me) that changed the type from a number to a string. As a result of this errant line, instead of &lt;code&gt;newNumber&lt;/code&gt; being a number, it's now &lt;code&gt;NaN&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;While TypeScript does not restrict the ability to have &lt;code&gt;NaN&lt;/code&gt;s and errant copy-pastes (oh how I wish it did), it can make it more obvious that mistakes like this have been made by marking &lt;code&gt;numberHere&lt;/code&gt; as a number type explicitly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;numberHere&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// 🛑 Error will be thrown during compilation:&lt;/span&gt;
&lt;span class="c1"&gt;// Type '"Test"' is not assignable to type 'number'.&lt;/span&gt;
&lt;span class="nx"&gt;numberHere&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Test&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;newNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;numberHere&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This point is made even more complex when dealing with how both values are handled internally in JavaScript. Especially when talking about ES6 classes, &lt;em&gt;the type-strict nature of TypeScript types and the "types" that are understood in JavaScript are not the same&lt;/em&gt;. While &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes" rel="noopener noreferrer"&gt;ES6 classes are syntactical sugar on top of JavaScript's prototype system&lt;/a&gt; and there &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures" rel="noopener noreferrer"&gt;are only seven base-types&lt;/a&gt; (called &lt;em&gt;primitive types&lt;/em&gt;) in JavaScript that every other value is composed of, TypeScript has a much more robust type system.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Author's Note:&lt;br&gt;
While the above mention of &lt;em&gt;primitive types&lt;/em&gt; and &lt;em&gt;syntactical sugar&lt;/em&gt; are meant as a path for you to learn more, don't feel discouraged from learning more about TypeScript if you're unfamiliar with such concepts.&lt;/p&gt;

&lt;p&gt;We're going to try to go at a high-level, and while we may hint at deeper concepts or knowledge, know that we all learn at our own pace. It's more than okay to take your time feeling comfortable before diving into those topics.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Why TypeScript?
&lt;/h1&gt;

&lt;p&gt;You may be asking yourself: "Why use TypeScript if it doesn't change the runtime behavior of your code?" There can be a few reasons you may want to integrate TypeScript in your project, such as the following.&lt;/p&gt;

&lt;h2&gt;
  
  
  Type Safety
&lt;/h2&gt;

&lt;p&gt;As mentioned before, JavaScript may have rudimentary types, but TypeScript's are far more robust. This robustness is able to lend developers to force their code inputs and outputs to strictly enforce the limitations the developer places on them. Let's look at  take the following code for example:&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;addFive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&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="nx"&gt;input&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;addFive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;5&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reading through this code quickly, you might be able to spot the problem. Because we passed in a string, rather than a number, we get the result of &lt;code&gt;'55'&lt;/code&gt; rather than the (likely) expected result of &lt;code&gt;10&lt;/code&gt;. &lt;em&gt;This is the kind of unintentional code safety concern that TypeScript fixes&lt;/em&gt;. Using TypeScript, we are able to check the properties passed into &lt;code&gt;addFive&lt;/code&gt; during compile time in order to warn a developer about these mistakes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// test.ts&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;addFive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&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="nx"&gt;input&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;addFive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;5&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Will now output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;tsc test.ts
test.ts:5:9 - error TS2345: Argument of &lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="s1"&gt;'"5"'&lt;/span&gt; is not assignable to parameter of &lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="s1"&gt;'number'&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
5 addFive&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'5'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In a smaller codebase, such as the given example, it can be easy to miss how important type checking is. Detecting the error in this small length of code is often trivial; however, it can be much more difficult to do so in larger, more complex codebases or when utilizing code that might not be from your project, such as a library or framework. In these use cases, it can be much easier to identify an edge case where changing a function's parameters would break another part of the codebase. Likewise, being able to quickly identify implementation errors when using a library is a significant factor in identifying problems effectively.&lt;/p&gt;

&lt;h2&gt;
  
  
  Developer Quality of Life
&lt;/h2&gt;

&lt;p&gt;While it can be easy to forget in the abstract world of development, developers make the code that we interact with on a daily basis. These developers (yourself included) tend to like enjoying certain experiences while working on their code. TypeScript provides a myriad of such quality-of-life improvements.&lt;/p&gt;

&lt;p&gt;Let's go over some of the arguments in favor of TypeScript's developer quality of life improvements.&lt;/p&gt;

&lt;h3&gt;
  
  
  Improved Tooling Support
&lt;/h3&gt;

&lt;p&gt;Historically, having the ability to make assumptions about code in order to provide developer niceties (such as autocomplete code suggestions) in loosely typed languages such as JavaScript has been incredibly hard to do. As time has gone on, support for these types of actions has gotten better; but due to the nature of JavaScript's type system, there will likely always be limitations on how effectively this can be done. TypeScript's syntax, however, &lt;em&gt;can provide much of the type data about your source code needed for tools to be able to provide those niceties&lt;/em&gt; that are otherwise tricky for these tools to build. &lt;em&gt;The TypeScript team even provides a tool to communicate directly to these IDEs&lt;/em&gt; so that the work on implementing this syntax data consumption is much more trivial than they otherwise would be. &lt;em&gt;This is why &lt;a href="https://www.typescriptlang.org/docs/handbook/release-notes/overview.html" rel="noopener noreferrer"&gt;many changelogs for TypeScript releases&lt;/a&gt; mention changes to editors such as &lt;a href="https://code.visualstudio.com" rel="noopener noreferrer"&gt;Visual Studio Code&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  3rd Party Library Support
&lt;/h4&gt;

&lt;p&gt;Because of JavaScript's awesome engineering diversity, many widely used projects do not use TypeScript. However, &lt;em&gt;there are ways we can still utilize TypeScript's tooling capabilities without porting the code&lt;/em&gt;. If you have a good understanding of the given project's codebase and TypeScript, &lt;em&gt;you can write a definition file that sits separated from the rest of the codebase&lt;/em&gt;. These definition files allow you many of the same tooling abilities native TypeScript source code allows.&lt;/p&gt;

&lt;p&gt;An example of these typings might look something like this:&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;// index.js&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;aNumberToAString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;numProp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;numProp&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Only numbers are supported&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;numProp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// index.d.ts&lt;/span&gt;
&lt;span class="kr"&gt;declare&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;aNumberToAString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;numProp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Accept a number arg, return a string&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Community Hosting
&lt;/h5&gt;

&lt;p&gt;Additionally, because TypeScript has a well established and widely used install-base, &lt;strong&gt;there are already many different definition files in the wild for supporting non-TypeScript supporting projects&lt;/strong&gt;. One of the more extensive collections of these typings lives at the &lt;a href="https://github.com/DefinitelyTyped/DefinitelyTyped" rel="noopener noreferrer"&gt;DefinitelyTyped repository&lt;/a&gt;, which publishes the package's community typings under the package names &lt;code&gt;@types/your-package-name&lt;/code&gt; (where &lt;code&gt;your-package-name&lt;/code&gt; is the name of the project you're looking for typings of) that you can look for on your package manager.&lt;/p&gt;

&lt;h3&gt;
  
  
  Documented Types
&lt;/h3&gt;

&lt;p&gt;Another way TypeScript can help with the workflow while coding is in regard to gaining references to APIs and code.&lt;/p&gt;

&lt;p&gt;When working on projects with objects that contain many properties that are used variously across files and functions, it can be difficult to track down what properties and methods are available to you without having to refer to the documentation of that scope in your application. With types present in your code, you're often able to reference that type (&lt;em&gt;often with a "jump to declaration" shortcut feature that is present in many IDEs&lt;/em&gt;) to quickly refer to the properties and methods present on a given value or class.&lt;/p&gt;

&lt;h2&gt;
  
  
  Type Information
&lt;/h2&gt;

&lt;p&gt;However, developer quality of life changes and type safety aren't the only positive for utilizing TypeScript in your projects!&lt;/p&gt;

&lt;p&gt;Although it's a much more complex and highly experimental feature of TypeScript, &lt;em&gt;you are also able to use the typing data from your program to do other operations without explicitly duplicating the type data.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;What do I mean by this? Take the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;HandleUserInput&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inputProp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;functionToHandle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Function&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;string&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;What if you had a way to mutate or modify this function? What if this way of mutating this function allowed you the ability to see that the first parameter is a number, the second is a function, and the return type is a string? &lt;strong&gt;While this may not seem to have any immediate advantages, this meta-type info allows us to do powerful things.&lt;/strong&gt; It can be used in a situation where you might want to generate a JSON schema based on a class declaration in a TypeScript file or when using ORMs and mapping TypeScript types to the databases' native type. &lt;em&gt;By doing something like this with your ORM, you could preserve both the database typing and the TypeScript compile type within the same file so that you don't have to do duplicate checks against either.&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Author's note:&lt;br&gt;
An ORM is an "Object Relational Model". An ORM is a library that helps developers keep database schemas mapped in their code, often by having classes reflect the shape of their (typically) SQL server schema.&lt;/p&gt;

&lt;p&gt;As always, feel free to search more on them (the terms "JavaScript ORM" might help) and always know that not knowing a thing is always okay 🤗&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here's an example &lt;a href="https://typeorm.io/#/" rel="noopener noreferrer"&gt;from a library built to do just that&lt;/a&gt; that allows you to preserve the TypeScript type to save data in specified field types in your database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&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;Entity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;PrimaryGeneratedColumn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Column&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="s2"&gt;typeorm&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="nd"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;PrimaryGeneratedColumn&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nx"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nx"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&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;And this feature doesn't have an API dissimilar to standards-based APIs; &lt;a href="https://www.typescriptlang.org/docs/handbook/decorators.html#metadata" rel="noopener noreferrer"&gt;it's being built with and on top of features proposed for a future version of JavaScript (commonly referred to as ESNext).&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  What isn't TypeScript
&lt;/h1&gt;

&lt;p&gt;Now that we've covered a bit of what TypeScript &lt;em&gt;is&lt;/em&gt;, it might be a good idea to quickly synopsis what it &lt;em&gt;isn't&lt;/em&gt;. After all, to know what something is not is oftentimes just as powerful as knowing what something &lt;em&gt;is&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  It's Not the Tower You Think It Is
&lt;/h2&gt;

&lt;p&gt;One of the things TypeScript is not is a transpiler. What this means is that TypeScript (alone) &lt;em&gt;will not take TypeScript source code that contains syntax from newer JavaScript versions (ES6+) and output older versions of JavaScript (ES5) in order to improve browser compatibility (IE11)&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;For anyone who's used TypeScript, this may confuse you, as there are various flags and config options for the output version of JavaScript it compiles to. What's really happening under-the-hood is that TypeScript hands off your source code to Babel after it compiles down to JavaScript. &lt;a href="https://devblogs.microsoft.com/typescript/typescript-and-babel-7/" rel="noopener noreferrer"&gt;With Babel 7 this is even harder to notice&lt;/a&gt;, but be aware that any transpilation you expect to occur when using TypeScript may force you to use and understand Babel tools.&lt;/p&gt;

&lt;p&gt;However, this does mean that you can utilize the entire arsenal of Babel tooling to your disposal, &lt;a href="https://babeljs.io/docs/en/plugins/" rel="noopener noreferrer"&gt;such as Babel plugins&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Logic != Typings
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;TypeScript will not find all your typing errors on its own&lt;/em&gt;. This is because TypeScript is only as useful as your typings are. Let's look back at an earlier example:&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;addFive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&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="nx"&gt;input&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;5&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;If you keep &lt;code&gt;addFive&lt;/code&gt;'s &lt;code&gt;input&lt;/code&gt; parameter without an explicit type, it will try to do its best to detect the type based on the operations you run on the value. &lt;strong&gt;While these inferred types are often very useful, it often has difficulty doing so in an accurate manner&lt;/strong&gt;. &lt;em&gt;This is why manually assigning types is almost always preferred to leaving them as inferred&lt;/em&gt;. If it couldn't properly detect a type for the value in this example, it does nothing to prevent strings from being passed as the parameter value.&lt;/p&gt;

&lt;p&gt;Although examples like this are simple, strict typings can also become fairly complex to maintain maximum type strictness. See the &lt;a href="https://www.typescriptlang.org/docs/handbook/advanced-types.html" rel="noopener noreferrer"&gt;Advanced section of the official handbook&lt;/a&gt; for examples that illustrate this.&lt;br&gt;
&lt;strong&gt;Also, because typings do nothing to test against the logic of your program, they should not be seen as a replacement for testing, but rather a companion to them.&lt;/strong&gt; &lt;em&gt;With strict typings and proper testing, regressions can be severely limited and improve code quality of life.&lt;/em&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  Typing Mishaps Happen
&lt;/h5&gt;

&lt;p&gt;Remember, because typings are kept separately from the project's logic code, typings can be misleading, incomplete, or otherwise incorrect. While this can also happen with TypeScript logic code, it tends to be more actively mitigated as a project's ability to compile (and therefore distribute) relies on that typing information. This isn't to say that you should immediately mistrust typings, but this is simply a reminder that they too may have their flaws — just as any other part of a codebase.&lt;/p&gt;

&lt;h2&gt;
  
  
  Don't Forget To Document
&lt;/h2&gt;

&lt;p&gt;Just as typings shouldn't replace tests, typings should also not replace documentation or comments. Typings can help understand what inputs and outputs you're expecting, but just the same as with testing; &lt;em&gt;it doesn't explain what the logic does or provide context as to why the data types have specific properties&lt;/em&gt;, what the properties are used for, and so forth. Additionally, typings often do little to help explain how to contribute in the larger scale when talking about documentation. For example, in a large-scale application, there may be come complex data patterns or order-of-operations that are required to do a task. Typings alone will not effectively communicate these design principles that are integral to the usage of the code.&lt;/p&gt;

&lt;p&gt;Essentially, I just want to make sure to iterate that while there may be tools that can let you auto-document the properties and the property type from TypeScript annotations, hand-done documentation is still extremely important.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;And with that, we have a better understanding of what TypeScript is! I hope this has been informative and helpful for those that may be new to the language in particular. What'd you learn, let us know!&lt;/p&gt;

&lt;p&gt;Now that you're more familiar with TypeScript, maybe you'd like to play around with one of their more experienced functionality: &lt;a href="https://unicorn-utterances.com/posts/typescript-type-generics/" rel="noopener noreferrer"&gt;Type generics&lt;/a&gt;? We have a whole post around that concept as well, &lt;a href="https://unicorn-utterances.com/posts/typescript-type-generics/" rel="noopener noreferrer"&gt;you can find that here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thanks for reading! Leave any questions or feedback in the comments below.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>beginners</category>
      <category>programming</category>
      <category>webdev</category>
    </item>
    <item>
      <title>What is React's useFormState and useFormStatus?</title>
      <dc:creator>Corbin Crutchley</dc:creator>
      <pubDate>Mon, 04 Mar 2024 16:00:00 +0000</pubDate>
      <link>https://dev.to/playfulprogramming/what-is-reacts-useformstate-and-useformstatus-22fj</link>
      <guid>https://dev.to/playfulprogramming/what-is-reacts-useformstate-and-useformstatus-22fj</guid>
      <description>&lt;p&gt;Thus far in our article series, we've taken a look at how React handles reactivity, server rendering, and how to send data back and forth between our React-based server and our client.&lt;/p&gt;

&lt;p&gt;In particular, our last article outlined how we can send data from the server down to the client and back:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff6cem5zqs9ewyl22iw2h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff6cem5zqs9ewyl22iw2h.png" alt="The server passes down data via async server components and is passed back data via server actions" width="485" height="1275"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a great &lt;em&gt;almost&lt;/em&gt; bi-directional communication from &lt;a href="https://unicorn-utterances.com/posts/what-are-react-server-components" rel="noopener noreferrer"&gt;React Server Components&lt;/a&gt; and back.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why do you say "almost"? What's missing?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Well, once you send an action back to the server, how do you get a response back from the server? What happens if the server action needs to inform you of some status?&lt;/p&gt;

&lt;p&gt;Well, this is where &lt;code&gt;useFormStatus&lt;/code&gt; and &lt;code&gt;useFormState&lt;/code&gt; come into play:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fysod4o19an2ye6gcy0s9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fysod4o19an2ye6gcy0s9.png" alt="Async data sends info to the client, server actions send it back to the server, useFormState listens for returned data from the server action" width="668" height="1275"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  What is &lt;code&gt;useFormStatus&lt;/code&gt;?
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;useFormStatus&lt;/code&gt; allows developers to listen for state changes on their React Server Actions. IE: When a server action is pending or not.&lt;/p&gt;

&lt;p&gt;While &lt;code&gt;useFormStatus&lt;/code&gt; isn't directly a way to listen for changes from the server (instead it relies on the information on the client to show its metadata) it allows us to make a nicer user experience by showing a loading indicator while the server is taking its action.&lt;/p&gt;

&lt;p&gt;Let's start with a &lt;a href="https://unicorn-utterances.com/posts/what-are-react-server-actions#What-are-React-form-actions" rel="noopener noreferrer"&gt;client-side actions&lt;/a&gt; demo:&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;useFormStatus&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-dom&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Submit&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;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useFormStatus&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;button&lt;/span&gt; &lt;span class="na"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pending&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pending&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Sending...&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Send&lt;/span&gt;&lt;span class="dl"&gt;'&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;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="p"&gt;}&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="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;waitASecond&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&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;setTimeout&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;resolve&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;1000&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;form&lt;/span&gt; &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;waitASecond&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="nc"&gt;Submit&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;form&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;Here, we're using the &lt;code&gt;pending&lt;/code&gt; field on &lt;code&gt;useFormStatus&lt;/code&gt; to tell us when our form is being submitted.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A note about &lt;code&gt;useFormStatus&lt;/code&gt;:&lt;/strong&gt;&lt;br&gt;
You might be wondering why I've extracted the &lt;code&gt;Submit&lt;/code&gt; component into its own function. This is because &lt;code&gt;useFormStatus&lt;/code&gt; is a hook that implicitly gathers its state from the parent &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; element.&lt;/p&gt;

&lt;p&gt;If you were to use &lt;code&gt;useFormStatus&lt;/code&gt; inside of the &lt;code&gt;App&lt;/code&gt; component, it would not work as expected. This is because the &lt;code&gt;App&lt;/code&gt; component is not a child of the &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; element.&lt;/p&gt;

&lt;p&gt;For example, the following code would not work as expected:&lt;/p&gt;


&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// This code does not work, as `useFormStatus` is not a child of the &amp;lt;form&amp;gt; element&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="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;waitASecond&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&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;setTimeout&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;resolve&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;1000&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;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useFormStatus&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;form&lt;/span&gt; &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;waitASecond&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;button&lt;/span&gt; &lt;span class="na"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pending&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
       &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pending&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Sending...&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Send&lt;/span&gt;&lt;span class="dl"&gt;'&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;button&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;form&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;/blockquote&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;useFormStatus&lt;/code&gt; usage with server actions
&lt;/h2&gt;

&lt;p&gt;But of course it works with server actions as well. Let's adapt our todo list example from our last article:&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="c1"&gt;// page.jsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Todo&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="s2"&gt;./client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;addTodoToDatabase&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getTodos&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="s2"&gt;./todos&lt;/span&gt;&lt;span class="dl"&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="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Home&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;todos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getTodos&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;addTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;use server&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;todo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;todo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;addTodoToDatabase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;todo&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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Todo&lt;/span&gt; &lt;span class="na"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todos&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;addTodo&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;addTodo&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;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// client.jsx&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;use client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&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="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useFormStatus&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="s2"&gt;react-dom&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;TodoFormInner&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;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useFormStatus&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;&amp;gt;&lt;/span&gt;
            &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pending&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Adding todo...&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&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;input&lt;/span&gt; &lt;span class="na"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pending&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"todo"&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;button&lt;/span&gt; &lt;span class="na"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pending&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                Add Todo
            &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;&amp;lt;/&amp;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;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Todo&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;addTodo&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;addTodoAndRefresh&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="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formData&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;await&lt;/span&gt; &lt;span class="nf"&gt;addTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reload&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;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt; &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;addTodoAndRefresh&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="nc"&gt;TodoFormInner&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;form&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;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;todo&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;li&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&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;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
                &lt;span class="p"&gt;})&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;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&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;h1&gt;
  
  
  What is &lt;code&gt;useFormState&lt;/code&gt;?
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;useFormState&lt;/code&gt; allows us to get a response from a React Server Action and handle the results any way we might want to; including (but not limited to) displaying the contents of the response to the client.&lt;/p&gt;

&lt;p&gt;This is a simple example of what &lt;code&gt;useFormState&lt;/code&gt; looks like on client-side form actions:&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="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="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;sayHi&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&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;setTimeout&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;resolve&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;1000&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Value from the action&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="c1"&gt;// State will be updated when `sayHi` returns a value&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;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useFormState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sayHi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Initial value&lt;/span&gt;&lt;span class="dl"&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="c1"&gt;// Pass the action from `useFormState`&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt; &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;action&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;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;state&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;p&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;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Submit&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;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;form&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;We can even implement a simple counter by utilizing the previous state (or initial value if there is no previous state):&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;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;previousState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;formData&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="nx"&gt;previousState&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;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;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useFormState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;increment&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="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;form&lt;/span&gt; &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;action&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;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;state&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;p&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;button&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;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;form&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;blockquote&gt;
&lt;p&gt;This increment example comes from &lt;a href="https://react.dev/reference/react-dom/hooks/useFormState#useformstate" rel="noopener noreferrer"&gt;the React docs for the Hook&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;useFormState&lt;/code&gt; usage with server actions
&lt;/h2&gt;

&lt;p&gt;While &lt;code&gt;useFormState&lt;/code&gt; works on the client-side, it's the most useful in conjuncture with server actions.&lt;/p&gt;

&lt;p&gt;Let's add some form validation to our todo list application so that the user can't submit an empty field:&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="c1"&gt;// page.jsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Todo&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="s2"&gt;./client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;addTodoToDatabase&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getTodos&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="s2"&gt;./todos&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;redirect&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="s2"&gt;next/navigation&lt;/span&gt;&lt;span class="dl"&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="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Home&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;todos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getTodos&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;addTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;previousState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;use server&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;todo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;todo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Please enter a todo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;addTodoToDatabase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nf"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Todo&lt;/span&gt; &lt;span class="na"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todos&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;addTodo&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;addTodo&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;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// client.jsx&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;use client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useFormState&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="s2"&gt;react-dom&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Todo&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;addTodo&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;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useFormState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;addTodo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&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;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt; &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;state&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;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&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;input&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"todo"&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;button&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                    Add Todo
                &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;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;form&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;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;todo&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;li&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&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;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
                &lt;span class="p"&gt;})&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;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&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;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Don't forget the API changes:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Don't forget that &lt;code&gt;useFormState&lt;/code&gt; requires you to change your server action to include a new first argument for &lt;code&gt;previousState&lt;/code&gt;. Otherwise you'll get the following error:&lt;/p&gt;


&lt;pre class="highlight plaintext"&gt;&lt;code&gt; ⨯ app\page.jsx (10:24) @ get
 ⨯ TypeError: formData.get is not a function
&lt;/code&gt;&lt;/pre&gt;

&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;useFormState&lt;/code&gt; usage without client-side JavaScript
&lt;/h2&gt;

&lt;p&gt;Because &lt;code&gt;useFormState&lt;/code&gt; utilizes the &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; element's native &lt;code&gt;action&lt;/code&gt; attribute under-the-hood, it works even without JavaScript enabled.&lt;/p&gt;

&lt;p&gt;Assume you have the above sample code, but you have JavaScript disabled. When you click the submit button, the form will submit to the &lt;code&gt;action&lt;/code&gt; attribute, and the page will refresh with the new information for the user.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://unicorn-utterances.com/content/blog/what-is-use-form-state-and-status/nextjs-use-state-js-disabled.mp4" rel="noopener noreferrer"&gt;https://unicorn-utterances.com/content/blog/what-is-use-form-state-and-status/nextjs-use-state-js-disabled.mp4&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Keep in mind that any client-side React code will not run if JavaScript is disabled. This includes the &lt;code&gt;useEffect&lt;/code&gt; Hook among others.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  How to use &lt;code&gt;useFormState&lt;/code&gt; and &lt;code&gt;useFormStatus&lt;/code&gt; together
&lt;/h1&gt;

&lt;p&gt;You may have noticed that &lt;code&gt;useFormState&lt;/code&gt; doesn't provide us the same pending information that &lt;code&gt;useFormStatus&lt;/code&gt; does. Let's combine them for the ultimate user experience:&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="c1"&gt;// page.jsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Todo&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="s2"&gt;./client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;addTodoToDatabase&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getTodos&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="s2"&gt;./todos&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;redirect&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="s2"&gt;next/navigation&lt;/span&gt;&lt;span class="dl"&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="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Home&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;todos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getTodos&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;addTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;previousState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;use server&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;todo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;todo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Please enter a todo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;addTodoToDatabase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nf"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Todo&lt;/span&gt; &lt;span class="na"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todos&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;addTodo&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;addTodo&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;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// client.jsx&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;use client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useFormState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useFormStatus&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="s2"&gt;react-dom&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;TodoFormInner&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;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useFormStatus&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;&amp;gt;&lt;/span&gt;
            &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pending&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Adding todo...&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&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;input&lt;/span&gt; &lt;span class="na"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pending&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"todo"&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;button&lt;/span&gt; &lt;span class="na"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pending&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                Add Todo
            &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;&amp;lt;/&amp;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;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Todo&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;addTodo&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;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useFormState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;addTodo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&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;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt; &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;state&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;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TodoFormInner&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;form&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;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;todo&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;li&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&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;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
                &lt;span class="p"&gt;})&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;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&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;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;And with that, that's our article series! We've covered a lot of ground; everything from how React's most fundamental values like reactivity works to advanced bi-directional data flow from the server and back!&lt;/p&gt;

&lt;p&gt;Want to keep learning React from lil' ole' me? Well shucks; first thank you for reading!&lt;/p&gt;

&lt;p&gt;But I can oblige! &lt;a href="https://framework.guide" rel="noopener noreferrer"&gt;I've written a book called "The Framework Field Guide" that teaches React, Angular, and Vue all-at-once, in-depth, and for free&lt;/a&gt;. Check it out and let me know what you think.&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>programming</category>
    </item>
    <item>
      <title>What are React Server Actions?</title>
      <dc:creator>Corbin Crutchley</dc:creator>
      <pubDate>Sat, 02 Mar 2024 16:00:00 +0000</pubDate>
      <link>https://dev.to/playfulprogramming/what-are-react-server-actions-147o</link>
      <guid>https://dev.to/playfulprogramming/what-are-react-server-actions-147o</guid>
      <description>&lt;p&gt;In our last article, we talked about &lt;a href="https://unicorn-utterances.com/posts/what-is-react-suspense-and-async-rendering" rel="noopener noreferrer"&gt;React's &lt;code&gt;use&lt;/code&gt; hook and Async Server Components&lt;/a&gt;; both means to handle async operations to display in a render.&lt;/p&gt;

&lt;p&gt;In the conclusion of that article, I hinted that there was going to be more to the Server Components story. Well, sure enough there is in the form of React Server Actions.&lt;/p&gt;

&lt;p&gt;First though, let's talk about the client-side once again.&lt;/p&gt;

&lt;h1&gt;
  
  
  What are React &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; actions?
&lt;/h1&gt;

&lt;p&gt;Let's say that we're building a todo list application:&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="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="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRef&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setTodos&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;todoInput&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setTodoInput&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="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;addTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nf"&gt;setTodos&lt;/span&gt;&lt;span class="p"&gt;([...&lt;/span&gt;&lt;span class="nx"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;todoInput&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&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;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;todo&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;li&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&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;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
                &lt;span class="p"&gt;})&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;ul&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;form&lt;/span&gt; &lt;span class="na"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;addTodo&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;input&lt;/span&gt;
                    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"todo"&lt;/span&gt;
                    &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todoInput&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                    &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setTodoInput&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&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;button&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Add Todo&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;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&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 works, but notice how we're having to &lt;code&gt;preventDefault&lt;/code&gt; here. This is because we're sidestepping &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/submit_event" rel="noopener noreferrer"&gt;&lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt;'s native &lt;code&gt;submit&lt;/code&gt; event's behavior&lt;/a&gt;; &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/action" rel="noopener noreferrer"&gt;submitting a form using the &lt;code&gt;action&lt;/code&gt; property&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Luckily, the React core team has noticed this and introduced a means to passing a function in the &lt;code&gt;action&lt;/code&gt; property in our client-side React applications:&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="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="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRef&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setTodos&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="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;addTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formData&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;todo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;todo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nf"&gt;setTodos&lt;/span&gt;&lt;span class="p"&gt;([...&lt;/span&gt;&lt;span class="nx"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&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;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;todo&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;li&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&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;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
                &lt;span class="p"&gt;})&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;ul&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;form&lt;/span&gt; &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;addTodo&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;input&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"todo"&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;button&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Add Todo&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;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&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;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A note on API versioning:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This feature is only currently available in &lt;a href="https://react.dev/community/versioning-policy#canary-channel" rel="noopener noreferrer"&gt;React Canary releases&lt;/a&gt;. This won't work with the current stable release.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This allows us to write less code and focus less on default DOM behavior and shift our efforts to shipping code.&lt;/p&gt;

&lt;p&gt;Now that we've seen how &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; actions work on the client, let's move back to the server and look at React server actions:&lt;/p&gt;

&lt;h1&gt;
  
  
  What are React Server Actions?
&lt;/h1&gt;

&lt;p&gt;In short; React Server Actions are a way to call server-side code in React's client-side rendering. If asynchronous server components with &lt;code&gt;await&lt;/code&gt; in them allow you to pass server data to the client, server actions enable you to pass data back from the client to the server.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuz1nk602ry4kgvch8u3s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuz1nk602ry4kgvch8u3s.png" alt="The server passes down data via async server components and is passed back data via server actions" width="485" height="1275"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, to pass a function from a server component down to the client we must designate our functions we want to pass with a special boundary string.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is &lt;code&gt;"use server"&lt;/code&gt;?
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;"use server"&lt;/code&gt; is the boundary string in React server apps that allows us to mark a function as "ready to pass to the client".&lt;/p&gt;

&lt;p&gt;Let's take our previous todo list and migrate the state to the server. This way all of our friends can see our shopping list!&lt;/p&gt;

&lt;p&gt;We'll start by using &lt;a href="https://unicorn-utterances.com/posts/what-is-react-suspense-and-async-rendering#What-are-React-Async-Server-Components" rel="noopener noreferrer"&gt;async server components&lt;/a&gt; to pass our todo list in from the server's database:&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="c1"&gt;// Theoretical API from a database wrapper&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getTodos&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="s2"&gt;./todos&lt;/span&gt;&lt;span class="dl"&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="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Todo&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;todos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getTodos&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;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;todo&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;li&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&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;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
                &lt;span class="p"&gt;})&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;ul&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="err"&gt;!--&lt;/span&gt; &lt;span class="na"&gt;This&lt;/span&gt; &lt;span class="na"&gt;form&lt;/span&gt; &lt;span class="na"&gt;doesn&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="na"&gt;t&lt;/span&gt; &lt;span class="na"&gt;work&lt;/span&gt; &lt;span class="na"&gt;yet&lt;/span&gt; &lt;span class="err"&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;form&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;input&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"todo"&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;button&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Add Todo&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;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
    );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we have a way to pass data to the client, but not a way to get the user's input back. Let's fix that by passing a server action to the client and using &lt;code&gt;&amp;lt;form action={}/&amp;gt;&lt;/code&gt; to call this function for us:&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;addTodoToDatabase&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getTodos&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="s2"&gt;./todos&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;redirect&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="s2"&gt;next/navigation&lt;/span&gt;&lt;span class="dl"&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="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Todo&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;todos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getTodos&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;addTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;use server&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;todo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;todo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;addTodoToDatabase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// Refresh the page to see the new todo&lt;/span&gt;
        &lt;span class="nf"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&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="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;todo&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;li&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&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;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
                &lt;span class="p"&gt;})&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;ul&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;form&lt;/span&gt; &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;addTodo&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;input&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"todo"&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;button&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Add Todo&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;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&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;Now if we:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Type something in the &lt;code&gt;&amp;lt;input/&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Click "Add Todo"&lt;/li&gt;
&lt;li&gt;Wait a moment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We'll see the todo we typed show up for all of our users on the page.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Keep in mind, this is using REST APIs, so it won't auto-refresh the page for all users, just the user who added the todo.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Adding in client-side components
&lt;/h2&gt;

&lt;p&gt;Notice that we're only exclusively using a server-component in the example above. Because of this, we don't have any loading indicator for the time the server is adding our todo.&lt;/p&gt;

&lt;p&gt;Let's add a &lt;code&gt;useState&lt;/code&gt; in our client-component to solve this user experience problem:&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;Todo&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="s2"&gt;./client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;addTodoToDatabase&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getTodos&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="s2"&gt;./todos&lt;/span&gt;&lt;span class="dl"&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="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Home&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;todos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getTodos&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;addTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;use server&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;todo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;todo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;addTodoToDatabase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;todo&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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Todo&lt;/span&gt; &lt;span class="na"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todos&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;addTodo&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;addTodo&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;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// client.jsx&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;use client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&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;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="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Todo&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;addTodo&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;isLoading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setIsLoading&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="kc"&gt;false&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;addTodoAndRefresh&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="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formData&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;await&lt;/span&gt; &lt;span class="nf"&gt;addTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reload&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;&amp;gt;&lt;/span&gt;
            &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;isLoading&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Adding todo...&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&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;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;todo&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;li&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&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;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
                &lt;span class="p"&gt;})&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;ul&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;form&lt;/span&gt;
                &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;addTodoAndRefresh&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                &lt;span class="na"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&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="c1"&gt;// We're using onSubmit so that we don't have to wait for the server&lt;/span&gt;
                    &lt;span class="c1"&gt;// to get the request before we set isLoading to true&lt;/span&gt;
                    &lt;span class="nf"&gt;setIsLoading&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;}&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;input&lt;/span&gt; &lt;span class="na"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;isLoading&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"todo"&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;button&lt;/span&gt; &lt;span class="na"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;isLoading&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                    Add Todo
                &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;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&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;Instead of passing a server action from a server component, we could also mark a whole file as &lt;code&gt;"use server"&lt;/code&gt; and import it from there;&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="c1"&gt;// server-actions.js&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;use server&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;addTodoToDatabase&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="s2"&gt;./todos&lt;/span&gt;&lt;span class="dl"&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;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;addTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formData&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;todo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;todo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;addTodoToDatabase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;todo&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// client.jsx&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;use client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;addTodo&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="s2"&gt;./server-actions&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&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;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="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Todo&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;addTodo&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;isLoading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setIsLoading&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="kc"&gt;false&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;addTodoAndRefresh&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="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formData&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;await&lt;/span&gt; &lt;span class="nf"&gt;addTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reload&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="c1"&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;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Be careful what you export:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Don't mark your whole database API file as &lt;code&gt;"use server"&lt;/code&gt;, otherwise it makes it easier to accidentally cause a security issue by exposing functions you might not wanted to've done otherwise.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What happens if you don't mark a function with &lt;code&gt;"use server"&lt;/code&gt;?
&lt;/h2&gt;

&lt;p&gt;If you forget to mark your server action with the &lt;code&gt;"use server"&lt;/code&gt; string, like so;&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="c1"&gt;// Server component&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Todo&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="s2"&gt;./client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getTodos&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="s2"&gt;./todos&lt;/span&gt;&lt;span class="dl"&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="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Home&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;todos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getTodos&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;addTodo&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="c1"&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="nc"&gt;Todo&lt;/span&gt; &lt;span class="na"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todos&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;addTodo&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;addTodo&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;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You get the following error, reminding you to explicitly mark your function as being ready to pass to the client:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;⨯ Error: Functions cannot be passed directly to Client Components unless you explicitly expose it by marking it with "use server".
&amp;lt;... todos={[...]} addTodo={function}&amp;gt;
^^^^^^^^^^
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a safety feature so you don't end up enabling the client to call functions that aren't allowed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Are synchronous functions allows in React server actions?
&lt;/h2&gt;

&lt;p&gt;No. Only &lt;code&gt;async&lt;/code&gt; functions are allowed in server actions. If you forget to mark your action as &lt;code&gt;async&lt;/code&gt;;&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="c1"&gt;// Server component&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Todo&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="s2"&gt;./client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getTodos&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="s2"&gt;./todos&lt;/span&gt;&lt;span class="dl"&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="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Home&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;todos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getTodos&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;addTodo&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;use server&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Testing&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Todo&lt;/span&gt; &lt;span class="na"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todos&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;addTodo&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;addTodo&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;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll receive the following error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error:
  × Server actions must be async functions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Can you define server actions in a client component file?
&lt;/h2&gt;

&lt;p&gt;No. You cannot mix-and-match server action definitions within your client component files. If you do the following:&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;use client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Todo&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;todos&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;

  &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;addTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;use server&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&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;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* ... */&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;form&lt;/span&gt;
        &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;addTodo&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* ... */&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;form&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&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;You'll see an error that looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error:
  × It is not allowed to define inline "use server" annotated Server Actions in Client Components.
  │ To use Server Actions in a Client Component, you can either export them from a separate file with "use server" at the top, or pass them down through props from a Server Component.
  │
  │ Read more: https://nextjs.org/docs/app/api-reference/functions/server-actions#with-client-components
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Remember where to place your server actions:&lt;/strong&gt;&lt;br&gt;
Server actions can only be defined in a file with &lt;code&gt;"use server"&lt;/code&gt; at the top or passed in via a server component marked with &lt;code&gt;"use server"&lt;/code&gt; at the top of the function definition.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Why are React Server Actions significant?
&lt;/h1&gt;

&lt;p&gt;React Server Actions not only make it easier to call data from the server from the client, but they play an important role in providing your applications &lt;a href="https://developer.mozilla.org/en-US/docs/Glossary/Progressive_Enhancement" rel="noopener noreferrer"&gt;"progressive enhancement"&lt;/a&gt;; they enable your server actions to call a server's function even when the user has JavaScript disabled in their browser.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Keep in mind that while your server action will go through, any client-ran React code (IE &lt;code&gt;useEffect&lt;/code&gt;) will still fail to execute when JavaScript is disabled.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For example, assume you're building a payment form:&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;This payment card graphic comes from &lt;a href="https://ui.shadcn.com/examples/cards" rel="noopener noreferrer"&gt;&lt;code&gt;shadcn/ui&lt;/code&gt;'s examples&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You want this payment form to be bulletproof. Any user having to attempt a re-purchase will likely not return to your site; leading to lost sales.&lt;/p&gt;

&lt;p&gt;If your user doesn't have JavaScript enabled but you've implemented Server Actions; no problem. The user's purchase will still go through.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;But this seems a bit like an edge-case, doesn't it? After all, &lt;a href="https://webaim.org/projects/screenreadersurvey8/#javascript" rel="noopener noreferrer"&gt;according to a survey from WebAIM showed that 99.7% of users have JavaScript enabled&lt;/a&gt; and I can't imagine many folks that would intentionally turn it off.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;While that may be true for some use-cases, consider the following examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A user in a developing country where data is expensive, disabling JavaScript could save money.&lt;/li&gt;
&lt;li&gt;A user on a subway train with limited cellular network; able to download the HTML but failed the JavaScript bundle download.&lt;/li&gt;
&lt;li&gt;A user with haywire browser extensions that has disabled the JavaScript on your page due to interference; either due to a bug or adblock.&lt;/li&gt;
&lt;li&gt;A user that works at a business that has strict security requirements and limits the loading of JavaScript on their network.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of these are possible scenarios for your users. The more users you account for, the more money your organization can make.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;React Server Actions make for a wonderful way of intermingling server and client state. It's never been easier to write code for React applications that span between both the frontend and backend alike. Moreover, it's only going to get better with time.&lt;/p&gt;

&lt;p&gt;But there's one more thing I still want to cover about React Server Components left... Let's look at &lt;code&gt;useFormState&lt;/code&gt; and &lt;code&gt;useFormStatus&lt;/code&gt; next time!&lt;/p&gt;

&lt;p&gt;Until then, &lt;a href="https://discord.gg/FMcvc6T" rel="noopener noreferrer"&gt;drop by our Discord server&lt;/a&gt; and tell us what you think of React Server Actions - we'd love to hear your thoughts!&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>programming</category>
    </item>
    <item>
      <title>What is React Suspense and Async Rendering?</title>
      <dc:creator>Corbin Crutchley</dc:creator>
      <pubDate>Thu, 29 Feb 2024 16:00:00 +0000</pubDate>
      <link>https://dev.to/playfulprogramming/what-is-react-suspense-and-async-rendering-3dh5</link>
      <guid>https://dev.to/playfulprogramming/what-is-react-suspense-and-async-rendering-3dh5</guid>
      <description>&lt;p&gt;In our last article, I introduced React Server Components (RSC) as a primitive to enable more efficient server-side React usage.&lt;/p&gt;

&lt;p&gt;I also hinted in the conclusion of that article that due to the nature of RSCs we'd be able to add on to our knowledge and utilize data fetching.&lt;/p&gt;

&lt;p&gt;Let's talk about data fetching, first by putting server-side behavior to the side, then we'll reintroduce the server-APIs soon after.&lt;/p&gt;

&lt;p&gt;To do this, I want to introduce you to three new APIs: the &lt;code&gt;use&lt;/code&gt; Hook, the &lt;code&gt;&amp;lt;Suspense&amp;gt;&lt;/code&gt; component, and Async React Server Components.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is the React &lt;code&gt;use&lt;/code&gt; Hook?
&lt;/h1&gt;

&lt;p&gt;The React &lt;code&gt;use&lt;/code&gt; Hook enables you to load data asynchronously in your components where data fetching is mission-critical.&lt;/p&gt;

&lt;p&gt;Let's say that you're in a traditional &lt;a href="https://unicorn-utterances.com/posts/what-is-ssr-and-ssg#csr" rel="noopener noreferrer"&gt;client-side rendered&lt;/a&gt; app and want to fetch data from the server. If you're not using a library like &lt;a href="https://tanstack.com/query/latest" rel="noopener noreferrer"&gt;TanStack Query&lt;/a&gt; (which you should be), you might have something 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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setData&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="na"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Please use TanStack Query&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="nf"&gt;fetchUser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;serverData&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;setData&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;serverData&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;catch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;err&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;setData&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&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="p"&gt;[]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While this works and &lt;code&gt;useEffect&lt;/code&gt; &lt;em&gt;can&lt;/em&gt; be used this way, &lt;code&gt;useEffect&lt;/code&gt; is not a built-in mechanism for asynchronous data loading. &lt;/p&gt;

&lt;p&gt;Instead, React 18.3 (in canary release at the time of writing) introduces a new Hook: &lt;a href="https://react.dev/reference/react/use" rel="noopener noreferrer"&gt;&lt;code&gt;use&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This hook allows you to pass a promise to it to load data:&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;use&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cache&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="s2"&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;UserDisplay&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;fetchUser&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;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Hello &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&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;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Without `cache`, a new instance of a promise would&lt;/span&gt;
&lt;span class="c1"&gt;// be returned to `use` on every render. That's bad.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fetchUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;cache&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="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Here, we're using &lt;code&gt;use&lt;/code&gt; in tandem with &lt;a href="https://unicorn-utterances.com/posts/explaining-reacts-cache-function" rel="noopener noreferrer"&gt;React's &lt;code&gt;cache&lt;/code&gt; function to avoid having to run &lt;code&gt;useMemo&lt;/code&gt; on &lt;code&gt;fetchUser&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now React will treat the &lt;code&gt;result&lt;/code&gt; as if it were not a promise, so that you can access properties and render them directly inside of your JSX. Effectively &lt;code&gt;use&lt;/code&gt; acts as an &lt;code&gt;await&lt;/code&gt; for promises in your client components.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If your only objective is to load data on the client, I'd still highly suggest using &lt;a href="https://tanstack.com/query/latest" rel="noopener noreferrer"&gt;TanStack Query&lt;/a&gt; or something similar. After all, even with &lt;code&gt;use&lt;/code&gt; you likely want to take into consideration the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Caching results&lt;/li&gt;
&lt;li&gt;Refetching with new inputs&lt;/li&gt;
&lt;li&gt;Abort signals to avoid timing issues&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  What is the &lt;code&gt;&amp;lt;Suspense&amp;gt;&lt;/code&gt; component?
&lt;/h1&gt;

&lt;p&gt;The React &lt;code&gt;&amp;lt;Suspense&amp;gt;&lt;/code&gt; component allows you to add a loading state to your components needing to use asynchronous APIs; such as the new &lt;code&gt;use&lt;/code&gt; Hook.&lt;/p&gt;

&lt;p&gt;Take the &lt;code&gt;&amp;lt;UserDisplay&amp;gt;&lt;/code&gt; component from before. To add a loading indicator to the &lt;code&gt;&amp;lt;UserDisplay&amp;gt;&lt;/code&gt; component, add a &lt;code&gt;&amp;lt;Suspense&amp;gt;&lt;/code&gt; component in the parent component alongside a &lt;code&gt;fallback={}&lt;/code&gt; property:&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="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="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="nc"&gt;Suspense&lt;/span&gt; &lt;span class="na"&gt;fallback&lt;/span&gt;&lt;span class="p"&gt;=&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;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Loading...&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&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="nc"&gt;UserDisplay&lt;/span&gt; &lt;span class="na"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;promise&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="nc"&gt;Suspense&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;h2&gt;
  
  
  Reusing Loading Indicators
&lt;/h2&gt;

&lt;p&gt;Loading indicators may be important to show in-progress data fetching, but users don't often like seeing a dashboard with 30 different loading spinners. &lt;/p&gt;

&lt;p&gt;Because of this, React has made handling multiple data sources easy using &lt;code&gt;&amp;lt;Suspense&amp;gt;&lt;/code&gt;; just wrap multiple &lt;code&gt;use&lt;/code&gt; Hook components inside of a single &lt;code&gt;&amp;lt;Suspense&amp;gt;&lt;/code&gt; component:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;UserDisplay&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;timeout&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;fetchUser&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;timeout&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;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Hello &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&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;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&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="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="nc"&gt;Suspense&lt;/span&gt; &lt;span class="na"&gt;fallback&lt;/span&gt;&lt;span class="p"&gt;=&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;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Loading...&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&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="nc"&gt;UserDisplay&lt;/span&gt; &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1500&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="nc"&gt;UserDisplay&lt;/span&gt; &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;3000&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="nc"&gt;Suspense&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;span class="c1"&gt;// Pretend this is fetching data from the server&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fetchUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;timeout&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="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&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;setTimeout&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;resolve&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
                &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John Doe&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;34&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="nx"&gt;timeout&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="mi"&gt;1000&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;To sidestep this behavior, wrap each &lt;code&gt;&amp;lt;UserDisplay&amp;gt;&lt;/code&gt; in their own &lt;code&gt;&amp;lt;Suspense&amp;gt;&lt;/code&gt;:&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="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="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
            &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* Will show "Loading..." for 3 seconds while
                waiting for BOTH promises to resolve */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Suspense&lt;/span&gt; &lt;span class="na"&gt;fallback&lt;/span&gt;&lt;span class="p"&gt;=&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;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Loading...&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&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="nc"&gt;UserDisplay&lt;/span&gt; &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1500&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="nc"&gt;Suspense&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;Suspense&lt;/span&gt; &lt;span class="na"&gt;fallback&lt;/span&gt;&lt;span class="p"&gt;=&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;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Loading...&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&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="nc"&gt;UserDisplay&lt;/span&gt; &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;3000&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="nc"&gt;Suspense&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&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;h2&gt;
  
  
  How do I handle rejected promises in &lt;code&gt;&amp;lt;Suspense&amp;gt;&lt;/code&gt;?
&lt;/h2&gt;

&lt;p&gt;While &lt;code&gt;use&lt;/code&gt; and &lt;code&gt;&amp;lt;Suspense&amp;gt;&lt;/code&gt; handle resolved promises just fine, they alone will not handle rejected promises passed to the &lt;code&gt;use&lt;/code&gt; Hook.&lt;/p&gt;

&lt;p&gt;To handle rejected promises in Suspense, you'll need to use an &lt;code&gt;&amp;lt;ErrorBoundary&amp;gt;&lt;/code&gt; class-based component which utilizes the &lt;code&gt;getDerivedStateFromError&lt;/code&gt; lifecycle method. &lt;/p&gt;

&lt;p&gt;Let's see how we can do this ourselves:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;UserDisplay&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;fetchUser&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;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Hello &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&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;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&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="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="nc"&gt;ErrorBoundary&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;Suspense&lt;/span&gt; &lt;span class="na"&gt;fallback&lt;/span&gt;&lt;span class="p"&gt;=&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;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Loading...&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&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="nc"&gt;UserDisplay&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;Suspense&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;ErrorBoundary&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;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ErrorBoundary&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nf"&gt;getDerivedStateFromError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&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="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;There was an error: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&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;p&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;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;children&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;h1&gt;
  
  
  Using &lt;code&gt;use&lt;/code&gt; on the server
&lt;/h1&gt;

&lt;p&gt;Now let's move back to server-land&lt;/p&gt;

&lt;p&gt;We know that we can make server-only components, that don't reinitialize on the client, right? Now what if we could load the data on the server and not have it passed to the client either?&lt;/p&gt;

&lt;p&gt;Well, luckily for us - we already have a mechanism for loading data in React that's async:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ServerComp&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="cm"&gt;/* This works, but is not the best way of doing
       things on the server */&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;fetchData&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="nc"&gt;ChildComp&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;data&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;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Parent&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="cm"&gt;/* We don't need a Suspense component here, since
       the server will wait for the promise to resolve before
       sending data to the client */&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="nc"&gt;ServerComp&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we're seeing an imaginary &lt;code&gt;ChildComp&lt;/code&gt; rendered with data passed from the server - this data is never fetched on the client thanks to how &lt;a href="https://unicorn-utterances.com/posts/what-are-react-server-components" rel="noopener noreferrer"&gt;React Server Components&lt;/a&gt; work.&lt;/p&gt;

&lt;p&gt;But wait a moment - we're on the server. &lt;code&gt;use&lt;/code&gt; accepts any promise... What if... What if we just polled our database directly?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ServerComp&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="cm"&gt;/* This also works, but is still not the best way
        of doing things in server components */&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;fetchOurUserFromTheDatabase&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="nc"&gt;ChildComp&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;data&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;}&lt;/span&gt;

&lt;span class="c1"&gt;// Still using cache... For now...&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fetchOurUserFromTheDatabase&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;cache&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="c1"&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 works!&lt;/p&gt;

&lt;h1&gt;
  
  
  What are React Async Server Components?
&lt;/h1&gt;

&lt;p&gt;While &lt;code&gt;use&lt;/code&gt; is undoubtably useful for client apps, server components have a better option available to us: async components.&lt;/p&gt;

&lt;p&gt;Here, we mark our component as being &lt;code&gt;async&lt;/code&gt; and simply &lt;code&gt;await&lt;/code&gt; the promise function to resolve it prior to reaching our JSX:&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="c1"&gt;// No need for `cache`!&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;fetchOurUserFromTheDatabase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;UserDetails&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;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetchOurUserFromTheDatabase&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;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&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;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can then use it as if it were any other server component:&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;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;Home&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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;UserDetails&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Not only is the developer experience for this component authoring better, but it's drastically more performant due to how its internals work.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If that's the case why don't we use &lt;code&gt;async&lt;/code&gt; components on the client as well?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;According to the React team, &lt;a href="https://github.com/acdlite/rfcs/blob/first-class-promises/text/0000-first-class-support-for-promises.md#why-cant-client-components-be-async-functions" rel="noopener noreferrer"&gt;there are technical limitations around using async components on the client that make it infeasible to use on the client&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A note about async server components:&lt;/strong&gt;&lt;br&gt;
Something to keep in mind is that while normal React Server Components can use &lt;em&gt;some&lt;/em&gt; Hooks (&lt;code&gt;useId&lt;/code&gt;, &lt;code&gt;useSearchParams&lt;/code&gt;, etc) &lt;a href="https://github.com/acdlite/rfcs/blob/first-class-promises/text/0000-first-class-support-for-promises.md#async-server-components-cannot-contain-hooks" rel="noopener noreferrer"&gt;async server components cannot use &lt;strong&gt;any&lt;/strong&gt; hooks of any kind.&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;In this article, we took a look at React's official solutions for async rendering behavior. This is great to see the team make strides&lt;br&gt;
in this area; I think most apps are going to end up utilizing these heavily.&lt;/p&gt;

&lt;p&gt;However, this is only half of the story for React's async support. Next up, we'll talk about React Server Actions, which enables the client to&lt;br&gt;
make RPC-like calls back to the server and execute server code for us.&lt;/p&gt;

&lt;p&gt;Can't wait to talk about what you learned about? &lt;a href="https://discord.gg/FMcvc6T" rel="noopener noreferrer"&gt;Join our Discord and tell us what you think about the Suspense API&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>What are React Server Components (RSCs)?</title>
      <dc:creator>Corbin Crutchley</dc:creator>
      <pubDate>Tue, 27 Feb 2024 16:00:00 +0000</pubDate>
      <link>https://dev.to/playfulprogramming/what-are-react-server-components-rscs-1d8c</link>
      <guid>https://dev.to/playfulprogramming/what-are-react-server-components-rscs-1d8c</guid>
      <description>&lt;p&gt;&lt;a href="https://unicorn-utterances.com/posts/what-is-ssr-and-ssg" rel="noopener noreferrer"&gt;In our last article in the series, we talked about how React is able to pre-generate HTML from JSX on the server (or developer's machine) prior to being shipped to the end-user&lt;/a&gt;. This process is called "SSR" and can be mission-critical in getting your applications as performant as possible.&lt;/p&gt;

&lt;p&gt;I originally wrote that article in early 2020. At this point in React's development lifecycle, there was an inherent problem to using SSR; it would lead to duplicate effort between the server and the client.&lt;/p&gt;

&lt;p&gt;See, up to that point Next.js and other React SSR solutions had one way of doings things:&lt;/p&gt;

&lt;p&gt;1) Render &lt;a href="https://unicorn-utterances.com/posts/what-is-reconciliation-and-the-vdom" rel="noopener noreferrer"&gt;the VDOM&lt;/a&gt; on the server&lt;br&gt;
2) Generate HTML from the server's VDOM&lt;br&gt;
3) Ship HTML and all of the React code to the client&lt;br&gt;
4) Re-generate the VDOM from scratch on the client&lt;br&gt;
5) Wipe away the old DOM and re-render all components from the new client's VDOM instance&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3i8jao1640yowlougn7u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3i8jao1640yowlougn7u.png" alt="The developer ships SSR and framework code to the server, which produces HTML. This HTML/CSS is then sent to the user machine where it re-initializes on the client's browser" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This process is called "Hydration" and while it &lt;em&gt;worked&lt;/em&gt; the way it did before, it introduced a new performance problem. Hydration could be needlessly expensive if most of your content coming from the server was going to be static anyway. This was a huge problem that the React team had to solve.&lt;/p&gt;

&lt;p&gt;Later in the same year of my article (December 2020), they had the answer: &lt;a href="https://legacy.reactjs.org/blog/2020/12/21/data-fetching-with-react-server-components.html" rel="noopener noreferrer"&gt;React Server Components&lt;/a&gt;.&lt;/p&gt;
&lt;h1&gt;
  
  
  What is a React Server Component (RSC)?
&lt;/h1&gt;

&lt;p&gt;In short; React Server components allow you to designate which React components render on the server and which components re-initialize on the client. This is done using a special syntax in your components and allows for special server-only data loading patterns when implemented properly.&lt;/p&gt;

&lt;p&gt;For example, take the following:&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="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="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* Render parts on the client */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* Render all of it on the client */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Dashboard&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* Render all of it on the server */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Footer&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When executed, it might look something like the following process:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffq4ft0mcpzkx1mkv1xvi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffq4ft0mcpzkx1mkv1xvi.png" alt="The developer authors JSX with distinct client and server components. These components are ALL rendered on the server, but only the client components are re-rendered on the client" width="800" height="1644"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here, we can see that &lt;code&gt;&amp;lt;ProfilePicture&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;Dashboard/&amp;gt;&lt;/code&gt;, and all of their children will be re-initialized on the client. Meanwhile the &lt;code&gt;&amp;lt;Footer&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;Header&amp;gt;&lt;/code&gt; components will not re-initialize on the client.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Keep in mind, client-components will still pre-generate HTML on the server by default. The difference here is that the client re-initialization is now informed by the VDOM constructed on the server, allowing for drastically reduced required execution.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  What is &lt;code&gt;"use client"&lt;/code&gt;?
&lt;/h1&gt;

&lt;p&gt;In React Server Components, &lt;code&gt;"use client"&lt;/code&gt; is a string at the top of the file or function that indicates that React should also render the component on the client. Rendering on the client side allows you to use state and rerender reactively. Without "use client", the component will be treated as a server component.&lt;/p&gt;

&lt;p&gt;Let's use this &lt;code&gt;"use client"&lt;/code&gt; syntax to build out the example from the image in the previous section, distinguishing which type of component is which along the way:&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="c1"&gt;// page.jsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;ProfilePicture&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Dashboard&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="s2"&gt;./client-components&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;export&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="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Header&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;Dashboard&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;Footer&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Footer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Header&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;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;SearchBar&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;ProfilePicture&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&amp;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;function&lt;/span&gt; &lt;span class="nf"&gt;SearchBar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;use client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="c1"&gt;// client-components.jsx&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Dashboard&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="nc"&gt;Chart&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;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Chart&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;profilePicture&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Limitations of Server Components
&lt;/h1&gt;

&lt;p&gt;Because a server component runs entirely on the server, there are a few limitations you should be aware of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;No usage of React Hooks that contain client-side state (&lt;code&gt;useState&lt;/code&gt;, &lt;code&gt;useReducer&lt;/code&gt;, etc)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This includes importing code that lazily uses these React Hooks, although &lt;a href="https://npmjs.com/package/rehackt" rel="noopener noreferrer"&gt;library authors have found a way around this for their needs&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Some Hooks that do not require client-side state are okay to use (&lt;code&gt;useId&lt;/code&gt;, Next.js' &lt;code&gt;useSearchParams&lt;/code&gt;, etc)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;code&gt;&amp;lt;Context.Provider&amp;gt;&lt;/code&gt; usage&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;No usage of browser APIs (&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage" rel="noopener noreferrer"&gt;&lt;code&gt;localstorage&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector" rel="noopener noreferrer"&gt;&lt;code&gt;querySelector&lt;/code&gt;&lt;/a&gt;, etc)&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;You cannot pass the following property values from a server component to a client component:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;React Elements/JSX (&lt;code&gt;component={&amp;lt;Component/&amp;gt;}&lt;/code&gt; or &lt;code&gt;component={Component}&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Functions (unless it's a Server Action - more on that in a future article)&lt;/li&gt;
&lt;li&gt;Classes&lt;/li&gt;
&lt;li&gt;Instances of Custom Classes&lt;/li&gt;
&lt;li&gt;Custom &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol" rel="noopener noreferrer"&gt;Symbols&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Cannot be called inside a Client component. IE:&lt;br&gt;&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ClientComponent&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="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ServerComponent&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Is not allowed but:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ClientComponent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;children&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;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&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;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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&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="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ClientComponent&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ServerComponent&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;ClientComponent&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Is allowed.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;React Server Components have been a huge topic of discussion lately. So much so that while the fixes to hydration are useful, you may be left wondering:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Is that all there is to RSCs?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Luckily, it's not!&lt;/p&gt;

&lt;p&gt;See, by providing a primitive for server behavior in React, the team has unlocked a great deal of potential in regards to data loading.&lt;/p&gt;

&lt;p&gt;But that's a story for next time. Next up? React's Suspense APIs!&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>javascript</category>
    </item>
    <item>
      <title>What is Server Side Rendering (SSR) and Static Site Generation (SSG)?</title>
      <dc:creator>Corbin Crutchley</dc:creator>
      <pubDate>Sun, 25 Feb 2024 16:00:00 +0000</pubDate>
      <link>https://dev.to/playfulprogramming/what-is-server-side-rendering-ssr-and-static-site-generation-ssg-308o</link>
      <guid>https://dev.to/playfulprogramming/what-is-server-side-rendering-ssr-and-static-site-generation-ssg-308o</guid>
      <description>&lt;p&gt;In recent years, projects like &lt;a href="https://nextjs.org/" rel="noopener noreferrer"&gt;Vercel's NextJS&lt;/a&gt; and &lt;a href="https://www.gatsbyjs.org/" rel="noopener noreferrer"&gt;Gatsby&lt;/a&gt; have garnered acclaim and higher and higher usage numbers. Not only that, but their core concepts of Server Side Rendering (SSR) and Static Site Generation (SSG) have been seen in other projects and frameworks such as &lt;a href="https://angular.io/guide/universal" rel="noopener noreferrer"&gt;Angular Universal&lt;/a&gt;, &lt;a href="https://scully.io/" rel="noopener noreferrer"&gt;ScullyIO&lt;/a&gt;, and &lt;a href="https://nuxtjs.org/" rel="noopener noreferrer"&gt;NuxtJS&lt;/a&gt;. Why is that? What &lt;em&gt;is&lt;/em&gt; SSR and SSG? How can I use these concepts in my applications?&lt;/p&gt;

&lt;p&gt;We'll walk through all of these questions and provide answers for each. First, we have to have an understanding of how a typical HTML site is able to serve content to your user.&lt;/p&gt;

&lt;h1&gt;
  
  
  Vanilla HTML Sites
&lt;/h1&gt;

&lt;p&gt;While many sites today are built using a component-based framework like Angular, React, or Vue, there's nothing wrong with good ole' HTML. For sites like this, you typically provide an HTML file for each of the routes of your site. When the user requests one of the routes, your server will return the HTML for it. From there, &lt;a href="http://unicorn-utterances.com/posts/understanding-the-dom/" rel="noopener noreferrer"&gt;your browser parses that code and provides the content directly to the user&lt;/a&gt;. All in all, the process looks something like this:&lt;/p&gt;

&lt;p&gt;1) You build HTML, CSS, JS&lt;br&gt;
2) You put it on a server&lt;br&gt;
3) The client downloads the HTML, CSS, JS from server&lt;br&gt;
4) The client immediately sees content on screen&lt;/p&gt;

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

&lt;p&gt;This is a reasonably straightforward flow once you get the hang of it. Let's take a look at what happens when you throw a component-based framework into the fray.&lt;/p&gt;

&lt;h1&gt;
  
  
  Client Side Rendering
&lt;/h1&gt;

&lt;p&gt;While you may not be familiar with this term, you're more than likely familiar with how you'd implement one of these; After all, this is the default when building an Angular, React, or Vue site. Let's use a React site as an example. When you build a typical React SPA without utilizing a framework like NextJS or Gatsby, you'd:&lt;/p&gt;

&lt;p&gt;1) You build the React code&lt;br&gt;
2) You put it on a server&lt;br&gt;
3) The client downloads the React code from the server&lt;br&gt;
4) The React code runs and generates the HTML/CSS on the client's computer&lt;br&gt;
5) The user &lt;strong&gt;then&lt;/strong&gt; sees the content on screen after React runs&lt;/p&gt;

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

&lt;p&gt;This is because React's code has to initialize to render the components on screen before it can spit out HTML for the browser to parse. Sure, there's an initial HTML file that might have loading spinner, but until your components have time to render, that's hardly useful content for your user. &lt;em&gt;While these load times can be sufficient for smaller applications&lt;/em&gt;, if you have many components loading on-screen, &lt;em&gt;you may be in trouble if you want to keep your time-to-interactive (TTI) low&lt;/em&gt;. That scenario is where SSR often comes into play.&lt;/p&gt;

&lt;h1&gt;
  
  
  Server Side Rendering (SSR)
&lt;/h1&gt;

&lt;p&gt;Because React has to initialize &lt;em&gt;somewhere&lt;/em&gt;, what if we were to move the initial rendering off to the server? Imagine - for each request the user sends your way, you spin up an instance of React. Then, you're able to serve up the initial render (also called "fully hydrated") HTML and CSS to the user, ready to roll. That's just what server-side rendering is!&lt;/p&gt;

&lt;p&gt;1) You build the React code&lt;br&gt;
2) You put it on a server&lt;br&gt;
3) The client requests data&lt;br&gt;
4) The server runs the React code on the server to generate the HTML/CSS&lt;br&gt;
5) The server then sends the generated HTML/CSS on screen&lt;br&gt;
6) The user then sees the content on screen. React doesn't have to run on their computer&lt;/p&gt;

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

&lt;p&gt;There are more improvements than there might initially see, however! Because you're hosting from a server - which has better network connectivity than a user's machine - you're able to make much faster network requests to perform that initial render.&lt;/p&gt;

&lt;p&gt;Say you need to grab data from the database to populate the screen's data, you're able to do that much faster as a result. Instead of displaying the user a loading screen while you wait to grab the data, you can simply tell your client, "don't show anything until I send you HTML that I've generated from React." Due to the speed of your network, you can typically ship down a hydrated UI from database data as quickly as you'd typically be able to display a spinner.&lt;/p&gt;

&lt;p&gt;Moreover, if you have your server and database in the same hosting location, you're even able to avoid out-of-intranet calls, which would provide faster, more reliable connectivity for your initial render.&lt;/p&gt;

&lt;p&gt;That said because you're relying on server functionality to do this rendering, you have to have a custom server setup. No simple CDN hosting here - your server has to initialize and render each user's page on request.&lt;/p&gt;

&lt;h1&gt;
  
  
  Static Site Generation (SSG)
&lt;/h1&gt;

&lt;p&gt;If SSR is &lt;a href="https://en.wikipedia.org/wiki/Buck_passing" rel="noopener noreferrer"&gt;"passing the buck"&lt;/a&gt; to the server to generate the initial page, then SSG is passing the buck to you - the developer.&lt;/p&gt;

&lt;p&gt;While the industry widely recognizes the term "Static Site Generation," I prefer the term "compile-side rendering" or "compile-time server-side rendering." This is because I feel they outline a better explanation of the flow of displaying content to the user. On an SSG site, you'd:&lt;/p&gt;

&lt;p&gt;1) You build the React code&lt;br&gt;
2) You generate the HTML and CSS on your development machine before deploying to a server (run build)&lt;br&gt;
3) You put the generated built code on a server&lt;br&gt;
4) The client downloads the HTML, CSS, JS from the built code on the server&lt;br&gt;
5) The client immediately sees content on screen&lt;/p&gt;

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

&lt;p&gt;This simply extends the existing build process that many front-end frameworks have. After &lt;a href="https://babeljs.io/" rel="noopener noreferrer"&gt;Babel's done with its transpilation&lt;/a&gt;, it merely executes code to compile your initial screen into static HTML and CSS. This isn't entirely dissimilar from how SSR hydrates your initial screen, but it's done at compile-time, not at request time. &lt;/p&gt;

&lt;p&gt;Since you're only hosting HTML and CSS again, you're able to host your site as you would a client-side rendered app: Using a CDN. This means that you can geo-sparse your hosting much more trivially but comes with the caveat that you're no longer to do rapid network queries to generate the UI as you could with SSR.&lt;/p&gt;

&lt;h1&gt;
  
  
  Pros and Cons
&lt;/h1&gt;

&lt;p&gt;It may be tempting to look through these options, find one that you think is the best, and &lt;a href="https://en.wiktionary.org/wiki/overfit" rel="noopener noreferrer"&gt;overfit&lt;/a&gt; yourself into a conclusion that one is superior to all the others. That said, each of these methods has its strengths and weaknesses.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Pros&lt;/th&gt;
&lt;th&gt;Cons&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Vanilla HTM&lt;/td&gt;
&lt;td&gt;&lt;ul&gt;&lt;li&gt;Fast&lt;/li&gt;&lt;/ul&gt;&lt;/td&gt;
&lt;td&gt;&lt;ul&gt;&lt;li&gt;Hard to scale&lt;/li&gt;&lt;/ul&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Client Side Rendering (CSR)&lt;/td&gt;
&lt;td&gt;&lt;ul&gt;
&lt;li&gt;Easy to scale&lt;/li&gt;
&lt;li&gt;Ease of engineering&lt;/li&gt;
&lt;/ul&gt;&lt;/td&gt;
&lt;td&gt;&lt;ul&gt;
&lt;li&gt;Slow JS initialization&lt;/li&gt;
&lt;li&gt;SEO concerns&lt;/li&gt;
&lt;/ul&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Server Server Render (SSR)&lt;/td&gt;
&lt;td&gt;&lt;ul&gt;
&lt;li&gt;Query based optimization&lt;/li&gt;
&lt;li&gt;Better SEO handling&lt;/li&gt;
&lt;li&gt;Usable without client JS enabled&lt;/li&gt;
&lt;/ul&gt;&lt;/td&gt;
&lt;td&gt;&lt;ul&gt;
&lt;li&gt;Heavier server load&lt;/li&gt;
&lt;li&gt;Needs specific server&lt;/li&gt;
&lt;li&gt;More dev effort than CSR&lt;/li&gt;
&lt;/ul&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Compile Time Rendering (SSG)&lt;/td&gt;
&lt;td&gt;&lt;ul&gt;
&lt;li&gt;Layout based optimization&lt;/li&gt;
&lt;li&gt;Better SEO handling&lt;/li&gt;
&lt;li&gt;Usable without client JS enabled&lt;/li&gt;
&lt;li&gt;CDN hostable&lt;/li&gt;
&lt;/ul&gt;&lt;/td&gt;
&lt;td&gt;&lt;ul&gt;
&lt;li&gt;No access to query data&lt;/li&gt;
&lt;li&gt;More dev effort than CSR&lt;/li&gt;
&lt;/ul&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Consider each of these utilities a tool in your toolbox. You may be working on a landing page for a client where SSG would fit best — working on an internal SPA that only has a limited budget allocated to it? Client-side rendering might be your best bet there! Are you working on a public-facing app that highly depends on real-time data? SSR's for you! Each of these has its utility in their problem-space. It's good to keep that in mind when selecting one for your next project.&lt;/p&gt;

&lt;p&gt;In fact, if you're using a framework that supports more than one of these methods (&lt;a href="https://nextjs.org/blog/next-9-3" rel="noopener noreferrer"&gt;like NextJS does as-of version 9.3&lt;/a&gt;), knowing which of these utilities to use for which pages can be critical for optimizing your app.&lt;/p&gt;

&lt;h1&gt;
  
  
  A Note Regarding Performance Benchmarks
&lt;/h1&gt;

&lt;p&gt;I was once tasked with migrating a landing page with an associated blog from CSR to use SSG. Once I had done so, however, I noticed that &lt;a href="https://developers.google.com/web/tools/lighthouse" rel="noopener noreferrer"&gt;my Lighthouse score&lt;/a&gt; had gone &lt;em&gt;down&lt;/em&gt; despite my page rendering a much more useful initial page significantly faster than it'd taken for my app's spinner to go away.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Why did my lighthouse scores go down when using SSG?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I wasn't able to find an answer quickly, but eventually, I found out. Lighthouse scores based on many factors. One of those factors is "time until fully loaded." Here's where my problems came into play:&lt;/p&gt;

&lt;p&gt;When doing server-side rendering or static site generation, you're shipped HTML and CSS. Then, to ensure your app fully works and is interactive after the intial load, it will preload the framework you built your site in. Once your framework preloads, it will oftentimes re-render the initial page that was shipped with HTML/CSS. Because the page is both pre-hydrated and responsible for initializing the framework afterwards on the client machine, your benchmarks may potentially suffer, despite the experience being better.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb2ezb0ocerv133y1s8zm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb2ezb0ocerv133y1s8zm.png" alt="A chart outlining how in SSG once the code is shipped, it simply needs to initialize on the client's browser" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;While it's &lt;em&gt;technically&lt;/em&gt; possible to do things like &lt;a href="https://github.com/zeit/next.js/issues/5054" rel="noopener noreferrer"&gt;compile React entirely out of an exported NextJS site&lt;/a&gt;, it's far from trivial and doesn't fit &lt;em&gt;most&lt;/em&gt; usage very well. It's certainly a harder mental model at the very least.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here's an anecdote that was told to me by &lt;a href="https://twitter.com/aaronfrost" rel="noopener noreferrer"&gt;Aaron Frost&lt;/a&gt; (the creator of the SSG utility &lt;a href="http://scully.io/" rel="noopener noreferrer"&gt;Scully&lt;/a&gt;) about this scenario:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;There once was an airport that had low ratings from an audit company that rated an airport's speed and quality. The biggest complaint from the rating was that the time it took to get un-boarded and to the baggage claim was too long. One of the reasons for this was due to how the planes were landing. When the planes landed, they were far away from the baggage claim, forcing their customers to walk a long distance before getting to the baggage claim.&lt;/p&gt;

&lt;p&gt;The airport decided to re-arrange how their planes landed in the future. While the customers seemed to be much happier overall, they received a lower rating on their next audit. This clearly contradicted the claims of their fliers. It turns out that the way the auditor was rating the airport was how much downtime they had before receiving a bag. While the others enjoyed reading articles on their phones during the downtime, the auditor was able to start their timer sooner as a result of walking for a shorter period of time.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;All in all, while lighthouse might score you lower, you can rest assured that your customers will be happier knowing that you have a much more useful interaction on first glance than a site that doesn't use something like SSG.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;As mentioned previously, having SSR and SSG in your toolbox are incredibly useful to have at your disposal. While not appropriate for every application, those that are tend to see great advantages from the concepts. Hopefully we've been able to provide a bit of insight that'll spark further learning and research into them.&lt;/p&gt;

&lt;p&gt;Now you have familiarity with what SSR and SSG are, maybe you want to take a stab at implementing it? &lt;a href="http://unicorn-utterances.com/posts/making-an-angular-blog-with-scully/" rel="noopener noreferrer"&gt;We took a look recently at creating a blog using an Angular SSG solution called Scully&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As always, let us know what you think down in the comments below or &lt;a href="https://discord.gg/FMcvc6T" rel="noopener noreferrer"&gt;in our community Discord&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>What is Reconciliation and the Virtual DOM (VDOM)?</title>
      <dc:creator>Corbin Crutchley</dc:creator>
      <pubDate>Fri, 23 Feb 2024 16:00:00 +0000</pubDate>
      <link>https://dev.to/playfulprogramming/what-is-reconciliation-and-the-virtual-dom-vdom-2p3c</link>
      <guid>https://dev.to/playfulprogramming/what-is-reconciliation-and-the-virtual-dom-vdom-2p3c</guid>
      <description>&lt;p&gt;&lt;a href="https://unicorn-utterances.com/posts/what-is-reactivity" rel="noopener noreferrer"&gt;In our last post we introduced how a modern frontend framework like React, Angular, or Vue are able to make your JavaScript state easier to sync to the DOM using "Reactivity"&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Towards the end of that post, I touched on how each of these frameworks' mechanisms for reactivity work under-the-hood through external links.&lt;/p&gt;

&lt;p&gt;One of those mechanisms used by frameworks like React and Vue is called the "Virtual DOM" (Also known as the "VDOM") and use a process called "Reconciliation" to reflect the changes made to this "VDOM" to the real DOM.&lt;/p&gt;

&lt;p&gt;Let's take a look at how this works in practical terms.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is the Virtual DOM (VDOM)?
&lt;/h1&gt;

&lt;p&gt;In a broad stroke, the virtual DOM (VDOM) is a reflection of the code you've written in your framework that eventually gets mirrored to the DOM. This is in order to make sure that updates to your JavaScript state are duplicated into the DOM via reactivity.&lt;/p&gt;

&lt;p&gt;Too terminology heavy? No problem, here's an example.&lt;/p&gt;

&lt;p&gt;Let's say that you have a bit of HTML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;&lt;/span&gt;One&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;&lt;/span&gt;One&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;&lt;/span&gt;One&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This might create a DOM tree that looks similar to the following:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4ouyjtxwh71mvoo0xb21.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4ouyjtxwh71mvoo0xb21.png" alt="A tree of elements starting with the ul at the top, three lis below, and each li has a p element"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you need a refresher on how the DOM works, &lt;a href="https://unicorn-utterances.com/posts/understanding-the-dom" rel="noopener noreferrer"&gt;check out our post on the topic&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Similarly, if you write the following JSX:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&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="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;ul&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;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;One&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&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;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;One&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&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;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;One&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&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;ul&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;You'll end up with a VDOM that mirrors the markup you've written in JSX. This JSX is then reflected to the DOM itself:&lt;/p&gt;

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

&lt;p&gt;The process of how these changes are mirrored is called "Reconciliation".&lt;/p&gt;

&lt;h1&gt;
  
  
  What is "Reconciliation"?
&lt;/h1&gt;

&lt;p&gt;Reconciliation is the process of reflecting changes from a frameworks' virtual DOM into the DOM via a three-step process:&lt;/p&gt;

&lt;p&gt;1) Listening for changes to the state&lt;br&gt;
2) Diffing the changes made to the VDOM&lt;br&gt;
3) Committing the changes from the VDOM to the DOM&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fniyzec8dtkvxz9gi3e87.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fniyzec8dtkvxz9gi3e87.png" alt="The same DOM tree as before is mirrored both in React's VDOM but in the browser's DOM as well"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  What is the &lt;code&gt;key&lt;/code&gt; property?
&lt;/h1&gt;

&lt;p&gt;While this process of reconciliation might seem simple at first, it can get quite complex. For example, consider how a list might be handled:&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;fakeNames&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Gulgowski&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Johnston&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Nader&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Flatley&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Lemke&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Stokes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Simonis&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Little&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Baumbach&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Spinka&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="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&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;function&lt;/span&gt; &lt;span class="nf"&gt;createPerson&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="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;fakeNames&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;fakeNames&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&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;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;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setList&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="nf"&gt;createPerson&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="nf"&gt;createPerson&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="nf"&gt;createPerson&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="p"&gt;]);&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;addPersonToList&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;newList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="c1"&gt;// Insert new friend at random location&lt;/span&gt;
    &lt;span class="nx"&gt;newList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;splice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;newList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&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="nf"&gt;createPerson&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;setList&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newList&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;My friends&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="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;addPersonToList&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Add friend&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;person&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&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;label&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="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; notes&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;input&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;label&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;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;))&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;ul&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;Here, we're storing a list of our friends and allowing the user to add to this list by pressing a button. We even have a little place to store notes about your friends!&lt;/p&gt;

&lt;p&gt;But notice what happens to those notes when someone gets added to the start of the list:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://unicorn-utterances.com/content/blog/what-is-reconciliation-and-the-vdom/incorrect-user.mp4" rel="noopener noreferrer"&gt;https://unicorn-utterances.com/content/blog/what-is-reconciliation-and-the-vdom/incorrect-user.mp4&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;See how the note about Little is now assigned to the wrong person.&lt;/p&gt;

&lt;p&gt;This is because React needs some way to identify which element is which in a list. By default, this is the index of the list item - which is why our note about Little (whom was originally at the top of the list) is still at the top of the list when someone else is added, despite that not being correct.&lt;/p&gt;

&lt;p&gt;Without this default behavior, the &lt;code&gt;input&lt;/code&gt;s inside of the list would all disappear every time the user added to the list, as it wouldn't know to avoid re-rendering the contents of the DOM on existing items:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmwc4e3icxdns2zinrbct.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmwc4e3icxdns2zinrbct.png" alt="Without React's default behavior, a list without keys would re-render all list items when a new item is added"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To fix this, we just need to explicitly tell React which user is which in the list using a special &lt;code&gt;key&lt;/code&gt; property:&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;person&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&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;label&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="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; notes&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;input&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;label&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;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;))&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;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr5vgd5i59yadzbq9aq74.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr5vgd5i59yadzbq9aq74.png" alt="When a list is keyed, it knows which item is being added and doesn't need to re-render the other elements in the list"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;In this series, we've explored how React handles reactivity and how it uses the Virtual DOM and reconciliation to make reactivity work.&lt;/p&gt;

&lt;p&gt;These two combined build the foundation for how React works behind the scenes. In the next few posts, starting with &lt;a href="https://unicorn-utterances.com/posts/what-is-ssr-and-ssg" rel="noopener noreferrer"&gt;"What is server-side rendering (SSR) and static site generation (SSG)"&lt;/a&gt;, we'll explore how React has gradually evolved past the typical client-side rendering process and into the server.&lt;/p&gt;

&lt;p&gt;Eventually, this series will show you how to use React Server Actions in-depth and how you can utilize your React knowledge to become a full-stack developer.&lt;/p&gt;

&lt;p&gt;Sound like fun? We hope so! &lt;a href="https://discord.gg/FMcvc6T" rel="noopener noreferrer"&gt;Join us in our Discord&lt;/a&gt; and let us know what other topics you'd like to see on the site.&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
