<?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: charlie⚡</title>
    <description>The latest articles on DEV Community by charlie⚡ (@charliewilco).</description>
    <link>https://dev.to/charliewilco</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%2F49311%2Fc69da600-8f63-41e9-80c4-bc77bfc5c8ce.png</url>
      <title>DEV Community: charlie⚡</title>
      <link>https://dev.to/charliewilco</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/charliewilco"/>
    <language>en</language>
    <item>
      <title>How to Make Your Code Reviews Awesome</title>
      <dc:creator>charlie⚡</dc:creator>
      <pubDate>Wed, 20 Oct 2021 16:19:34 +0000</pubDate>
      <link>https://dev.to/charliewilco/reviewing-pull-requests-like-a-human-89l</link>
      <guid>https://dev.to/charliewilco/reviewing-pull-requests-like-a-human-89l</guid>
      <description>&lt;p&gt;You ever stare at a pull request (PR) with 40 open comments, all of which require resolution or response in order to merge your work? I have. I learned loads from those, we would get into great discussions documented right in your project. But it's a double-edge sword, you can learn a lot from these experiences and at the same time it can also suck the life out of you leaving you just a desiccated hunk of VSCode shortcuts and a mild caffeine addiction.&lt;/p&gt;

&lt;p&gt;It doesn't have to be that way. It can actually get worse, pull request reviews can become a politic dumping ground and a toxic element of broken engineering cultures and horrible teams.&lt;/p&gt;

&lt;p&gt;You deserve better.&lt;/p&gt;

&lt;p&gt;You invested in the work you did and your reviewer invested energy and attention into reviewing it. It's easy to forget that, your reviewer is an impediment to your progress, and you're a distraction from whatever they were working on. You both are worthy of respect and kindness.&lt;/p&gt;

&lt;p&gt;So I developed a system for PRs I like to float when I'm working with teams. I call it: &lt;em&gt;Ranked PRs&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;These are kinda my rules for Ranked PRs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep things low stakes for both the reviewer and the author.&lt;/li&gt;
&lt;li&gt;Buffer harsh interactions with sincere praise.&lt;/li&gt;
&lt;li&gt;Make opportunities to bail&lt;/li&gt;
&lt;li&gt;Automate as much as possible&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But the manner for doing all of this is pretty blunt: &lt;strong&gt;&lt;em&gt;If you're leaving a comment on someone else's work it should be qualified or at the very least categorized.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In practice, I end up prefixing each comment:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;REQUIRED&lt;/strong&gt; must resolve the following comment, usually provide a link for more context or example&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;QUESTION/CLARIFICATION&lt;/strong&gt; = must respond to question or create follow up comment&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NIT&lt;/strong&gt; can be ignored, usually response to stylistic preference or consistency&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;COMMENT&lt;/strong&gt; general, no need for resolution&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PRAISE&lt;/strong&gt; encouraging&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Emojis for some teams might be neater:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;❗️ = must resolve the following comment, usually provide a link for more context or example&lt;/li&gt;
&lt;li&gt;✅ = must respond to question or create follow up comment&lt;/li&gt;
&lt;li&gt;🙄 = can be ignored, usually response to stylistic preference or consistency&lt;/li&gt;
&lt;li&gt;✨ = general, no need for resolution&lt;/li&gt;
&lt;li&gt;🎉 = encouraging&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This accomplishes two big things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You get a focused scope as the reviewer to work in. You can prevent a lot of hassle from knowing you have a finite way of responding; fewer rabbit trails to go down and clearer targets to hit.&lt;/li&gt;
&lt;li&gt;You give the author of the PR a way to navigate your feedback. For instance, if they've got 4 REQUIRED comments, they can resolve them quickly and focus on bigger pieces of feedback.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It ends up looking like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BOzfx9L4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://charliewil.co/images/posts/pr-post-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BOzfx9L4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://charliewil.co/images/posts/pr-post-1.png" alt="A comment on a code review with a NIT flag"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4s4dsZQV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://charliewil.co/images/posts/pr-post-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4s4dsZQV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://charliewil.co/images/posts/pr-post-2.png" alt="A comment on a code review with a REQUIRED flag"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HQU6jD0p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://charliewil.co/images/posts/pr-post-3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HQU6jD0p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://charliewil.co/images/posts/pr-post-3.png" alt="A comment on a code review with a PRAISE flag"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Making praise and ignorable comments a key part of this setup makes it easy to call out growth and identify what issues you should let go of in time. For instance do I actually care if someone is casting something to a type? Maybe I do, maybe I don't, but calling it out gives them an opportunity to explain or ignore you and you can be okay with either. Should another engineer get some praise for making a cleaner abstraction for that one thing that bugs everyone? Yes, yes they should.&lt;/p&gt;

