<?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: Sid</title>
    <description>The latest articles on DEV Community by Sid (@siddharthkp).</description>
    <link>https://dev.to/siddharthkp</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%2F666%2F50377d8b-d5c3-46f9-8a47-855edf52d2d1.jpg</url>
      <title>DEV Community: Sid</title>
      <link>https://dev.to/siddharthkp</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/siddharthkp"/>
    <language>en</language>
    <item>
      <title>So you want to start a blog</title>
      <dc:creator>Sid</dc:creator>
      <pubDate>Fri, 24 May 2019 05:50:50 +0000</pubDate>
      <link>https://dev.to/siddharthkp/so-you-want-to-start-a-blog-2a04</link>
      <guid>https://dev.to/siddharthkp/so-you-want-to-start-a-blog-2a04</guid>
      <description>&lt;p&gt;I wrote this post for my newsletter, &lt;a href="https://sid.studio/newsletter"&gt;sign up here&lt;/a&gt; to get emails like these every week.&lt;/p&gt;

&lt;p&gt;Before I started my blog/newsletter ~ 11 months ago, I had a lot of reasons not to. Most of these are insecurities disguised as excuses.&lt;/p&gt;

&lt;p&gt;Let's pick them apart one by one.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I don't have anything interesting to say&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let me be the first one to tell you - Your point of view is unique and I would love to hear it.&lt;/p&gt;

&lt;p&gt;All of us work on similar things and engage with the same technologies, but all of us have a different way of looking at the world.&lt;/p&gt;

&lt;p&gt;When you write a blog post, you are sharing your point of view. Folks who share your world view will find it relatable, that's great. They might not have the same point of view and get a chance to see the same thing from a different perspective, that's also really valuable.&lt;/p&gt;

&lt;p&gt;Think about what you have learned or done in the last 6 months that was new for you - make a small list of potential blog posts titles.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I'm not experienced enough to write an article&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you are learning something new and don't feel like an expert, here's a secret: Nobody feels like an expert.&lt;/p&gt;

&lt;p&gt;In the javascript space, there's so much to learn and it changes so fast.&lt;/p&gt;

&lt;p&gt;Small detour into what &lt;a href="https://medium.com/javascript-scene/why-im-thankful-for-js-fatigue-i-know-you-re-sick-of-those-words-but-this-is-different-296fae0c888f"&gt;Eric Elliot wrote about javascript fatigue&lt;/a&gt; because I think it's a great perspective:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Learning JS can be overwhelming. I know it can feel like there is an ocean of stuff you don’t know. Trying to soak it all up is like trying to soak up the real ocean with a beach towel.&lt;/p&gt;

&lt;p&gt;It’s never going to happen. I can’t keep up. Dan Abramov isn’t keeping up. Brendan Eich isn’t keeping up. Don’t stress out because you can’t, either. We’re all on the same bullet train here, and no matter what seat you’re sitting in, the world outside the windows is all a blur.&lt;/p&gt;

&lt;p&gt;We “experts” know a lot about our little corners of the web platform, but we don’t know every little thing about every little thing. If you’ve been at it more than a year or two, chances are very good that you know a lot of stuff I don’t know about web development. I’m cool with that.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;All that to say, waiting till you "become an expert" is a waste of time. We can all contribute with what we know today. With anything that you learned this year, there are hundreds around you that want to learn that.&lt;/p&gt;

&lt;p&gt;There's this quote I really like: &lt;em&gt;"Document, not create"&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;We're not inventing new things here. At best, we're discovering patterns. Share as you learn. I wrote an entire series about &lt;a href="https://sid.studio/component-api"&gt;writing Good Components&lt;/a&gt;, I didn't invent any of those patterns. I learned them from others and presented them from my perspective and examples.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I just started learning, I'll share more when I have more knowledge&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you just learned something, you have a perspective that is more useful than someone who is doing this for a while.&lt;/p&gt;

&lt;p&gt;After working with React (and javascript) for a while now, there are a lot of weird quirks that I take for granted. I have to constantly remind myself not to use technical jargon that would alienate someone new.&lt;/p&gt;

&lt;p&gt;I have stopped conducting beginner workshops for React because I'm simply not a good teacher for that anymore. If you are in the learning new things stage, your fresh perspective will help others in the same stage.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What If I make mistakes?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This one is the hardest for me. What if I say something that I believe to be true, but it turns out wrong. Or worse, what if I share an opinion that's works for me but harmful for others.&lt;/p&gt;

&lt;p&gt;I try not to be wrong. I do my research before putting something in an article, I'll run all the code that I show as examples.&lt;/p&gt;

&lt;p&gt;That fear is sometimes a feature not a bug - it helps you to put in the work and reach a layer of understanding that is deeper than you had before. It helps me choose my words wisely and become better at communicating.&lt;/p&gt;

&lt;p&gt;But most of the times, the fear is just a bug - it's my imposter syndrome talking. It's easier to keep my thoughts to myself and never find out if I'm wrong.&lt;/p&gt;

&lt;p&gt;Here's the thing, it's okay to be wrong. The folks who read your article won't hold it against you as a person. You might get a mean comment on rare occasions, but trust me, you get over that after a few times because the folks who you're able to help would be way higher.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I have a topic in mind, but will anyone find it interesting?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This happens to me almost every week. I have a post in mind but I'm not sure if it's interesting to others.&lt;/p&gt;

&lt;p&gt;It's impossible to write for the masses, you can't please everyone. It helps to keep a specific person in mind when you're writing - you're only trying to help one person. Chances are there are plenty others that will benefit from the same article.&lt;/p&gt;

&lt;p&gt;Bonus: This style of writing feels personal to the reader which makes it more enjoyable.&lt;/p&gt;

&lt;p&gt;When it's your own blog, you get to do whatever you want. You are writing for yourself (and for that one person). If you feel like writing about a topic, go for it!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Even if I write it, nobody will read it&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you're just starting out, I hear you. If you don't have folks that you can send your article to, it's hard to find the motivation. I've been there.&lt;/p&gt;

&lt;p&gt;Fortunately for us, we are part of a very welcoming community.&lt;/p&gt;

&lt;p&gt;You can post your article on community sites like &lt;a href="https://dev.to"&gt;dev.to&lt;/a&gt;, &lt;a href="https://hashnode.com"&gt;hashnode&lt;/a&gt; and &lt;a href="https://spectrum.chat"&gt;spectrum&lt;/a&gt; or submit to medium publications like &lt;a href="https://medium.freecodecamp.org/"&gt;freeCodeCamp&lt;/a&gt; and &lt;a href="https://hackernoon.com"&gt;hackernoon&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;All of the above are way more fun than reddit/hackernews. &lt;a href="https://dev.to"&gt;dev.to&lt;/a&gt; is my favorite right.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I just need to rebuild my blog before I start writing&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The best designed blog wouldn't be helpful if there are no posts on it. This is usually a way to procrastinate.&lt;/p&gt;

&lt;p&gt;Clone a &lt;a href="https://github.com/gatsbyjs/gatsby-starter-blog"&gt;starter kit&lt;/a&gt; and start writing. Hell, you can even write your posts in a public GitHub repository and share them.&lt;/p&gt;

&lt;p&gt;When you have some posts rolling and some folks reading them, it will be more fun to over-engineer your blog.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Hope that was useful and gives you a tiny nudge to start&lt;/p&gt;

&lt;p&gt;Sid&lt;/p&gt;




&lt;p&gt;&lt;a href="https://sid.studio/newsletter"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lTObUt2X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sid.studio/newsletter-snapshot.png%3Fv%3D4" alt="newsletter"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>blog</category>
    </item>
    <item>
      <title>Why do we keep talking about CSS-in-JS?</title>
      <dc:creator>Sid</dc:creator>
      <pubDate>Tue, 07 May 2019 04:03:23 +0000</pubDate>
      <link>https://dev.to/siddharthkp/why-do-we-keep-talking-about-css-in-js-35i8</link>
      <guid>https://dev.to/siddharthkp/why-do-we-keep-talking-about-css-in-js-35i8</guid>
      <description>&lt;p&gt;Remember the first time you wrote some html/css? It was amazing, right?&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"color: blue"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Hello world&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;So simple, so pure.&lt;/p&gt;

&lt;p&gt;Then, of course, the senior developer™ told you not to write your css like this and put it a separate file.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"blue-text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Hello world&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* style.css */&lt;/span&gt;
&lt;span class="nc"&gt;.blue-text&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;blue&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;As you build more elements and pages, your &lt;code&gt;style.css&lt;/code&gt; starts getting long, so you split it into multiple files.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* landing-page.css */&lt;/span&gt;
&lt;span class="nc"&gt;.heading&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;64px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;orange&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"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* forms.css */&lt;/span&gt;
&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;blue&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;Soon, you realise that styles intended for one element start clashing and overwriting others. You adopt some form of name-spacing to create a &lt;em&gt;scope&lt;/em&gt; for these styles.&lt;/p&gt;

&lt;p&gt;Maybe something as simple as this:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;form&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;placeholder=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;button&amp;gt;&lt;/span&gt;Submit&lt;span class="nt"&gt;&amp;lt;button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* form.css */&lt;/span&gt;
&lt;span class="nt"&gt;form&lt;/span&gt; &lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;blue&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;Or something more advanced like &lt;a href="http://getbem.com"&gt;BEM&lt;/a&gt;:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"form"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"form__input"&lt;/span&gt; &lt;span class="na"&gt;placeholder=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"form__button"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Submit&lt;span class="nt"&gt;&amp;lt;button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* form.css */&lt;/span&gt;
&lt;span class="nc"&gt;.form__button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;blue&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;I really liked BEM (and other convention based methods like OOCSS, ITCSS, etc.). You can solve a hairy problem by merely adopting a common convention in your team.&lt;/p&gt;

&lt;p&gt;Either way, the problem you are solving here is of scoping styles to a specific context.&lt;/p&gt;

&lt;p&gt;The same problems and solutions are carried into React land as well. Take this &lt;code&gt;LoginForm&lt;/code&gt; for example:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;LoginForm&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;className=&lt;/span&gt;&lt;span class="s2"&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;placeholder=&lt;/span&gt;&lt;span class="s2"&gt;"username"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s2"&gt;"text "&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;placeholder=&lt;/span&gt;&lt;span class="s2"&gt;"password"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s2"&gt;"password"&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;className=&lt;/span&gt;&lt;span class="s2"&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 have no idea if that button is going to clash with another button in the application somewhere else. We should use some sort of scope here. You can still use namespacing like BEM here with React.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"form__button"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Submit&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This is where the story get's interesting. In a React component, we aren't writing plain &lt;code&gt;HTML&lt;/code&gt; anymore, we are writing &lt;code&gt;JSX&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The above line of JSX is converted to this block of javascript at build time:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="s1"&gt;'button'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'form__button'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="s1"&gt;'Submit'&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You have the full power of a programming language (javascript) at your disposal now. You can do things which wouldn't be possible with pure CSS.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  The promise of CSS-in-JS
&lt;/h3&gt;

&lt;p&gt;You can defer the job of creating a scope or name-spacing to the language instead of doing it manually.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://glenmaddern.com/articles/css-modules"&gt;CSS Modules&lt;/a&gt; is the gateway drug the of css-in-js ecosystem.&lt;/p&gt;

&lt;p&gt;This is what you write:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* form.css */&lt;/span&gt;

&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;/* look ma, no name spacing */&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;blue&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"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styles&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;'./form.css'&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;LoginForm&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="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;className=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="si"&gt;}&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;And this is what &lt;code&gt;styles.button&lt;/code&gt; get's compiled to:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;LoginForm&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="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;className=&lt;/span&gt;&lt;span class="s2"&gt;"form__button__abc1"&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;This is very similar to what you would write by hand, but it frees you up from the responsibility of avoiding conflicts. I find it incredibly liberating to be able to write my styles as if they were locally scoped.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  The next wave of CSS-in-JS libraries
&lt;/h3&gt;

&lt;p&gt;We were able to leverage the power of the language in the tooling/automation bit, can we also bring it to writing styles?&lt;/p&gt;

&lt;p&gt;This is where it becomes controversial. Each CSS-in-JS takes a slightly different approach to enable a certain new feature by making a tradeoff.&lt;/p&gt;

&lt;p&gt;For example: &lt;code&gt;jsxstyle&lt;/code&gt; lets you write styles that look like classic inline styles on the element but extracts them out into a file through a webpack plugin.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Block&lt;/span&gt; &lt;span class="nx"&gt;component&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"button"&lt;/span&gt; &lt;span class="nx"&gt;backgroundColor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"blue"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;On the other hand, &lt;code&gt;styled-components&lt;/code&gt; lets you mix runtime logic inside css. This means you can start using it without touching your config but you can't extract the styles out.&lt;/p&gt;



&lt;div class="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;Button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="s2"&gt;`
  background: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;getBackground&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;;
`&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getBackground&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="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;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;appearance&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s1"&gt;'primary'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s1"&gt;'blue'&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="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;appearance&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s1"&gt;'disabled'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s1"&gt;'grey'&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s1"&gt;'white'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;code&gt;linaria&lt;/code&gt; takes an interesting middle route with its &lt;code&gt;css&lt;/code&gt; tag, you can create classes right next to the component and these extract them out during build using a babel plugin. This means you can still use javascript but it can't depend on runtime logic like the previous example.&lt;/p&gt;



&lt;div class="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;button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;css&lt;/span&gt;&lt;span class="s2"&gt;`
  background: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;colors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;;