&lt;p&gt;However, I have found some caveats (YMMV):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In teams that are growing I’ve found this method for commenting works effectively, especially when you have a mix of junior and senior engineers.&lt;/li&gt;
&lt;li&gt;If you present this as a prescriptive solution it will fail, it's usually better floated as a discussion topic or an experiment.&lt;/li&gt;
&lt;li&gt;If you haven't automated formatting and code linting rules (think SwiftLint, Prettier, ESLint, etc), you're in for a bad time. It's not worth the collective energy to keep calling these things out and usually ends up looking like dog-piling on someone. Like just set it up and if someone has a real issue with it, have a conversation and be flexible. (My experience has been bad managers don't like these tools but they don't have to write the code so 🤷.)&lt;/li&gt;
&lt;li&gt;If you have someone new to a team or new to coding and it's their first PR, setting expectations of "Hey, 40 comments is totally normal, not an indicator of anything wrong" can be so helpful.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;There are some tools that can help make working like this a little bit easier:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://sindresorhus.com/jiffy"&gt;Jiffy&lt;/a&gt;: This is really great for adding GIFs to a PR because you can just drag from a menubar app directly onto GitHub&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/mshick/add-pr-comment"&gt;Add PR Comment&lt;/a&gt;: I've used this to automatically add the legend of what comments mean what anytime someone opens a PR. It works pretty okay.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hQR2B8nI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://charliewil.co/images/posts/pr-post-legend.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hQR2B8nI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://charliewil.co/images/posts/pr-post-legend.png" alt="A legend for PR comments"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Ultimately GIFs and emojis cannot fix a broken engineering culture, but a little bit of levity and lowering the stakes of giving feedback fosters a more giving group of engineers.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This was originally posted &lt;a href="https://charliewil.co/writing/pull-requests"&gt;here&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>codereview</category>
      <category>teams</category>
      <category>leadership</category>
      <category>growth</category>
    </item>
    <item>
      <title>A Self-Care Primer</title>
      <dc:creator>charlie⚡</dc:creator>
      <pubDate>Fri, 27 Dec 2019 20:50:19 +0000</pubDate>
      <link>https://dev.to/charliewilco/a-self-care-primer-4aj7</link>
      <guid>https://dev.to/charliewilco/a-self-care-primer-4aj7</guid>
      <description>&lt;p&gt;"Self-care" was something I'd had read about a lot on Twitter and I couldn't help but think of it as a troupe. Ask my therapist, well, ask her if I ever waive confidentiality but there's paperwork for that so not likely. But every time I heard "self-care" like most skeptics I conjured the most ludicrous and lavish examples that the internet hash-tagged into ubiquity. Images of spend money irresponsibly or being selfish for purposes of gratification and pleasure.&lt;/p&gt;

&lt;p&gt;If you're thinking this is ridiculous, most definitions that come from a quick Google search will have to disambiguate from that what self-care actually is and does for you. Eventually, I discovered that's not self-care, that's pageantry. Self-care is literally, doing something to care for yourself and your health or well-being. It's not necessarily champagne, spa retreats, removing all meaning from the word "mindfulness", spamming Instagram with your candle business.&lt;/p&gt;




&lt;p&gt;I've been having some hard days at work, I ended working close to 60 hours last week on top of attending a conference. I'm doing more &lt;a href="https://dev.to/writing/urgency-importance/"&gt;lead work recently&lt;/a&gt;. Sleeping has been rough going (which is my normal, but this is worse), relaxing seems like a chore, things I was super excited for like replacing. If my therapist is to be believed, self-care is essential to keep being a human.&lt;/p&gt;

&lt;p&gt;Self-care needs to be an intentional choice, so when I get into binge mode by default and consume streams of content.&lt;/p&gt;

&lt;p&gt;One thing that I've observed, is that I can't really do my job nor should I super be expected to if I can't function as a human. Self-care, taking care of yourself, or "humaning". Whatever you want to call it is essential to maintaining that functionality.&lt;/p&gt;

&lt;h3&gt;
  
  
  A note about privilege and ableism
&lt;/h3&gt;

&lt;p&gt;What I'm about to outline, is a framework I apply to thinking about taking care of myself, it is in by nature personal. And not every application can be applied to everyone, my hope is that after reading you see the framework behind the questions and can take the questions as starting blocks.&lt;/p&gt;

&lt;p&gt;My biases in forming these revolve around my own privilege that comes from being white, cisgender, reasonably able-bodied, male and being seen (wrongly) as straight. The questions and particulars as to how I apply this framework come from that privilege that's not distributed evenly, and I can't in good faith continue without prefacing this fact.&lt;/p&gt;

&lt;h3&gt;
  
  
  Back to Basics
&lt;/h3&gt;

&lt;p&gt;When I get into this state I've described of being barely functioning, it's helpful to go back to the basics. Abraham Maslow's classic &lt;a href="https://en.wikipedia.org/wiki/Maslow%27s_hierarchy_of_needs"&gt;"Hierarchy of needs"&lt;/a&gt;, represents a progressive state of needs, ranking physical needs as a bedrock for being able to the next level of needs and that level being the foundation for being able to attain the next set of needs. For example, it's hard to worry about whether you're loved or have a sense of belonging if you're starving and need shelter.&lt;/p&gt;

&lt;p&gt;It's hard to focus on the whole litany of everything you're supposed to be or do as a software engineer if you can't keep your eyes open. So I started to develop a framework (because I am who I am) of questions to start to probe whether those needs are being met:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Did I eat something recently that was actually food?&lt;/li&gt;
&lt;li&gt;Do I have clean underwear and matched socks?&lt;/li&gt;
&lt;li&gt;Did I talk to a human being that doesn't reside in my apartment building?&lt;/li&gt;
&lt;li&gt;Did I try and sleep in the last 36 hours?&lt;/li&gt;
&lt;li&gt;Does the screen go all fuzzy when I try to look at it?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Yea that's a low bar. That's intentionally a low bar, some of these things sound trivial or worrying that you might need to double check. I've found in my life living off of McDonald's and delivery is a bad idea, eating a plate of eggs and ham is better. Having clean underwear and matched socks is evidence of laundry having been done recently and speculation around the idea of a shower has happened. Talking to other humans is a chore sometimes but cheap shots on Twitter aren't great substitutes for human interaction.&lt;/p&gt;

&lt;p&gt;These concerns all certain around forming a baseline.&lt;/p&gt;

&lt;h3&gt;
  
  
  Next Level
&lt;/h3&gt;

&lt;p&gt;If those concerns are addressed I feel like I can move onto the next level of things. This group is more concerned with feeling like a person once you can do basic human things.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Did I go to therapy this month?&lt;/strong&gt; &lt;em&gt;Mental health is so important. Therapy can be such a trope but it can also be an opportunity to confess in a space "Things are not okay and I don't know what to do next". Plus my therapist is awesome, she wears glasses and everything.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Did I read a book made out of a dead tree?&lt;/strong&gt; &lt;em&gt;"Blue light is bad and a tree had to die for me to get this book in my apartment, I should read it." That's a little chant I say in my head sometimes to convince myself to read a book. Just remember disengaging from work can be as simple as a context switch and opening a physical book or closing your eyes and listening to an audiobook can do wonders to get you there.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Is the bed made?&lt;/strong&gt; &lt;em&gt;This is a weird new obsession of mine from the last two months. There's books written about how this can help your outlook and I have no interest in reading them. For me, it's a reminder that my home and my place in it have value and that being in a place of rest won't be a burden later. Also it's really fun now that I figured out what the hell "hospital corners" are and how to make them.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Is the mess in my apartment going to prohibit me from doing the stuff I need to do or the stuff I want to do?&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Next Next Level
&lt;/h3&gt;

&lt;p&gt;This layer actively preserves the previous too, in mind this goes &lt;code&gt;human → person → semi-responsible person&lt;/code&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Is there anything nagging at me?&lt;/strong&gt; &lt;em&gt;Is there anything I'm ignoring that's keeping me up at night? That's not a cliche to me, there's a whole host of things that have real potential to interrupt my ability to sleep. These things usually revolve around money, or phone calls or messages that I tend to ignore. Occasionally this can be mounds of trivial things like: "Is Notion organized?" or "It's been a minute since I've written a blog post."&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Is everyone just hard to deal with?&lt;/strong&gt; &lt;em&gt;This is usually a good question to ask when being around other humans reaches a new height of difficulty. Usually, if everyone around me is being a jerk, it's them being the jerk it's me and usually that indicates something wrong internally like lack of sleep, feeling restricted, something personal going on that they had no hand in.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Do I actually know where I'm going?&lt;/strong&gt; &lt;em&gt;Often a source of lack of focus or productivity and in turn a lack of being well is a result of not having a clear understanding of why I'm doing what I'm doing or how it will be in service of whatever goal and worse not knowing what the goal was to begin with. Not understanding where you're going can confuse where you are. Sometimes this distance is where I'm hoping to be in the next hour or next three years, it doesn't matter, taking basic inventory of the why can only clarify the what.&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Ever Upwards
&lt;/h3&gt;

&lt;p&gt;This is where I think we have some basic level of functioning and cognition and we move onto what can actually bring some excitement back into the work itself.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Am I engaged in what I'm being paid to build or am I just applying a "paint by numbers" approach?&lt;/strong&gt; &lt;em&gt;Some times that's easy to do. Some times this is the job and that's fine. Just getting a clear answer to this can tell you a lot and give you coordinates as to what to do next. Say you're content with the work being simple, it gives you some reserves back to invest in the rest of your team or pick up some background task. If you're not okay with the answer being yes, it's a great opportunity for on a technical level automation or abstraction and on a career level the chance to say to your manager, you need something with more to chew.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Is there any tech that I care about that I'd like to see at use at work?&lt;/strong&gt; &lt;em&gt;We all have little lists, maybe it's Rust or Go or Elixir or Vue.js. We all have things we want to learn and this list can shame or taunt us. Spending an hour of your time (or better yet your employers time) to do a "Hello world!" tutorial with one of the things on your list is a low-cost remedy to this.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Why am I building what I'm building and who does it help?&lt;/strong&gt; &lt;em&gt;You can take as many tickets as you like, work your backlog until someone notices, but if don't understand who you're building it for, there's not a lot of point. Some times the answer to this question is unsavory, like you're building something so people in suits and put a PowerPoint presentation together to talk to other people in suits. Other times, what you're doing can bring someone real value. Find that answer.&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  What about making software?
&lt;/h3&gt;

&lt;p&gt;If you got this far and were expecting a post about software engineering and have been disappointed. I'm going to balance that binary tree in your heart.&lt;/p&gt;

&lt;p&gt;First of all you can think of this outline as a framework, let's see how many stars on GitHub it gets.&lt;/p&gt;