`&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;MyComponent&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;button&lt;/span&gt; &lt;span class="na"&gt;className=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Click me&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As you can see, all of these libraries bring something to the table in exchange of a something else. This is why it's so controversial, you can take any library and find flaws in it.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;css-modules&lt;/code&gt; automates the work of namespacing styles but requires some setup which can be looked as over-engineering (we already have manual BEM that works without any setup)&lt;/p&gt;

&lt;p&gt;&lt;code&gt;styled-components&lt;/code&gt; on the other hand does not require any babel/webpack setup but it requires the library to be present on runtime, increasing the size of your javascript bundle by a small amount.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;You must choose the tradeoff that works for your project.&lt;/p&gt;

&lt;p&gt;With the &lt;a href="https://github.com/auth0/cosmos"&gt;design system in Auth0&lt;/a&gt;, we chose &lt;code&gt;styled-components&lt;/code&gt; because it helped us create flexible components based on a set of underlying tokens and design patterns.&lt;/p&gt;

&lt;p&gt;Last week, I had to build a bunch of pages with some form logic in them and really enjoyed using &lt;code&gt;css-modules&lt;/code&gt; because it helped me write both global and page specific styles without adopting a manual methodology like BEM.&lt;/p&gt;

&lt;p&gt;You can use this &lt;a href="https://github.com/MicheleBertoli/css-in-js"&gt;comparison table&lt;/a&gt; that my friend &lt;a href="https://twitter.com/michelebertoli"&gt;Michele Bertoli&lt;/a&gt; created.&lt;/p&gt;

&lt;p&gt;Hope that was helpful on your journey&lt;/p&gt;

&lt;p&gt;Sid&lt;/p&gt;




&lt;p&gt;&lt;a href="https://sid.studio/newsletter"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lTObUt2X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sid.studio/newsletter-snapshot.png%3Fv%3D4" alt="newsletter"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>css</category>
      <category>cssinjs</category>
    </item>
    <item>
      <title>React.lazy API in 60 seconds (Code-Splitting with Suspense)</title>
      <dc:creator>Sid</dc:creator>
      <pubDate>Mon, 22 Apr 2019 05:52:52 +0000</pubDate>
      <link>https://dev.to/siddharthkp/react-lazy-api-in-60-seconds-code-splitting-with-suspense-4n16</link>
      <guid>https://dev.to/siddharthkp/react-lazy-api-in-60-seconds-code-splitting-with-suspense-4n16</guid>
      <description>

</description>
      <category>react</category>
      <category>performance</category>
    </item>
    <item>
      <title>Lessons learned from starting a small conference</title>
      <dc:creator>Sid</dc:creator>
      <pubDate>Mon, 22 Apr 2019 05:38:52 +0000</pubDate>
      <link>https://dev.to/siddharthkp/lessons-learned-from-starting-a-small-conference-o61</link>
      <guid>https://dev.to/siddharthkp/lessons-learned-from-starting-a-small-conference-o61</guid>
      <description>&lt;p&gt;I wrote this post for my newsletter, &lt;a href="https://sid.studio/newsletter"&gt;sign up here&lt;/a&gt; to get emails like these every week.&lt;/p&gt;

&lt;p&gt;I'm prepping up for a big project right now. And it's definitely out of my area of expertise. My heart is excited but my brain tells me I have no business even attempting this. I'd like to tell you (and myself) a story the last time I thought I should "stay in my lane".&lt;/p&gt;

&lt;p&gt;I went to a bunch of conferences last year and I had a great time in most of them. Conferences are great for getting inspired from the talks, meeting old friends and making some new ones.&lt;/p&gt;

&lt;p&gt;But, here's the thing, I only watch half the talks. Sitting and listening to one talk after another gets boring real fast. You can always watch the rest of the talks later on youtube at 1.5x.&lt;/p&gt;

&lt;p&gt;Instead, I like to spend time talking to people that I don't see very often.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GqU-E6Ut--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sid.studio/blog/36/talking.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GqU-E6Ut--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sid.studio/blog/36/talking.png" alt="talking to people"&gt;&lt;/a&gt;&lt;br&gt;
&lt;small&gt;I don't know why we look so sad, it was a happy conversation!&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;As an introvert, I find it really hard to just walk up to a stranger and introduce myself. But, when I give a talk, it's an invitation for others come talk to me after the talk about a topic I already like, which makes it so much easier 😇&lt;/p&gt;

&lt;p&gt;Most conferences have a jam-packed schedule with short coffee breaks after every few talks. This forces you to pick - you can either have a long conversation with someone or cut that short and attend the next talk. I usually end up missing talks that I wanted to attend.&lt;/p&gt;

&lt;p&gt;I realised I got the most value out of a conference by having deeper conversations about the topics I really care about and feeling inspired. This could be with a speaker after their talk or with fellow attendees.&lt;/p&gt;

&lt;p&gt;This is my biased experience with conferences, I also know folks who like to attend all the talks, absorb everything like a sponge and synthesise them later. Whatever works for you!&lt;/p&gt;

&lt;p&gt;I wanted to attend a conference that focused on the parts I like - longer meaningful conversations. An event other folks like me would enjoy.&lt;/p&gt;

&lt;p&gt;Couldn't find any. From my experience with helping out with the first ReactFoo, I know organising a conference isn't a small task.&lt;/p&gt;

&lt;p&gt;It takes sponsors and ticket sales and speakers and marketing and an auditorium and catering and audio visual setup and so much more. I didn't really think about it for a few months until I attended another conference.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Screw it, I'm gonna do it - Me&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I always start all my projects with the website because it forces me to explain the idea clearly in a few words.&lt;/p&gt;

&lt;p&gt;I knew the kind of conference I wanted to host.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This conference is designed to involve everyone in the discourse with short talks and plenty of time for discussions and follow-up conversations.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It's really difficult to create an involving 400 people. &lt;em&gt;Small group, meaningful conversations&lt;/em&gt; seems more like the experience I'd enjoy.&lt;/p&gt;

&lt;p&gt;I was really creating a conference for myself and hoping I can find a few other people who would enjoy the same experience.&lt;/p&gt;

&lt;p&gt;Need speakers for a conference, right? Something that can serve as jumping off points for the conversations.&lt;/p&gt;

&lt;p&gt;I wrote down "8 speakers, 25 attendees". Called it &lt;a href="https://tinyconf.in"&gt;tinyconf&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You don't need an auditorium for 25 people, got in touch with my friends at &lt;a href="https://geekyants.com"&gt;Geeky Ants&lt;/a&gt; for their office venue, they have a meetup space which can fit everyone. (shoutout to Maheshwari for all the help!)&lt;/p&gt;

&lt;p&gt;To create a space where you can have meaningful conversations, we removed Q&amp;amp;A after the talk. The Q&amp;amp;A are always too rushed to get a wholesome answer.&lt;/p&gt;

&lt;p&gt;Instead we put a 30 minute break after every 2 talks (which were a crisp 20 mins) and an hour long lunch.&lt;/p&gt;

&lt;p&gt;Talking of lunch, you don't need catering to feed a small of group, we just ordered lunch using one of the food delivery apps.&lt;/p&gt;

&lt;p&gt;Next step, convince 8 people to come and give a talk.&lt;br&gt;
If I'm creating the perfect conference experience, I'd love to have a diverse set of speakers. I got in touch with a few friends for help.&lt;/p&gt;

&lt;p&gt;We didn't have international speakers* but we had a gender balanced lineup with a mix of first time speakers and experienced speakers.&lt;/p&gt;

&lt;h5&gt;
  
  
  *well, we kind of did. &lt;a href="https://twitter.com/PKodmad"&gt;Pavithra&lt;/a&gt; was already in town from Australia.
&lt;/h5&gt;

&lt;p&gt;I added speakers to the website and announced the conference on twitter a day before opening up sales to build up some hype. The next day, early bird tickets were sold out in 20 minutes! This was validation that there were others like me that really wanted a similar experience.&lt;/p&gt;

&lt;p&gt;Because it was a really small event event, the tickets didn't have to priced high. We didn't even need to find sponsors! &lt;a href="https://hashnode.com"&gt;Hashnode&lt;/a&gt; offered to sponsor anyways and we were able to add some diversity tickets.&lt;/p&gt;

&lt;p&gt;I was still feeling really under confident. This wasn't as fancy as the other conferences people are used to. They will be disappointed and call me out for scamming them! The format was too different, people will be bored between talks, etc.&lt;/p&gt;

&lt;p&gt;But, It was too late to get cold feet now, people had already bought tickets!&lt;/p&gt;

&lt;p&gt;I was surprised how well things turned out.&lt;/p&gt;

&lt;p&gt;We had talks about State management, React Native, Animation, GraphQL and even a talk about stealing ideas from Vue.js 😋. There were plenty of things to talk about! The breaks didn't feel long at all, everyone was excited and nerding out over the details, it was great.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--37Ke-MjY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sid.studio/blog/36/talks.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--37Ke-MjY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sid.studio/blog/36/talks.png" alt="swag"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We did't have any conference swag, I brought a few stickers from my &lt;a href="http://stackstickers.shop"&gt;stickers side project&lt;/a&gt; and &lt;a href="https://twitter.com/NashVail"&gt;Nash&lt;/a&gt; (one of the speakers) brought t-shirts 🙌&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OTV0lLjJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sid.studio/blog/36/swag.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OTV0lLjJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sid.studio/blog/36/swag.jpeg" alt="swag"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The food was alright, we only had vegetarian because I forgot to ask for preferences in advance. 🤷&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uw6LfJj1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sid.studio/blog/36/food.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uw6LfJj1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sid.studio/blog/36/food.jpeg" alt="food"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Overall, it felt like everyone had a good time.&lt;/p&gt;

&lt;p&gt;I talked to a few folks for feedback and they weren't too sad. Twitter confirmed this feeling.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JThzcb3C--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sid.studio/blog/36/tweets.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JThzcb3C--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sid.studio/blog/36/tweets.png" alt="swag"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What's the lesson here?&lt;/p&gt;

&lt;p&gt;In our heads, we sometimes create a picture that is so perfect that it seems unattainable. But if you push the fear aside for 5 minutes, you can break it down to see what are the parts that you really need and what parts exist to satisfy your fear.&lt;/p&gt;

&lt;p&gt;I just came back from React Amsterdam which had over 1200 attendees! To throw an event that big and sell as many tickets, you do need international speakers and sponsors to fly them there and a really big venue. It's a great conference, but that's not the only way. There's plenty of room for tinyconfs as well.&lt;/p&gt;

&lt;p&gt;In my case, I didn't need an auditorium or sponsors to host a good conference, I needed a date and a handful of excited people. Everything else is gravy. The hardest part is to start, after that, everything else falls into place.&lt;/p&gt;

&lt;p&gt;Next time you feel you can't, &lt;a href="https://www.youtube.com/watch?v=jG7dSXcfVqE"&gt;watch this video&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Hope that was helpful on your journey&lt;/p&gt;

&lt;p&gt;Sid&lt;/p&gt;




&lt;p&gt;&lt;a href="https://sid.studio/newsletter"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lTObUt2X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sid.studio/newsletter-snapshot.png%3Fv%3D4" alt="newsletter"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>conference</category>
    </item>
    <item>
      <title>Week of April 02 - Top 3 React articles from around the web</title>
      <dc:creator>Sid</dc:creator>
      <pubDate>Tue, 02 Apr 2019 14:32:33 +0000</pubDate>
      <link>https://dev.to/siddharthkp/week-of-april-02-top-3-react-articles-from-around-the-web-2dlg</link>
      <guid>https://dev.to/siddharthkp/week-of-april-02-top-3-react-articles-from-around-the-web-2dlg</guid>
      <description>&lt;h4&gt;
  
  
  1. &lt;a href="https://spicefactory.co/blog/2019/03/26/how-to-avoid-the-boolean-trap-when-designing-react-components"&gt;How to Avoid the Boolean Trap When Designing React Components&lt;/a&gt; by Filip Danić
&lt;/h4&gt;

&lt;p&gt;Using CSS conventions from Bootstrap for the API design of your React components can lead to bad decisions. Here's what you can learn from "The Clean Code" by Robert C. Martin in the context of React.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. &lt;a href="https://levelup.gitconnected.com/building-a-componentized-and-reusable-scroll-to-top-feature-in-react-7fa5ac8d4c2d"&gt;Building a Componentized and Reusable Scroll to Top Feature in React&lt;/a&gt; by Sarah Sweat
&lt;/h4&gt;

&lt;p&gt;One of the main considerations in creating this component was that I needed it to be reusable on multiple pages of the site, so my goal was to create something that could be imported and utilized in other react components in order to add to a div which had content that would need to be scrolled through.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. &lt;a href="https://github.com/davnicwil/react-frontload"&gt;react-frontload&lt;/a&gt; (library) by Dave Williams
&lt;/h4&gt;

&lt;p&gt;Load data asynchronously into your React components. Works on both client and server render.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://tinyreact.email"&gt;Get emails like this in your inbox, every Tuesday&lt;/a&gt; . Short and sweet. No spam.&lt;/p&gt;

</description>
      <category>react</category>
    </item>
    <item>
      <title>The best time to write tests</title>
      <dc:creator>Sid</dc:creator>
      <pubDate>Tue, 02 Apr 2019 14:21:59 +0000</pubDate>
      <link>https://dev.to/siddharthkp/the-best-time-to-write-tests-45l5</link>
      <guid>https://dev.to/siddharthkp/the-best-time-to-write-tests-45l5</guid>
      <description>&lt;p&gt;I wrote this post for my newsletter, &lt;a href="https://sid.studio/newsletter" rel="noopener noreferrer"&gt;sign up here&lt;/a&gt; to get emails like these every week.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Me, from the past:&lt;/p&gt;

&lt;p&gt;"Writing tests for my code is pointless. I just tested my code, writing tests for them doesn't add any extra value.&lt;/p&gt;

&lt;p&gt;And every time I change the code, I also have to change the tests because they become outdated."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It took me a while to realise that testing code isn't useless, my testing workflow was useless.&lt;/p&gt;

&lt;p&gt;Maintaining a good test suite with respectable code coverage is hard. It always feels like more work and is the first thing that gets left out when you're short on time. If you want to keep a healthy test suite, should you write tests before you write the code or immediately after it?&lt;/p&gt;

&lt;p&gt;Here's what I do: I don't write tests when I write a new feature. I write them just before I have to change it.&lt;/p&gt;

&lt;p&gt;Let me explain,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For each desired change, make the change easy (warning: this may be hard), then make the easy change – &lt;a href="https://twitter.com/kentbeck/status/250733358307500032?lang=en" rel="noopener noreferrer"&gt;Kent Beck&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's my favorite quote on maintaining code. I had to read that a few times before I understood what it meant -&lt;/p&gt;

&lt;p&gt;When you write a block of code, you write it with the best understanding and the latest information you have at that time.&lt;/p&gt;

&lt;p&gt;Months later, you have to extend this code to add support for another use case. You will have to fit this new logic on top of existing code. It works but isn't always the prettiest result. Your code becomes complex because it wasn't originally written with this new feature in mind. Next week, someone in your team will call this "legacy code".&lt;/p&gt;

&lt;p&gt;If you had all this information from the start, you would have written the original code very differently. It would be able to accommodate this feature in a clean way. But, of course, we're not good at predicting the future.&lt;/p&gt;

&lt;p&gt;Kent Beck suggests that instead of trying to force fit the new use case on top of the existing code, perform the change in 2 steps:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;make the change easy (to perform)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;First, refactor the exiting code to make it look like you knew this new feature was coming from the start.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;then make the easy change&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Next, add code to support the new use case. This part is fairly easy because your code is built for this change.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;This approach really resonates with me. You're always refactoring code to keep it fresh.&lt;/p&gt;

&lt;p&gt;And you don't have to ask for time or permission to pay tech debt because you're constantly reducing it while you add new features. The code never becomes "legacy".&lt;/p&gt;

&lt;p&gt;On the surface, it might look like this will slow you down because you're doing more work. In my experience, it's almost always faster than making the &lt;em&gt;hard change&lt;/em&gt; because you don't spend any time trying to understand complex code or fixing regression bugs.&lt;/p&gt;

&lt;p&gt;As you can imagine, it would be incredibly handy to have tests in this scenario. But, do I already have them? Probably not.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Here's my workflow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;I start by writing tests for the existing block of code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Then, I refactor it to make the new change easier to introduce. The tests help make these changes faster without breaking any existing features.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When that's done, I make the easy change of adding the new feature and tests to support it.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;Make the change easy, then make the easy change.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;When needed, I would create 2 different pull requests - one that introduces tests and shows that they still pass after refactoring and the second which adds the new feature.&lt;/p&gt;

&lt;p&gt;Both of these pull requests breeze through the review process because the reviewer is looking at simplified code and has the confidence of tests. Can't the same about a pull request which tries to implement the &lt;em&gt;hard change&lt;/em&gt; on top of existing logic.&lt;/p&gt;

&lt;h5&gt;
  
  
  Note: On a lazy day, I would often just shove the new feature without making an effort. And that's okay, you can't be on your best game everyday. This does, however, comes back to bite me either with long code reviews or bugs that slipped in or simply more refactoring the next time I need to touch this code.
&lt;/h5&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;There are 2 things I'd like you to point out in this workflow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The best time to write tests for a feature is just before you change it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you are working on a codebase that does not have tests, you can start adding them whenever you have to make a change that looks difficult.&lt;/p&gt;

&lt;p&gt;The part of your codebase which changes frequently is the one that will benefit the most from tests. &lt;a href="https://kentcdodds.com/blog/write-tests/" rel="noopener noreferrer"&gt;Chasing code coverage for the sake of it will not improve your app.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2) Tests are not just for catching bugs.&lt;/p&gt;

&lt;p&gt;With the above approach, tests can help you create a to-do list of use cases that can be checked one by one ✅&lt;/p&gt;

&lt;p&gt;Once you know what logic needs to be written, the rest of the work is to simply type it.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;This workflow helps me get the benefit of tests even when I'm not able to invest a lot of time up front.&lt;/p&gt;

&lt;p&gt;I've learned the best methodology is the one that works for you and helps you write better applications.&lt;/p&gt;

&lt;p&gt;Hope this was useful on your journey!&lt;/p&gt;

&lt;p&gt;Sid&lt;/p&gt;




&lt;p&gt;&lt;a href="https://sid.studio/newsletter" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsid.studio%2Fnewsletter-snapshot.png%3Fv%3D4" alt="newsletter"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>testing</category>
    </item>
    <item>
      <title>Pirates and CSS animations</title>
      <dc:creator>Sid</dc:creator>
      <pubDate>Tue, 12 Mar 2019 03:57:51 +0000</pubDate>
      <link>https://dev.to/siddharthkp/pirates-and-css-animations-36gj</link>
      <guid>https://dev.to/siddharthkp/pirates-and-css-animations-36gj</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;I wrote this post for my &lt;a href="https://sid.studio/newsletter" rel="noopener noreferrer"&gt;newsletter&lt;/a&gt;, sign up here to get emails like these every week.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Hi!&lt;/p&gt;

&lt;p&gt;For my &lt;a href="https://react.games" rel="noopener noreferrer"&gt;course on React Hooks&lt;/a&gt;, I have to make a bunch of animations for it to be interesting.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsid.studio%2Fblog%2F32%2Ffinal.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsid.studio%2Fblog%2F32%2Ffinal.gif" alt="final result"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A few folks asked how do those animations work...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsid.studio%2Fblog%2F32%2Ftweets.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsid.studio%2Fblog%2F32%2Ftweets.png" alt="tweets"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You'll be surprised at how easy it is with CSS.&lt;/p&gt;

&lt;p&gt;First, let's break down our composition:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We have a bird and a pirate that's hanging from the bird&lt;/li&gt;
&lt;li&gt;They enter together from the right side of the screen&lt;/li&gt;
&lt;li&gt;After reaching half way, the bird drops the pirate and leaves the screen from the left&lt;/li&gt;
&lt;li&gt;The pirate falls to the bottom of the screen&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  Step #1: Characters
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsid.studio%2Fblog%2F32%2Fcharacters.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsid.studio%2Fblog%2F32%2Fcharacters.png" alt="characters"&gt;&lt;/a&gt;&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;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"bird"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pirate"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;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 css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.bird&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sx"&gt;url('./bird.png')&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.pirate&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sx"&gt;url('./pirate-hanging.png')&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;With some hit and trial, we can position the pirate at exactly the right spot.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsid.studio%2Fblog%2F32%2Fhanging.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsid.studio%2Fblog%2F32%2Fhanging.png" alt="hanging"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.pirate&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;27px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin-left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;49px&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 need another image for the pirate in his falling state. Because the image is a vector image (SVG), we can modify it to get the right posture. (I used sketch, but you do this in any image editor)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsid.studio%2Fblog%2F32%2Fredesign.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsid.studio%2Fblog%2F32%2Fredesign.gif" alt="redesign"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Okay, now that we have the graphics ready, let's think about the &lt;em&gt;choreography&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  Step #2: Choreography
&lt;/h3&gt;

&lt;p&gt;Before we write any code, it's useful to write down the different steps of the animation.&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="nx"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;     &lt;span class="mi"&gt;1&lt;/span&gt;     &lt;span class="mi"&gt;2&lt;/span&gt;     &lt;span class="mi"&gt;3&lt;/span&gt;     &lt;span class="mi"&gt;4&lt;/span&gt;     &lt;span class="mi"&gt;5&lt;/span&gt;         &lt;span class="mi"&gt;6&lt;/span&gt;     &lt;span class="mi"&gt;7&lt;/span&gt;     &lt;span class="mi"&gt;8&lt;/span&gt;     &lt;span class="mi"&gt;9&lt;/span&gt;
    &lt;span class="err"&gt;←&lt;/span&gt;&lt;span class="o"&gt;---------&lt;/span&gt;  &lt;span class="nx"&gt;enter&lt;/span&gt;  &lt;span class="o"&gt;--------&lt;/span&gt;&lt;span class="err"&gt;⇥&lt;/span&gt;  &lt;span class="err"&gt;←&lt;/span&gt;  &lt;span class="nx"&gt;pause&lt;/span&gt; &lt;span class="err"&gt;⇥&lt;/span&gt;  &lt;span class="err"&gt;←&lt;/span&gt;&lt;span class="o"&gt;-----&lt;/span&gt; &lt;span class="nx"&gt;exit&lt;/span&gt; &lt;span class="o"&gt;----&lt;/span&gt;&lt;span class="err"&gt;⇥&lt;/span&gt;

&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;bird&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;fly&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;pirate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;fly&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;pause&lt;/span&gt;
&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;bird&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;fly&lt;/span&gt; &lt;span class="nx"&gt;out&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;pirate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;fall&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's start with the bird flying in.&lt;/p&gt;

&lt;p&gt;We want the bird to come in from outside the screen to the middle. We can attach the same animation to the pirate because he is hanging to the bird for this part.&lt;/p&gt;

&lt;p&gt;Shout out to my friend &lt;a href="https://twitter.com/andresgalante" rel="noopener noreferrer"&gt;Andres&lt;/a&gt; who helped me improve this article. He pointed out that animating &lt;code&gt;position&lt;/code&gt; produces a repaint on every keyframe and using &lt;code&gt;translation&lt;/code&gt; is way more performant. You should follow &lt;a href="https://twitter.com/andresgalante" rel="noopener noreferrer"&gt;Andres&lt;/a&gt; on twitter, he's a CSS wizard.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsid.studio%2Fblog%2F32%2Fenter.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsid.studio%2Fblog%2F32%2Fenter.gif" alt="enter"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.bird&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;bird-enter&lt;/span&gt; &lt;span class="m"&gt;5s&lt;/span&gt; &lt;span class="n"&gt;ease-out&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.pirate&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;bird-enter&lt;/span&gt; &lt;span class="m"&gt;5s&lt;/span&gt; &lt;span class="n"&gt;ease-out&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;bird-enter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nt"&gt;from&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;/* right end of the screen */&lt;/span&gt;
    &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;100vw&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nt"&gt;to&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;/* half way */&lt;/span&gt;
    &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;50vw&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;Looking good!&lt;/p&gt;

&lt;p&gt;By default, the characters will reposition snap to their default position after the animation is finished. That's because CSS animations do not affect the element before the first keyframe is played or after the last keyframe is played.&lt;/p&gt;

&lt;p&gt;We can use the property &lt;code&gt;animation-fill-mode&lt;/code&gt; to override this behavior:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.bird&lt;/span&gt; &lt;span class="nc"&gt;.pirate&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation-fill-mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;forwards&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;&lt;code&gt;forwards&lt;/code&gt; will make the element stay in the same position as the final keyframe.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Alright, let's talk about the exit.&lt;/p&gt;

&lt;p&gt;An element can have multiple animations applied to it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.bird&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;/*         ↓ enter animation       ↓ exit animation   */&lt;/span&gt;
  &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;bird-enter&lt;/span&gt; &lt;span class="m"&gt;5s&lt;/span&gt; &lt;span class="n"&gt;ease-out&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bird-exit&lt;/span&gt; &lt;span class="m"&gt;3s&lt;/span&gt; &lt;span class="n"&gt;ease-in&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;Both of these animations will start at the same time though. That's not good, we want the second animation (exit) to start some time after the first animation finishes (enter).&lt;/p&gt;

&lt;p&gt;This is where the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/animation-delay" rel="noopener noreferrer"&gt;animation-delay&lt;/a&gt; property comes in. The delay for the exit animation should be the duration of the first animation + the pause we want to take between animations: &lt;code&gt;5 + 1 = 6s&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Because we have multiple animations, we need to specify the delay for each of the animation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsid.studio%2Fblog%2F32%2Fmidway.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsid.studio%2Fblog%2F32%2Fmidway.gif" alt="midway"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.bird&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;/*         ↓ enter animation       ↓ exit animation   */&lt;/span&gt;
  &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;bird-enter&lt;/span&gt; &lt;span class="m"&gt;5s&lt;/span&gt; &lt;span class="n"&gt;ease-out&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bird-exit&lt;/span&gt; &lt;span class="m"&gt;3s&lt;/span&gt; &lt;span class="n"&gt;ease-in&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;animation-delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;6s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c"&gt;/* 0s delay for the entry animation, 6s for the exit  */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;bird-exit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nt"&gt;from&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;50vw&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nt"&gt;to&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;/* exit outside the frame */&lt;/span&gt;
    &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;-10vw&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;h5&gt;
  
  
  Sidenote: you can also write the above code with the animation shorthand, where the 4th argument is delay: &lt;code&gt;bird-exit 3s ease-in 6s&lt;/code&gt;.
&lt;/h5&gt;

&lt;p&gt;Okay, now let's talk about the pirate's exit. The timing is the same as the bird, but the animation is a little different. We want the pirate to fall down from it's original position to the bottom end of the screen.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsid.studio%2Fblog%2F32%2Ffall-1.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsid.studio%2Fblog%2F32%2Ffall-1.gif" alt="pirate falling"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.pirate&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;/*         ↓ enter animation       ↓ exit animation   */&lt;/span&gt;
  &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;bird-enter&lt;/span&gt; &lt;span class="m"&gt;5s&lt;/span&gt; &lt;span class="n"&gt;ease-out&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fall&lt;/span&gt; &lt;span class="m"&gt;3s&lt;/span&gt; &lt;span class="n"&gt;ease-in&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;animation-delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;6s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c"&gt;/* 0s delay for the entry animation, 6s for the exit  */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;fall&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nt"&gt;from&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;/* keep it's X position */&lt;/span&gt;
    &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;50vw&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nt"&gt;to&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;/* keep X position, fall to the bottom end of the screen */&lt;/span&gt;
    &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;50vw&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;translateY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;100vw&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;Okay that's a good start, but we also need to change the image.&lt;/p&gt;

&lt;p&gt;We can attach a different &lt;code&gt;class&lt;/code&gt; to the pirate element with javascript to have a different background image. But, we can also achieve this through css.&lt;/p&gt;

&lt;p&gt;If we supply the new &lt;code&gt;background-image&lt;/code&gt; to the element in the &lt;code&gt;from&lt;/code&gt; and &lt;code&gt;to&lt;/code&gt; of the animation, it will apply it for the whole duration.&lt;/p&gt;

&lt;p&gt;To make the effect even better, let's rotate the pirate while he falls.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;fall&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nt"&gt;from&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;/* keep it's X position */&lt;/span&gt;
    &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;50vw&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nl"&gt;background-image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sx"&gt;url('./pirate-falling.png')&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0deg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nt"&gt;to&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;/* keep X position, fall to the bottom end of the screen */&lt;/span&gt;
    &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;50vw&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;translateY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;100vw&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;90deg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nl"&gt;background-image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sx"&gt;url('./pirate-falling.png')&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;This is the combined result:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsid.studio%2Fblog%2F32%2Ffall-2.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsid.studio%2Fblog%2F32%2Ffall-2.gif" alt="pirate falling"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If we use the SVG version of the pirate instead of PNG, we can go really deep and animate each part of the pirate. Something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.pirate&lt;/span&gt; &lt;span class="nc"&gt;.hand&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;raise-up&lt;/span&gt; &lt;span class="m"&gt;2s&lt;/span&gt; &lt;span class="n"&gt;ease-in&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 don't have to, of course. A few lines of CSS keyframes combined together gave a pretty good result too!&lt;/p&gt;

&lt;p&gt;If you want to experiment, &lt;a href="https://codepen.io/siddharthkp/pen/ywoQLL?editors=1100" rel="noopener noreferrer"&gt;here's a codepen link&lt;/a&gt; to this animation.&lt;/p&gt;

&lt;p&gt;Hope that was useful on your journey&lt;/p&gt;

&lt;p&gt;Sid&lt;/p&gt;




&lt;p&gt;&lt;a href="https://sid.studio/newsletter" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsid.studio%2Fnewsletter-snapshot.png%3Fv%3D4" alt="newsletter"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>css</category>
      <category>animation</category>
      <category>pirates</category>
    </item>
    <item>
      <title>How to get a job without experience</title>
      <dc:creator>Sid</dc:creator>
      <pubDate>Mon, 25 Feb 2019 09:36:33 +0000</pubDate>
      <link>https://dev.to/siddharthkp/how-to-get-a-job-without-experience-nif</link>
      <guid>https://dev.to/siddharthkp/how-to-get-a-job-without-experience-nif</guid>
      <description>&lt;p&gt;I wrote this post for my newsletter, &lt;a href="https://sid.studio/newsletter"&gt;sign up here&lt;/a&gt; to get emails like these every week.&lt;/p&gt;

&lt;p&gt;I had a conversation with someone on twitter last week, and I think their situation was very relatable.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I've been an Android Developer for the last 1.5 years and I'm trying to get into a web developer role.&lt;/p&gt;

&lt;p&gt;The issue I'm facing is most companies don't seem to look at my web dev credentials, they keep pushing for an Android role.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I've heard the same story in multiple flavors.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I am a junior developer trying to get a senior role at a better company, but I don't have interesting work to show — Someone I met last month&lt;/p&gt;

&lt;p&gt;I want to get a job in tech, but I don't have a Computer Science degree — me in 2012&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This meme is probably overplayed at this point:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HRDrPij1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sid.studio/blog/30/meme.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HRDrPij1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sid.studio/blog/30/meme.jpg" alt="old played out meme"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Here's you can beat the cycle:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Be specific on the kind of work you want
&lt;/h3&gt;

&lt;p&gt;This sounds silly, but you have to know the kind of work you want first. "Better job" / "more money" are honest but not specific enough.&lt;/p&gt;

&lt;p&gt;Better: I want a frontend developer role in a team that works with React.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  2. Position yourself as an &lt;del&gt;expert&lt;/del&gt; experienced in that field
&lt;/h3&gt;

&lt;p&gt;I'm going to be honest here, if you don't have relevant experience, a company shouldn't hire you.&lt;/p&gt;

&lt;p&gt;Put yourself in the shoes of a CTO or team lead, you're hiring developers for your team. Which one of these developers would you hire?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Dipti who has worked on the same technologies your team uses and can start being productive from day 1&lt;/p&gt;

&lt;p&gt;OR&lt;/p&gt;

&lt;p&gt;Rahul who has no relevant experience but is enthusiastic and a fast learner.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Rahul seems like a great guy but he's probably not going to get the job.&lt;/p&gt;

&lt;p&gt;How do you position yourself as an experienced developer? Well, you actively seek experience.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Learn &amp;amp; Practice&lt;/p&gt;

&lt;p&gt;This isn't a secret, you have to learn a skill before you can get paid for it.&lt;/p&gt;

&lt;p&gt;However, just completing a course or reading a book does not qualify as skill. You have to practice it, like a lot. The best way I know to learn a skill properly is to &lt;em&gt;build something&lt;/em&gt; with it.&lt;/p&gt;

&lt;p&gt;I wrote about this all the way back in newsletter #2: &lt;a href="https://sid.studio/post/learn"&gt;The best way to learn&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Build a few small applications/side projects&lt;/p&gt;

&lt;p&gt;You don't have to have relevant projects at another company to prove you know your stuff. That is only a trust proxy for the interviewer to see that other people value your skills.&lt;/p&gt;

&lt;p&gt;You can showcase your personal projects as well, in fact, in most cases, you can showcase your skills better in a personal project because you get to define the requirements.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Contribute to open source projects&lt;/p&gt;

&lt;p&gt;Another way of showcasing your skills is to contribute to popular open source projects.&lt;/p&gt;

&lt;p&gt;You don't have to make the next big MVC framework, consistent tiny fixes to an existing library shows that you know what you're doing and can work with other people.&lt;/p&gt;

&lt;p&gt;And guess what, you will learn a lot in the process. Not sure where to start? &lt;a href="https://egghead.io/courses/how-to-contribute-to-an-open-source-project-on-github/"&gt;Click here&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Share what you learn&lt;/p&gt;

&lt;p&gt;The most underrated way to showcase your new skills is to share it with others.&lt;/p&gt;

&lt;p&gt;Give a talk at your local meetup, write a blog post and submit it to a &lt;a href="https://medium.freecodecamp.org/how-to-get-published-in-the-freecodecamp-medium-publication-9b342a22400e"&gt;medium publication&lt;/a&gt;. Put that in your resume.&lt;/p&gt;

&lt;p&gt;To give a good talk / write a good blog post, you will have to research and explain the concept clearly - which gives you an instant increase in credibility.&lt;/p&gt;

&lt;p&gt;If you meet someone who can explain a concept in simple words, you immediately conclude they must be really smart. Nope, they just spent a lot of time refining their understanding.&lt;/p&gt;

&lt;p&gt;In an interview from the past, my interviewer spent the entire time discussing a blog post I had mentioned on my resume. The interview went really well because it revolved around what I already knew!&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;But, I don't have enough knowledge to share it with others.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I hear you, that's fair. When you're learning something new, your confidence is low.&lt;/p&gt;

&lt;p&gt;Here's the kicker though, you don't have to be an expert in a topic to teach it. In fact, you're chances of giving a good talk or writing a good article are higher if you just learned that topic.&lt;/p&gt;

&lt;p&gt;When you have spend a few years on a technology, you get used to things. I have to constantly remind myself that something that's obvious to me is completely alien to the person who is seeing it for the first time.&lt;/p&gt;

&lt;p&gt;If you're still not convinced, watch this video on the concept of &lt;a href="https://youtu.be/cv3Ytabl1_g?t=25"&gt;Document, not Create&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  3. Get referred
&lt;/h3&gt;

&lt;p&gt;There's one fundamental thing you have to change about your job hunt: You need to stop applying.&lt;/p&gt;

&lt;p&gt;I can't say it better than how Kyle Shevlin did:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Stop Trying to Win the Resume Lottery&lt;/p&gt;

&lt;p&gt;There's this game that so many people play that I like to call the "resume lottery". People throw their resume and cover letter into a giant pile of other resumes and cover letters and hope and pray that somehow they stand out. It's nearly impossible to win this game. I mean that literally. According to Designing Your Life, a book I've been loving lately, their research suggests that playing the "resume lottery" has a success rate of about 5%. That's horrible!&lt;/p&gt;

&lt;p&gt;Why is that percentage so low? Because as much as 80% of job openings never make it to a job board. When they do, they aren't always really open. Often, they have a candidate in mind that they've customized the opening to fit to appease HR. On top of this, according to a 2015 report, 52% of managers admitted to responding to fewer than half of people who applied for a position. What chance do you have of winning the "resume lottery" up against those odds?!&lt;/p&gt;

&lt;p&gt;Try smarter, not harder.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://buttondown.email/kyleshevlin/archive/c4dc2984-bf25-43d8-b741-3d2b4a2eb712"&gt;You should read the entire post.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There is no better way to increase your chances of getting the job than getting a warm introduction.&lt;/p&gt;

&lt;p&gt;When someone on the team vouches for you, you get a good first impression before you even enter the building.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;But, I don't know anyone who could refer me&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Yeah, that's the tricky part about referrals, you can't just ask a stranger to refer you, you have to earn it.&lt;/p&gt;

&lt;p&gt;The good news is if you take the advice from step #2 above, you're giving people a good reason to refer you. You're not just asking for a favor, you're asking them to review your work and see if it they like it.&lt;/p&gt;

&lt;p&gt;As a mega-introvert, I have hard time making new friends and (for lack of better words) expanding my network. But, being a regular at &lt;a href="https://www.meetup.com/ReactJS-Bangalore/"&gt;the local meetup&lt;/a&gt; and sharing knowledge has made it easier to meet new people because the conversations start with the topic of my talk instead of awkward introductions.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  4. Deploy patience
&lt;/h3&gt;

&lt;p&gt;Credibility takes time. People don't remember announcements, they notice consistency.&lt;/p&gt;

&lt;p&gt;Don't just write one blog post and give up, write a bunch of blog posts. Give a few talks, fix a bunch of open source issues.&lt;/p&gt;

&lt;p&gt;This might take a couple of months, but the reward at the end will be worth it! You don't want just any job, you want the perfect job for you.&lt;/p&gt;

&lt;p&gt;The job hunt in itself is a long stressful process. Sometimes things don't work out even when you give it your best.&lt;/p&gt;

&lt;p&gt;I once went for an interview which lasted the entire day. I met 5 different people and the interviews went well, I went home feeling great. Next day, I got a call from HR telling me the CEO didn't approve the team's budget to hire more people. 🤷&lt;/p&gt;

&lt;p&gt;Trust the work you are putting in.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;That's all, here are some articles for further reading:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://buttondown.email/kyleshevlin/archive/c4dc2984-bf25-43d8-b741-3d2b4a2eb712"&gt;How to be More Successful in a Job Hunt - Kyle Shevlin&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://buttondown.email/kyleshevlin/archive/8354e900-a2c1-4d0d-89a7-95c75461be2e"&gt;The Role of Timing in a Job Hunt - Kyle Shevlin&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://blog.kentcdodds.com/increase-your-marketability-ced1cb315d18"&gt;Increase your marketability - Kent C. Dodds&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://egghead.io/courses/how-to-contribute-to-an-open-source-project-on-github"&gt;How to contribute to open source - Kent C. Dodds&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://codeburst.io/how-to-land-a-good-front-end-developer-job-ded8f61d6721"&gt;How to land a good front-end developer job - Sooraj Chandran&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Hope that was useful on your journey!&lt;/p&gt;

&lt;p&gt;Sid&lt;/p&gt;




&lt;p&gt;&lt;a href="https://sid.studio/newsletter"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lTObUt2X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sid.studio/newsletter-snapshot.png%3Fv%3D4" alt="newsletter"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>career</category>
    </item>
    <item>
      <title>Compound.Components and Context</title>
      <dc:creator>Sid</dc:creator>
      <pubDate>Mon, 18 Feb 2019 07:06:54 +0000</pubDate>
      <link>https://dev.to/siddharthkp/29-compoundcomponents-and-context-5b0h</link>
      <guid>https://dev.to/siddharthkp/29-compoundcomponents-and-context-5b0h</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This post was sent on &lt;a href="https://sid.studio/newsletter"&gt;my newsletter&lt;/a&gt; a few weeks ago, just saying.&lt;/p&gt;

&lt;p&gt;This is part of a series of posts about &lt;a href="https://sid.studio/component-api"&gt;writing good components&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Today, let's talk about forms.&lt;/p&gt;

&lt;p&gt;You have probably read a bunch of articles about state management in forms, this isn't one of them. Instead, I'd like to talk about the design and API of forms.&lt;/p&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SgjWhdk4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sid.studio/blog/29/label-on-left.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SgjWhdk4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sid.studio/blog/29/label-on-left.png" alt="form with label on left"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;There are a bunch of things happening here, but first let me show you the API.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Form&lt;/span&gt; &lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"label-on-left"&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;.&lt;/span&gt;&lt;span class="nc"&gt;Field&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Name"&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;TextInput&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;"text"&lt;/span&gt; &lt;span class="na"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Enter your name"&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;.&lt;/span&gt;&lt;span class="nc"&gt;Field&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;.&lt;/span&gt;&lt;span class="nc"&gt;Field&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Email"&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;TextInput&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;"email"&lt;/span&gt;
      &lt;span class="na"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"email@domain.com"&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;.&lt;/span&gt;&lt;span class="nc"&gt;Field&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Let's look at each one of the components and break them down:&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  Form
&lt;/h3&gt;

&lt;p&gt;It starts with a &lt;code&gt;Form&lt;/code&gt; component which on the surface is a basic form element with a class attached. It renders whatever you put inside it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&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;props&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;form&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"form"&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;props&lt;/span&gt;&lt;span class="p"&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;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="nx"&gt;render&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="na"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"label-on-left"&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It also accepts a &lt;code&gt;layout&lt;/code&gt; prop, which is useful for use cases where you are short on space.&lt;/p&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bOaNMVK5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sid.studio/blog/29/label-on-top-phone.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bOaNMVK5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sid.studio/blog/29/label-on-top-phone.png" alt="form with label on top"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Form&lt;/span&gt; &lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"label-on-top"&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;p&gt;This changes how the labels are aligned (right to left) and how margins work.&lt;/p&gt;

&lt;p&gt;The form doesn't control the width and margin of it's inner contents though. That's for the form field to take care of.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Form&lt;/code&gt; does need to communicate this layout information down though.&lt;/p&gt;

&lt;p&gt;The easiest thing to do would be to pass the layout in &lt;code&gt;props&lt;/code&gt;, but because the contents of a form is dynamic (decided by the developer who uses this form), we can't control that.&lt;/p&gt;

&lt;p&gt;This is where the context API comes in.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* Create a new context */&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;LayoutContext&lt;/span&gt; &lt;span class="o"&gt;=&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;createContext&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="kd"&gt;function&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;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="cm"&gt;/*
    Wrap the children in a context provider
    with the value based on props
  */&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;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&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;LayoutContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Provider&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="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;layout&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;layout&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="si"&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="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;LayoutContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Provider&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;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Form&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;LayoutContext&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now a form field can consume this context and get the value of &lt;code&gt;layout&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Form Field
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;FormField&lt;/code&gt; component adds a &lt;code&gt;label&lt;/code&gt; before rendering whatever you put inside it (like a text input).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Field&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="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="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"form-field"&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="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;props&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;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;label&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;label&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;props&lt;/span&gt;&lt;span class="p"&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In addition to that, it adds a class for layout - which comes from the context we created in &lt;code&gt;Form&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* Get the layout consumer */&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;LayoutContext&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;./form&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="cm"&gt;/*
  Use the consumer to get access to the
  context - it uses the render prop API

  We pass this as the class to the form field
*/&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Field&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="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;LayoutContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Consumer&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;context&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;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`form-field &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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;label&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;props&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;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;label&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;label&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;props&lt;/span&gt;&lt;span class="p"&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="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;LayoutContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Consumer&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;The &lt;code&gt;useContext&lt;/code&gt; hook from React 16.8+ makes the syntax easier to understand&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* Get the layout consumer */&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;LayoutContext&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;./form&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Field&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="p"&gt;{&lt;/span&gt;
  &lt;span class="cm"&gt;/*
    Grab the context from the useContext hook
    which accepts the context variable as the input
  */&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;LayoutContext&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="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`form-field &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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;label&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;props&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;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;label&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;label&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;props&lt;/span&gt;&lt;span class="p"&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If you're curious, you can check the css here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.form-field.label-on-left&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;625px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* align vertically */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.form-field.label-on-left&lt;/span&gt; &lt;span class="nt"&gt;label&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;text-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;right&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="m"&gt;175px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin-right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;25px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.form-field.label-on-top&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="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* instead of flex*/&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.form-field.label-on-top&lt;/span&gt; &lt;span class="nt"&gt;label&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;text-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;left&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* instead of right */&lt;/span&gt;
  &lt;span class="nl"&gt;margin-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;25px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* instead of margin-right */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Form.Field?