&lt;p&gt;Second, software is made by humans, ensuring the bare minimum care and humanity of anyone who needs to build things and affirming that humans actually have needs can only aide in the process of growing as an engineer. To put that more practically, I don't care how the performance of using observables in my application really impacts my users, if I haven't slept or eaten something proper.&lt;/p&gt;




&lt;p&gt;I can't be a good engineer, if I'm not a good human. I'm done shirking that notion or battering with it. Most software engineers make software for other humans to use, if we can't acknowledge the baseline humanity we possess and care for it, why are we making things for other humans? If we can't, we're no better than the amassing pile of La Croix and Red Bull cans in the recycling bins.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Originally published on &lt;a href="https://charlespeters.net/writing/self-care/"&gt;charlespeters.net&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Sign up for my &lt;a href="https://tinyletter.com/charlespeters"&gt;newsletter&lt;/a&gt;, follow me on Twitter &lt;a href="https://twitter.com/charlespeters"&gt;@charlespeters&lt;/a&gt; or find me at &lt;a href="https://charlespeters.net/"&gt;charlespeters.net&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>growth</category>
      <category>career</category>
      <category>personal</category>
    </item>
    <item>
      <title>Formik &amp; React Testing Library and Screaming at a Computer for an Hour</title>
      <dc:creator>charlie⚡</dc:creator>
      <pubDate>Mon, 16 Dec 2019 01:37:38 +0000</pubDate>
      <link>https://dev.to/charliewilco/formik-react-testing-library-and-screaming-at-a-computer-for-an-hour-5h5f</link>
      <guid>https://dev.to/charliewilco/formik-react-testing-library-and-screaming-at-a-computer-for-an-hour-5h5f</guid>
      <description>&lt;p&gt;I have loved using both &lt;a href="https://jaredpalmer.com/formik/"&gt;Formik&lt;/a&gt; and &lt;a href="https://testing-library.com/"&gt;React Testing Library&lt;/a&gt;. At this point in the React community, I consider these tools to be nice sensible defaults of projects of any real size.&lt;/p&gt;

&lt;p&gt;This afternoon, I needed to write some unit tests for some components that I had to add to my project and they were horribly broken.&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="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;React&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="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@testing-library/jest-dom/extend-expect&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;Formik&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Field&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;formik&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;render&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fireEvent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;waitForElement&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;@testing-library/react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Very important form&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;submits values and fires&lt;/span&gt;&lt;span class="dl"&gt;'&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="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;mock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fn&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;getByText&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getByTestId&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;render&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;Formik&lt;/span&gt; &lt;span class="na"&gt;initialValues&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="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="p"&gt;}&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="nx"&gt;mock&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;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="nc"&gt;Field&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;"name"&lt;/span&gt; &lt;span class="na"&gt;data-testid&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&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;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;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="nc"&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="nc"&gt;Formik&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;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;waitForElement&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;getByTestId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Input&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;button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;waitForElement&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;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Submit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

    &lt;span class="nx"&gt;fireEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;change&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="na"&gt;target&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Charles&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="p"&gt;});&lt;/span&gt;

    &lt;span class="nx"&gt;fireEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mock&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toBeCalled&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;calls&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Charles&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="p"&gt;});&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;What I want to validate is that &lt;code&gt;mock&lt;/code&gt; was called when the form submits and to see the results of &lt;code&gt;onSubmit&lt;/code&gt; include the value I typed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Identifying the Problem
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ⛔️ Jest's Cache
&lt;/h3&gt;

&lt;p&gt;Normally, when I have tests like this don't pass, where everything looks good, I start to blame Jest itself. Jest has a pretty heavy caching system. This allows you to continually be watching test files and run them very quickly and its cache is a good thing. But occasionally (am empirically) that cache gives false positives and I have found that clearing this cache and re-running your tests can give you the validation that your tests are rightfully passing. You can do that by running:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;And typically in your CI process (like Travis or GitHub Actions), you should include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;jest --no-cache
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But running your tests locally on your machine, caching is a good thing.&lt;/p&gt;

&lt;p&gt;And with the cache cleared, still broken.&lt;/p&gt;

&lt;h3&gt;
  
  
  ⛔️ Maybe &lt;code&gt;act()&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;React DOM's test utils package (&lt;code&gt;react-dom/test-utils&lt;/code&gt;) has a utility called &lt;code&gt;act()&lt;/code&gt; and React Testing Library has a wrapper around it too. &lt;code&gt;act()&lt;/code&gt; (from what I understand) prepares a container to be updated by batching all updates like the way it would work in the browser. So things like updating the state or re-rendering components should be wrapped in &lt;code&gt;act()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Anytime you're performing an async operation, it's helpful to wrap things in &lt;code&gt;act()&lt;/code&gt; and it's covered in the &lt;a href="https://testing-library.com/docs/react-testing-library/faq"&gt;FAQ&lt;/a&gt; section of React Testing Library.&lt;/p&gt;

&lt;p&gt;Wrapping the events that update the component like this:&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;act&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fireEvent&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;@testing-library/react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;span class="nx"&gt;act&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;fireEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;change&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="na"&gt;target&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Charles&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="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;act&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;fireEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;button&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;Didn't help, still broken.&lt;/p&gt;

&lt;h3&gt;
  
  
  ⛔️ User Error
&lt;/h3&gt;

&lt;p&gt;At this point, I read through (perhaps too quickly) both Formik and React Testing Library's documentation sites and not finding anything that stood out about the tests I was writing being wrong or missing anything.&lt;/p&gt;

&lt;p&gt;I read through all of the documentation from Jest on using &lt;code&gt;jest.fn()&lt;/code&gt; mocks. And nothing. 😭&lt;/p&gt;

&lt;p&gt;At this point, I was incredibly frustrated, I uttered every swear word at an array of volumes at my computer and even perhaps invented new swear words. I contemplated switching professions, I went for a walk around the office and drank a glass of water. 🤬&lt;/p&gt;

&lt;p&gt;My tests were still broken. 😤&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ A mysterious solution found buried in GitHub Issues
&lt;/h3&gt;

&lt;p&gt;Then I searched for "React Testing Library" in the Issues section of the Formik repo and found this &lt;a href="https://github.com/jaredpalmer/formik/issues/1554"&gt;#1554&lt;/a&gt;. Since, Formik runs it's validations internally, async, then calls the &lt;code&gt;onSubmit&lt;/code&gt; props, we need to await the results. React Testing Library gives us a utility for this it's called &lt;a href="https://testing-library.com/docs/dom-testing-library/api-async#wait"&gt;&lt;code&gt;wait()&lt;/code&gt;&lt;/a&gt;. We need to wait to see if &lt;code&gt;mock&lt;/code&gt; is called and to checkout the results.&lt;/p&gt;

&lt;p&gt;The solution looks like this:&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="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;React&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="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@testing-library/jest-dom/extend-expect&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;Formik&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Field&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;formik&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;render&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fireEvent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;waitForElement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;wait&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;@testing-library/react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Very important form&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;submits values and fires&lt;/span&gt;&lt;span class="dl"&gt;'&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="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;mock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fn&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;getByText&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getByTestId&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;render&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;Formik&lt;/span&gt; &lt;span class="na"&gt;initialValues&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="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="p"&gt;}&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="nx"&gt;mock&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;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="nc"&gt;Field&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;"name"&lt;/span&gt; &lt;span class="na"&gt;data-testid&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&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;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;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="nc"&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="nc"&gt;Formik&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;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;waitForElement&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;getByTestId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Input&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;button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;waitForElement&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;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Submit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

    &lt;span class="nx"&gt;fireEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;change&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="na"&gt;target&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Charles&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="p"&gt;});&lt;/span&gt;

    &lt;span class="nx"&gt;fireEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;wait&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;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mock&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toBeCalled&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;calls&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Charles&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="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 now my tests are passing.&lt;/p&gt;

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

&lt;p&gt;Feel your feelings. If your tests aren't passing with either of these libraries, see if using &lt;code&gt;wait()&lt;/code&gt; or &lt;code&gt;act()&lt;/code&gt; might help and swearing at your computer isn't the worst thing in the world but having a glass of water is also a good idea.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Sign up for my &lt;a href="https://tinyletter.com/charlespeters"&gt;newsletter&lt;/a&gt;, follow me on Twitter &lt;a href="https://twitter.com/charlespeters"&gt;@charlespeters&lt;/a&gt; or find me at &lt;a href="https://charlespeters.net/"&gt;charlespeters.net&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>testing</category>
      <category>formik</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Learning TypeScript: Value of a Strongly Typed Projects 💪</title>
      <dc:creator>charlie⚡</dc:creator>
      <pubDate>Tue, 05 Nov 2019 22:06:48 +0000</pubDate>
      <link>https://dev.to/charliewilco/learning-typescript-value-of-a-strongly-typed-projects-1647</link>
      <guid>https://dev.to/charliewilco/learning-typescript-value-of-a-strongly-typed-projects-1647</guid>
      <description>&lt;p&gt;One the first things you're going to encounter working with TypeScript is this idea that it's prohibitive or it's a lot of setup. I've been there. Then I remember this quote:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;TypeScript shines not on day 1, but on on day 100, and becomes a freaking supernova on day 500. -- &lt;a href="https://twitter.com/jaredpalmer/status/1057115161616637952"&gt;Jared Palmer&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As you start working in a codebase you don't have a lot there. Then add some community types for the libraries you're using; that's one level of productivity, the libraries you're using are now showing where you're using their API wrongly, and that's sort of helpful on a level but we can do better.&lt;/p&gt;

&lt;p&gt;Then you have more code and more requirements in your project and those types you're adding accrue by a magnitude. At this point your application has certain models or pieces of UI or concepts that you want to make discernible, like in a chat app you might have a type interface for the message and one for the thread of messages.&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;IMessage&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;content&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;attachments&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;IAttachment&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="nl"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;IUser&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;dateSent&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="p"&gt;}&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IThread&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;IMessage&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="nl"&gt;isTyping&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;pollingInterval&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;Now let's image the &lt;code&gt;IMessage&lt;/code&gt; interface changes, your code to add a message or poll for new messages is likely to be broken because of that. Because you introducted this interface and can now see where your application was using, you can see with a small change the impact of that change. That to me this is one of the key values of using strong types and it's not one you see you day one, it's one you see when you're deep into a project and adding new features.&lt;/p&gt;