&lt;/h3&gt;

&lt;p&gt;The last detail I want to talk about is this awkward dot syntax for components.&lt;/p&gt;

&lt;p&gt;Because the form &lt;code&gt;Field&lt;/code&gt; is always used with a &lt;code&gt;Form&lt;/code&gt;, it makes sense to group them together for the user.&lt;/p&gt;

&lt;p&gt;One way to do that is to export it from the same file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* form.js */&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Field&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;./field&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;function&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;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="cm"&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="nx"&gt;Form&lt;/span&gt;

&lt;span class="k"&gt;export&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now, users can import them together:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;,&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;components/form&lt;/span&gt;&lt;span class="dl"&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;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="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="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;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We can make a tiny improvement by attaching the &lt;code&gt;Field&lt;/code&gt; on the &lt;code&gt;Form&lt;/code&gt; component itself.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* form.js */&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Field&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;./field&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;function&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;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="cm"&gt;/* ... */&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="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Field&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Form&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This code works because React components are javascript objects, and you can add additional keys on this object.&lt;/p&gt;

&lt;p&gt;What this means for the user is when they import &lt;code&gt;Form&lt;/code&gt;, they get the &lt;code&gt;Field&lt;/code&gt; automatically.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Form&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;components/form&lt;/span&gt;&lt;span class="dl"&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;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;Form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Field&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;.&lt;/span&gt;&lt;span class="nc"&gt;Field&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;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I really like this API because it makes the connection between &lt;code&gt;Form&lt;/code&gt; and &lt;code&gt;Form.Field&lt;/code&gt; obvious.&lt;/p&gt;