&lt;h3&gt;
  
  
  Strongly Typed?
&lt;/h3&gt;

&lt;p&gt;You might've heard people throw around this term "strongly typed" (like I just did), a strongly typed project or a strongly typed language. When I first heard it, I wasn't quite sure what it meant. To answer that we need to define what a "weak" types are; weak types are type annotations that don't break compliation or in some way permissible where by contrast, strongly typed projects or languages fail compliation if a type error exists. Using TypeScript's &lt;a href="https://dev.to/briwa/how-strict-is-typescript-s-strict-mode-311a"&gt;"strict mode"&lt;/a&gt; can be a method for building a strongly typed project.&lt;/p&gt;

&lt;p&gt;Anyway, if you're feeling the pain or the tedium of migrating to TypeScript or getting start with it, trust me from experience, it pays off, especially when you get to a point where you have to make bigger refactors in your project or need to build more features, from experience you can do that with my more confidence embracing a strong types in your project.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Wherever you are in your journey with TypeScript, sign up for my &lt;a href="https://charlespeters.net/subscribe"&gt;newsletter&lt;/a&gt;, follow me on Twitter &lt;a href="https://twitter.com/charlespeters"&gt;@charlespeters&lt;/a&gt; or find me at &lt;a href="https://charlespeters.net/"&gt;charlespeters.net&lt;/a&gt;, I'm working on some resources to help.&lt;/em&gt; &lt;/p&gt;




&lt;h2&gt;
  
  
  Links 📝
&lt;/h2&gt;

&lt;p&gt;These are some seriously cool things I encountered while I was working the last couple of weeks.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/jaredpalmer/formik/releases/tag/v2.0.1"&gt;&lt;strong&gt;Formik 2 in Hooks&lt;/strong&gt;&lt;/a&gt;: Formik, like React Router or is one of those tools you just grab when you're building a project of any real size. With the latest release, you can now ditch the Render Props pattern for hooks and components and I got the rare chance to role this out on a branch in my current sprint and I couldn't be happier with how much code I got rid and how much easier it was to work with.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.amazon.com/Effective-TypeScript-Specific-Ways-Improve/dp/1492053740"&gt;&lt;strong&gt;&lt;em&gt;Effective TypeScript: 62 Specific Ways to Improve Your TypeScript&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt;: I heard Dan Vanderkam speak at TSConf this year and I am ridiculously excited for the giant company that delivers things quickly to my house, to quickly deliver his book to my house.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Sign up for my &lt;a href="https://tinyletter.com/charlespeters"&gt;newsletter&lt;/a&gt;, follow me on Twitter &lt;a href="https://twitter.com/charlespeters"&gt;@charlespeters&lt;/a&gt; or find me at &lt;a href="https://charlespeters.net/"&gt;charlespeters.net&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>learning</category>
      <category>growth</category>
    </item>
    <item>
      <title>Exponents: Learning to Grow</title>
      <dc:creator>charlie⚡</dc:creator>
      <pubDate>Fri, 01 Nov 2019 20:09:41 +0000</pubDate>
      <link>https://dev.to/charliewilco/exponents-learning-to-grow-15k6</link>
      <guid>https://dev.to/charliewilco/exponents-learning-to-grow-15k6</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;I wrote this last year and each one of these things are still something I do every day&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I feel like I've been falling into front-end engineering roles for years. I'm mostly self-taught (and that story is detailed &lt;a href="https://charlespeters.net/writing/a-defense-of-frameworks/"&gt;more here&lt;/a&gt;). Some concept or problem never quite clicked right, something I don't know how to describe well or even understand. I shrug it off, I get back to the job at hand, fervently googling, finding a good fix and moving on. Lately, I'm noticing I want to grow more deliberately versus as just a byproduct of my experience.&lt;/p&gt;

&lt;p&gt;Don't get me wrong: &lt;strong&gt;&lt;em&gt;practical experience is good&lt;/em&gt;&lt;/strong&gt;. Top shelf; would recommend.&lt;/p&gt;