&lt;h5&gt;
  
  
  Note: You have to move the context into a different file to avoid cyclic dependency loop.
&lt;/h5&gt;

&lt;p&gt;The combination of the dot syntax and context makes our &lt;code&gt;Form&lt;/code&gt; component smart while keeping it composable at the same time.&lt;/p&gt;

&lt;p&gt;Hope that was helpful in your journey&lt;/p&gt;

&lt;p&gt;Sid&lt;/p&gt;




&lt;p&gt;&lt;a href="https://sid.studio/newsletter"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lTObUt2X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sid.studio/newsletter-snapshot.png%3Fv%3D4" alt="newsletter"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
    </item>
    <item>
      <title>Rethinking the component model with Hooks</title>
      <dc:creator>Sid</dc:creator>
      <pubDate>Mon, 11 Feb 2019 05:11:50 +0000</pubDate>
      <link>https://dev.to/siddharthkp/28-rethinking-the-component-model-with-hooks-55l5</link>
      <guid>https://dev.to/siddharthkp/28-rethinking-the-component-model-with-hooks-55l5</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This post was sent to &lt;a href="https://sid.studio/newsletter" rel="noopener noreferrer"&gt;my newsletter&lt;/a&gt; last week.&lt;/p&gt;

&lt;p&gt;Thanks to &lt;a href="https://twitter.com/dan_abramov" rel="noopener noreferrer"&gt;Dan Abramov&lt;/a&gt; for reviewing it and suggesting improvements.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you're a fan of React, you might have already heard that the release with Hooks (v16.8) is here.&lt;/p&gt;

&lt;p&gt;I've been playing with the alpha version for a few weeks now and I really like it. The adoption hasn't been all rainbows and unicorns though.&lt;/p&gt;

&lt;p&gt;Learning &lt;code&gt;useState&lt;/code&gt; and &lt;code&gt;useReducer&lt;/code&gt; was pretty straightforward and has improved how I handle state.&lt;/p&gt;

&lt;p&gt;I wrote about &lt;code&gt;useState&lt;/code&gt; &lt;a href="https://sid.studio/post/react-hooks" rel="noopener noreferrer"&gt;in an earlier post&lt;/a&gt;. Here's the short version:&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;Counter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="cm"&gt;/*
    create a new state pair with useState,
    you can specify the initial value
    as an argument
  */&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="cm"&gt;/*
    create a function to increase this count
    you have access to the current count as it
    is a local variable.

    Calling setCount will trigger a re-render
    just like setState would.
  */&lt;/span&gt;
  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;increase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&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="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&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;count&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;increase&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;Increase&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&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; &lt;/p&gt;

&lt;p&gt;However, I really struggled with the &lt;code&gt;useEffect&lt;/code&gt; hook.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Effect Hook lets you perform side effects in function components.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Side effects can mean anything from updating the document title to making an API request. Anything that happens outside your React render tree is a side effect for the component.&lt;/p&gt;

&lt;p&gt;With classes, you would typically do this in &lt;code&gt;componentDidMount&lt;/code&gt;. With hooks, it looks 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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useEffect&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="c1"&gt;// username is passed in props&lt;/span&gt;
&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;UserProfile&lt;/span&gt; &lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;siddharthkp&lt;/span&gt;&lt;span class="dl"&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;function&lt;/span&gt; &lt;span class="nf"&gt;UserProfile&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="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// create a new state pair with empty object as default&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;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setUser&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="c1"&gt;// create a pair for loading state&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;loading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setLoading&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="c1"&gt;// Similar to componentDidMount&lt;/span&gt;
  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// set loading to true at start&lt;/span&gt;
    &lt;span class="nf"&gt;setLoading&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="c1"&gt;// fetch the user's details&lt;/span&gt;
    &lt;span class="c1"&gt;// username is passed in props&lt;/span&gt;
    &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/get-user?username=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&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;username&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;response&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&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;user&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;setUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// set user in state&lt;/span&gt;
        &lt;span class="nf"&gt;setLoading&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="c1"&gt;// set loading to false&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="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Fetching&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Hi&lt;/span&gt; &lt;span class="p"&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="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&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;This feels familiar. It looks like &lt;code&gt;componentDidMount&lt;/code&gt; in a different suit.&lt;/p&gt;

&lt;p&gt;Well, it doesn't have the same way. The above code has a bug!&lt;/p&gt;

&lt;p&gt;Look at this preview, it's on an infinite loop of fetching user and re-rending it (and not just because it's a gif!)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsid.studio%2Fblog%2F28%2Ffetch-1.gif%3Fv%3D2" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsid.studio%2Fblog%2F28%2Ffetch-1.gif%3Fv%3D2" alt="fetch user"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;componentDidMount&lt;/code&gt; is called after the component has mounted. It fires just once.&lt;/p&gt;

&lt;p&gt;On the other hand, the effect inside &lt;code&gt;useEffect&lt;/code&gt; is applied on every render by default.&lt;/p&gt;

&lt;p&gt;This is a subtle shift in the mental model, we need to change how we think about the component lifecycle - instead of mount and update, we need to think in terms of &lt;em&gt;renders and effects&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;useEffect&lt;/code&gt; lets us pass an optional argument - an array of &lt;code&gt;dependencies&lt;/code&gt; that informs React when should the effect be re-applied. If none of the dependencies change, the effect will not be re-applied.&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="nf"&gt;useEffect&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;effect&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;dependencies&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some folks find this annoying - it feels like something that was simple is now complex with no benefit.&lt;/p&gt;

&lt;p&gt;The benefit of &lt;code&gt;useEffect&lt;/code&gt; is that it replaces three different API methods (&lt;code&gt;componentDidMount&lt;/code&gt;, &lt;code&gt;componentDidUpdate&lt;/code&gt; and &lt;code&gt;componentWillUnmount&lt;/code&gt;) and hence makes you think about all those scenarios from the start - first render, update or re-render and unmount.&lt;/p&gt;

&lt;p&gt;In the above component, the component should fetch user details again when we want to show a different user's profile, i.e. when &lt;code&gt;props.username&lt;/code&gt; changes.&lt;/p&gt;

&lt;p&gt;With a class component, you would handle this with &lt;code&gt;componentDidUpdate&lt;/code&gt; or &lt;code&gt;getDerivedStateFromProps&lt;/code&gt;. This usually comes as an after thought and until then the component shows stale data.&lt;/p&gt;

&lt;p&gt;With &lt;code&gt;useEffect&lt;/code&gt;, you are forced to think about these use cases early on. We can pass &lt;code&gt;props.username&lt;/code&gt; as the additional argument to &lt;code&gt;useEffect&lt;/code&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="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setLoading&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="c1"&gt;// set loading to true&lt;/span&gt;

    &lt;span class="c1"&gt;// fetch the user's details&lt;/span&gt;
    &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/get-user?username=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&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;username&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;response&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&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;user&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;setUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// set user in state&lt;/span&gt;
        &lt;span class="nf"&gt;setLoading&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="c1"&gt;// set loading to false&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;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;username&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;React will now keep track of &lt;code&gt;props.username&lt;/code&gt; and re-apply the effect when it changes.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Let's talk about another kind of side effect: Event listeners.&lt;/p&gt;