&lt;p&gt;But I don't feel like I grew as an engineer as exponentially as I wanted to and I didn't know what to do other than getting a CS degree (which I didn't feel like investing time or money in). Or more succinctly, I plateaued on experience. So I started working with different senior engineers and seeking advice and cobbling together something of a curriculum.&lt;/p&gt;

&lt;p&gt;This post is basically 5 quick behavior changes and shifts in thinking that have helped me grow more as an engineer in the last summer.&lt;/p&gt;

&lt;p&gt;If you wanna save some time, watch this older &lt;a href="https://www.youtube.com/watch?v=v0TFmdO4ZP0"&gt;talk &lt;em&gt;"JavaScript Masterclass"&lt;/em&gt;&lt;/a&gt;, by Angelina Fabbro from JSConf US 2013. I watch it pretty regularly and still learn a lot from it, every one of her points is still relevant 5 years later. Below are things I've been trying to do, most of those come from that talk.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Read the Source Code
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Read the source code of the projects you use&lt;/strong&gt;. I use React almost everyday, &lt;a href="https://nextjs.org/"&gt;Next.js&lt;/a&gt; just as much. I spend time browsing these repositories a lot. I don't understand all the code I read; that's okay. Occasionally I learn something.&lt;/p&gt;

&lt;p&gt;This process takes about 20 minutes, a few times a week of the projects you use. With Next.js I found settings that weren't well documented, I understood more about the way data-fetching works in that framework and more importantly made sense of &lt;em&gt;work I was currently doing&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I feel like you'd get more diminishing returns on projects you don't use or care about. Like if I read Angular's source code, I wouldn't necessarily get any value from it, because I have never used it.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Spend Time in Another Language
&lt;/h3&gt;

&lt;p&gt;JavaScript is my first programming language. I worked in PHP for a little bit, but primarily just JavaScript. But I get tunnel visioned since I know how to get things done without having to think too much about it. Spending time in another language, where that cursory knowledge doesn't exist, forces you to rethink why you're making the choices you're making.&lt;br&gt;
Vacation in another language; ReasonML and Elixir are pretty damn cool and so is Python or C#.&lt;/p&gt;

&lt;p&gt;Coming back to the work you do every day, knowing why the pipe operator exists in Elixir or why C# has namespaces or how immutability works in Python, has made me appreciate JavaScript more and want to see the overarching design patterns in programming.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Test — Let the Errors Guide You
&lt;/h3&gt;

&lt;p&gt;This one feels like common sense. This is more of a shift in perspective. Errors used to piss me off, so, so much. I watched a preview for Ben Orenstein's &lt;a href="https://www.refactoringrails.io/"&gt;&lt;em&gt;Refactoring Rails&lt;/em&gt;&lt;/a&gt; course and one guiding principle was:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Write the code you wish you had. Let the errors guide you.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;First, this makes me want to write more unit tests that are unit tests and not &lt;a href="http://wiki.c2.com/?PinningTests"&gt;pinning tests&lt;/a&gt;; meaning that tests cover the objective versus the hyper specific implementation you have. Then, it gives me a different way to look at errors, instead of angry demands from a cold indifferent universe but as guide-posts towards code I want to have in my project.&lt;/p&gt;

&lt;p&gt;Static analysis is often a great stop gap to testing and arguably can give you more immediate and relevant value than unit testing alone. I had to learn TypeScript when I started my current contract. The process of learning how to use TypeScript made me rethink how I want to write JavaScript to make sure my code is easier to read, share and annotate.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Learn Big O Notation
&lt;/h3&gt;

&lt;p&gt;Big O is the runtime of an algorithm. It measures how long a piece of code will take to run, the input and how much memory they use. There are different types of algorithms: Constant, Linear, Quadratic, Logarithmic, Factorial. The more iteration, the longer your code needs to run.&lt;/p&gt;

&lt;p&gt;To be honest, I don't understand this concept really well. My main take away was that arrays and for loops were not a great answer for everything. Sometimes Maps and Sets in JavaScript were better answers and led me to spend time reading and finding ways to implement them. But the awareness of other options makes a huge difference, in that you're less isolated with the wrong primitives.&lt;/p&gt;

&lt;p&gt;If you want to read something about Data Structures and Big O read &lt;a href="https://github.com/jamiebuilds/itsy-bitsy-data-structures"&gt;&lt;em&gt;‌Itsy Bitsy Data Structures&lt;/em&gt;&lt;/a&gt;, by Jamie Kyle. It makes these difficult concepts easier to understand.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/cesars-tech-insights/big-o-notation-javascript-25c79f50b19b"&gt;https://medium.com/cesars-tech-insights/big-o-notation-javascript-25c79f50b19b&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Try Vim
&lt;/h3&gt;

&lt;p&gt;This is more of a bonus. Lately, I'm using a Vim mode inside VSCode because my team really loves the workflow with shared settings; I really miss terminal Vim.&lt;/p&gt;

&lt;p&gt;But working in Vim makes you think about how you navigate around a file and how inefficiently you move. Vim uses an idea called "modal editing" which means you update text by switching in and out of modes. Normal Mode doesn't allow you to type, where Insert mode actually allows you to add code to your file. The common wisdom is that you don't live in Insert mode but you should &lt;em&gt;normally&lt;/em&gt; be in Normal mode and this switch just causes me to be more deliberate about what I write. It's just a mental switch.&lt;/p&gt;




&lt;p&gt;That's all I got so far. Small behavior changes and shifts in thinking. As always: YMMV.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Originally published on &lt;a href="https://charlespeters.net/writing/exponents/"&gt;charlespeters.net&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Sign up for my &lt;a href="https://tinyletter.com/charlespeters"&gt;newsletter&lt;/a&gt;, follow me on Twitter &lt;a href="https://twitter.com/charlespeters"&gt;@charlespeters&lt;/a&gt; or find me at &lt;a href="https://charlespeters.net/"&gt;charlespeters.net&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>growth</category>
      <category>career</category>
      <category>motivation</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Learning TypeScript: Start By Adding Notes 👩‍💻</title>
      <dc:creator>charlie⚡</dc:creator>
      <pubDate>Tue, 22 Oct 2019 05:22:21 +0000</pubDate>
      <link>https://dev.to/charliewilco/learning-typescript-start-by-adding-notes-21cf</link>
      <guid>https://dev.to/charliewilco/learning-typescript-start-by-adding-notes-21cf</guid>
      <description>&lt;p&gt;A lot of people I've talked to who are getting started with TypeScript have some sentiment that it feels more daunting than it might actually be or they don't know enough to get started. I can definitely empathize with both. There's a lot of misconceptions about how you have to write code or changing your code to fit into being typed or that there's a lot they need to learn to be efficient.&lt;/p&gt;

&lt;p&gt;When I had to learn TypeScript, I just kept thinking that it was notes on the code I'm already writing, nothing is really changing, only adding "annotations" on top of the components I'm already writing.&lt;/p&gt;

&lt;p&gt;Before:&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;class&lt;/span&gt; &lt;span class="nx"&gt;CustomComponent&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nx"&gt;defaultProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;default&lt;/span&gt;&lt;span class="dl"&gt;"&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;content&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="nx"&gt;updateContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;content&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;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="nx"&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;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;p&gt;After with TypeScript:&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="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;default&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;warning&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="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;State&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;content&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="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;CustomComponent&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&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;State&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;static&lt;/span&gt; &lt;span class="na"&gt;defaultProps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;default&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="na"&gt;state&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;content&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="nx"&gt;updateContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;content&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;void&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;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;JSX&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Element&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;p&gt;The code I wrote didn't change at all while writing this, it only added small annotations as to what types, and what shape some objects are intended to be. There's really not a lot that you need to understand, primitive types for return values for each method, &lt;code&gt;string&lt;/code&gt; and &lt;code&gt;void&lt;/code&gt; (meaning returns a string or nothing, respectively), there's now an interface and that just shows what an object will look like and they're attached via this syntax with the &lt;code&gt;&amp;lt;,&amp;gt;&lt;/code&gt; (they're called generics and they're not super important to getting started, you'll typically see them a lot when you're working with a framework). We also added a type for the parameter, (content: string), meaning the only value we can pass that method must be a string.&lt;/p&gt;

&lt;p&gt;When you're getting started with TypeScript, my number one recommendation is to change your file type from &lt;code&gt;.js&lt;/code&gt; to &lt;code&gt;.ts&lt;/code&gt; or &lt;code&gt;.tsx&lt;/code&gt; and don't amend the code you were going to write, just add annotations. Eventually you'll run into some errors, and when they do come up, let the errors guide you. But don't intentionally change your code.&lt;/p&gt;

&lt;p&gt;You'll notice as you start doing this your application will start show patterns you may not have noticed, useful places you can breakout in to sharable patterns, you'll also start to notice that there's parameters you're not using or parts of objects you're not using.&lt;/p&gt;

&lt;p&gt;TypeScript can do a lot for a project, big or small, but it doesn't take a lot to start feeling the value and reaping the benefits.&lt;/p&gt;

&lt;p&gt;Writing code and documenting the type annotations can start to inform how you write code and write your type annotations. My experience has been after a few weeks, I was thinking about types before I started to write code and then wrote the code and saw where TypeScript was throwing errors and those became guides to what to work on next.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Wherever you are in your journey with TypeScript, sign up for my &lt;a href="https://charlespeters.net/subscribe"&gt;newsletter&lt;/a&gt;, follow me on Twitter &lt;a href="https://twitter.com/charlespeters"&gt;@charlespeters&lt;/a&gt; or find me at &lt;a href="https://charlespeters.net/"&gt;charlespeters.net&lt;/a&gt;, I'm working on some resources to help.&lt;/em&gt; &lt;/p&gt;




&lt;h2&gt;
  
  
  Links 📝
&lt;/h2&gt;

&lt;p&gt;These are some seriously cool things I encountered while I was working the last couple of weeks.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://graphql-code-generator.com/"&gt;&lt;code&gt;graphql-codegen&lt;/code&gt;&lt;/a&gt;&lt;/strong&gt;: seriously, this tool saved so much of my time this week. If you use TypeScript or GraphQL this tool is pure MAGIC ✨. It not only autogenerated the interfaces from my schema but custom hooks 🎣 to match the queries and mutations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://twitter.com/wycats/status/1183503530524475392"&gt;Yehuda Katz on TypeScript 3.7&lt;/a&gt;&lt;/strong&gt; (a Twitter thread): "TS has also helped push JS forward. It's not only a mostly-compliant JS transpiler (e.g. class features), but it also does a really great job of adding type semantics to virtually all new features as quickly as possible (symbols in interfaces, generators, optional chaining)"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://reacttraining.com/blog/react-router-v5-1/"&gt;React Router v5.1&lt;/a&gt;&lt;/strong&gt;: React Router now ships with hooks and I deleted so much code because of it. And there's nothing nicer.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Sign up for my &lt;a href="https://tinyletter.com/charlespeters"&gt;newsletter&lt;/a&gt;, follow me on Twitter &lt;a href="https://twitter.com/charlespeters"&gt;@charlespeters&lt;/a&gt; or find me at &lt;a href="https://charlespeters.net/"&gt;charlespeters.net&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>react</category>
      <category>learning</category>
    </item>
  </channel>
</rss>