&lt;p&gt;I was trying to build a utility that shows you which keyboard button is pressed. Adding a listener on &lt;code&gt;window&lt;/code&gt; to listen to keyboard events is a side effect.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsid.studio%2Fblog%2F28%2Fkey-debugger-1.gif%3Fv%3D2" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsid.studio%2Fblog%2F28%2Fkey-debugger-1.gif%3Fv%3D2" alt="key debugger"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Add event listener in effect
&lt;/h3&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;KeyDebugger&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="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;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setKey&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;null&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;handleKeyDown&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// set key in state&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// attach event listener&lt;/span&gt;
    &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;keydown&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleKeyDown&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Last&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="nx"&gt;hit&lt;/span&gt; &lt;span class="nx"&gt;was&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&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;This looks similar to the previous example.&lt;/p&gt;

&lt;p&gt;This effect will be applied on every render and we will end up with multiple event listeners that fire on the same event. This can lead to unexpected behavior and eventually a memory leak!&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Clean up phase
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;useEffect&lt;/code&gt; gives us a way of cleaning up our listeners.&lt;/p&gt;

&lt;p&gt;If we return a function from the effect, React will run it before re-applying the effect.&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;KeyDebugger&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="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;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setKey&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;null&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;handleKeyDown&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&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="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;keydown&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleKeyDown&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;cleanup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// remove the event listener we had attached&lt;/span&gt;
      &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;keydown&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleKeyDown&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Last&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="nx"&gt;hit&lt;/span&gt; &lt;span class="nx"&gt;was&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Note: In addition to running before re-applying an effect, the cleanup function is also called when the component unmounts.
&lt;/h5&gt;

&lt;p&gt;Much better. We can make one more optimisation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Add dependencies for re-applying effect
&lt;/h3&gt;

&lt;p&gt;Remember: If we don't pass dependencies, it will run on every render.&lt;/p&gt;

&lt;p&gt;In this case, we only need to apply the effect once, i.e. attach event listener on window once.&lt;/p&gt;

&lt;p&gt;Unless the listener itself changes, of course! We should add the listener &lt;code&gt;handleKeyDown&lt;/code&gt; as the only dependency here.&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;KeyDebugger&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="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;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setKey&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;null&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;handleKeyDown&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&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="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;keydown&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleKeyDown&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;cleanup&lt;/span&gt;&lt;span class="p"&gt;()&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="nf"&gt;removeEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;keydown&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleKeyDown&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;handleKeyDown&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Last&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="nx"&gt;hit&lt;/span&gt; &lt;span class="nx"&gt;was&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&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;The &lt;code&gt;dependencies&lt;/code&gt; are a powerful hint.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;no dependencies: apply the effect on every render&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;[]&lt;/code&gt;: only apply on first render&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;[props.username]&lt;/code&gt;: apply when the variable changes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;We can even abstract this effect out into a &lt;em&gt;custom hook&lt;/em&gt; with cleanup baked in. This makes our component worry about one less thing.&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;KeyDebugger&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="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;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setKey&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;null&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;handleKeyDown&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;useEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;keydown&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleKeyDown&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Last&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="nx"&gt;hit&lt;/span&gt; &lt;span class="nx"&gt;was&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// re-usable event listener hook with cleanup&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;useEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;eventName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&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="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;eventName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;cleanup&lt;/span&gt;&lt;span class="p"&gt;()&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="nf"&gt;removeEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;eventName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Note: &lt;code&gt;useEventListener&lt;/code&gt; as defined above works for our example, but is not the complete implementation. If you're curious what a robust version would look like, &lt;a href="https://github.com/siddharthkp/use-event-listener" rel="noopener noreferrer"&gt;see this repo&lt;/a&gt;.
&lt;/h5&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Let's add one more feature to our &lt;code&gt;KeyDebugger&lt;/code&gt;. After a second, the key should disappear until another key is pressed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsid.studio%2Fblog%2F28%2Fkey-debugger-2.gif%3Fv%3D2" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsid.studio%2Fblog%2F28%2Fkey-debugger-2.gif%3Fv%3D2" alt="key debugger"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's just a &lt;code&gt;setTimeout&lt;/code&gt;, should be easy right?&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;handleKeyDown&lt;/code&gt;, we can unset the key after a delay of a second. And as responsible developers, we will also clear the timeout in the cleanup function.&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;KeyDebugger&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="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;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setKey&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;null&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;timeout&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleKeyDown&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key&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="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;setKey&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="c1"&gt;// reset key&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="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&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="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;keydown&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleKeyDown&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;cleanup&lt;/span&gt;&lt;span class="p"&gt;()&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="nf"&gt;removeEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;keydown&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleKeyDown&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nf"&gt;clearTimeout&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="c1"&gt;// additional cleanup task&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Last&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="nx"&gt;hit&lt;/span&gt; &lt;span class="nx"&gt;was&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&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;This code has become a little more complex than before, thanks to the two side effects happening in the same effect - &lt;code&gt;setTimeout&lt;/code&gt; nested within a &lt;code&gt;keydown&lt;/code&gt; listener. This makes the changes harder to keep track of.&lt;/p&gt;

&lt;p&gt;Because the two effects are nested, we couldn't reap the benefits of our custom hook as well. One way to simplify this code is to separate them into their own respective hooks.&lt;/p&gt;

&lt;h5&gt;
  
  
  Sidenote: There is a very subtle bug in the above code which is difficult to surface - Because timeout is not cleared when &lt;code&gt;key&lt;/code&gt; changes, old callbacks will continue to be called which can lead to bugs.
&lt;/h5&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;KeyDebugger&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="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;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setKey&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;null&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;handleKeyDown&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// keyboard event effect&lt;/span&gt;
  &lt;span class="nf"&gt;useEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;keydown&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleKeyDown&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;// timeout effect&lt;/span&gt;
  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="kd"&gt;function&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;timeout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;setKey&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="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;cleanup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;clearTimeout&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="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;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Last&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="nx"&gt;hit&lt;/span&gt; &lt;span class="nx"&gt;was&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&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;By creating two different effects, we are able to keep the logic separate (easier to track) and define different dependencies for each effect. If we want, we can extract the timeout effect into a custom hook as well - &lt;a href="https://github.com/siddharthkp/use-timeout" rel="noopener noreferrer"&gt;useTimeout&lt;/a&gt;.&lt;/p&gt;

&lt;h5&gt;
  
  
  Sidenote: Because this component runs cleanup on every &lt;code&gt;key&lt;/code&gt; change, it does not have the sidenote bug from before.
&lt;/h5&gt;

&lt;p&gt;I know it sounds difficult at first, but I promise it will become easy with a little practice.&lt;/p&gt;

&lt;p&gt;Hope that was useful in your journey.&lt;/p&gt;

&lt;p&gt;Sid&lt;/p&gt;

&lt;p&gt;P.S. I'm working on a React Hooks course - &lt;a href="https://react.games?s=d" rel="noopener noreferrer"&gt;Learn React Hooks by building a game&lt;/a&gt;. I really believe it is going to be amazing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://react.games?s=d" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsid.studio%2Fblog%2F28%2Freact-game.jpg" alt="react.games preview"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Visit &lt;a href="https://react.games?s=d" rel="noopener noreferrer"&gt;react.games&lt;/a&gt; to watch a preview of the course and drop your email to get a discount when it launches (March 15).&lt;/p&gt;




&lt;p&gt;&lt;a href="https://sid.studio/newsletter" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsid.studio%2Fnewsletter-snapshot.png%3Fv%3D4" alt="newsletter"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
    </item>
    <item>
      <title>Don't create conflicting props</title>
      <dc:creator>Sid</dc:creator>
      <pubDate>Thu, 10 Jan 2019 10:04:11 +0000</pubDate>
      <link>https://dev.to/siddharthkp/dont-create-conflicting-props-518c</link>
      <guid>https://dev.to/siddharthkp/dont-create-conflicting-props-518c</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This is part of a series of posts about writing component API for great developer experience.&lt;/p&gt;

&lt;p&gt;This post was originally posted on &lt;a href="https://sid.studio/newsletter" rel="noopener noreferrer"&gt;my newsletter&lt;/a&gt; a few weeks ago, just saying.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is one of the easier ones:&lt;/p&gt;

&lt;p&gt;We have a button here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsid.studio%2Fblog%2F21%2Fbutton-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsid.studio%2Fblog%2F21%2Fbutton-1.png" alt="button-1"&gt;&lt;/a&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Click me&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Button&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;You probably also need a primary button to serve as your main action on a page. I used to like shaping the API just like you would say it - "Give me a primary button"&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsid.studio%2Fblog%2F21%2Fbutton-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsid.studio%2Fblog%2F21%2Fbutton-2.png" alt="button-2"&gt;&lt;/a&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Click me&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&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;Button&lt;/span&gt; &lt;span class="na"&gt;primary&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Click me&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Button&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;So pretty.&lt;/p&gt;

&lt;p&gt;Now, as it goes with buttons, you probably need a few more. Here's what the props table ends up looking like:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;name&lt;/th&gt;
&lt;th&gt;description&lt;/th&gt;
&lt;th&gt;type&lt;/th&gt;
&lt;th&gt;default&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;primary&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;used to indicate the main action&lt;/td&gt;
&lt;td&gt;&lt;code&gt;boolean&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;secondary&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;used for actions which are less important&lt;/td&gt;
&lt;td&gt;&lt;code&gt;boolean&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;destructive&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;indicate that the user should be cautious, example: delete&lt;/td&gt;
&lt;td&gt;&lt;code&gt;boolean&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;link&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;used to style button similarly to a hyperlink&lt;/td&gt;
&lt;td&gt;&lt;code&gt;boolean&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;There are multiple props that can be used to change the appearance of the button. What is the expected outcome if someone uses them together?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsid.studio%2Fblog%2F21%2Fbutton-3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsid.studio%2Fblog%2F21%2Fbutton-3.png" alt="button-3"&gt;&lt;/a&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt; &lt;span class="na"&gt;primary&lt;/span&gt; &lt;span class="na"&gt;destructive&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  Click me
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Button&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;Will one of them win, which one? Is it dependent on the order?&lt;/p&gt;

&lt;p&gt;I would always ask: Why would someone write that? Is this even a real use case - "Give me a primary destructive button"?&lt;/p&gt;

&lt;p&gt;Most of the times, this would be by mistake. But, if the developers have to ask questions like the ones above, it's probably not a good API.&lt;/p&gt;

&lt;p&gt;As someone who is deciding the API, it's your job to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;minimise mistakes&lt;/li&gt;
&lt;li&gt;minimise confusions around the API&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So here's tip #1 for you: &lt;em&gt;Don't create conflicting props&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We can fix our above code pretty easily by using one prop which allows a list of options: &lt;code&gt;appearance&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsid.studio%2Fblog%2F21%2Fbutton-4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsid.studio%2Fblog%2F21%2Fbutton-4.png" alt="button-4"&gt;&lt;/a&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt; &lt;span class="na"&gt;appearance&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"default"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Click me&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&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;Button&lt;/span&gt; &lt;span class="na"&gt;appearance&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"primary"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Click me&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&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;Button&lt;/span&gt; &lt;span class="na"&gt;appearance&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"destructive"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Click me&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Button&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;We can add a list of supported &lt;code&gt;appearance&lt;/code&gt; using &lt;a href="https://reactjs.org/docs/typechecking-with-proptypes.html" rel="noopener noreferrer"&gt;prop-types&lt;/a&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="nx"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PropTypes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;appearance&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PropTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;oneOf&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;default&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;primary&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;secondary&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;link&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;destructive&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;Now, even if the developer makes a mistake, they will get a helpful warning on their developer tools.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsid.studio%2Fblog%2F21%2Fbutton-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsid.studio%2Fblog%2F21%2Fbutton-1.png" alt="button-1"&gt;&lt;/a&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt; &lt;span class="na"&gt;appearance&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"danger"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Click me&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;&amp;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 plaintext"&gt;&lt;code&gt;Warning: Failed prop type:
Invalid prop `appearance` of value `danger` supplied to `Button`,
expected one of `["default","primary","secondary","link","destructive"]`
in Button
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tip is pretty easy to implement, but will make your API a lot easier to use (and maintain).&lt;/p&gt;

&lt;p&gt;Hope this was helpful on your journey&lt;/p&gt;

&lt;p&gt;Sid&lt;/p&gt;




&lt;p&gt;&lt;a href="https://sid.studio/newsletter" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1544503948215%2FSJE5fp2JV.png" alt="newsletter"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
    </item>
    <item>
      <title>Give names to behaviors not interactions</title>
      <dc:creator>Sid</dc:creator>
      <pubDate>Thu, 03 Jan 2019 12:48:17 +0000</pubDate>
      <link>https://dev.to/siddharthkp/give-names-to-behaviors-not-interactions-5jf</link>
      <guid>https://dev.to/siddharthkp/give-names-to-behaviors-not-interactions-5jf</guid>
      <description>&lt;p&gt;When it comes to React components, props are the API that developers consume. A good API should be obvious, something the developer can guess. You want to make it easier for the developer to implement their feature and move on.&lt;/p&gt;

&lt;p&gt;This is valid not just for developers creating component libraries, but also for developers building applications. Your team mates have to use the component API you create.&lt;/p&gt;

&lt;p&gt;After consuming a bunch of articles + talks and doing an inventory of all the props we have in cosmos, I've come up a few guidelines.&lt;/p&gt;

&lt;p&gt;Here's one of them:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This post was originally posted on &lt;a href="https://sid.studio/newsletter"&gt;my newsletter&lt;/a&gt; a few weeks ago, just saying.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We have this &lt;code&gt;Switch&lt;/code&gt; component that accepts a prop, let's call it &lt;code&gt;something&lt;/code&gt; for now.&lt;/p&gt;

&lt;p&gt;A developer using our component can pass a function and we'll call it when the value changes.&lt;/p&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8AlbrbIa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sid.studio/blog/22/switch.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8AlbrbIa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sid.studio/blog/22/switch.png" alt="switch"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Switch&lt;/span&gt; &lt;span class="nx"&gt;something&lt;/span&gt;&lt;span class="o"&gt;=&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="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;p&gt;React gives us the freedom to call the prop whatever we want - &lt;code&gt;handler&lt;/code&gt; / &lt;code&gt;clickHandler&lt;/code&gt; / &lt;code&gt;onClick&lt;/code&gt; / &lt;code&gt;onToggle&lt;/code&gt; etc.&lt;/p&gt;

&lt;p&gt;It has become sort of a popular convention to start your event handlers with an 'on' like &lt;code&gt;onClick&lt;/code&gt;. This is because the HTML spec has a bunch of handlers that follow this convention already: &lt;code&gt;onkeydown&lt;/code&gt;, &lt;code&gt;onchange&lt;/code&gt;, &lt;code&gt;onclick&lt;/code&gt;, etc.&lt;/p&gt;

&lt;p&gt;Reusing an already existing convention is a great idea, your developers don't have to learn a new thing.&lt;/p&gt;

&lt;p&gt;Okay, how about &lt;code&gt;onClick&lt;/code&gt;?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Switch&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&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="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I'm not a big fan of the &lt;code&gt;onClick&lt;/code&gt; handler here because it assumes that a mouse click is the only way to interact with this component.&lt;/p&gt;

&lt;p&gt;Users on a mobile device would &lt;code&gt;tap&lt;/code&gt; the switch with their finger or &lt;code&gt;drag&lt;/code&gt; it to the right. Users with visual impairment will use it with a screen reader and keyboard &lt;code&gt;keyPress&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;As a developer using this component, I don't want to think about how end users interact with this component. I just want to attach a function that is called when the value changes.&lt;/p&gt;

&lt;p&gt;Let's use a interaction agnostic API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Switch&lt;/span&gt; &lt;span class="nx"&gt;onToggle&lt;/span&gt;&lt;span class="o"&gt;=&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="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That makes sense, right? The switch &lt;code&gt;toggles&lt;/code&gt; between it's two values.&lt;/p&gt;

&lt;p&gt;Inside the component, you might want to proxy all possible interactions to the same function&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Switch&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="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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;
      &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;switch&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="cm"&gt;/* click for mouse users */&lt;/span&gt;
      &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&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;onToggle&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;onKeyDown&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="cm"&gt;/* if the enter key is hit, call event handler */&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;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Enter&lt;/span&gt;&lt;span class="dl"&gt;'&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;onToggle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;}}&lt;/span&gt;
      &lt;span class="nx"&gt;onDrag&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="cm"&gt;/* pseudo code */&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;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toElement&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;rightSide&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;onToggle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;}}&lt;/span&gt;
    &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&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've internalised all the implementation detail to expose a nice API for our users (developers).&lt;/p&gt;

&lt;p&gt;Now, let's talk about a component hopefully all of us can agree on - a text input.&lt;/p&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jJhQWIQg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sid.studio/blog/22/input.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jJhQWIQg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sid.studio/blog/22/input.png" alt="input"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TextInput&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;p&gt;HTML has an &lt;a href="https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XUL/Attribute/onchange"&gt;&lt;code&gt;onchange&lt;/code&gt; attribute&lt;/a&gt;, the &lt;a href="https://reactjs.org/docs/forms.html"&gt;React docs&lt;/a&gt; use &lt;code&gt;onChange&lt;/code&gt; in their examples as well. There seems to be consensus around this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TextInput&lt;/span&gt; &lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="o"&gt;=&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="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Easy peasy.&lt;/p&gt;

&lt;p&gt;Now, let's put both these components together.&lt;/p&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SXMMC96u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sid.studio/blog/22/together.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SXMMC96u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sid.studio/blog/22/together.png" alt="together"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TextInput&lt;/span&gt; &lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="o"&gt;=&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="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Switch&lt;/span&gt;    &lt;span class="nx"&gt;onToggle&lt;/span&gt;&lt;span class="o"&gt;=&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="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;p&gt;Notice something odd?&lt;/p&gt;

&lt;p&gt;Even though both the components need similar behavior, the prop is named differently. The props are perfect for their respective component, but when you look at all your components together, it's very inconsistent.&lt;/p&gt;

&lt;p&gt;What this means for developer experience is that you always have to check what the prop is called before using it. Not ideal.&lt;/p&gt;

&lt;p&gt;So, here's tip #2 for you: &lt;em&gt;Aim for consistent props across components.&lt;/em&gt; The same behaviour should have the same prop across components.&lt;/p&gt;

&lt;p&gt;This tip can also be phrased as &lt;em&gt;Aim for a minimal API surface area.&lt;/em&gt; You should limit the amount of API a developer has to learn before they can start being productive.&lt;/p&gt;

&lt;p&gt;That's a beautiful way to put it, all credit goes to &lt;a href="https://twitter.com/sebmarkbage"&gt;Sebastian Markbåge&lt;/a&gt;. (I've linked his talk at the end of this post)&lt;/p&gt;

&lt;p&gt;The way to implement this tip is to pick one prop and use it across all your components. From the two props we have in our example &lt;code&gt;onChange&lt;/code&gt; is also in the HTML spec, so some developers might have already heard of it.&lt;/p&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SXMMC96u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sid.studio/blog/22/together.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SXMMC96u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sid.studio/blog/22/together.png" alt="together"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TextInput&lt;/span&gt; &lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="o"&gt;=&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="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Switch&lt;/span&gt;    &lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="o"&gt;=&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="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Select&lt;/span&gt;    &lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="o"&gt;=&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="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="c1"&gt;// etc.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;p&gt;The consistency across components and the resulting ease of learning your API outweighs having the perfect prop for an individual component.&lt;/p&gt;




&lt;p&gt;Made it till here? Great! Here's some bonus content for you.&lt;/p&gt;

&lt;p&gt;Let's talk about that function signature for a minute.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TextInput&lt;/span&gt; &lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="o"&gt;=&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="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;An &lt;code&gt;onChange&lt;/code&gt; event handler (&lt;code&gt;fn&lt;/code&gt; in the above example), receives one argument - &lt;code&gt;event&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It is triggered on each change to the input. You can get a bunch of useful information from this event&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&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="c1"&gt;// input element&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&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="c1"&gt;// text inside the input element&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;which&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// which keyboard key was hit&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I assume most developers would be interested in &lt;code&gt;event.target.value&lt;/code&gt;, so that they can use it for some other task - setting in state, submitting a form, etc.&lt;/p&gt;

&lt;p&gt;In the case of our custom &lt;code&gt;Switch&lt;/code&gt; component, every action exposes a different &lt;code&gt;event&lt;/code&gt;. This &lt;code&gt;event&lt;/code&gt; will have different properties for a &lt;code&gt;click&lt;/code&gt; event and a &lt;code&gt;drag&lt;/code&gt; event. How we make sure the API is consistent?&lt;/p&gt;

&lt;p&gt;We can manually set &lt;code&gt;event.target.value&lt;/code&gt; for every event:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Switch&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="p"&gt;{&lt;/span&gt;
  &lt;span class="cm"&gt;/* custom handler */&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fireHandler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&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;newValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;oldValue&lt;/span&gt;

    &lt;span class="cm"&gt;/* consistent property that devs can rely on: */&lt;/span&gt;
    &lt;span class="nx"&gt;event&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="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;newValue&lt;/span&gt;

    &lt;span class="cm"&gt;/* fire the handler from props */&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;onChange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;
      &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;switch&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="cm"&gt;/* click for mouse users */&lt;/span&gt;
      &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;fireHandler&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;onKeyDown&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&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="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Enter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;fireHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;}}&lt;/span&gt;
      &lt;span class="nx"&gt;onDrag&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&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="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toElement&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;rightSide&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;fireHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;}}&lt;/span&gt;
    &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&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;Watch Sebastian's talk if you want to learn more about this concept: &lt;a href="https://www.youtube.com/watch?v=4anAwXYqLG8s"&gt;Minimal API Surface Area&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hope this was helpful on your journey&lt;/p&gt;

&lt;p&gt;Sid&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;That was part of an ongoing series. If you enjoyed this, there's more where that came from 😉&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://sid.studio/newsletter"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZTzSXoh7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sid.studio/newsletter-snapshot.png%3Fv%3D1" alt="newsletter"&gt;&lt;/a&gt;&lt;/p&gt;

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