<?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>Forem: Dave Ceddia</title>
    <description>The latest articles on Forem by Dave Ceddia (@dceddia).</description>
    <link>https://forem.com/dceddia</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%2F18647%2F348c53cd-9963-4d42-987f-e565f9d26a5b.jpg</url>
      <title>Forem: Dave Ceddia</title>
      <link>https://forem.com/dceddia</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/dceddia"/>
    <language>en</language>
    <item>
      <title>Implementing a Mockup: CSS Layout Step by Step</title>
      <dc:creator>Dave Ceddia</dc:creator>
      <pubDate>Tue, 30 Apr 2019 00:23:35 +0000</pubDate>
      <link>https://forem.com/dceddia/implementing-a-mockup-css-layout-step-by-step-3ag0</link>
      <guid>https://forem.com/dceddia/implementing-a-mockup-css-layout-step-by-step-3ag0</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgynfmrak4l6jwgv300e1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgynfmrak4l6jwgv300e1.png" alt="Implementing a mockup with CSS" width="670" height="222"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Creating layouts is one of the hardest parts of front end development for a lot of people.&lt;/p&gt;

&lt;p&gt;You can spend &lt;em&gt;hours&lt;/em&gt; trying random CSS properties, copying and pasting from Stack Overflow, and hoping to stumble upon that &lt;em&gt;magical combination&lt;/em&gt; that will produce the layout you want.&lt;/p&gt;

&lt;p&gt;If your usual strategy is to approach layout in an item-by-item way – put A over &lt;em&gt;here&lt;/em&gt;, and now that A is in its place, I want to put B over &lt;em&gt;there&lt;/em&gt;… well, that’s a guaranteed route to frustration. CSS doesn’t work like Sketch or Photoshop.&lt;/p&gt;

&lt;p&gt;In this post I want to show you a way to approach layouts wholistically, as a cohesive problem to be solved.&lt;/p&gt;

&lt;p&gt;We’ll go through a small example, start to finish, and I’ll explain all the CSS along the way – so even if you don’t know or remember how &lt;code&gt;position&lt;/code&gt; and &lt;code&gt;display&lt;/code&gt; work, or you can’t tell your &lt;code&gt;align-items&lt;/code&gt; from your &lt;code&gt;justify-content&lt;/code&gt;, you’ll get something out of this.&lt;/p&gt;

&lt;p&gt;We’re also gonna use plain HTML and CSS here, so you don’t need to know anything about React/Vue/Angular/CSS-in-JS or even JavaScript.&lt;/p&gt;

&lt;p&gt;Sound good? Let’s get into it.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Small Layout Example
&lt;/h2&gt;

&lt;p&gt;For this post we’re going to replicate something that looks like a tweet:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpdz6s6l6znf63mch6dui.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpdz6s6l6znf63mch6dui.jpg" alt="Sketch of a tweet" width="400" height="132"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Whether you’re starting from a sketch like this, or a pixel-perfect mockup, it’s a good idea to have &lt;em&gt;something&lt;/em&gt; to go off of.&lt;/p&gt;

&lt;p&gt;CSS layout goes more smoothly when you’re not trying to cobble it together in the browser while simultaneously designing it in your head. You absolutely &lt;em&gt;can&lt;/em&gt; get to that level! But if you’re reading this, I’ll assume you’re not there &lt;em&gt;yet&lt;/em&gt; :)&lt;/p&gt;

&lt;h2&gt;
  
  
  First Step: Identify the Pieces
&lt;/h2&gt;

&lt;p&gt;Before we write any HTML or CSS, we’ll highlight the individual parts of this layout:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpn8yiean6mguzw4ckgvz.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpn8yiean6mguzw4ckgvz.jpg" alt="Tweet with component parts highlighted" width="400" height="135"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When laying things out with CSS I find it helpful to think in terms of rows and columns. So you either have elements going &lt;em&gt;down&lt;/em&gt; the page one-after-another, or a series of elements arranged left-to-right. Thinking in terms of rows and columns maps nicely to two layout techniques CSS gives us: Flexbox and Grid.&lt;/p&gt;

&lt;p&gt;This layout doesn’t really look like rows and columns, though. There’s an image flush-left, and a jumble of stuff to the right of it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Second Step: Draw Boxes Around Stuff
&lt;/h2&gt;

&lt;p&gt;Let’s draw some boxes around the elements and see if we can get this into some semblance of rows and columns. We’ll put boxes around the parts that are flowing in the same direction.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0yzmiz63z57tpptbad5c.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0yzmiz63z57tpptbad5c.jpg" alt="Tweet with boxes around sections" width="400" height="135"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Every element you place on the page with HTML is &lt;em&gt;basically&lt;/em&gt; a rectangle. Sure, sometimes they have rounded corners, or they’re circles, or fancy SVG shapes… Often you don’t actually &lt;em&gt;see&lt;/em&gt; a bunch of rectangles on the page. But you can always draw a bounding box around a thing. So it helps to imagine everything as a rectangle.&lt;/p&gt;

&lt;p&gt;I mention the rectangles because if you have a set of items you need to align – like the first row with the Name/@handle/Time or the last row with the icons – you can always wrap them in a box for styling purposes, to make it easier to arrange them.&lt;/p&gt;

&lt;p&gt;If we were to stop here, and code this up in HTML, we’d have something like this:&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;article&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt;
    &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"http://www.gravatar.com/avatar"&lt;/span&gt;
    &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"Name"&lt;/span&gt;
  &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt;@handle&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt;Name&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt;3h ago&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;
    Some insightful message.
  &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;button&amp;gt;&lt;/span&gt;Reply&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;button&amp;gt;&lt;/span&gt;Retweet&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;button&amp;gt;&lt;/span&gt;Like&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;button&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And you’d see something like this (here’s a &lt;a href="https://codesandbox.io/embed/wo6wvvynlw" rel="noopener noreferrer"&gt;sandbox&lt;/a&gt;):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyfnw4j39dq22drp5ih75.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyfnw4j39dq22drp5ih75.png" alt="Screenshot of tweet with default styling" width="422" height="494"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;…which is not even close to what we want. But! All the content is there. And some of the clusters of elements are even flowing in the right direction.&lt;/p&gt;

&lt;p&gt;You could make the case that this layout gets the point across even &lt;em&gt;without&lt;/em&gt; further styling, and that’s a great benchmark to aim for with HTML.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Note on Semantic HTML
&lt;/h3&gt;

&lt;p&gt;You might wonder why I picked those particular elements – the &lt;code&gt;article&lt;/code&gt;, the &lt;code&gt;p&lt;/code&gt;, etc. Why not make everything a &lt;code&gt;div&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;Why this…&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;article&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="err"&gt;...&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;span/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;span/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;span/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt; ... &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;button&amp;gt;&lt;/span&gt; ... &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of this?&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&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="err"&gt;...&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt; ... &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&amp;gt;&lt;/span&gt; ... &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&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;Well, the names of HTML elements actually have meanings, and it’s a good idea to use elements that semantically match the thing they represent.&lt;/p&gt;

&lt;p&gt;It’s good for humans, like the programmer trying to decipher the code, and the viewer using an assistive technology like a screenreader. It’s also good for search engines, which are trying to decipher what the page &lt;em&gt;means&lt;/em&gt;, so they can &lt;del&gt;show relevant ads and make a ton of money&lt;/del&gt; help searchers find what they’re looking for.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;article&lt;/code&gt; tag represents an article-like thing, and a tweet is sorta like an article if you squint hard enough.&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;p&lt;/code&gt; tag represents a paragraph, and the text of the tweet is sorta like a paragraph.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;ul&lt;/code&gt; tag represents an unordered list of things (as opposed to an ordered, or numbered, list), and in this case it holds a list of actions you can take.&lt;/p&gt;

&lt;p&gt;The semantic meanings of HTML elements and which specific ones to use in specific situations is… not straightforward. But for the most part, a semantic element – even a very loosely-related one – will be better than a &lt;code&gt;div&lt;/code&gt;, which just denotes “a division”.&lt;/p&gt;

&lt;h3&gt;
  
  
  Default Styling of Elements
&lt;/h3&gt;

&lt;p&gt;What makes it look the way it does? Why are some elements on their own line, while others appear side-by-side?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyfnw4j39dq22drp5ih75.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyfnw4j39dq22drp5ih75.png" alt="Screenshot of tweet with default styling" width="422" height="494"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This happens because of the &lt;em&gt;default styling&lt;/em&gt; applied to the elements, and it brings us to our first bit of CSS knowledge: &lt;em&gt;inline&lt;/em&gt; versus &lt;em&gt;block&lt;/em&gt; elements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Inline elements&lt;/strong&gt; will squeeze next to each other on one line (and wrap if they have to, just like words in a sentence). A &lt;code&gt;span&lt;/code&gt;, a &lt;code&gt;button&lt;/code&gt;, and an &lt;code&gt;img&lt;/code&gt; are all inline elements, according to default browser styling.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Block elements&lt;/strong&gt; , on the other hand, like to stand alone. In terms of console output, you could think of a block element as having a &lt;code&gt;\n&lt;/code&gt; newline before and after it. It’s like a &lt;code&gt;console.log("\ndiv\n")&lt;/code&gt;. The &lt;code&gt;article&lt;/code&gt;, &lt;code&gt;div&lt;/code&gt;, &lt;code&gt;li&lt;/code&gt;, &lt;code&gt;ul&lt;/code&gt;, and &lt;code&gt;p&lt;/code&gt; tags are block-level elements.&lt;/p&gt;

&lt;p&gt;In the example above, notice how the avatar image is on its own line, even though the &lt;code&gt;img&lt;/code&gt; tag is inline? That’s because the &lt;code&gt;div&lt;/code&gt; below it is a block element.&lt;/p&gt;

&lt;p&gt;Then, notice how the @handle, Name, and time are all on one line? That’s because they’re inside &lt;code&gt;span&lt;/code&gt; tags, which are inline.&lt;/p&gt;

&lt;p&gt;Those three are on a separate line from the “insightful message” because (a) they’re within a &lt;code&gt;div&lt;/code&gt;, which will have a newline after it and (b) the &lt;code&gt;p&lt;/code&gt; tag is &lt;em&gt;also&lt;/em&gt; a block element, so it would’ve forced a newline too. (you don’t see 2 newlines though, for the same reason that HTML combines adjacent whitespace).&lt;/p&gt;

&lt;p&gt;If you look closely, you’ll notice the space above and below the “insightful message” is &lt;em&gt;bigger&lt;/em&gt; than the space between the avatar image and the handle/name/time below it. That space is controlled by the default styles too: &lt;code&gt;p&lt;/code&gt; tags have a top and bottom &lt;strong&gt;margin&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You’ll also notice the bullets on the list of buttons, and that the bulleted list is indented. That’s all default styling too. We’re gonna turn it off in a bit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step Three: More Boxes
&lt;/h2&gt;

&lt;p&gt;We want to arrange the avatar image on the left, and everything else to the right. Given what you know about inline and block elements, you might think you could just wrap the right-side stuff in an inline element like a &lt;code&gt;span&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That won’t work, though. An inline element won’t prevent block elements inside it from breaking the line.&lt;/p&gt;

&lt;p&gt;To arrange elements the way we want, we’re going to need something more powerful, like Flexbox or Grid layout. We’ll solve this one with flexbox.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Flexbox Works
&lt;/h3&gt;

&lt;p&gt;CSS “flex” layouts can arrange items into rows &lt;em&gt;or&lt;/em&gt; columns. It’s a one-dimensional layout system. In order to have alternating rows and columns (like in our tweet design), we’ll need to add a few wrapper elements to flip the direction.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftrta72t26tq02b03tmt5.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftrta72t26tq02b03tmt5.jpg" alt="Tweet with boxes around every layer of the layout" width="400" height="138"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can turn on flex layout for a container by setting the property &lt;code&gt;display: flex;&lt;/code&gt;. The container itself will then be a block-level element (so it’ll get its own line), and the elements &lt;em&gt;inside&lt;/em&gt; the container will become “flex items” – meaning they’re no longer inline or block; they’re controlled by the flex container.&lt;/p&gt;

&lt;p&gt;In our case, we’ll have a few flex containers nested within each other, so that we can arrange some of them into rows and some into columns.&lt;/p&gt;

&lt;p&gt;We’ll arrange the outer wrapper (the green box) into columns, then the blue box will be arranged into rows, and each of the red boxes will be columns again.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpdz127lyb6t67gcfznyr.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpdz127lyb6t67gcfznyr.jpg" alt="Tweet with arrows showing flex directions" width="400" height="140"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Flexbox Instead of Grid?
&lt;/h3&gt;

&lt;p&gt;I’m using flexbox here instead of CSS Grid for a few reasons. I think flexbox is a bit easier to learn, and it’s also better-suited to small layouts than grid. Flexbox is especially good for layouts where things are &lt;em&gt;mostly rows&lt;/em&gt; or &lt;em&gt;mostly columns&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The other important thing to know is that even though Grid is newer than Flexbox, Grid does not &lt;em&gt;replace&lt;/em&gt; Flexbox. They are each well-suited to different kinds of layouts, and it’s good to know both. In some layouts you might even use both – say, Grid to lay out a page and Flexbox for a contact form within the page.&lt;/p&gt;

&lt;p&gt;I know, I know… in other corners of web dev, the “new hotness” always replaces the “old and busted”, but CSS doesn’t work that way. Flexbox and Grid happily coexist.&lt;/p&gt;

&lt;p&gt;There’s usually more than one way to solve a problem with CSS!&lt;/p&gt;

&lt;h3&gt;
  
  
  Step Four: Apply Flexbox
&lt;/h3&gt;

&lt;p&gt;Alright, now that we have a plan, let’s apply some styles. I’ve gone and wrapped the left-side stuff in a &lt;code&gt;div&lt;/code&gt;, and given a &lt;code&gt;class&lt;/code&gt; to most of the elements to make them easier to target with CSS.&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;article&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"tweet"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt;
    &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"avatar"&lt;/span&gt;
    &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"http://www.gravatar.com/avatar"&lt;/span&gt;
    &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"Name"&lt;/span&gt;
  &lt;span class="nt"&gt;/&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;"content"&lt;/span&gt;&lt;span class="nt"&gt;&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;"author-meta"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"handle"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;@handle&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Name&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"time"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;3h ago&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;
      Some insightful message.
    &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"actions"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;button&amp;gt;&lt;/span&gt;Reply&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;button&amp;gt;&lt;/span&gt;Retweet&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;button&amp;gt;&lt;/span&gt;Like&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;button&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(&lt;a href="https://codesandbox.io/s/0y98qov0rn" rel="noopener noreferrer"&gt;here’s the CodeSandbox&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Visually, it still looks the same.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyfnw4j39dq22drp5ih75.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyfnw4j39dq22drp5ih75.png" alt="Screenshot of tweet with default styling" width="422" height="494"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That’s because &lt;code&gt;div&lt;/code&gt;s, aside from being block elements (and introducing a newline if there wasn’t one) are otherwise invisible. When you need something to contain other elements, and there’s not a more semantic option, a &lt;code&gt;div&lt;/code&gt; makes a great wrapper.&lt;/p&gt;

&lt;p&gt;Here’s our first bit of CSS, which we’ll put inside a &lt;code&gt;style&lt;/code&gt; tag inside the &lt;code&gt;head&lt;/code&gt; tag of the document:&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;.tweet&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It’s a step in the right direction! We’re using a &lt;strong&gt;class selector&lt;/strong&gt; to target &lt;em&gt;all elements&lt;/em&gt; with the class of &lt;code&gt;tweet&lt;/code&gt;. We only have one such element, but if we had ten of ‘em, they would all be flex containers now.&lt;/p&gt;

&lt;p&gt;The leading &lt;code&gt;.&lt;/code&gt; in CSS means it’s a class selector. Why a &lt;code&gt;.&lt;/code&gt;? I dunno. You’ll just have to commit that one to memory.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frcrb77p97eybp0flmura.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frcrb77p97eybp0flmura.png" alt="Screenshot of tweet with display:flex" width="600" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now the content is to the right of the avatar… but the image is skewed pretty weird.&lt;/p&gt;

&lt;p&gt;This is because, by default, a flex container will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;arrange its items side-by-side&lt;/li&gt;
&lt;li&gt;make them only as wide as the content they contain, and&lt;/li&gt;
&lt;li&gt;set all of their heights based on the tallest one.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can control their vertical alignment with the &lt;code&gt;align-items&lt;/code&gt; property.&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;.tweet&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="n"&gt;flex-start&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 default for &lt;code&gt;align-items&lt;/code&gt; was &lt;code&gt;stretch&lt;/code&gt;, but setting it to &lt;code&gt;flex-start&lt;/code&gt; shoves them up to the top, &lt;em&gt;and&lt;/em&gt; it lets the items govern their own heights.&lt;/p&gt;

&lt;h3&gt;
  
  
  Direction: Row or Column?
&lt;/h3&gt;

&lt;p&gt;By the way, the default direction for flex containers is &lt;code&gt;flex-direction: row;&lt;/code&gt;. Yes, it’s called “row,” even though, depending on how you look at it, you might be inclined to call that 2 columns. Think of it instead as a &lt;em&gt;row&lt;/em&gt; of items side-by-side and it’ll make more sense.&lt;/p&gt;

&lt;p&gt;Kind of like this picture of a vase. Or two faces. Whatever.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxn3k9f58g720h092y772.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxn3k9f58g720h092y772.jpg" alt="Rubin's vase" width="630" height="480"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/Rubin_vase" rel="noopener noreferrer"&gt;Wikipedia&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Content Should Take More Space
&lt;/h3&gt;

&lt;p&gt;The flex items only take as much horizontal space as they need, but we’d like the &lt;code&gt;content&lt;/code&gt; area to take up as much width as possible.&lt;/p&gt;

&lt;p&gt;To do that, we’ll apply the &lt;code&gt;flex: 1;&lt;/code&gt; property to the &lt;code&gt;content&lt;/code&gt; div. (Since it has a class, we’ll use another class selector!)&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;.content&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&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 we’ll also add some space between the avatar and the content, by giving the avatar a little margin:&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;.avatar&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;10px&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;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frtghbk2v9kotidklsng9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frtghbk2v9kotidklsng9.png" alt="Screenshot of tweet with display:flex" width="800" height="249"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Looking a little better!&lt;/p&gt;

&lt;h3&gt;
  
  
  margin vs padding
&lt;/h3&gt;

&lt;p&gt;So… why &lt;code&gt;margin&lt;/code&gt; instead of &lt;code&gt;padding&lt;/code&gt;? And why put it on the right of the avatar, instead of the left of the content?&lt;/p&gt;

&lt;p&gt;As a general rule: put margins on the right and bottom of things, instead of left and top.&lt;/p&gt;

&lt;p&gt;At least for layouts like English, things flow from right to left and top to bottom, so in a sense, each element “depends on” the one to its left, or the one above it.&lt;/p&gt;

&lt;p&gt;With CSS, every item’s position is affected by those “before” it. (at least until you start messing with &lt;code&gt;position: absolute&lt;/code&gt; and friends)&lt;/p&gt;

&lt;h3&gt;
  
  
  Separation of Concerns
&lt;/h3&gt;

&lt;p&gt;Technically, in this case, where &amp;amp; how we place the gap between the &lt;code&gt;avatar&lt;/code&gt; and the &lt;code&gt;content&lt;/code&gt; doesn’t really matter. Space is space, and there are no borders to interfere (&lt;code&gt;padding&lt;/code&gt; goes inside borders; &lt;code&gt;margin&lt;/code&gt; goes outside).&lt;/p&gt;

&lt;p&gt;But it does matter in terms of maintainability, and in terms of how you &lt;em&gt;think about&lt;/em&gt; the elements from the standpoint of organization.&lt;/p&gt;

&lt;p&gt;I try to think of each element as a standalone thing, with the same intention as having a JavaScript function that only does One Thing: if each thing only has one job to do, it’s easier to write the code, and easier to debug when it goes wrong.&lt;/p&gt;

&lt;p&gt;If we had added the margin to the left of the &lt;code&gt;content&lt;/code&gt;, and then one day decided to delete the &lt;code&gt;avatar&lt;/code&gt;, we’d be left with that space. We’d have to hunt down what was causing the extra space (the surrounding &lt;code&gt;tweet&lt;/code&gt;? the &lt;code&gt;content&lt;/code&gt;?) and get rid of it.&lt;/p&gt;

&lt;p&gt;Or, if the &lt;code&gt;content&lt;/code&gt; had the left margin and we decided to replace the &lt;code&gt;content&lt;/code&gt; with some &lt;em&gt;other&lt;/em&gt; thing, we’d need to remember to &lt;em&gt;add the space back&lt;/em&gt; to whatever took its place.&lt;/p&gt;

&lt;p&gt;Ok, that was a lot to say about 10 pixels. Put the margins on the right and bottom. Let’s get back to styling.&lt;/p&gt;

&lt;h3&gt;
  
  
  Removing the List Style
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;ul&lt;/code&gt; unordered list and the &lt;code&gt;li&lt;/code&gt; list items inside it come stock with a bunch of space on the left, and bullets. We don’t want any of that.&lt;/p&gt;

&lt;p&gt;The unordered list has a lot of left padding that we can turn off. Let’s also make it a flex container, so that the buttons will be arranged side-by-side (in a row, remember… with &lt;code&gt;flex-direction: row&lt;/code&gt; by default)&lt;/p&gt;

&lt;p&gt;The list items have a &lt;code&gt;list-style-type&lt;/code&gt; of &lt;code&gt;disc&lt;/code&gt; which shows the bullets, and we can turn that off by setting &lt;code&gt;list-style: none;&lt;/code&gt; (&lt;code&gt;list-style&lt;/code&gt; is a &lt;em&gt;shorthand property&lt;/em&gt; that sets multiple other properties, including &lt;code&gt;list-style-type&lt;/code&gt;, at the same time).&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;.actions&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;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.actions&lt;/span&gt; &lt;span class="nt"&gt;li&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;list-style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&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;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhrsd0rr3sxfu2x737t8p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhrsd0rr3sxfu2x737t8p.png" alt="Screenshot of tweet with actions side-by-side" width="692" height="252"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;.actions&lt;/code&gt; selector is just another class selector. Nothing special there.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;.actions li&lt;/code&gt; selector, though, says “all &lt;code&gt;li&lt;/code&gt; elements &lt;em&gt;anywhere inside&lt;/em&gt; elements with class &lt;code&gt;actions&lt;/code&gt;”. It’s a combination of a class selector (&lt;code&gt;.actions&lt;/code&gt;) and an element selector (&lt;code&gt;li&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Separating selectors with a space like that &lt;em&gt;narrows down the selection&lt;/em&gt; with each one. CSS actually reads selectors in reverse order. It goes “find all the &lt;code&gt;li&lt;/code&gt;s on the page” and then “ok now only target the &lt;code&gt;li&lt;/code&gt;s that are somewhere inside an element with class of &lt;code&gt;actions&lt;/code&gt;”. You can think about it either way and you’ll get the same result. (more on the reasoning behind it &lt;a href="https://stackoverflow.com/questions/5797014/why-do-browsers-match-css-selectors-from-right-to-left" rel="noopener noreferrer"&gt;at StackOverflow&lt;/a&gt;)&lt;/p&gt;

&lt;h3&gt;
  
  
  Spread out the Buttons
&lt;/h3&gt;

&lt;p&gt;We can spread out the buttons a few ways.&lt;/p&gt;

&lt;p&gt;One would be by setting the &lt;em&gt;justification&lt;/em&gt; of the flex items. You’re probably familiar with these buttons at the top of pretty much every rich text editor ever:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F095pfhujvrya9dnelgcy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F095pfhujvrya9dnelgcy.png" alt="Justification buttons for left/center/right/justify" width="288" height="88"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;They justify the content in your document to the left, center, right, or, uhh, “justified” a.k.a. full-width.&lt;/p&gt;

&lt;p&gt;In flexbox you can do the this with the &lt;code&gt;justify-content&lt;/code&gt; attribute. When you’re in &lt;code&gt;flex-direction: row&lt;/code&gt; (the default, and the one we’ve been using so far), &lt;code&gt;justify-content&lt;/code&gt; will move the items left and right. It defaults to &lt;code&gt;flex-start&lt;/code&gt; (so everything is squeezed to the left). If we set &lt;code&gt;justify-content: space-between&lt;/code&gt; on the &lt;code&gt;.actions&lt;/code&gt; it will distribute them evenly across the entire width, like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F61iv8jpxlhg2ldzm6q5l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F61iv8jpxlhg2ldzm6q5l.png" alt="Tweet with buttons justified space-between" width="800" height="153"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That’s not quite what we want, though. It’d be better if they didn’t span the whole width. So take that out.&lt;/p&gt;

&lt;p&gt;Instead, we can apply a right margin to each of the list items to space them out. Let’s also give the whole tweet a border so we can tell what’s going on. &lt;code&gt;1px solid #ccc&lt;/code&gt; will make it 1 pixel wide, a solid line (as opposed to dotted or dashed) and gray.&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;.tweet&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="n"&gt;flex-start&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#ccc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.actions&lt;/span&gt; &lt;span class="nt"&gt;li&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;list-style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&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;30px&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 it looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fayq9wzac0aug0hz8vqkd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fayq9wzac0aug0hz8vqkd.png" alt="Tweet with a border, and buttons spaced out" width="800" height="176"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The buttons look better, but the border highlights the fact that everything is right up against the edge of that &lt;code&gt;tweet&lt;/code&gt; container. Let’s give it some space with &lt;code&gt;padding&lt;/code&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;.tweet&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="n"&gt;flex-start&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#ccc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&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 the tweet has some padding, but there’s also some extra space coming from somewhere. If we highlight the elements in the browser’s developer tools, you’ll notice margins above and below the &lt;code&gt;p&lt;/code&gt; and &lt;code&gt;ul&lt;/code&gt; elements (in Chrome devtools, margins are orange and padding is green):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Futpup2psveyfq10ik38w.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Futpup2psveyfq10ik38w.gif" alt="Tweet with padding, showing padding around p and ul" width="800" height="255"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It’s also interesting that the margin &lt;em&gt;between&lt;/em&gt; the lines is the same as above and below – it’s not doubled up! That’s because CSS &lt;strong&gt;collapses margins&lt;/strong&gt; vertically. When two margins touch top-to-bottom like this, the bigger one wins. Read more about &lt;a href="https://css-tricks.com/what-you-should-know-about-collapsing-margins/" rel="noopener noreferrer"&gt;collapsing margins at CSS-Tricks&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For this layout, I’ll change the margin manually on those 3 elements on the right: the &lt;code&gt;.author-meta&lt;/code&gt;, &lt;code&gt;p&lt;/code&gt;, and &lt;code&gt;ul&lt;/code&gt;. For a real site layout you might consider pulling in a &lt;a href="https://bitsofco.de/a-look-at-css-resets-in-2018/" rel="noopener noreferrer"&gt;CSS reset&lt;/a&gt; to give you a common starting point across the different browsers.&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="nt"&gt;p&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;ul&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.author-meta&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="p"&gt;{&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;1em&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;Separating selectors with commas &lt;code&gt;,&lt;/code&gt; is a way to apply a set of properties to multiple selectors at once. So &lt;code&gt;p, ul&lt;/code&gt; says “all &lt;code&gt;p&lt;/code&gt; elements, AND all &lt;code&gt;ul&lt;/code&gt; elements”. It’s a union of both.&lt;/p&gt;

&lt;p&gt;We’re also using a new unit here, the &lt;code&gt;em&lt;/code&gt; in &lt;code&gt;1em&lt;/code&gt;. One &lt;code&gt;em&lt;/code&gt; is equal to the body font size in pixels. The default font size is &lt;code&gt;16px&lt;/code&gt; (16 pixels high), so in our case &lt;code&gt;1em == 16px&lt;/code&gt;. As the font size changes, the &lt;code&gt;em&lt;/code&gt; scale changes with it, so &lt;code&gt;1em&lt;/code&gt; is a nice way to express “I want the margin below the text to be as tall as the text, whatever that is.”&lt;/p&gt;

&lt;p&gt;And now we have this:&lt;/p&gt;

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

&lt;p&gt;Now let’s make the image a bit smaller, and turn it into a circle. We’ll make it 48px, which is the same size Twitter uses.&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;.avatar&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;10px&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;48px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50%&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;border-radius&lt;/code&gt; property lets us round the corners of boxes, and there are a few ways to specify its value. You can give it a number in &lt;code&gt;px&lt;/code&gt; or &lt;code&gt;em&lt;/code&gt; or another unit, if you want a small radius. Here’s &lt;code&gt;border-radius: 5px&lt;/code&gt; for instance:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Figc4bv7k46vb3vheaaoy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Figc4bv7k46vb3vheaaoy.png" alt="Gravatar with border radius of 5 pixels" width="130" height="134"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If we set the border radius to half the width and height (24px in this case) we’ll get a circle. But an easier way is to set it to &lt;code&gt;50%&lt;/code&gt;, which will figure out the correct size to make a circle without us having to know the exact size ahead of time. And, bonus, if the size changes later, we don’t need to touch the &lt;code&gt;border-radius&lt;/code&gt; at all!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8saiucxmyhtobl6pfsfe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8saiucxmyhtobl6pfsfe.png" alt="Tweet with a round avatar" width="800" height="182"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Draw the Rest of the Owl
&lt;/h2&gt;

&lt;p&gt;There are a few more changes we can make to polish up the final product.&lt;/p&gt;

&lt;p&gt;We’ll set the font to Helvetica (the one Twitter uses), bring the font size down a bit, bold the Name, and, um, flip the order of the “@handle Name” (in the HTML) because that’s not how it looks on Twitter :D&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;.tweet&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="n"&gt;flex-start&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#ccc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c"&gt;/* 
    Change the font and size.
    Setting it on .tweet changes it for all child elements.
    (except the buttons. buttons are weird)
  */&lt;/span&gt;
  &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Helvetica&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Arial&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;sans-serif&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;14px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.name&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.handle&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nc"&gt;.time&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="m"&gt;#657786&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;Using &lt;code&gt;font-weight: 600;&lt;/code&gt; is the same as &lt;code&gt;font-weight: bold;&lt;/code&gt; Some fonts come in lots of different weights, and you can specify from 100 to 900 (thinnest to boldest). &lt;code&gt;normal&lt;/code&gt; (the default) is the same as 400.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By the way&lt;/em&gt;… CSS technically does not allow comments to start with &lt;code&gt;//&lt;/code&gt; like in JS and other langauges. The &lt;code&gt;//&lt;/code&gt; style will work in some browsers, but it’s not safe across all of them. Surround your comments with the C-style &lt;code&gt;/* */&lt;/code&gt; and you’ll be all set.&lt;/p&gt;

&lt;p&gt;One more little trick: we’ll add a raised dot between the “handle” and the “time” by using a &lt;strong&gt;pseudo-element&lt;/strong&gt;. Since the dot is purely stylistic, it makes sense to do it in CSS without muddying up the HTML.&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;.handle&lt;/span&gt;&lt;span class="nd"&gt;::after&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;" \00b7"&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;::after&lt;/code&gt; part creates a pseudo-element which gets placed inside &lt;code&gt;.handle&lt;/code&gt;, but at the end of it (“after” the content). You can also use &lt;code&gt;::before&lt;/code&gt;. The &lt;code&gt;content&lt;/code&gt; attribute can be set to any text, including Unicode characters. You can go wild styling pseudo elements, same as any other. They can be handy for things like badges, notification indicators, or other little flourishes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Icon Buttons
&lt;/h3&gt;

&lt;p&gt;We’ll do one more thing, which is to replace the buttons with icons. We’ll add Font Awesome inside the &lt;code&gt;head&lt;/code&gt; tag:&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;link&lt;/span&gt;
  &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt;
  &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://use.fontawesome.com/releases/v5.8.1/css/all.css"&lt;/span&gt;
  &lt;span class="na"&gt;integrity=&lt;/span&gt;&lt;span class="s"&gt;"sha384-50oBUHEmvpQ+1lW4y57PTFmhCaXp0ML5d60M1M7uH2+nqUivzIebhndOJK28anvf"&lt;/span&gt;
  &lt;span class="na"&gt;crossorigin=&lt;/span&gt;&lt;span class="s"&gt;"anonymous"&lt;/span&gt;
&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then replace the actions &lt;code&gt;ul&lt;/code&gt; with this one, where each button has an icon and some hidden text:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"actions"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;i&lt;/span&gt;
        &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"fas fa-reply"&lt;/span&gt;
        &lt;span class="na"&gt;aria-hidden=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;gt;&amp;lt;/i&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"sr-only"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Reply&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;i&lt;/span&gt;
        &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"fas fa-retweet"&lt;/span&gt;
        &lt;span class="na"&gt;aria-hidden=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;gt;&amp;lt;/i&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"sr-only"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Retweet&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;i&lt;/span&gt;
        &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"fas fa-heart"&lt;/span&gt;
        &lt;span class="na"&gt;aria-hidden=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;gt;&amp;lt;/i&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"sr-only"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Like&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;aria-hidden=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"sr-only"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;More Actions&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Font Awesome is an icon font, and it co-opts the &lt;code&gt;i&lt;/code&gt; “italic” tag to display icons. Since it’s a font, CSS properties that apply to text (like &lt;code&gt;color&lt;/code&gt; and &lt;code&gt;font-size&lt;/code&gt;) will work on the icons too.&lt;/p&gt;

&lt;p&gt;Here we’ve added a few small tweaks to make the buttons accessible:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;aria-hidden="true"&lt;/code&gt; attribute tells screen readers to ignore the icon.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;sr-only&lt;/code&gt; class is provided by Font Awesome. It visually hides elements that it’s applied to, while leaving them accessible to screen readers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here’s an excellent &lt;a href="https://egghead.io/lessons/css-accessible-icon-buttons" rel="noopener noreferrer"&gt;free egghead lesson from Marcy Sutton about creating accessible icon buttons&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now we’ll add a little bit of style to the buttons – removing the border, giving them a better color, and enlarging the font a bit. We’ll also set &lt;code&gt;cursor: pointer&lt;/code&gt; which will turn the mouse cursor into the “hand” you usually see when you hover over a link. Finally, &lt;code&gt;.actions button:hover&lt;/code&gt; will target buttons that are being hovered-over, and color them blue.&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;.actions&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;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&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="m"&gt;#657786&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;16px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.actions&lt;/span&gt; &lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="nd"&gt;:hover&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="m"&gt;#1da1f2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the final styled tweet in all its glory:&lt;/p&gt;

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

&lt;p&gt;And &lt;a href="https://codesandbox.io/s/q88k8n337w" rel="noopener noreferrer"&gt;here’s the CodeSandbox&lt;/a&gt; if you want to play around with it yourself.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Get Better at CSS
&lt;/h2&gt;

&lt;p&gt;The biggest thing you can do to improve your CSS skills is to practice.&lt;/p&gt;

&lt;p&gt;Pick existing sites that you like, and copy them. Designers and artists call this “copy work”. I wrote an article about &lt;a href="https://dev.to/dceddia/cheat-to-win-learn-react-with-copywork-3lk-temp-slug-7141783"&gt;how to learn React with copywork&lt;/a&gt; and the principles all apply to CSS as well.&lt;/p&gt;

&lt;p&gt;Pick layouts that look interesting, and a bit outside your comfort zone. Recreate them with HTML and CSS. When you get stuck, use your browser’s developer tools to inspect the existing sites and figure out their tricks. Lather, rinse, repeat :)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://daveceddia.com/implement-a-design-with-css/" rel="noopener noreferrer"&gt;Implementing a Mockup: CSS Layout Step by Step&lt;/a&gt; was originally published on &lt;a href="https://daveceddia.com" rel="noopener noreferrer"&gt;my blog&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>css</category>
    </item>
    <item>
      <title>The Path to Becoming a Front End Developer in 2019</title>
      <dc:creator>Dave Ceddia</dc:creator>
      <pubDate>Tue, 15 Jan 2019 19:06:24 +0000</pubDate>
      <link>https://forem.com/dceddia/the-path-to-becoming-a-front-end-developer-in-2019-1l5d</link>
      <guid>https://forem.com/dceddia/the-path-to-becoming-a-front-end-developer-in-2019-1l5d</guid>
      <description>&lt;p&gt;As 2019 kicks off, there’s always a flood of New Years’ resolutions.&lt;/p&gt;

&lt;p&gt;Lose weight. Eat healthy. Get a job as a front end developer.&lt;/p&gt;

&lt;p&gt;You know. Little, easy things. Nothing crazy.&lt;/p&gt;

&lt;p&gt;I’m kidding, of course. These big life goals are never easy. &lt;em&gt;Simple&lt;/em&gt;, maybe – go to the gym every day, choose salad for lunch, practice coding every evening – but we know from experience that actually &lt;em&gt;doing the work every day&lt;/em&gt; is not easy.&lt;/p&gt;

&lt;p&gt;And the results never come as quick as we want. Day-to-day, sometimes it feels like a slog. Honestly, it &lt;em&gt;is&lt;/em&gt; a slog sometimes.&lt;/p&gt;

&lt;p&gt;And yet, if we want to make progress on our goals, &lt;em&gt;real&lt;/em&gt; progress, some amount of daily effort is a big help. Daily effort quickens the pace.&lt;/p&gt;

&lt;p&gt;The big decision, then, is &lt;strong&gt;what to focus on&lt;/strong&gt;. What are the critical skills you need to master, and what order should you tackle them?&lt;/p&gt;

&lt;p&gt;I’m going to try to give you some perspective and a concrete plan of action.&lt;/p&gt;

&lt;h2&gt;
  
  
  Learning is a Puzzle
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hhchxOeb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://daveceddia.com/images/learning-puzzle.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hhchxOeb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://daveceddia.com/images/learning-puzzle.png" alt="Puzzle with JavaScript, HTML, CSS"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you’re putting together a puzzle, you probably wouldn’t try to assemble the top row, then the second row, then the third. Puzzle pieces don’t tend to fit into “rows.” Except in that image I drew, because it was easier to draw that way.&lt;/p&gt;

&lt;p&gt;More likely, you’ll start from the corners and the edges, and work your way in. Start with some pieces you’re &lt;em&gt;sure of&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Along the way you might discover a handful pieces that fit together in a little clump. 2, 3, maybe 5 pieces. Then you’ll wonder “where does this clump fit?”, but you might not find an answer until much later in the puzzle.&lt;/p&gt;

&lt;p&gt;Learning web development is like this.&lt;/p&gt;

&lt;p&gt;You are collecting little clusters of knowledge. Some of those clusters you’ll use every day, and some of them you’ll use rarely (but they’ll come in super handy one day, like when the server crashes at 2am and you remember that you used &lt;code&gt;grep&lt;/code&gt; once, and start grepping through logs to find the problem.). They’re all part of the massive puzzle we call “web development.”&lt;/p&gt;

&lt;h2&gt;
  
  
  Learn in Isolation
&lt;/h2&gt;

&lt;p&gt;Whenever you can, break down the subject you are trying to learn into the smallest atoms possible – individual skills.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jmBi7OXS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://daveceddia.com/images/learning-atoms.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jmBi7OXS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://daveceddia.com/images/learning-atoms.png" alt="Some of React's pieces are Props, State, JSX, Context, Hooks, and Redux"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, learn each skill all by itself, even if that means taking a diversion and creating a small sandbox project to focus on that one skill. This will make the learning go much faster, and you’ll retain more of it.&lt;/p&gt;

&lt;p&gt;If there was one “hack” I could give to every person learning web development, it would be this: the ability to see a problem or project not as an &lt;em&gt;indivisible thing&lt;/em&gt;, but as a cluster of skills which can be broken apart, learned separately, and then recombined.&lt;/p&gt;

&lt;h3&gt;
  
  
  Break it down: Full Stack React App
&lt;/h3&gt;

&lt;p&gt;Here’s an example. Let’s say you want to learn all the parts of building a production-level app with React, so you can build your own (or get hired to build one).&lt;/p&gt;

&lt;p&gt;An app like this is made up of many parts.&lt;/p&gt;

&lt;p&gt;There’s the front end. It’s written in JavaScript, probably. It uses React. Maybe Redux or MobX. There might be a Webpack config. There’s definitely JSX. Maybe CSS or Sass, or maybe CSS-in-JS. There are probably HTTP requests with &lt;code&gt;fetch&lt;/code&gt; or &lt;code&gt;axios&lt;/code&gt;. There might be GraphQL.&lt;/p&gt;

&lt;p&gt;The back end might be written with Node + Express, or Ruby on Rails, or Elixir and Phoenix, or any number of things. And that back end probably talks to a database, which might be SQL-based (PostgreSQL or MySQL) or document-based (MongoDB).&lt;/p&gt;

&lt;p&gt;All of that is &lt;em&gt;waaaaayyy&lt;/em&gt; too much to learn simultaneously. If you take it on as one big project, intending to learn it all as you go, it turns into a big jumble in your head and it’s hard to remember which pieces go where. Even if you just try to isolate the front end part, it’s still an overwhelming amount of stuff.&lt;/p&gt;

&lt;p&gt;So ask yourself, could I split it up by technology, and learn one at a time?&lt;/p&gt;

&lt;h3&gt;
  
  
  Learn Each Skill on Its Own
&lt;/h3&gt;

&lt;p&gt;Could you learn JavaScript by itself? Sure, there’s the excellent &lt;a href="https://github.com/getify/You-Dont-Know-JS"&gt;You Don’t Know JS&lt;/a&gt; series (free online), and plenty of other resources.&lt;/p&gt;

&lt;p&gt;Could you learn React by itself? Yep, there’s &lt;a href="https://daveceddia.com/pure-react/"&gt;a book focused on just React&lt;/a&gt; (I wrote it!).&lt;/p&gt;

&lt;p&gt;JSX looks a lot like HTML, so it’s probably easier to figure out how HTML works before going too far with React + JSX.&lt;/p&gt;

&lt;p&gt;You could write a janky-looking app without even touching CSS at all, so you could definitely learn React without CSS. Or CSS without React. And you could wait to learn &lt;a href="https://www.styled-components.com/"&gt;styled-components&lt;/a&gt; or some other CSS-in-JS lib until after you figure out how CSS rules work.&lt;/p&gt;

&lt;p&gt;Redux is an add-on to React, so you could &lt;a href="https://daveceddia.com/how-does-redux-work/"&gt;learn Redux by itself&lt;/a&gt;. (once you know a bit about React)&lt;/p&gt;

&lt;p&gt;Webpack configuration is orthogonal to the goal of getting a React app on the screen; you could use &lt;a href="https://github.com/facebook/create-react-app"&gt;Create React App&lt;/a&gt; now and figure out Webpack later.&lt;/p&gt;

&lt;p&gt;External data, no matter whether it comes from plain a REST API or GraphQL, is another complication. For the purposes of learning how React works, you can use static data initially, by copying the JSON response data from the API and storing it in a variable – open up DevTools, Network tab, pick a request, copy-paste the response! Then learn how to asynchronously fetch the data later.&lt;/p&gt;

&lt;p&gt;The back end can be broken down in the same way.&lt;/p&gt;

&lt;p&gt;Always question the assumption that a problem or project must be learned or built as a whole. See if you can break it down. Tease out the individual parts or layers. Learn those parts on their own when you can. Sometimes you can’t do that, and in that case, still: strip out as much unnecssary stuff as possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Web Development Learning Plan
&lt;/h2&gt;

&lt;p&gt;All that said, real-life you needs some real-life direction right now.&lt;/p&gt;

&lt;p&gt;Here’s the path I suggest, linearized the best I can. Keep in mind the idea of “just in time learning.”&lt;/p&gt;

&lt;p&gt;Practice each new thing as you learn it. Reading blogs &amp;amp; watching tutorials is great, but your brain won’t remember it for long without practice. Devise your own exercises if none are given. Here are some ideas for how to &lt;a href="https://daveceddia.com/your-own-react-project-ideas/"&gt;come up with your own React practice projects&lt;/a&gt;, for instance.&lt;/p&gt;

&lt;p&gt;For each of these things, learn &lt;em&gt;just enough&lt;/em&gt;, then move on.&lt;/p&gt;

&lt;p&gt;You do not need an encyclopedic knowledge of every HTML element, CSS selector, JavaScript feature, or command line tool. That’s what Google and StackOverflow are for. Most of us who’ve been coding for years can tell you about recently learning some fairly basic thing and being amazed by it. (right this moment: &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog"&gt;omg there’s a &lt;code&gt;dialog&lt;/code&gt; element&lt;/a&gt;?)&lt;/p&gt;

&lt;h2&gt;
  
  
  A Bit of Command Line
&lt;/h2&gt;

&lt;p&gt;Often times the first step to getting started on a project is cloning a repo from Github, or creating a blank project with &lt;code&gt;create-react-app&lt;/code&gt;. Then you’ll need to run &lt;code&gt;npm&lt;/code&gt; or &lt;code&gt;yarn&lt;/code&gt; to install packages, and be able to navigate your project on the filesystem.&lt;/p&gt;

&lt;p&gt;A little bit of command line knowledge can help make all of this feel less like typing magical commands into a magical box.&lt;/p&gt;

&lt;p&gt;You don’t need to go crazy here, but it’s worthwhile to understand the basics of navigating the fileystem, displaying files, and that kind of thing. &lt;a href="https://www.learnenough.com/command-line-tutorial"&gt;Learn Enough Command Line to Be Dangerous&lt;/a&gt; by Michael Hartl (of Rails Tutorial fame) is a nice intro, and it’s free to read online. This DEV article by Max Antonucci is also good: &lt;a href="https://dev.to/maxwell_dev/the-shell-introduction-i-wish-i-had-551k"&gt;The Shell Introduction I Wish I Had&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Version Control with Git
&lt;/h2&gt;

&lt;p&gt;You know that problem where your code is working great, and then you change one tiny thing, and then for some reason it breaks?&lt;/p&gt;

&lt;p&gt;And &lt;em&gt;then&lt;/em&gt;, when you undo that change, it’s &lt;strong&gt;still broken&lt;/strong&gt;? wtf!!&lt;/p&gt;

&lt;p&gt;This is literally the worst.&lt;/p&gt;

&lt;p&gt;Version control solves this problem, and I wish I had learned about it earlier than I did. (I also wish someone had framed version control as a &lt;em&gt;benefit&lt;/em&gt; to me rather than a &lt;em&gt;chore&lt;/em&gt;. Because the benefit is HUGE, and Git makes it pretty easy.)&lt;/p&gt;

&lt;p&gt;My introduction was this explanation of how Git works in story form, &lt;a href="http://tom.preston-werner.com/2009/05/19/the-git-parable.html"&gt;The Git Parable&lt;/a&gt;. Give it a read, it’s great. Even if you understand Git commands I bet you’ll learn something new.&lt;/p&gt;

&lt;p&gt;Git is just one of many different version control systems, but it’s the current reigning champion, popularized by Github.&lt;/p&gt;

&lt;p&gt;Also, fun fact: Git and Github are not the same thing. Github is a hosting service for Git repositories, but Git existed long before Github and it can be used independently. You can use Git to manage your code locally without even having an internet connection, which is part of what makes it so awesome.&lt;/p&gt;

&lt;p&gt;So once you’ve got a bit of command line knowledge under your belt, install the &lt;code&gt;git&lt;/code&gt; command. Then whenever you create a new project directory, do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git init .
git add .
git commit -m "Initial commit"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And then every time you get the code into a working state, or before you make a change that might break something, commit your code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git add .
git commit -m "Saving this before I break it."
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Each commit is like a checkpoint. You can go jump back in time to any previous commit (back when your code was working). This all exists locally on your computer. If your computer goes up in flames, your code is gone. That’s what Github is for (and offsite backups, I suppose).&lt;/p&gt;

&lt;p&gt;If you want to learn more about Git, like how to checkout previous commits to get back to your working code, push to Github, and more, go through this &lt;a href="https://www.learnenough.com/git-tutorial"&gt;Learn Enough Git to Be Dangerous&lt;/a&gt; tutorial. It’s not too long and at the end you’ll even have a webpage deployed to Github Pages. Which is a great sandbox for...&lt;/p&gt;

&lt;h2&gt;
  
  
  The Languages of the Web
&lt;/h2&gt;

&lt;p&gt;To build software for the web, you need to know HTML, CSS, and JavaScript. At least enough of each to get by.&lt;/p&gt;

&lt;p&gt;You can write HTML without any CSS or JS. You can’t do much with CSS unless you have an HTML document to style. So you’ll want to &lt;a href="https://www.codecademy.com/learn/learn-html"&gt;learn some HTML&lt;/a&gt; before you &lt;a href="https://www.codecademy.com/learn/learn-css"&gt;learn some CSS&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;JavaScript’s utility is multi-pronged, though. It can be added on top of an HTML document, to make an interactive app... or it can be used outside the browser with &lt;a href="https://nodejs.org/"&gt;Node.js&lt;/a&gt; to do any number of interesting things – from writing servers, to command line apps, to controlling IoT devices and doing machine learning.&lt;/p&gt;

&lt;p&gt;What seems more fun? Writing JS to do stuff in a browser, or learning it in isolation with little coding exercises in Node? No right answer here. It depends on your goals.&lt;/p&gt;

&lt;p&gt;If you’re leaning toward front end development, I’d suggest learning JS in the browser from the beginning, &lt;a href="https://developer.mozilla.org/en-US/docs/Learn/Getting_started_with_the_web/JavaScript_basics"&gt;starting with “vanilla” JS&lt;/a&gt;, without React and Webpack builds and all that stuff.&lt;/p&gt;

&lt;p&gt;And in all of these, remember, the point is not to &lt;em&gt;master each skill to completion&lt;/em&gt; before moving on. Just learn enough, until it feels like you can tackle the next skill.&lt;/p&gt;

&lt;p&gt;I’ll probably get yelled at for saying this, but I don’t believe you need to master vanilla JS and the DOM before you move on to something like React, if what you really want to do is use frameworks. I &lt;em&gt;do&lt;/em&gt; think it’s good to get at least a bit of practice with them, and know that they exist, and be able to look up the specifics (&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript"&gt;on MDN, for example&lt;/a&gt;) when you need them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Learn to Debug
&lt;/h2&gt;

&lt;p&gt;Debugging is a learnable skill. Luckily, if you’re like me, or most other people getting started, you’ll have plenty of practice running into errors and needing to solve them.&lt;/p&gt;

&lt;p&gt;The easiest solution, of course, is to copy and paste your error into Google.&lt;/p&gt;

&lt;p&gt;Sometimes, though, Google is no help. Maybe the error is too specific to your code, like a syntax error.&lt;/p&gt;

&lt;p&gt;And then sometimes, Google finds almost no related results. This is &lt;em&gt;almost always&lt;/em&gt; a sign that it’s a simple, silly mistake somewhere. Like “I forgot to save the file” or “I forgot to restart the server.”&lt;/p&gt;

&lt;p&gt;One time, I hit upon an editor bug in some flavor of Eclipse where the Save function &lt;em&gt;stopped working&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I’d change the file. The title bar would show &lt;code&gt;AbstractFactoryObserverPatternImpl.java *&lt;/code&gt; (with the little star, showing it had been changed). I’d click “Save” and mash Ctrl+S, but the little star remained. “Maybe it’s a UI bug,” I thought. So after saving I opened up the file in &lt;code&gt;vim&lt;/code&gt; – and sure enough, it hadn’t been changed.&lt;/p&gt;

&lt;p&gt;This was (a) ridiculous, because text editors basically have only two jobs, editing text and &lt;em&gt;saving it&lt;/em&gt;... and (b) a nice reminder to always check assumptions. Even crazy ones.&lt;/p&gt;

&lt;p&gt;So the next time you run into a weird problem, break down the problem into layers, and check every assumption in the stack. Brainstorm possible reasons for failure.&lt;/p&gt;

&lt;p&gt;For example, with the “I changed the code but it didn’t do anything” problem:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is that section of code running at all? Can you add a &lt;code&gt;console.log&lt;/code&gt; and see it printed?&lt;/li&gt;
&lt;li&gt;Is the automatic build working? (or, if it’s manual, did you run the build?)&lt;/li&gt;
&lt;li&gt;If it’s part of a running server, has that server been restarted?&lt;/li&gt;
&lt;li&gt;Are you hitting the right server?&lt;/li&gt;
&lt;li&gt;Are you changing the right file?&lt;/li&gt;
&lt;li&gt;Are you changing the right &lt;em&gt;project&lt;/em&gt;? (e.g. maybe you made a copy, &lt;code&gt;myproject-working-for-real-this-time-7&lt;/code&gt;, but your editor is still open to &lt;code&gt;myproject-working-for-real-this-time-6&lt;/code&gt;. Also: stop doing that and start using Git ;)&lt;/li&gt;
&lt;li&gt;Is the file actually changing? Did the Save function in your editor stop working?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After you ask all those questions, and you check everything, and everything seems correct but it’s still broken... it’s time to start restarting things. Trust nothing and nobody.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JI2OJXbY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://daveceddia.com/images/off-on-again.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JI2OJXbY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://daveceddia.com/images/off-on-again.jpg" alt="Have you tried turning it off and on again?"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Remember how I mentioned earlier how learning web dev is like building little clusters of interconnected skills? Debugging time is when you draw upon all those skills. The better you understand &lt;em&gt;why&lt;/em&gt; things work the way they do, including the interconnections between different parts of your app, the better and faster you can debug problems when they arise.&lt;/p&gt;

&lt;p&gt;You’ll begin to see problems and solutions in high resolution. Instead of just “the app is broken,” you’ll see “the server threw an exception while preparing part of the data” or “the JS code failed to parse the JSON and stopped running.”&lt;/p&gt;

&lt;h2&gt;
  
  
  Learn How The Web Works
&lt;/h2&gt;

&lt;p&gt;It will be a big help to understand how the web works in general. Having the big picture in mind will help not only during development, but also help a TON when debugging.&lt;/p&gt;

&lt;p&gt;Learn &lt;a href="https://medium.com/@maneesha.wijesinghe1/what-happens-when-you-type-an-url-in-the-browser-and-press-enter-bb0aa2449c1a"&gt;what happens when you visit a web page&lt;/a&gt;. There’s a lot going on behind the scenes! Most of it can fail sometimes, too. If you know all the steps you can diagnose whether, for example, the server is down, or the DNS entry is wrong, or the server &lt;em&gt;machine&lt;/em&gt; is up but the webserver process is not, or an adblocker prevented your icon font from loading, or whatever other weird thing might happen.&lt;/p&gt;

&lt;p&gt;The Developer Tools are a huge help in learning how this works. Open up the devtools in your browser, look at the Network tab, and refresh the page. Look at all the requests that went out. Look for failures. Click into them and see the data they returned. This, by the way, is a great way to discover and use an undocumented “API” from a site you want to build an app around!&lt;/p&gt;

&lt;h2&gt;
  
  
  Learn a Framework
&lt;/h2&gt;

&lt;p&gt;React is very popular right now, and it benefits from a ton of good resources online for learning. The job market is also good for React developers at the moment.&lt;/p&gt;

&lt;p&gt;The official &lt;a href="https://reactjs.org/tutorial/tutorial.html"&gt;React Tutorial&lt;/a&gt; is a great place to start. It’s well-written, and will help you get from setup to a working app. I also put together a nice little &lt;a href="https://daveceddia.com/pure-react-email-course/"&gt;free 5-day React course&lt;/a&gt; for learning the basics, and if you want something more long-form, I wrote a book, &lt;a href="https://daveceddia.com/pure-react/"&gt;Pure React&lt;/a&gt;, that goes deep on &lt;em&gt;just React&lt;/em&gt; with plenty of exercises and examples to make it all stick.&lt;/p&gt;

&lt;p&gt;If you try React and don’t like it, check out &lt;a href="https://vuejs.org/"&gt;Vue.js&lt;/a&gt;. It’s a popular alternative to React and a lot of people love it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Begin (or continue) Today!
&lt;/h2&gt;

&lt;p&gt;If learning web development is a goal of yours this year, I encourage you to take action on it &lt;em&gt;right now&lt;/em&gt;. Reading and wishing and hoping won’t get you much closer. Putting hands to keyboard and writing code will.&lt;/p&gt;

&lt;p&gt;Even though it’s impossible to cover everything and provide a path for everyone’s own unique starting point, I hope this guide has given you some direction in your web development learning journey. Leave a comment if it helped, or if you have done something specific that helped &lt;em&gt;you&lt;/em&gt; move forward!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published at Dave's blog as &lt;a href="https://daveceddia.com/path-to-frontend-developer-2019/"&gt;The Path to Becoming a Front End Developer in 2019&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>webdev</category>
      <category>career</category>
      <category>javascript</category>
    </item>
    <item>
      <title>React Project Ideas, and How to Invent Your Own</title>
      <dc:creator>Dave Ceddia</dc:creator>
      <pubDate>Tue, 11 Dec 2018 14:12:08 +0000</pubDate>
      <link>https://forem.com/dceddia/react-project-ideas-and-how-to-invent-your-own-3kbk</link>
      <guid>https://forem.com/dceddia/react-project-ideas-and-how-to-invent-your-own-3kbk</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi1nkxv04d5rnxg7h3lue.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi1nkxv04d5rnxg7h3lue.png" alt="Invent Your Own React Practice Projects"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you get right down to it, learning React (or any new thing) is all about practice. Sure, you need to read some tutorials and docs first. Maybe watch a few videos.&lt;/p&gt;

&lt;p&gt;But then? Once you get stuck in the rut of googling for the answer every time, it can be a &lt;em&gt;very&lt;/em&gt; tough habit to break. You find yourself googling for every little thing, and then – the next time you have the exact same problem – you have to google it &lt;em&gt;again&lt;/em&gt;. I still do this every time I have to quit vim. Please send help.&lt;/p&gt;

&lt;p&gt;The truth is, when you don’t understand the underlying concepts – &lt;a href="https://daveceddia.com/visual-guide-to-state-in-react/" rel="noopener noreferrer"&gt;how state works&lt;/a&gt;, how to pass props, &lt;a href="https://daveceddia.com/pure-react/" rel="noopener noreferrer"&gt;how to think in components&lt;/a&gt; – it’s pretty damn hard to build an app from scratch.&lt;/p&gt;

&lt;p&gt;Even though you know you can probably struggle through and figure it out, it’s way faster to just google it.&lt;/p&gt;

&lt;p&gt;You can find lists of &lt;a href="https://daveceddia.com/react-practice-projects/" rel="noopener noreferrer"&gt;React project ideas&lt;/a&gt;, but even those might not be exactly what you want. Maybe they don’t cover the skills you want to learn, or they just don’t seem fun to you, despite how hard I worked on making that list.&lt;/p&gt;

&lt;p&gt;So how can you come up with &lt;em&gt;your own&lt;/em&gt; project ideas?&lt;/p&gt;

&lt;h2&gt;
  
  
  Invent Your Own Project Ideas
&lt;/h2&gt;

&lt;p&gt;Where do good project ideas come from?&lt;/p&gt;

&lt;p&gt;Personally, I tend to reach for things that are modeled after existing apps or real-world objects. I try to avoid anything &lt;em&gt;too&lt;/em&gt; original. That might seem weird, but originality adds complexity.&lt;/p&gt;

&lt;p&gt;If this project is for practice, then your goal is to practice React (or Redux, or GraphQL, or whatever) – not to &lt;em&gt;also&lt;/em&gt; simultaneously practice design, and user experience, and product development (unless, of course, it is).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Focus&lt;/strong&gt; is key here. Scope the problem down to the bare minimum. The Minimum Viable Practice Project. A tiny atom. A mere slice of the full functionality of an entire production application.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Do You Want To Learn?
&lt;/h2&gt;

&lt;p&gt;Before you can focus, you’ll need to figure out what you want to focus &lt;em&gt;on&lt;/em&gt;. Pick one thing, even if you have a whole laundry list of tech to learn.&lt;/p&gt;

&lt;p&gt;Want to learn React? Then just focus on React, all by itself (the way I teach it in &lt;a href="https://daveceddia.com/pure-react/" rel="noopener noreferrer"&gt;my book&lt;/a&gt;). Don’t add Redux yet. Don’t add other tech that you don’t yet understand (whether that’s GraphQL, AWS Lambdas, server-side rendering, or whatever).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://daveceddia.com/how-does-redux-work/" rel="noopener noreferrer"&gt;Want to learn Redux&lt;/a&gt;? Hopefully you already understand the basics of React – great! Now create a tiny React app and add Redux to it, so you can focus on the new things that Redux brings to the table: a store, actions, &lt;a href="https://daveceddia.com/what-is-a-reducer/" rel="noopener noreferrer"&gt;reducers&lt;/a&gt;, &lt;a href="https://daveceddia.com/what-is-a-thunk/" rel="noopener noreferrer"&gt;thunks&lt;/a&gt;, etc.&lt;/p&gt;

&lt;p&gt;Want to learn GraphQL? Awesome. Make sure you understand React. Then create a small app that includes React + GraphQL. Now you have to find or create a GraphQL server for the backend, too.&lt;/p&gt;

&lt;p&gt;You could find a public one – like &lt;a href="https://developer.github.com/v4/" rel="noopener noreferrer"&gt;GitHub’s GraphQL API&lt;/a&gt;, and just focus on learning the client side… or you could stand up your own little GraphQL server to play with.&lt;/p&gt;

&lt;h3&gt;
  
  
  Minimize and Simplify
&lt;/h3&gt;

&lt;p&gt;The point is this: &lt;em&gt;More moving parts&lt;/em&gt; means &lt;em&gt;more things that can break&lt;/em&gt;, and a much bigger headache to debug. Anyone who’s ever googled &lt;a href="https://daveceddia.com/access-control-allow-origin-cors-errors-in-react-express/" rel="noopener noreferrer"&gt;“react CORS error”&lt;/a&gt; knows the pain of thinking that the problem lies in &lt;em&gt;one&lt;/em&gt; piece of tech they’re focused on, while the root cause is something else entirely.&lt;/p&gt;

&lt;p&gt;So: Choose your own difficulty setting. You don’t have to learn it all at once, in parallel. You can learn it all in time. Piece-by-piece, like building a brick wall.&lt;/p&gt;

&lt;p&gt;Whenever you can, cut down on the number of moving pieces that are not &lt;strong&gt;the one thing&lt;/strong&gt; you are trying to learn.&lt;/p&gt;

&lt;h2&gt;
  
  
  Brainstorm Project Ideas
&lt;/h2&gt;

&lt;p&gt;Look around at the apps you use – mobile and desktop. Look at the sites you visit. Look around your house for physical objects that you could represent digitally.&lt;/p&gt;

&lt;p&gt;Pick something that interests you, or relates to one of your hobbies in some way.&lt;/p&gt;

&lt;p&gt;Into woodworking? Make a “cut list” app.&lt;/p&gt;

&lt;p&gt;Into aviation? Maybe a “log book” would be a fun project.&lt;/p&gt;

&lt;p&gt;Playing music? How about building a Circle of Fifths calculator.&lt;/p&gt;

&lt;p&gt;Saving for early retirement a la &lt;a href="https://www.mrmoneymustache.com/" rel="noopener noreferrer"&gt;Mr. Money Mustache&lt;/a&gt;? Maybe a gas mileage calculator would help. (or bike mileage, for that matter).&lt;/p&gt;

&lt;p&gt;Here are a bunch of ideas I came up with while brainstorming examples for a new course. Hopefully it’ll get your creative ideas flowing.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Thermostat. It’s a physical object with controls and state; basically a “Counter” plus a timer)&lt;/li&gt;
&lt;li&gt;Toaster. A few pieces of state – on/off, light/dark. A timer.&lt;/li&gt;
&lt;li&gt;Traffic light. Red/Yellow/Green lights and a timer.&lt;/li&gt;
&lt;li&gt;Activity tracker. At its most basic, it’s just a list of things you did. You could also design it like a chain-based &lt;a href="https://chains.cc/" rel="noopener noreferrer"&gt;habit tracker&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Podcast player. Model it after iTunes, or Overcast, or whatever you like.&lt;/li&gt;
&lt;li&gt;Weather app. This could be extremely simple, with just a few days… or it could be hugely complex, like a whole weather site.&lt;/li&gt;
&lt;li&gt;Notes recorder. Learn the Web Audio API, make short recordings, and then store them in a list. Add/Rename/Delete recordings.&lt;/li&gt;
&lt;li&gt;Shopping site w/ cart. It’s a list of products, and a list of items in the cart. Add/Remove/Update. You could make it client-side only (static data) or integrate it with a server.&lt;/li&gt;
&lt;li&gt;Customizable dashboard w/ graphs. Everyone loves a good dashboard. Here’s a chance to learn D3.js and integrate it with React.&lt;/li&gt;
&lt;li&gt;Website Analytics. Mostly, it’s a list of page names and view counts. But if you fancied it up with graphs, you could work in some D3. And to do it for real, you’ll need a whole back end, and some minimal plain JS code to track page views.&lt;/li&gt;
&lt;li&gt;Blog + editor. It’s basically Wordpress. Clone their UI design.&lt;/li&gt;
&lt;li&gt;Some kind of quiz/survey builder like TypeForm (that would be great practice for getting the little UX details right)&lt;/li&gt;
&lt;li&gt;Trip packer. It’s pretty much a Todo List, but reframed. You could save multiple lists, like “Going on Vacation” vs. “Work Trip”.&lt;/li&gt;
&lt;li&gt;Email client. Model an app after Gmail or Fastmail. Great practice for using static data.&lt;/li&gt;
&lt;li&gt;Slack clone. Model an app after Slack or IRC. Channels &amp;amp; messages. Good Redux practice.&lt;/li&gt;
&lt;li&gt;Course platform. Model it after Teachable or Podia or &lt;a href="https://egghead.io" rel="noopener noreferrer"&gt;egghead&lt;/a&gt;, with a list of lessons on the side and content in the middle. Good CRUD practice.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Go Forth And Build Things
&lt;/h2&gt;

&lt;p&gt;Now that you can invent endless project ideas on your own, all that’s left to do is… go build them :)&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://daveceddia.com/your-own-react-project-ideas/" rel="noopener noreferrer"&gt;React Project Ideas, and How to Invent Your Own&lt;/a&gt; was originally published on &lt;a href="https://daveceddia.com" rel="noopener noreferrer"&gt;my blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>projectideas</category>
    </item>
    <item>
      <title>Redux vs. The React Context API</title>
      <dc:creator>Dave Ceddia</dc:creator>
      <pubDate>Tue, 17 Jul 2018 13:50:31 +0000</pubDate>
      <link>https://forem.com/dceddia/redux-vs-the-react-context-api-1nof</link>
      <guid>https://forem.com/dceddia/redux-vs-the-react-context-api-1nof</guid>
      <description>&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%2Fdaveceddia.com%2Fimages%2Fcontext-vs-redux.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%2Fdaveceddia.com%2Fimages%2Fcontext-vs-redux.png" alt="React Context vs Redux: which to use, and why"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;React 16.3 added a new Context API – &lt;em&gt;new&lt;/em&gt; in the sense that the &lt;em&gt;old&lt;/em&gt; context API was a behind-the-scenes feature that most people either didn’t know about, or avoided using because the docs said to avoid using it.&lt;/p&gt;

&lt;p&gt;Now, though, the Context API is a first-class citizen in React, open to all (not that it wasn’t before, but it’s, like, official now).&lt;/p&gt;

&lt;p&gt;As soon as React 16.3 came out there were articles all across the web proclaiming the death of Redux because of this new Context API. If you asked Redux, though, I think it would say “the reports of my death &lt;a href="https://blog.isquaredsoftware.com/2018/03/redux-not-dead-yet/" rel="noopener noreferrer"&gt;are greatly exaggerated&lt;/a&gt;.”&lt;/p&gt;

&lt;p&gt;In this post I want to cover how the new Context API works, how it is similar to Redux, when you might want to use Context &lt;em&gt;instead of&lt;/em&gt; Redux, and why Context doesn’t replace the need for Redux in every case.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Motivating Example
&lt;/h2&gt;

&lt;p&gt;I’m going to assume you’ve got the basics of React down pat (props &amp;amp; state), but if you don’t, I have a free 5-day course to help you &lt;a href="https://daveceddia.com/pure-react-email-course/" rel="noopener noreferrer"&gt;learn react here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let’s look at an example that would cause most people to reach for Redux. We’ll start with a plain React version, and then see what it looks like in Redux, and finally with Context.&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%2Fdaveceddia.com%2Fimages%2Fcontext-v-redux-app-screenshot.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%2Fdaveceddia.com%2Fimages%2Fcontext-v-redux-app-screenshot.png" alt="The component hierarchy"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This app has the user’s information displayed in two places: in the nav bar at the top-right, and in the sidebar next to the main content.&lt;/p&gt;

&lt;p&gt;The component structure looks like this:&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%2Fdaveceddia.com%2Fimages%2Fcontext-v-redux-app-tree.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%2Fdaveceddia.com%2Fimages%2Fcontext-v-redux-app-tree.png" alt="The component hierarchy"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With pure React (just regular props), we need to store the user’s info high enough in the tree that it can be passed down to the components that need it. In this case, the keeper of user info has to be &lt;code&gt;App&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Then, in order to get the user info down to the components that need it, App needs to pass it along to Nav and Body. They, in turn, need to pass it down &lt;em&gt;again&lt;/em&gt;, to UserAvatar (hooray!) and Sidebar. Finally, Sidebar has to pass it down to UserStats.&lt;/p&gt;

&lt;p&gt;Let’s look at how this works in code (I’m putting everything in one file to make it easier to read, but in reality these would probably be split out into separate files).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ReactDOM&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-dom&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./styles.css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;UserAvatar&lt;/span&gt; &lt;span class="o"&gt;=&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;size&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;img&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;`user-avatar &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;""&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="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"user avatar"&lt;/span&gt;
    &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;avatar&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;UserStats&lt;/span&gt; &lt;span class="o"&gt;=&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="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="s"&gt;"user-stats"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;UserAvatar&lt;/span&gt; &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&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;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;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;"stats"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;followers&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; Followers&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Following &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;following&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;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Nav&lt;/span&gt; &lt;span class="o"&gt;=&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="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="s"&gt;"nav"&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;UserAvatar&lt;/span&gt; &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"small"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&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;"content"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;main content here&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Sidebar&lt;/span&gt; &lt;span class="o"&gt;=&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="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="s"&gt;"sidebar"&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;UserStats&lt;/span&gt; &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Body&lt;/span&gt; &lt;span class="o"&gt;=&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="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="s"&gt;"body"&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;Sidebar&lt;/span&gt; &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Content&lt;/span&gt; &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;avatar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://www.gravatar.com/avatar/5c3dd2d257ff0e14dbd2583485dbd44b&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Dave&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;followers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1234&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;following&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;123&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="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="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="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;"app"&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;Nav&lt;/span&gt; &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Body&lt;/span&gt; &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;ReactDOM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;,&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#root&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://codesandbox.io/s/q8yqx48074" rel="noopener noreferrer"&gt;Here’s a working example on CodeSandbox&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now, this isn’t &lt;em&gt;terrible&lt;/em&gt;. It works just fine. But it’s a bit annoying to write. And it gets more annoying when you have to pass down a lot of props (instead of just one).&lt;/p&gt;

&lt;p&gt;There’s a bigger downside to this “prop drilling” strategy though: it creates coupling between components that would otherwise be decoupled. In the example above, &lt;code&gt;Nav&lt;/code&gt; needs to accept a “user” prop and pass it down to &lt;code&gt;UserAvatar&lt;/code&gt;, even though Nav does not have any need for the &lt;code&gt;user&lt;/code&gt; otherwise.&lt;/p&gt;

&lt;p&gt;Tightly-coupled components (like ones that forward props down to their children) are more difficult to reuse, because you’ve gotta wire them up with their new parents whenever you plop one down in a new location.&lt;/p&gt;

&lt;p&gt;Let’s look at how we might improve it with Redux.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Redux to Improve Data Flow
&lt;/h2&gt;

&lt;p&gt;I’m going to go through the Redux example quickly so we can look more deeply at how Context works, so if you are fuzzy on Redux, read this &lt;a href="https://dev.to/dceddia/how-does-redux-work-cal"&gt;intro to Redux&lt;/a&gt; first (or &lt;a href="https://youtu.be/sX3KeP7v7Kg" rel="noopener noreferrer"&gt;watch the video&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Here’s the React app from above, refactored to use Redux. The &lt;code&gt;user&lt;/code&gt; info has been moved to the Redux store, which means we can use react-redux’s &lt;code&gt;connect&lt;/code&gt; function to directly inject the &lt;code&gt;user&lt;/code&gt; prop into components that need it.&lt;/p&gt;

&lt;p&gt;This is a big win in terms of decoupling. Take a look at &lt;code&gt;Nav&lt;/code&gt;, &lt;code&gt;Body&lt;/code&gt;, and &lt;code&gt;Sidebar&lt;/code&gt; and you’ll see that they’re no longer accepting and passing dow the &lt;code&gt;user&lt;/code&gt; prop. No more playing hot potato with props. No more needless coupling.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ReactDOM&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-dom&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// We need createStore, connect, and Provider:&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;createStore&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;redux&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Provider&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-redux&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Create a reducer with an empty initial state&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;initialState&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="nf"&gt;reducer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;switch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Respond to the SET_USER action and update&lt;/span&gt;
    &lt;span class="c1"&gt;// the state accordingly&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SET_USER&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="nl"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;state&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="c1"&gt;// Create the store with the reducer&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reducer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Dispatch an action to set the user&lt;/span&gt;
&lt;span class="c1"&gt;// (since initial state is empty)&lt;/span&gt;
&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SET_USER&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;avatar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://www.gravatar.com/avatar/5c3dd2d257ff0e14dbd2583485dbd44b&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Dave&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;followers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1234&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;following&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;123&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// This mapStateToProps function extracts a single&lt;/span&gt;
&lt;span class="c1"&gt;// key from state (user) and passes it as the `user` prop&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mapStateToProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// connect() UserAvatar so it receives the `user` directly,&lt;/span&gt;
&lt;span class="c1"&gt;// without having to receive it from a component above&lt;/span&gt;

&lt;span class="c1"&gt;// could also split this up into 2 variables:&lt;/span&gt;
&lt;span class="c1"&gt;// const UserAvatarAtom = ({ user, size }) =&amp;gt; ( ... )&lt;/span&gt;
&lt;span class="c1"&gt;// const UserAvatar = connect(mapStateToProps)(UserAvatarAtom);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;UserAvatar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mapStateToProps&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;size&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;img&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;`user-avatar &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;""&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="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"user avatar"&lt;/span&gt;
    &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;avatar&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="c1"&gt;// connect() UserStats so it receives the `user` directly,&lt;/span&gt;
&lt;span class="c1"&gt;// without having to receive it from a component above&lt;/span&gt;
&lt;span class="c1"&gt;// (both use the same mapStateToProps function)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;UserStats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mapStateToProps&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="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="s"&gt;"user-stats"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;UserAvatar&lt;/span&gt; &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&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;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;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;"stats"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;followers&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; Followers&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Following &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;following&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;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;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="c1"&gt;// Nav doesn't need to know about `user` anymore&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Nav&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="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;"nav"&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;UserAvatar&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"small"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="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;"content"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;main content here&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="c1"&gt;// Sidebar doesn't need to know about `user` anymore&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Sidebar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="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;"sidebar"&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;UserStats&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Body doesn't need to know about `user` anymore&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="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;"body"&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;Sidebar&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;Content&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// App doesn't hold state anymore, so it can be&lt;/span&gt;
&lt;span class="c1"&gt;// a stateless function&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="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;"app"&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;Nav&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;Body&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Wrap the whole app in Provider so that connect()&lt;/span&gt;
&lt;span class="c1"&gt;// has access to the store&lt;/span&gt;
&lt;span class="nx"&gt;ReactDOM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Provider&lt;/span&gt; &lt;span class="na"&gt;store&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;App&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;Provider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;,&lt;/span&gt;
  &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#root&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;&lt;a href="https://codesandbox.io/s/943yr0qp3o" rel="noopener noreferrer"&gt;Here’s the Redux example on CodeSandbox&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now you might be wondering how Redux achieves this magic. It’s a good thing to wonder. How is it that React doesn’t support passing props down multiple levels, but Redux is able to do it?&lt;/p&gt;

&lt;p&gt;The answer is, Redux uses React’s &lt;em&gt;context&lt;/em&gt; feature. Not the modern Context API (not yet) – the old one. The one the React docs said not to use unless you were writing a library or knew what you were doing.&lt;/p&gt;

&lt;p&gt;Context is like an electrical bus running behind every component: to receive the power (data) passing through it, you need only plug in. And (React-)Redux’s &lt;code&gt;connect&lt;/code&gt; function does just that.&lt;/p&gt;

&lt;p&gt;This feature of Redux is just the tip of the iceberg, though. Passing data around all over the place is just the most &lt;em&gt;apparent&lt;/em&gt; of Redux’s features. Here are a few other benefits you get out of the box:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;connect&lt;/code&gt; is pure
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;connect&lt;/code&gt; automatically makes connected components “pure,” meaning they will only re-render when their props change – a.k.a. when their slice of the Redux state changes. This prevents needless re-renders and keeps your app running fast. DIY method: Create a class that extends &lt;code&gt;PureComponent&lt;/code&gt;, or implement &lt;code&gt;shouldComponentUpdate&lt;/code&gt; yourself.&lt;/p&gt;

&lt;h3&gt;
  
  
  Easy Debugging with Redux
&lt;/h3&gt;

&lt;p&gt;The ceremony of writing actions and reducers is balanced by the awesome debugging power it affords you.&lt;/p&gt;

&lt;p&gt;With the &lt;a href="https://github.com/zalmoxisus/redux-devtools-extension" rel="noopener noreferrer"&gt;Redux DevTools extension&lt;/a&gt; you get an automatic log of every action your app performed. At any time you can pop it open and see which actions fired, what their payload was, and the state before and after the action occurred.&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%2Fdaveceddia.com%2Fimages%2Fredux-devtools.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%2Fdaveceddia.com%2Fimages%2Fredux-devtools.gif" alt="Redux devtools demo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Another great feature the Redux DevTools enable is &lt;em&gt;time travel debugging&lt;/em&gt; a.k.a. you can click on any past action and jump to that point in time, basically replaying every action up to and including that one (but no further). The reason this can work is because each action &lt;em&gt;immutably&lt;/em&gt; update’s the state, so you can take a list of recorded state updates and replay them, with no ill effects, and end up where you expect.&lt;/p&gt;

&lt;p&gt;Then there are tools like &lt;a href="https://logrocket.com/" rel="noopener noreferrer"&gt;LogRocket&lt;/a&gt; that basically give you an always-on Redux DevTools &lt;em&gt;in production&lt;/em&gt; for every one of your users. Got a bug report? Sweet. Look up that user’s session in LogRocket and you can see a replay of what they did, and exactly which actions fired. That all works by tapping into Redux’s stream of actions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Customize Redux with Middleware
&lt;/h3&gt;

&lt;p&gt;Redux supports the concept of &lt;em&gt;middleware&lt;/em&gt;, which is a fancy word for “a function that runs every time an action is dispatched.” Writing your own middleware isn’t as hard as it might seem, and it enables some powerful stuff.&lt;/p&gt;

&lt;p&gt;For instance…&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Want to kick off an API request every time an action name starts with &lt;code&gt;FETCH_&lt;/code&gt;? You could do that with middleware.&lt;/li&gt;
&lt;li&gt;Want a centralized place to log events to your analytics software? Middleware is a good place for that.&lt;/li&gt;
&lt;li&gt;Want to prevent certain actions from firing at certain times? You can do that with middleware, transparent to the rest of your app.&lt;/li&gt;
&lt;li&gt;Want to intercept actions that have a JWT token and save them to localStorage, automatically? Yep, middleware.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here’s a good article with some &lt;a href="https://medium.com/@jacobp100/you-arent-using-redux-middleware-enough-94ffe991e6" rel="noopener noreferrer"&gt;examples of how to write Redux middleware&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Use the React Context API
&lt;/h2&gt;

&lt;p&gt;But hey, maybe you don’t need all those fancy features of Redux. Maybe you don’t care about the easy debugging, the customization, or the automatic performance improvements – all you want to do is pass data around easily. Maybe your app is small, or you just need to get something working and address the fancy stuff later.&lt;/p&gt;

&lt;p&gt;React’s new Context API will probably fit the bill. Let’s see how it works.&lt;/p&gt;

&lt;p&gt;I published a quick Context API lesson on Egghead if you’d rather watch than read (3:43):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://egghead.io/lessons/react-pass-props-through-multiple-levels-with-react-s-context-api" 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%2Fdaveceddia.com%2Fimages%2Fcontext-api-egghead-video.png" alt="Context API lesson on Egghead.io"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are 3 important pieces to the context API:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;React.createContext&lt;/code&gt; function which creates the context&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;Provider&lt;/code&gt; (returned by &lt;code&gt;createContext&lt;/code&gt;) which establishes the “electrical bus” running through a component tree&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;Consumer&lt;/code&gt; (also returned by &lt;code&gt;createContext&lt;/code&gt;) which taps into the “electrical bus” to extract the data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;Provider&lt;/code&gt; is very similar to React-Redux’s &lt;code&gt;Provider&lt;/code&gt;. It accepts a &lt;code&gt;value&lt;/code&gt; prop which can be whatever you want (it could even be a Redux store… but that’d be silly). It’ll most likely be an object containing your data and any actions you want to be able to perform on the data.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Consumer&lt;/code&gt; works a little bit like React-Redux’s &lt;code&gt;connect&lt;/code&gt; function, tapping into the data and making it available to the component that uses it.&lt;/p&gt;

&lt;p&gt;Here are the highlights:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Up top, we create a new context&lt;/span&gt;
&lt;span class="c1"&gt;// This is an object with 2 properties: { Provider, Consumer }&lt;/span&gt;
&lt;span class="c1"&gt;// Note that it's named with UpperCase, not camelCase&lt;/span&gt;
&lt;span class="c1"&gt;// This is important because we'll use it as a component later&lt;/span&gt;
&lt;span class="c1"&gt;// and Component Names must start with a Capital Letter&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;UserContext&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="nf"&gt;createContext&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Components that need the data tap into the context&lt;/span&gt;
&lt;span class="c1"&gt;// by using its Consumer property. Consumer uses the&lt;/span&gt;
&lt;span class="c1"&gt;// "render props" pattern.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;UserAvatar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;size&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;UserContext&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;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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;img&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;`user-avatar &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;""&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="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"user avatar"&lt;/span&gt;
        &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;avatar&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;UserContext&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="c1"&gt;// Notice that we don't need the 'user' prop any more,&lt;/span&gt;
&lt;span class="c1"&gt;// because the Consumer fetches it from context&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;UserStats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;UserContext&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;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="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;"user-stats"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;UserAvatar&lt;/span&gt; &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&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;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;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;"stats"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;followers&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; Followers&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Following &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;following&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;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;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;UserContext&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="c1"&gt;// ... all those other components go here ...&lt;/span&gt;
&lt;span class="c1"&gt;// ... (the ones that no longer need to know or care about `user`)&lt;/span&gt;

&lt;span class="c1"&gt;// At the bottom, inside App, we pass the context down&lt;/span&gt;
&lt;span class="c1"&gt;// through the tree using the Provider&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;avatar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://www.gravatar.com/avatar/5c3dd2d257ff0e14dbd2583485dbd44b&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Dave&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;followers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1234&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;following&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;123&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;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;"app"&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;UserContext&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Nav&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;Body&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;UserContext&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;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;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here’s the &lt;a href="https://codesandbox.io/s/q9w2qrw6q4" rel="noopener noreferrer"&gt;full code in a CodeSandbox&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let’s go over how this works.&lt;/p&gt;

&lt;p&gt;Remember there’s 3 pieces: the context itself (created with &lt;code&gt;React.createContext&lt;/code&gt;), and the two components that talk to it (&lt;code&gt;Provider&lt;/code&gt; and &lt;code&gt;Consumer&lt;/code&gt;).&lt;/p&gt;

&lt;h3&gt;
  
  
  Provider and Consumer are a Pair
&lt;/h3&gt;

&lt;p&gt;The Provider and Consumer are bound together. Inseperable. And they only know how to talk to &lt;em&gt;each other&lt;/em&gt;. If you created two separate contexts, say “Context1” and “Context2”, then Context1’s Provider and Consumer would not be able to communicate with Context2’s Provider and Consumer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Context Holds No State
&lt;/h3&gt;

&lt;p&gt;Notice how the context &lt;em&gt;does not have its own state&lt;/em&gt;. It is merely a conduit for your data. You have to pass a value to the &lt;code&gt;Provider&lt;/code&gt;, and that exact value gets passed down to any &lt;code&gt;Consumer&lt;/code&gt;s that know how to look for it (Consumers that are bound to the same context as the Provider).&lt;/p&gt;

&lt;p&gt;When you create the context, you can pass in a “default value” like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Ctx&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="nf"&gt;createContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;yourDefaultValue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This default value is what the &lt;code&gt;Consumer&lt;/code&gt; will receive when it is placed in a tree with no &lt;code&gt;Provider&lt;/code&gt; above it. If you don’t pass one, the value will just be &lt;code&gt;undefined&lt;/code&gt;. Note, though, that this is a &lt;em&gt;default&lt;/em&gt; value, not an &lt;em&gt;initial&lt;/em&gt; value. A context doesn’t retain anything; it merely distributes the data you pass in.&lt;/p&gt;

&lt;h3&gt;
  
  
  Consumer Uses the Render Props Pattern
&lt;/h3&gt;

&lt;p&gt;Redux’s &lt;code&gt;connect&lt;/code&gt; function is a higher-order component (or HoC for short). It &lt;em&gt;wraps&lt;/em&gt; another component and passes props into it.&lt;/p&gt;

&lt;p&gt;The context &lt;code&gt;Consumer&lt;/code&gt;, by contrast, expects the child component to be a function. It then calls that function at render time, passing in the value that it got from the &lt;code&gt;Provider&lt;/code&gt; somewhere above it (or the context’s default value, or &lt;code&gt;undefined&lt;/code&gt; if you didn’t pass a default).&lt;/p&gt;

&lt;h3&gt;
  
  
  Provider Accepts One Value
&lt;/h3&gt;

&lt;p&gt;Just a single value, as the &lt;code&gt;value&lt;/code&gt; prop. But remember that the value can be anything. In practice, if you want to pass multiple values down, you’d create an object with all the values and pass &lt;em&gt;that object&lt;/em&gt; down.&lt;/p&gt;

&lt;p&gt;That’s pretty much the nuts and bolts of the Context API.&lt;/p&gt;

&lt;h2&gt;
  
  
  Context API is Flexible
&lt;/h2&gt;

&lt;p&gt;Since creating a context gives us two components to work with (Provider and Consumer), we’re free to use them however we want. Here are a couple ideas.&lt;/p&gt;

&lt;h3&gt;
  
  
  Turn the Consumer into a Higher-Order Component
&lt;/h3&gt;

&lt;p&gt;Not fond of the idea of adding the &lt;code&gt;UserContext.Consumer&lt;/code&gt; around every place that needs it? Well, it’s your code! You can do what you want. You’re an adult.&lt;/p&gt;

&lt;p&gt;If you’d rather receive the value as a prop, you could write a little wrapper around the &lt;code&gt;Consumer&lt;/code&gt; like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;withUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="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;ConnectedComponent&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;UserContext&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;user&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Component&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="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&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="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;UserContext&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;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then you could rewrite, say, &lt;code&gt;UserAvatar&lt;/code&gt; to use this new &lt;code&gt;withUser&lt;/code&gt; function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;UserAvatar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;withUser&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;size&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="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;img&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;`user-avatar &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;""&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="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"user avatar"&lt;/span&gt;
    &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;avatar&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And BOOM, context can work just like Redux’s &lt;code&gt;connect&lt;/code&gt;. Minus the automatic purity.&lt;/p&gt;

&lt;p&gt;Here’s an &lt;a href="https://codesandbox.io/s/jpy76nm1v" rel="noopener noreferrer"&gt;example CodeSandbox with this higher-order component&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hold State in the Provider
&lt;/h3&gt;

&lt;p&gt;The context’s Provider is just a conduit, remember. It doesn’t retain any data. But that doesn’t stop you from making your &lt;em&gt;own&lt;/em&gt; wrapper to hold the data.&lt;/p&gt;

&lt;p&gt;In the example above, I left &lt;code&gt;App&lt;/code&gt; holding the data, so that the only new thing you’d need to understand was the Provider + Consumer components. But maybe you want to make your own “store”, of sorts. You could create a component to hold the state and pass them through context:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserStore&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;avatar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://www.gravatar.com/avatar/5c3dd2d257ff0e14dbd2583485dbd44b&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Dave&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;followers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1234&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;following&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;123&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;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;UserContext&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;UserContext&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;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// ... skip the middle stuff ...&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="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;"app"&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;Nav&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;Body&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;ReactDOM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;UserStore&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;App&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;UserStore&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;,&lt;/span&gt;
  &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#root&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 your user data is nicely contained in its own component whose &lt;em&gt;sole&lt;/em&gt; concern is user data. Awesome. &lt;code&gt;App&lt;/code&gt; can be stateless once again. I think it looks a little cleaner, too.&lt;/p&gt;

&lt;p&gt;Here’s an &lt;a href="https://codesandbox.io/s/jpy76nm1v" rel="noopener noreferrer"&gt;example CodeSandbox with this UserStore&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pass Actions Down Through Context
&lt;/h3&gt;

&lt;p&gt;Rememeber that the object being passed down through the &lt;code&gt;Provider&lt;/code&gt; can contain whatever you want. Which means it can contain functions. You might even call them “actions.”&lt;/p&gt;

&lt;p&gt;Here’s a new example: a simple Room with a lightswitch to toggle the background color – err, I mean lights.&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%2Fdaveceddia.com%2Fimages%2Flightswitch-app.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%2Fdaveceddia.com%2Fimages%2Flightswitch-app.gif" alt="the fire is dead. the room is freezing."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The state is kept in the store, which also has a function to toggle the light. Both the state and the function are passed down through context.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ReactDOM&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-dom&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./styles.css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Plain empty context&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;RoomContext&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="nf"&gt;createContext&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// A component whose sole job is to manage&lt;/span&gt;
&lt;span class="c1"&gt;// the state of the Room&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RoomStore&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;isLit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="nx"&gt;toggleLight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;isLit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isLit&lt;/span&gt; &lt;span class="p"&gt;}));&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Pass down the state and the onToggleLight action&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;RoomContext&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;isLit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isLit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;onToggleLight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toggleLight&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;RoomContext&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;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Receive the state of the light, and the function to&lt;/span&gt;
&lt;span class="c1"&gt;// toggle the light, from RoomContext&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Room&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;RoomContext&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="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;isLit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;onToggleLight&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;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;`room &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;isLit&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lit&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="s2"&gt;dark&lt;/span&gt;&lt;span class="dl"&gt;"&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;
        The room is &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;isLit&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lit&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="s2"&gt;dark&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;.
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;br&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onToggleLight&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Flip&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;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;RoomContext&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="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;"app"&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;Room&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Wrap the whole app in the RoomStore&lt;/span&gt;
&lt;span class="c1"&gt;// this would work just as well inside `App`&lt;/span&gt;
&lt;span class="nx"&gt;ReactDOM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;RoomStore&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;App&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;RoomStore&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;,&lt;/span&gt;
  &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#root&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;Here’s the &lt;a href="https://codesandbox.io/s/jvky9o0nvw" rel="noopener noreferrer"&gt;full working example in CodeSandbox&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Should You Use Context, or Redux?
&lt;/h2&gt;

&lt;p&gt;Now that you’ve seen both ways – which one should you use? Well, if there’s one thing that will make your apps &lt;em&gt;better&lt;/em&gt; and &lt;em&gt;more fun to write&lt;/em&gt;, it’s &lt;strong&gt;taking control of making the decisions&lt;/strong&gt;. I know you might just want “The Answer,” but I’m sorry to have to tell you, “it depends.”&lt;/p&gt;

&lt;p&gt;It depends on things like how big your app is, or will grow to be. How many people will work on it – just you, or a larger team? How experienced are you or your team with functional concepts (the ones Redux relies upon, like immutability and pure functions).&lt;/p&gt;

&lt;p&gt;One big pernicious fallacy that pervades the JavaScript ecosystem is the idea of &lt;em&gt;competition&lt;/em&gt;. The idea that every choice is a zero-sum game: if you use &lt;em&gt;Library A&lt;/em&gt;, you must not use &lt;em&gt;its competitor Library B&lt;/em&gt;. The idea that when a new library comes out that’s better in some way, that it must supplant an existing one. There’s a perception that everything must be either/or, that you must either choose The Best Most Recent or be relegated to the back room with the developers of yesteryear.&lt;/p&gt;

&lt;p&gt;A better approach is to look at this wonderful array of choices like a &lt;em&gt;toolbox&lt;/em&gt;. It’s like the choice between using a screwdriver or an impact driver. For 80% of the jobs, the impact driver is gonna put the screw in faster than the screwdriver. But for that other 20%, the screwdriver is actually the better choice – maybe because the space is tight, or the item is delicate. When I got an impact driver I didn’t immediately throw away my screwdriver, or even my non-impact drill. The impact driver didn’t &lt;em&gt;replace&lt;/em&gt; them, it simply gave me another &lt;em&gt;option&lt;/em&gt;. Another way to solve a problem.&lt;/p&gt;

&lt;p&gt;Context doesn’t “replace” Redux any more than React “replaced” Angular or jQuery. Heck, I still use jQuery when I need to do something quick. I still sometimes use server-rendered EJS templates instead of spinning up a whole React app. Sometimes React is more than you need for the task at hand. Sometimes Redux is more than you need.&lt;/p&gt;

&lt;p&gt;Today, when Redux is more than you need, you can reach for Context.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://daveceddia.com/context-api-vs-redux/" rel="noopener noreferrer"&gt;Redux vs. The React Context API&lt;/a&gt; was originally published by Dave Ceddia at &lt;a href="https://daveceddia.com" rel="noopener noreferrer"&gt;Dave Ceddia&lt;/a&gt; on July 17, 2018.&lt;/p&gt;

</description>
      <category>react</category>
      <category>redux</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Perfect Pulled Pork with React Native, Expo, and Express</title>
      <dc:creator>Dave Ceddia</dc:creator>
      <pubDate>Thu, 07 Jun 2018 13:51:09 +0000</pubDate>
      <link>https://forem.com/dceddia/perfect-pulled-pork-with-react-native-expo-and-express-2dag</link>
      <guid>https://forem.com/dceddia/perfect-pulled-pork-with-react-native-expo-and-express-2dag</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally posted on &lt;a href="https://daveceddia.com/perfect-pulled-pork-react-native-expo-express/"&gt;my blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gd8RkwY8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://daveceddia.com/images/pulled-pork-post.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gd8RkwY8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://daveceddia.com/images/pulled-pork-post.png" alt="Perfect Pulled Pork with React Native, Expo, and Express"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Or: &lt;em&gt;Taking a Picture Every 30 Seconds and Sending It To A Server&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I was planning to make pulled pork the next day. That evening I set up the Weber kettle, got out the bag of charcoal and some chunks of apple wood, and laid everything out. &lt;em&gt;Mise en place&lt;/em&gt;, as they say. I’d be waking up at 7am the next morning to light it up, and I didn’t trust my sleepy self to remember everything.&lt;/p&gt;

&lt;p&gt;One of the things I set out was the probe thermometer and 2 probes: one to measure the air temperature, and one to measure the internal temperature of the meat. Smoking is a &lt;em&gt;low and slow&lt;/em&gt; method of cooking: you want to get the air temperature up to 225˚F and hold it there for &lt;em&gt;hours&lt;/em&gt; as the meat slowly cooks and infuses with smoke. Smoking a pork shoulder (a.k.a. pulled-pork-to-be) can take 8 - 12 hours. Hence why I’m waking up at 7am.&lt;/p&gt;

&lt;p&gt;So where does React Native play into all this?&lt;/p&gt;

&lt;p&gt;Well, holding a temperature with a Weber kettle is a bit of a trick. And a manual one at that. There are 2 air vents you can tweak – one on top, one on the bottom. Open them up to increase the temperature, close them down to lower it. The fire takes a while to respond, though. It’s a fire, not a digital dial. So you, as the pit master, get to be a human PID controller for the day.&lt;/p&gt;

&lt;p&gt;What I mean is: you have to keep watching the temperature, adjusting the vents, and re-checking. If you’re good at it, you don’t have to tweak it much, but I’m a newb, so I’m out there a lot.&lt;/p&gt;

&lt;p&gt;I wanted to be able to know, without running out to the smoker every 15 minutes, whether the temperature was at 225˚F or close enough.&lt;/p&gt;

&lt;p&gt;This is where React Native comes in.&lt;/p&gt;

&lt;p&gt;At 9pm, after I’d laid out all the materials, I had the idea: I’ll make an app to take a picture of the thermometer every 30 seconds, and upload it to a server – and then I can just refresh a page instead of running down to the smoker!&lt;/p&gt;

&lt;p&gt;And before you tell me – yes, I know there are remote thermometers for sale that do exactly this. And yes, I also know I could’ve just sat outside with a beer all day watching the thing, and that would’ve been fun too. But really I just wanted an excuse to play with React Native :)&lt;/p&gt;

&lt;h2&gt;
  
  
  Grand Plans: The System Layout
&lt;/h2&gt;

&lt;p&gt;Like any good project, I started off thinking about how I wanted it to work.&lt;/p&gt;

&lt;p&gt;I would need:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A phone with a camera (old iPhone 4S).&lt;/li&gt;
&lt;li&gt;An app running on the phone to take pictures all day.&lt;/li&gt;
&lt;li&gt;A server to receive the pictures, running on my laptop.&lt;/li&gt;
&lt;li&gt;The same server to serve up the latest picture.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I decided I wanted to keep this as minimal as possible (mostly because it was 9pm and I still needed to wake up at 7). There would be little to no security. There would be no websockets notifying a React app to download the latest image. This server would simply accept images, and send back the latest upon request.&lt;/p&gt;

&lt;h3&gt;
  
  
  React Native
&lt;/h3&gt;

&lt;p&gt;You’ve probably heard of &lt;a href="https://facebook.github.io/react-native/"&gt;React Native&lt;/a&gt; - a framework for building native mobile apps using React and JS. If you can write React apps, you can figure out React Native pretty quickly. The core concepts are the same, just props and state.&lt;/p&gt;

&lt;p&gt;Since there’s no DOM behind React Native, though, there are some differences. Mainly, the HTML elements you know and love (&lt;code&gt;div&lt;/code&gt;, &lt;code&gt;span&lt;/code&gt;, &lt;code&gt;img&lt;/code&gt;, etc.) are replaced by React Native components (&lt;code&gt;div&lt;/code&gt; == &lt;code&gt;View&lt;/code&gt;, &lt;code&gt;span&lt;/code&gt; == &lt;code&gt;Text&lt;/code&gt;, &lt;code&gt;img&lt;/code&gt; == &lt;code&gt;Image&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Also, “real” CSS isn’t supported, but RN does support styling through inline styles. Flexbox layout and most normal styles like &lt;code&gt;color&lt;/code&gt; and &lt;code&gt;backgroundColor&lt;/code&gt; and the like will work. I noticed that some shorthand properties don’t work either: something like &lt;code&gt;border: 1px solid red&lt;/code&gt; would instead be described explicitly, like &lt;code&gt;{ borderWidth: 1, borderColor: 'red' }&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Expo
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://expo.io/features"&gt;Expo&lt;/a&gt; is a tool, and a platform, for building apps with React Native.&lt;/p&gt;

&lt;p&gt;One nice thing about using Expo is that it lets you deploy apps to your phone without signing up for an Apple Developer subscription (for us iPhone people anyway). I’ve read that you actually &lt;em&gt;can&lt;/em&gt; get an app onto your phone without the Apple Developer subscription, but it requires messing with Xcode and that wasn’t something I wanted to tackle this evening.&lt;/p&gt;

&lt;p&gt;The other big bonus with Expo is that it comes with the &lt;a href="https://docs.expo.io/"&gt;Expo SDK&lt;/a&gt; which gives you a bunch of native APIs out of the box – like the accelerometer, compass, location, maps, and the most important one for this project: the camera.&lt;/p&gt;

&lt;h4&gt;
  
  
  Install Expo on Computer and Phone
&lt;/h4&gt;

&lt;p&gt;I used the Expo command line but they also provide an IDE. If you want to follow along, install the Expo commandline tool with NPM or Yarn:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; exp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Yes, it’s &lt;code&gt;exp&lt;/code&gt;, not expo).&lt;/p&gt;

&lt;p&gt;Then you need to install the Expo app on your phone, and you can find that in the App Store / Play Store.&lt;/p&gt;

&lt;h4&gt;
  
  
  Create the Project
&lt;/h4&gt;

&lt;p&gt;With the command line tool installed, run this command to create a new project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;exp init grillview
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It’ll prompt for a template: choose the “blank” one.&lt;/p&gt;

&lt;p&gt;Then follow the provided instructions to start it up:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;grillview
&lt;span class="nv"&gt;$ &lt;/span&gt;exp start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At some point it will ask you to create an account with Expo. This is needed in order to deploy the app from your computer to Expo’s servers. Then the Expo app on your phone can load your app.&lt;/p&gt;

&lt;p&gt;Follow the instructions to send the URL to your device, or just type it in. Expo also lets you run this in a simulator, but I thought it’d be more fun with the real phone so that’s what I did.&lt;/p&gt;

&lt;p&gt;Once you’ve got it open on your phone, the developer experience is pretty nice. Change code, save, and the app will live reload (auto-refresh) automatically – just like developing locally with Create React App. There’s a small delay as it downloads the JS bundle each time. You can also enable hot reloading (no refresh) from Expo’s developer menu, which you can bring up if you shake your phone. Gently. Don’t throw it through a window or whatever.&lt;/p&gt;

&lt;h4&gt;
  
  
  File Structure
&lt;/h4&gt;

&lt;p&gt;Expo sets us up with an &lt;code&gt;App.js&lt;/code&gt; file in the root of the project, which exports the &lt;code&gt;App&lt;/code&gt; component. Here’s the entirety of the generated app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;StyleSheet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;View&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-native&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&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;container&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Open up App.js to start working on your app!&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&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="nc"&gt;View&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="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;styles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;StyleSheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;container&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#fff&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;alignItems&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;justifyContent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You’ll notice there’s a &lt;code&gt;Text&lt;/code&gt; component inside the &lt;code&gt;View&lt;/code&gt;. Try leaving the “Open up App.js…” text alone, but removing the wrapping &lt;code&gt;Text&lt;/code&gt; component and see what happens.&lt;/p&gt;

&lt;p&gt;If you peek inside &lt;code&gt;package.json&lt;/code&gt; you’ll see this line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node_modules/expo/AppEntry.js"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is what kicks off our app, and it expects to find an &lt;code&gt;App.js&lt;/code&gt; file that exports the root component.&lt;/p&gt;

&lt;p&gt;If you wanted to reorganize the project structure, the first step would be to copy AppEntry.js into your project and modify it accordingly, but we’re gonna stick with defaults on this one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using the Camera
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Permission Granted
&lt;/h3&gt;

&lt;p&gt;To take pictures, Expo provides a &lt;code&gt;Camera&lt;/code&gt; component. But before we can use it, we need to ask for permission.&lt;/p&gt;

&lt;p&gt;Open up &lt;code&gt;App.js&lt;/code&gt;, add a new &lt;code&gt;import&lt;/code&gt; for the camera and permissions objects, and change the component to look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;StyleSheet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;View&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-native&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// add this:&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;Camera&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Permissions&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;expo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// initialize state&lt;/span&gt;
  &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;cameraPermission&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="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;cameraPermission&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Render one of 3 things depending on permissions&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;View&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&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;container&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;cameraPermission&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Waiting for permission...&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&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="nx"&gt;cameraPermission&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Permission denied&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&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="p"&gt;(&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;yay camera&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&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;View&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the app should render “Waiting for permission…” and just be stuck there, since we’re not doing anything yet.&lt;/p&gt;

&lt;p&gt;We’ll ask for permission in the &lt;code&gt;componentDidMount&lt;/code&gt; lifecycle hook. Add that in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;

  &lt;span class="nx"&gt;componentDidMount&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;Permissions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;askAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Permissions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CAMERA&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
          &lt;span class="na"&gt;cameraPermission&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;granted&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;
      &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;render&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;p&gt;When you save, and the app refreshes, you’ll see a dialog asking for camera permission. And once you allow it, the text should change.&lt;/p&gt;

&lt;p&gt;If this is your first time using Expo, it will probably ask for permissions for Expo itself before asking about your app.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1ZsSsXCf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://daveceddia.com/images/expo_permission_check.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1ZsSsXCf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://daveceddia.com/images/expo_permission_check.gif" alt="When permission is granted, the app re-renders"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Live Camera View
&lt;/h3&gt;

&lt;p&gt;Now let’s replace the “yay camera” text with a component that will render the camera. Add a new component to &lt;code&gt;App.js&lt;/code&gt; named &lt;code&gt;Autoshoot&lt;/code&gt;. For now, it will just render the Camera, and we can make sure everything is working.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Autoshoot&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt; &lt;span class="na"&gt;style&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;flex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;100%&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Camera&lt;/span&gt;
          &lt;span class="na"&gt;style&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;flex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Camera&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Constants&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;back&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="na"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;cam&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;camera&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cam&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Camera&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;View&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We’re putting the Camera inside a View, giving both &lt;code&gt;flex: 1&lt;/code&gt; so they take up the entire height, and the &lt;code&gt;width: '100%'&lt;/code&gt; so the View takes the entire screen (without the width set, you’ll see a blank screen: try it!).&lt;/p&gt;

&lt;p&gt;We’re using the “better” camera (on iPhone anyway – the &lt;code&gt;back&lt;/code&gt; one, as opposed to the &lt;code&gt;front&lt;/code&gt; selfie one).&lt;/p&gt;

&lt;p&gt;And we’re saving a &lt;code&gt;ref&lt;/code&gt; to this camera component, because that’s how we’ll trigger the shutter in the next section.&lt;/p&gt;

&lt;p&gt;Now that this component exists, go back to the render method of &lt;code&gt;App&lt;/code&gt; and replace the “yay camera” element with this Autoshoot component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;cameraPermission&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Render one of 3 things depending on permissions&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;View&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&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;container&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;cameraPermission&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Waiting for permission...&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&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="nx"&gt;cameraPermission&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Permission denied&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&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="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Autoshoot&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;View&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;h3&gt;
  
  
  Finally: Taking a Picture
&lt;/h3&gt;

&lt;p&gt;To trigger the shutter, we’ll put a “button” of sorts inside the Camera component. Unfortunately &lt;code&gt;Camera&lt;/code&gt; doesn’t support the &lt;code&gt;onPress&lt;/code&gt; prop (the one that gets triggered when you tap it), so we’ll import &lt;code&gt;TouchableOpacity&lt;/code&gt; and render one of those inside.&lt;/p&gt;

&lt;p&gt;At the top, import it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;StyleSheet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;View&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;TouchableOpacity&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-native&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And in Autoshoot’s &lt;code&gt;render&lt;/code&gt;, insert the component as a child of Camera:&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="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;photo&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="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;Camera&lt;/span&gt;
      &lt;span class="na"&gt;style&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;flex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Camera&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Constants&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;back&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;cam&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;camera&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cam&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TouchableOpacity&lt;/span&gt;
        &lt;span class="na"&gt;style&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;flex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;onPress&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;takePicture&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Camera&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;Then we need a &lt;code&gt;takePicture&lt;/code&gt; method, which we can insert above &lt;code&gt;render&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;takePicture&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;camera&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;takePictureAsync&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;quality&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;base64&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;exif&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;photo&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;photo&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;At this point, the app will behave the same: when you tap the screen, the app will still display the camera (and hopefully no errors).&lt;/p&gt;

&lt;p&gt;Next, we need to initialize the state of &lt;code&gt;photo&lt;/code&gt; at the top:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Autoshoot&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;photo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then inside &lt;code&gt;render&lt;/code&gt;, we’ll either render the photo (if there is one) or the camera:&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="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;photo&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="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;View&lt;/span&gt; &lt;span class="na"&gt;style&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;flex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;100%&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
     &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;photo&lt;/span&gt; &lt;span class="p"&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="nc"&gt;ImageBackground&lt;/span&gt;
         &lt;span class="na"&gt;style&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;flex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
         &lt;span class="na"&gt;source&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;uri&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;photo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;uri&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
     &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&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="nc"&gt;Camera&lt;/span&gt;
         &lt;span class="na"&gt;style&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;flex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
         &lt;span class="na"&gt;onPress&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;takePicture&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
         &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Camera&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Constants&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;back&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
         &lt;span class="na"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;cam&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;camera&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cam&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
         &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TouchableOpacity&lt;/span&gt;
           &lt;span class="na"&gt;style&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;flex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
           &lt;span class="na"&gt;onPress&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;takePicture&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
       &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Camera&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;View&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’re using the &lt;code&gt;ImageBackground&lt;/code&gt; component for the first time here too, so make sure to import that at the top from ‘react-native’:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;StyleSheet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;View&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;TouchableOpacity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ImageBackground&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-native&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There we go! Now you can tap the screen to take a picture, and it will stay up on the screen.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here’s a quick exercise for you:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Make it so that when you tap the captured photo, the app goes back to displaying the Camera. Hint: &lt;code&gt;ImageBackground&lt;/code&gt; doesn’t support &lt;code&gt;onPress&lt;/code&gt;, so you’ll need to use the same trick we used with the &lt;code&gt;TouchableOpacity&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Taking Photos On a Timer
&lt;/h2&gt;

&lt;p&gt;We’ve got the code in place to take a picture &lt;em&gt;manually&lt;/em&gt; – now let’s automate it.&lt;/p&gt;

&lt;p&gt;We can do this by essentially calling &lt;code&gt;takePicture&lt;/code&gt; on an interval. But there’s a small problem: the camera needs a bit of time to focus before it takes the shot. So what we really need is something like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Activate camera (screen shows live camera)&lt;/li&gt;
&lt;li&gt;Let it focus for 3 seconds&lt;/li&gt;
&lt;li&gt;Take a picture (screen shows still image)&lt;/li&gt;
&lt;li&gt;Wait 27 seconds&lt;/li&gt;
&lt;li&gt;GOTO 1&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And once we get that working, we’ll insert a step “3a”: send the picture to the server. (which doesn’t exist yet, but we’ll get to that in a bit)&lt;/p&gt;

&lt;p&gt;When &lt;code&gt;Autoshoot&lt;/code&gt; initially renders, we’ll start a 30-second timer. Let’s create a constant for the timer, and the amount of time to focus, because we’ll need it in a few places.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PHOTO_INTERVAL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;30000&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;FOCUS_TIME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Autoshoot&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;componentDidMount&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;countdown&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;takePicture&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;PHOTO_INTERVAL&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;componentWillUnmount&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;clearInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;countdown&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And for testing purposes, just change the timeout to 2 seconds so we’re not waiting around all day.&lt;/p&gt;

&lt;p&gt;When the app reloads (which you can trigger manually by shaking your device, and choosing “Reload JS Bundle”), a photo will be taken automatically. Awesome.&lt;/p&gt;

&lt;h3&gt;
  
  
  Start Another Timer
&lt;/h3&gt;

&lt;p&gt;Now that we’re taking a photo automatically, we just need a couple more timers to have it take photos all day long.&lt;/p&gt;

&lt;p&gt;There are a few ways to write this: we could do it with two stacked timers (one for 27 seconds, which then triggers one for 3 seconds), or we could do it with 2 simultaneous timers, or we could do it with &lt;code&gt;setState&lt;/code&gt; callbacks.&lt;/p&gt;

&lt;p&gt;The latter option is probably the most precise (and avoids potential race conditions), but we’ll go with the easy option: 2 simultaneous timers. With the triggers this far apart, a race condition/overlapping timers is &lt;em&gt;pretty&lt;/em&gt; unlikely.&lt;/p&gt;

&lt;p&gt;To make it work, replace &lt;code&gt;takePicture&lt;/code&gt; with this implementation:&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="nx"&gt;takePicture&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;camera&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;takePictureAsync&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;quality&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;base64&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;exif&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;photo&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;photo&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="c1"&gt;// In 27 seconds, turn the camera back on&lt;/span&gt;
    &lt;span class="nx"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;photo&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="nx"&gt;PHOTO_INTERVAL&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;FOCUS_TIME&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// In 30 seconds, take the next picture&lt;/span&gt;
    &lt;span class="nx"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;takePicture&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;PHOTO_INTERVAL&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;Now when the app refreshes, it will take pictures for infinity. (or until your battery runs out)&lt;/p&gt;

&lt;h2&gt;
  
  
  The Express Server
&lt;/h2&gt;

&lt;p&gt;We have the React Native app taking pictures now. Let’s work on building a server to send them to.&lt;/p&gt;

&lt;p&gt;We’re going to use Express to write a barebones server to handle two routes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;POST /&lt;/code&gt;: Upload a new photo&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GET /&lt;/code&gt;: View the latest photo&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For this most simple of servers, we’re just gonna create a &lt;code&gt;server.js&lt;/code&gt; file in the root of our &lt;code&gt;grillview&lt;/code&gt; project. React Native and Express, side-by-side. (Is this a recommended way to create Real Projects™? Nah, but this whole thing is a bit of a hack, so.).&lt;/p&gt;

&lt;p&gt;We’ll need a couple packages to make this work, so install those now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add express body-parser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we can start with a barebones Express server. Create the &lt;code&gt;server.js&lt;/code&gt; file and paste this in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bodyParser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;body-parser&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// If your phone has a modern camera (unlike my iPhone 4S)&lt;/span&gt;
&lt;span class="c1"&gt;// you might wanna make this bigger.&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bodyParser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;10mb&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}));&lt;/span&gt;

&lt;span class="c1"&gt;// TODO: handle requests&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;5005&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;port&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="s2"&gt;`Grill server listening on &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This won’t handle requests yet, but it will run. We have &lt;code&gt;bodyparser.json&lt;/code&gt; in place to handle the POST’ed images. Now let’s add the POST request handler in place of the TODO:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Store the single image in memory.&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;latestPhoto&lt;/span&gt; &lt;span class="o"&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;// Upload the latest photo for this session&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Very light error handling&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sendStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;400&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;got photo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;// Update the image and respond happily&lt;/span&gt;
  &lt;span class="nx"&gt;latestPhoto&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;photo&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sendStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&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 just accepts the image from the client and saves it in a local variable, to be returned later.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Quick warning&lt;/em&gt;: this is doing &lt;em&gt;nothing&lt;/em&gt; about security. We’re blindly saving something from the client and will parrot it back, which is a recipe for disaster in a deployed app. But since I’m only running it on my local network, I’m not too worried. For a real app, do some validation of the image before saving it.&lt;/p&gt;

&lt;p&gt;Underneath that we’ll add the GET handler that will send back the latest image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// View latest image&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Does this session have an image yet?&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;latestPhoto&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Nothing here yet&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sending photo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Send the image&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;img&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;latestPhoto&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;base64&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;writeHead&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&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;image/png&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;Content-Length&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;end&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Log the error and stay alive&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;e&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sendStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&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;We’re creating a buffer to convert the base64 image to binary, and then sending it to the client.&lt;/p&gt;

&lt;p&gt;And just to reiterate: this is not a secure setup. We’re assuming that the client sent us a good base64 image, but Rule 1 is “Don’t trust the client” – we should be validating the image before storing it.&lt;/p&gt;

&lt;p&gt;That’s all we need for the server! Start it up:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;node server.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then visit &lt;a href="http://localhost:5005"&gt;http://localhost:5005&lt;/a&gt; – you should see the message “Nothing here yet”. Leave the server running in a separate command line terminal, and we’ll go work on sending images to the server.&lt;/p&gt;

&lt;h3&gt;
  
  
  Uploading the Pictures
&lt;/h3&gt;

&lt;p&gt;Back in &lt;code&gt;App.js&lt;/code&gt; and the &lt;code&gt;Autoshoot&lt;/code&gt; component, we need to add a method for uploading the picture. In a larger app we might pull the API methods into a separate file and export them as individual functions – but since we only have the single call to make, we’ll put it in &lt;code&gt;Autoshoot&lt;/code&gt;. Add this method:&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="nx"&gt;uploadPicture&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;SERVER_URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;photo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;base64&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;content-type&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;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&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="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we’re using &lt;code&gt;fetch&lt;/code&gt; (which is built into React Native) to POST the data to the server. Notice the &lt;code&gt;SERVER_URL&lt;/code&gt; variable, which we haven’t created yet. Since this will only be working on our local network, we can hard-code that above &lt;code&gt;Autoshoot&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SERVER_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://&amp;lt;your-ip&amp;gt;:5005/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;&amp;lt;your-ip&amp;gt;&lt;/code&gt; with your own dev machine’s IP address. If you don’t know where to find that, &lt;a href="https://www.google.com/search?q=get+local+ip+address&amp;amp;oq=get+local+ip+address"&gt;Google is your friend&lt;/a&gt; :)&lt;/p&gt;

&lt;p&gt;Now we’ll change &lt;code&gt;takePicture&lt;/code&gt; to call &lt;code&gt;uploadPicture&lt;/code&gt;, and as part of that change, we’ll pull out the timer code into a separate method because we want to call it from 2 places:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Here's the timer code, lifted from takePicture:&lt;/span&gt;
&lt;span class="nx"&gt;queuePhoto&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// In 27 seconds, turn the camera back on&lt;/span&gt;
  &lt;span class="nx"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;photo&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="nx"&gt;PHOTO_INTERVAL&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;FOCUS_TIME&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// In 30 seconds, take the next picture&lt;/span&gt;
  &lt;span class="nx"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;takePicture&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;PHOTO_INTERVAL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Take the picture, upload it, and&lt;/span&gt;
&lt;span class="c1"&gt;// then queue up the next one&lt;/span&gt;
&lt;span class="nx"&gt;takePicture&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;camera&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;takePictureAsync&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;quality&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;base64&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;exif&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;photo&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;photo&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;uploadPicture&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;queuePhoto&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;queuePhoto&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that I’m calling &lt;code&gt;queuePhoto&lt;/code&gt; in both the &lt;code&gt;.then&lt;/code&gt; and &lt;code&gt;.catch&lt;/code&gt; handlers.&lt;/p&gt;

&lt;p&gt;I wanted the app to keep on chugging away even if I restarted the server (which will cause failed requests), so I just made it ignore errors entirely.&lt;/p&gt;

&lt;p&gt;During development it was helpful to add a console log in there to see why things were failing (syntax errors, etc), but I took it out once everything was working.&lt;/p&gt;

&lt;h2&gt;
  
  
  Time to cook some pulled pork!
&lt;/h2&gt;

&lt;p&gt;With those last changes in place, the app is working!&lt;/p&gt;

&lt;p&gt;I was excited to try it out. The next morning, I set up the thermometer and the phone. Started up the app, aaand… hmm, there’s no good place to put the phone.&lt;/p&gt;

&lt;p&gt;I could’ve just put the phone and the thermometer on the ground. That’s what I should’ve done. What a reasonable person would do.&lt;/p&gt;

&lt;p&gt;7am Dave did not do that. He grabbed an old board, cut 2 pieces of scrap wood, and fashioned it together into a little shelf leaned against the house.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SVmWEuxO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://daveceddia.com/images/phone-shelf.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SVmWEuxO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://daveceddia.com/images/phone-shelf.jpg" alt="A makeshift shelf for the phone"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;“Carpentry.” It has &lt;em&gt;pocket screws&lt;/em&gt;. Why? I have no idea.&lt;/p&gt;

&lt;p&gt;As for the app?&lt;/p&gt;

&lt;p&gt;It performed admirably. Mostly. It only crashed a &lt;em&gt;few&lt;/em&gt; times.&lt;/p&gt;

&lt;p&gt;It turned out to be pretty useful, and saved me a bunch of running up and down the stairs to check the temperature. A+++ would build again.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gxYWV2Bz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://daveceddia.com/images/grill-cam-action-shot.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gxYWV2Bz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://daveceddia.com/images/grill-cam-action-shot.jpg" alt="The view from the grill cam"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And the pulled pork was &lt;em&gt;delicious&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lAoho57o--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://daveceddia.com/images/pulled-pork.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lAoho57o--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://daveceddia.com/images/pulled-pork.jpg" alt="The final product: pulled pork"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaways
&lt;/h2&gt;

&lt;p&gt;I think it’s important to work some fun into programming projects. Give yourself permission to build something that already exists, if only to learn how to build it yourself. It doesn’t have to be a big serious project, or a perfect portfolio piece.&lt;/p&gt;

&lt;p&gt;And on that note, don’t be afraid to hack things together. It’s a fun project! Write some terrible code that you know is terrible. Don’t stress so much about perfect abstractions and Best Practices and feeling like you have to incorporate every new library and tool. It’ll be &lt;em&gt;fine&lt;/em&gt;. You can always refactor it when you write the blog post ;)&lt;/p&gt;

&lt;h4&gt;
  
  
  Recipes, Tools, Code…
&lt;/h4&gt;

&lt;p&gt;You can get the full code for this project &lt;a href="https://github.com/dceddia/grillview"&gt;on Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I followed Amazing Ribs’s &lt;a href="https://amazingribs.com/tested-recipes/pork-chops-pulled-pork-ham-and-more-pork-recipes/perfect-pulled-pork-recipe"&gt;Perfect Pulled Pork&lt;/a&gt; recipe.&lt;/p&gt;

&lt;p&gt;I used a &lt;a href="https://www.amazon.com/Weber-741001-Original-22-Inch-Charcoal/dp/B00004RALU"&gt;Weber 22” Grill&lt;/a&gt; with a &lt;a href="https://abcbarbecue.com/product/slow-n-sear/"&gt;Slow n’ Sear&lt;/a&gt; (evidently discontinued, but I see there’s a &lt;a href="https://abcbarbecue.com/product/slow-n-sear-2-0/"&gt;v2&lt;/a&gt; which looks similar).&lt;/p&gt;

&lt;p&gt;The thermometer is a &lt;a href="https://www.thermoworks.com/DOT"&gt;ThermoWorks DOT&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;(no affiliate links, just good products)&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I have more articles on React and Redux at &lt;a href="https://daveceddia.com/archives/"&gt;my blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Why Not To Modify React State Directly</title>
      <dc:creator>Dave Ceddia</dc:creator>
      <pubDate>Fri, 01 Jun 2018 18:19:48 +0000</pubDate>
      <link>https://forem.com/dceddia/why-not-to-modify-react-state-directly-4p5e</link>
      <guid>https://forem.com/dceddia/why-not-to-modify-react-state-directly-4p5e</guid>
      <description>&lt;p&gt;Everybody says &lt;em&gt;&lt;strong&gt;don’t do it&lt;/strong&gt;&lt;/em&gt;. &lt;em&gt;Never mutate state directly&lt;/em&gt;, always call &lt;code&gt;setState&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;But why, though?&lt;/p&gt;

&lt;p&gt;If you’ve tried it out, you might’ve noticed nothing bad happened. If you modify state directy, call &lt;code&gt;this.setState({})&lt;/code&gt; or even &lt;code&gt;this.forceUpdate()&lt;/code&gt;, then everything might &lt;em&gt;appear&lt;/em&gt; to be just fine.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cart&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;cart&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cart&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="c1"&gt;// renders like normal! maybe?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a bad idea for two reasons (even though it would work in this example, and many others).&lt;/p&gt;

&lt;p&gt;(other patterns to avoid are things like &lt;code&gt;this.state.something = x&lt;/code&gt; and &lt;code&gt;this.state = x&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;Mutating state directly can lead to odd bugs, and components that are hard to optimize. Here’s an example.&lt;/p&gt;

&lt;p&gt;As you may already know, a common way to tune a React component for performance is to make it “pure,” which causes it to only re-render when its props change (instead of every time its parent re-renders). This can be done automatically by extending &lt;code&gt;React.PureComponent&lt;/code&gt; instead of &lt;code&gt;React.Component&lt;/code&gt;, or manually by implementing the &lt;code&gt;shouldComponentUpdate&lt;/code&gt; lifecycle method to compare &lt;code&gt;nextProps&lt;/code&gt; with current props. If the props look the same, it skips the render, and saves some time.&lt;/p&gt;

&lt;p&gt;Here is a simple component that renders a list of items (notice that it extends &lt;code&gt;React.PureComponent&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;ItemList&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PureComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;);&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, here is a tiny app that renders the &lt;code&gt;ItemList&lt;/code&gt; and allows you to add items to the list – the good way (immutably), and the bad way (by mutating state). Watch what happens.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Initialize items to an empty array&lt;/span&gt;
  &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;items&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="c1"&gt;// Initialize a counter that will increment&lt;/span&gt;
  &lt;span class="c1"&gt;// for each item ID&lt;/span&gt;
  &lt;span class="nx"&gt;nextItemId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;makeItem&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 ID and use&lt;/span&gt;
    &lt;span class="c1"&gt;// a random number as the value&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nextItemId&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;random&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="c1"&gt;// The Right Way:&lt;/span&gt;
  &lt;span class="c1"&gt;// copy the existing items and add a new one&lt;/span&gt;
  &lt;span class="nx"&gt;addItemImmutably&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;makeItem&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="c1"&gt;// The Wrong Way:&lt;/span&gt;
  &lt;span class="c1"&gt;// mutate items and set it back&lt;/span&gt;
  &lt;span class="nx"&gt;addItemMutably&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;makeItem&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addItemImmutably&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          Add item immutably (good)
        &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;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addItemMutably&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Add item mutably (bad)&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ItemList&lt;/span&gt; &lt;span class="na"&gt;items&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Try it out!&lt;/p&gt;

&lt;p&gt;Click the &lt;strong&gt;immutable&lt;/strong&gt; Add button a few times and notice how the list updates as expected.&lt;/p&gt;

&lt;p&gt;Then click the &lt;strong&gt;mutable&lt;/strong&gt; Add button and notice how the new items don’t appear, even though state is being changed.&lt;/p&gt;

&lt;p&gt;Finally, click the immutable Add button again, and watch how the ItemList re-renders with all the missing (mutably-added) items.&lt;/p&gt;

&lt;p&gt;This happens because &lt;code&gt;ItemList&lt;/code&gt; is pure, and because pushing a new item on the &lt;code&gt;this.state.items&lt;/code&gt; array does not replace the underlying array. When &lt;code&gt;ItemList&lt;/code&gt; is asked to re-render, it will notice that its props haven’t changed and it will not re-render.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recap
&lt;/h2&gt;

&lt;p&gt;So there you go: that’s why you shouldn’t mutate state, even if you immediately call setState. Optimized components might not re-render if you do, and the rendering bugs will be tricky to track down.&lt;/p&gt;

&lt;p&gt;Instead, always create new objects and arrays when you call &lt;code&gt;setState&lt;/code&gt;, which is what we did above with the spread operator. &lt;a href="https://daveceddia.com/immutable-updates-react-redux"&gt;Learn more about how to use the spread operator for immutable updates&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://daveceddia.com/why-not-modify-react-state-directly/"&gt;Why Not To Modify React State Directly&lt;/a&gt; was originally published by Dave Ceddia at &lt;a href="https://daveceddia.com"&gt;Dave Ceddia&lt;/a&gt; on June 01, 2018.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.codeproject.com"&gt;CodeProject&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
    </item>
    <item>
      <title>Where to Initialize State in React</title>
      <dc:creator>Dave Ceddia</dc:creator>
      <pubDate>Thu, 29 Mar 2018 14:08:13 +0000</pubDate>
      <link>https://forem.com/dceddia/where-to-initialize-state-in-react-c03</link>
      <guid>https://forem.com/dceddia/where-to-initialize-state-in-react-c03</guid>
      <description>&lt;p&gt;Ahh, the many ways of initializing state… It can be confusing. Do you put the &lt;code&gt;state = {...}&lt;/code&gt; directly inside the class, or do you write a constructor and say &lt;code&gt;this.state = { ... }&lt;/code&gt; inside the constructor? And do you need to have a constructor at all?&lt;/p&gt;

&lt;h2&gt;
  
  
  2 Ways to Initialize State
&lt;/h2&gt;

&lt;p&gt;There are two ways to initialize state in a React component: inside the constructor, and directly inside the class. Here are a couple examples.&lt;/p&gt;

&lt;h2&gt;
  
  
  Inside the Constructor
&lt;/h2&gt;

&lt;p&gt;Initializing state inside the constructor looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class App extends React.Component {
  constructor(props) {
    // Required step: always call the parent class' constructor
    super(props);

    // Set the state directly. Use props if necessary.
    this.state = {
      loggedIn: false,
      currentState: "not-panic"
      someDefaultThing: this.props.whatever
    }
  }

  render() {
    // whatever you like
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the component class is created, the constructor is the first method called, so it’s the right place to initialize everything – state included. The class instance has already been created in memory, so you can use &lt;code&gt;this&lt;/code&gt; to set properties on it.&lt;/p&gt;

&lt;p&gt;This is the &lt;em&gt;one place&lt;/em&gt; where it is acceptable to have &lt;code&gt;this.state&lt;/code&gt; on the left side of an equal sign. Everywhere else, you should always use &lt;code&gt;this.setState&lt;/code&gt; instead of doing &lt;code&gt;this.state.whatever = ...&lt;/code&gt; – that way, React will know that you’ve changed something, and it can re-render the component.&lt;/p&gt;

&lt;p&gt;One important thing to note when you write a constructor is to make sure to call the parent class’ constructor: the &lt;code&gt;super(props)&lt;/code&gt; line in the example above. The default constructor (provided by JS when you create a class) automatically calls &lt;code&gt;super&lt;/code&gt; with any arguments passed in.&lt;/p&gt;

&lt;p&gt;By writing your own constructor, you’re overriding that default behavior, and unless you call &lt;code&gt;super&lt;/code&gt; yourself, it could lead to bugs if the parent needed to do some initialization.&lt;/p&gt;

&lt;h4&gt;
  
  
  Is a constructor required?
&lt;/h4&gt;

&lt;p&gt;You aren’t required to write one, because JS provides a default constructor. To see how this works, try running these 3 lines in your browser’s console:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Parent { constructor(arg) { console.log('constructing Parent with', arg) } }
class Child extends Parent {}
new Child(5);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice how it prints “constructing Parent with 5” when you create a new Child, even though Child has no explicitly-defined constructor, and doesn’t explicitly call the parent’s with &lt;code&gt;super(arg)&lt;/code&gt;. This &lt;code&gt;super&lt;/code&gt; call is handled by JS automatically when you don’t define your own constructor.&lt;/p&gt;

&lt;h2&gt;
  
  
  Directly Inside the Class
&lt;/h2&gt;

&lt;p&gt;The second way to initialize state is directly inside the class definition, using a class property. Here’s what that looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class App extends React.Component {
  state = {
    loggedIn: false,
    currentState: "not-panic",
    someDefaultThing: this.props.whatever
  }

  render() {
    // whatever you like
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nice and clean! A couple things to note here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;There’s no constructor&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;state&lt;/code&gt; property is referenced directly. It’s not &lt;code&gt;this.state&lt;/code&gt;, just &lt;code&gt;state&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The scope is inside the class, but not inside a method.&lt;/li&gt;
&lt;li&gt;You can still refer to &lt;code&gt;this.props&lt;/code&gt; (and &lt;code&gt;this.context&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;This is a class &lt;em&gt;instance&lt;/em&gt; property, as opposed to a static one, which you might use for propTypes (e.g. &lt;code&gt;static propTypes = {...}&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As I’m writing this, the class property syntax is a &lt;a href="https://github.com/tc39/proposal-class-fields"&gt;Stage 3 proposal&lt;/a&gt; so it’s not part of the official JS spec yet. To use it, you’ll need to enable &lt;a href="https://babeljs.io/docs/plugins/transform-class-properties/"&gt;Babel’s class properties transform&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;But! If you’re &lt;a href="https://dev.to/create-react-app-official-project-generator/"&gt;using Create React App to bootstrap your projects&lt;/a&gt;, it already has the class properties transform turned on, and you can start using this class property syntax today.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which is better? Constructor or no?
&lt;/h2&gt;

&lt;p&gt;Like all things, it’s up to you.&lt;/p&gt;

&lt;p&gt;Me, I prefer the clean look of the class property. I don’t like the extra boilerplate of the constructor, and having to remember to call &lt;code&gt;super(props)&lt;/code&gt; (though ESlint can remind you to do that, and Create React App’s config does that out of the box).&lt;/p&gt;

&lt;p&gt;You may have seen event handling functions being bound in the constructor, and might think constructors are required to pull this off. I’m talking about code like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Thing extends React.Component {
  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick(event) {
    // do stuff
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another type of syntax supported by the class properties feature can make this constructor unnecessary: you can set a property equal to an arrow function, and the arrow function inherits the &lt;code&gt;this&lt;/code&gt; binding of the class instance so you don’t have to bind it explicitly. It looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Thing extends React.Component {
  // This is all you need to do:
  handleClick = (event) =&amp;gt; {
    // do stuff
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This might look at little odd at first, but you can think of it this way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// This statement:
const add = (a, b) =&amp;gt; console.log(a + b);

// Can be thought of as assigning an arrow function to `add`:
const add = arrowFunction;

// where `arrowFunction` is expanded to:
(a, b) =&amp;gt; console.log(a + b)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With that in mind, take another look at the &lt;code&gt;class Thing&lt;/code&gt; example above. Hopefully it looks a little less weird. If you still hate it, give it some time and write some more arrow functions. I had the same problem at first. Your eyes will adjust :)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://daveceddia.com/where-initialize-state-react/"&gt;Where to Initialize State in React&lt;/a&gt; was originally published by Dave Ceddia at &lt;a href="https://daveceddia.com"&gt;Dave Ceddia&lt;/a&gt; on March 29, 2018.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.codeproject.com"&gt;CodeProject&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>What is a Redux reducer?</title>
      <dc:creator>Dave Ceddia</dc:creator>
      <pubDate>Mon, 19 Mar 2018 14:08:13 +0000</pubDate>
      <link>https://forem.com/dceddia/what-is-a-redux-reducer-1mbo</link>
      <guid>https://forem.com/dceddia/what-is-a-redux-reducer-1mbo</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;reducer&lt;/strong&gt; , &lt;em&gt;n.&lt;/em&gt; – A word Redux made up to confuse you.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In order to write Redux code, you need to know a few things. One of those things is what a &lt;strong&gt;reducer&lt;/strong&gt; is and what it does. It might seem a bit scary and foreign, but after this short article I think you’ll come to agree that it is, as the saying goes, “just a function.”&lt;/p&gt;

&lt;p&gt;First off, where does the name “reducer” come from? Redux didn’t actually make it up (I was kidding about that). It might not seem too foreign if you’re familiar with functional programming and JavaScript’s &lt;code&gt;Array.reduce&lt;/code&gt; function. And if you know &lt;code&gt;Array.reduce&lt;/code&gt;, you know that it takes a function (one might call it a “reducer” function) that has the signature &lt;code&gt;(accumulatedValue, nextItem) =&amp;gt; nextAccumulatedValue&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Array.reduce is like a sister to Redux
&lt;/h2&gt;

&lt;p&gt;If you aren’t yet familar with &lt;code&gt;Array.reduce&lt;/code&gt;, here’s what’s up:&lt;/p&gt;

&lt;p&gt;JavaScript’s Array has a built-in function called &lt;code&gt;reduce&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;(&lt;em&gt;Technically&lt;/em&gt; I should be writing it as &lt;code&gt;Array.prototype.reduce&lt;/code&gt;, because it is a function on &lt;em&gt;array instances&lt;/em&gt;, not on the capital-A &lt;code&gt;Array&lt;/code&gt; constructor.)&lt;/p&gt;

&lt;p&gt;It takes a function as an argument, and it calls your provided function once for each element of the array, similar to how &lt;code&gt;Array.map&lt;/code&gt; works (or a &lt;code&gt;for&lt;/code&gt; loop, for that matter). Your function gets called with 2 arguments: the last iteration’s result, and the current array element. This will make more sense with an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var letters = ['r', 'e', 'd', 'u', 'x'];

// `reduce` takes 2 arguments:
// - a function to do the reducing (you might say, a "reducer")
// - an initial value for accumulatedResult
var word = letters.reduce(
  function(accumulatedResult, arrayItem) {
    return accumulatedResult + arrayItem;
  },
''); // &amp;lt;-- notice this empty string argument: it's the initial value

console.log(word) // =&amp;gt; "redux"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, the reducer will get called 5 times (because there are 5 elements in the array). The calls go like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;first called with &lt;code&gt;('', 'r')&lt;/code&gt; =&amp;gt; returns &lt;code&gt;'r'&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;the empty string &lt;code&gt;''&lt;/code&gt; comes from the 2nd argument to &lt;code&gt;reduce&lt;/code&gt;, and the &lt;code&gt;'r'&lt;/code&gt; is the first element of the array&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;then &lt;code&gt;('r', 'e')&lt;/code&gt; =&amp;gt; returns &lt;code&gt;'re'&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;the ‘r’ comes from the previous return value, and ‘e’ is the next element of the array&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;then &lt;code&gt;('re', 'd')&lt;/code&gt; =&amp;gt; returns &lt;code&gt;'red'&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;the ‘re’ is the previous return value, and ‘d’ is the third array element&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;then &lt;code&gt;('red', 'u')&lt;/code&gt; =&amp;gt; returns &lt;code&gt;'redu'&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;by now you are sensing a pattern&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;then &lt;code&gt;('redu', 'x')&lt;/code&gt; =&amp;gt; returns &lt;code&gt;'redux'&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;the pattern is all too clear now&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The last return value, &lt;code&gt;'redux'&lt;/code&gt;, is returned as the final result and stored in the &lt;code&gt;word&lt;/code&gt; variable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Redux Reducers
&lt;/h2&gt;

&lt;p&gt;Now that you know how &lt;code&gt;Array.reduce&lt;/code&gt; works, I can tell you that Redux is &lt;em&gt;basically&lt;/em&gt; a fancy Array.reduce function (ok ok that’s a huge oversimplification, but bear with me).&lt;/p&gt;

&lt;p&gt;A Redux reducer function has this signature:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;(state, action) =&amp;gt; newState&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;As in: it takes the current &lt;code&gt;state&lt;/code&gt;, and an &lt;code&gt;action&lt;/code&gt;, and returns the &lt;code&gt;newState&lt;/code&gt;. Looks a lot like the signature of an Array.reduce reducer, eh? Remember:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;(accumulatedValue, nextItem) =&amp;gt; nextAccumulatedValue&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Plainly speaking, a Redux reducer gets to decide how each action affects the state. Let’s look at an example one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function wordReducer(state = '', action) {
  switch(action.type) {
    case 'ADD_LETTER':
      return state + action.letter;
    case 'RESET':
      return '';
    default:
      return state;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Quick quiz: is there any Redux-specific code in here? Anything that depends on the Redux library to work? Go ahead, think it over, I’ll wait.&lt;/p&gt;

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

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

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

&lt;p&gt;Answer: Nope! This is a plain old function. Sure, it takes &lt;code&gt;(state, action)&lt;/code&gt; arguments and returns a new state. And it expects &lt;code&gt;action&lt;/code&gt; to look something like &lt;code&gt;{type: 'ADD_LETTER', letter: 'r'}&lt;/code&gt;. But none of that is particularly &lt;em&gt;bound&lt;/em&gt; to Redux.&lt;/p&gt;

&lt;h3&gt;
  
  
  How it Works
&lt;/h3&gt;

&lt;p&gt;But anyway, what does it actually do? Let’s try calling it with a few things and see what it returns.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let state = '';
console.log(wordReducer(state, {type: 'ADD_LETTER', letter: 'y'}));
  // =&amp;gt; y
console.log(wordReducer(state, {type: 'ADD_LETTER', letter: 'y'}));
  // =&amp;gt; y
console.log(wordReducer(state, {type: 'ADD_LETTER', letter: 'y'}));
  // =&amp;gt; y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First: notice that &lt;code&gt;wordReducer&lt;/code&gt; does not &lt;em&gt;remember&lt;/em&gt; anything. It holds no state within.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let state = '';
console.log(wordReducer(state, {type: 'ADD_LETTER', letter: 'a'}));
  // =&amp;gt; a
console.log(wordReducer(state, {type: 'ADD_LETTER', letter: 'b'}));
  // =&amp;gt; b
console.log(state)
  // =&amp;gt; ''
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next: notice that &lt;code&gt;wordReducer&lt;/code&gt; does not &lt;em&gt;change&lt;/em&gt; the state. It merely returns a new one. It treats state as &lt;em&gt;immutable&lt;/em&gt;. This is important because, by updating state in an immutable way, Redux is able to tell which pieces of state changed, and optimize how your app is re-rendered.&lt;/p&gt;

&lt;p&gt;One more thing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.log(wordReducer(undefined, {type: 'UNHANDLED'}));
  // =&amp;gt; ''
console.log(wordReducer('existing state', {type: 'UNHANDLED'}));
  // =&amp;gt; 'existing state'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that the reducer has an initial state (when given &lt;code&gt;undefined&lt;/code&gt;, it returns an empty string anyway), and that it has a &lt;code&gt;default&lt;/code&gt; case that handles any actions it doesn’t understand (it returns the existing state, unchanged, when it sees such an action).&lt;/p&gt;

&lt;h3&gt;
  
  
  Pilot Needed
&lt;/h3&gt;

&lt;p&gt;I can tell you don’t think this is very useful. What good is a function that doesn’t remember anything, and doesn’t change anything?&lt;/p&gt;

&lt;p&gt;I’ll tell you: This function is nice because it is &lt;em&gt;predictable&lt;/em&gt;. If you call it with the same arguments, you get the same outputs, every single time. It doesn’t matter what else has changed in your app – this function will always act the same way.&lt;/p&gt;

&lt;p&gt;It is easy to figure out what it does by reading its code (and easy to debug!) because it’s all self-contained.&lt;/p&gt;

&lt;p&gt;Now, the downside with a function like this is that it needs a &lt;em&gt;driver&lt;/em&gt; of sorts. Something needs to hold on to the intermediate state, otherwise the app won’t really do much of anything.&lt;/p&gt;

&lt;p&gt;The driver, in this case, is Redux. Specifically, the Redux store. It does something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let state = '';
state = wordReducer(state, {type: 'ADD_LETTER', letter: 'a'}));
state = wordReducer(state, {type: 'ADD_LETTER', letter: 'b'}));
state = wordReducer(state, {type: 'ADD_LETTER', letter: 'c'}));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The store maintains an internal &lt;code&gt;state&lt;/code&gt; variable. When an action is dispatched, the store calls the reducer, and replaces its internal &lt;code&gt;state&lt;/code&gt; with whatever the reducer returned. Every time the store calls the reducer, it passes in the last-known state.&lt;/p&gt;

&lt;p&gt;Around and around it goes: Redux sitting there waiting for an action, handling that action, updating the state, re-rendering your app, on and on forever.&lt;/p&gt;

&lt;p&gt;So that’s it! That’s how Redux reducers work, in a nutshell. Not too bad?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://daveceddia.com/what-is-a-reducer/"&gt;What is a Redux reducer?&lt;/a&gt; was originally published by Dave Ceddia at &lt;a href="https://daveceddia.com"&gt;Dave Ceddia&lt;/a&gt; on March 19, 2018.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.codeproject.com"&gt;CodeProject&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Love JavaScript, but hate CSS?</title>
      <dc:creator>Dave Ceddia</dc:creator>
      <pubDate>Thu, 15 Mar 2018 01:02:42 +0000</pubDate>
      <link>https://forem.com/dceddia/love-javascript-but-hate-css-254e</link>
      <guid>https://forem.com/dceddia/love-javascript-but-hate-css-254e</guid>
      <description>&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%2Fdaveceddia.com%2Fimages%2Flove-js-hate-css.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%2Fdaveceddia.com%2Fimages%2Flove-js-hate-css.png" alt="Love JS, Hate CSS"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A reader wrote in to say that he was having great fun with JS and React, but when it came to styling, he was at a loss.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I love JavaScript but hate CSS. I just don’t have the patience to make something look good.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Writing code is fun. Solving problems is fun. That feeling of bliss when you finally get the computer to do what you want? Awesome.&lt;/p&gt;

&lt;p&gt;But then: &lt;em&gt;oh crap, the CSS&lt;/em&gt;. The app works fine but it looks terrible, and nobody will take it seriously because it doesn’t Look Like Apple(TM).&lt;/p&gt;

&lt;h2&gt;
  
  
  You’re Not Alone
&lt;/h2&gt;

&lt;p&gt;First, I want to get this out there: if you like everything about front end development &lt;em&gt;except CSS&lt;/em&gt;, you are not alone. I have known real actual professional UI developers &lt;em&gt;with jobs&lt;/em&gt; that were either rubbish at styling, or could &lt;em&gt;do&lt;/em&gt; it but they held their nose and tried to get it over with as quickly as possible.&lt;/p&gt;

&lt;p&gt;I was in that spot a few years ago. CSS was like a magical black box where I’d type things in and it would, at least 60% of the time, spit out something that looked worse than when I started. I solved most CSS problems with Google and StackOverflow and hoping like crazy that someone had encountered my exact problem before (somehow, they usually had).&lt;/p&gt;

&lt;p&gt;But I’ve since emerged from that dark place, and I can say that CSS (and the process of applying styles to a page) is a learnable skill. Even &lt;em&gt;design&lt;/em&gt; is a learnable skill. And for the record, they are different skills.&lt;/p&gt;

&lt;h2&gt;
  
  
  Styling is not Design
&lt;/h2&gt;

&lt;p&gt;The process of taking an existing visual design and writing the CSS to transform a hunk of &lt;code&gt;div&lt;/code&gt;s to match the visual design is called &lt;strong&gt;styling&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The process of taking a blank canvas and coming up with a beautiful looking web site is called &lt;strong&gt;design&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You can be good (even very good) at one of these while simultaneously being very bad at the other.&lt;/p&gt;

&lt;p&gt;To be a front end developer, you need some styling (CSS) skills but not necessarily design skills.&lt;/p&gt;

&lt;h2&gt;
  
  
  Can you avoid CSS?
&lt;/h2&gt;

&lt;p&gt;I wish I could tell you that you could forget all about CSS and stay in JS land 100% of the time.&lt;/p&gt;

&lt;p&gt;But in truth, I can’t do that. If you want to do front end development you’ll eventually need to get your hands dirty and learn you some CSS.&lt;/p&gt;

&lt;p&gt;I can tell you from experience though that CSS sucks a lot less once you understand a little bit about it. It can even be fun! I find it satisfying when I can get a page laid out just right, and know just which parameters to tweak to make it look the way I want.&lt;/p&gt;

&lt;h2&gt;
  
  
  What To Do
&lt;/h2&gt;

&lt;p&gt;While you can’t avoid CSS entirely, there are a few things that can make styling less sucky.&lt;/p&gt;

&lt;h3&gt;
  
  
  Frameworks
&lt;/h3&gt;

&lt;p&gt;CSS frameworks can help you get projects started quickly, and even make up for a lack of design skills. They are usually available as installable libraries with npm/yarn, or from a CDN. Each one has its own visual style, so you’ll want to weigh the appearance of each when you make a choice. CSS frameworks help you build a nice-looking app without fussing over styles (much).&lt;/p&gt;

&lt;p&gt;Here are some popular choices (I’m focusing on ones that work nicely with React):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://getbootstrap.com/" rel="noopener noreferrer"&gt;Bootstrap&lt;/a&gt; - Extremely popular (read: lots of questions and answers on SO) and decent looking. The latest version (v4) is more modern looking, but the older ones can look a bit dated these days. You can customize it with some of your own CSS, or use free and &lt;a href="https://themes.getbootstrap.com/" rel="noopener noreferrer"&gt;paid themes&lt;/a&gt; to change the look. If you’re using React, have a look at &lt;a href="https://react-bootstrap.github.io/getting-started/introduction" rel="noopener noreferrer"&gt;react-bootstrap&lt;/a&gt; for a bunch of pre-made components like modal dialogs, popovers, forms, etc.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://react.semantic-ui.com/introduction" rel="noopener noreferrer"&gt;Semantic UI&lt;/a&gt; - Another popular CSS framework with React components, it has a few more components available than Bootstrap, and (I think) a more modern look.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="http://blueprintjs.com/" rel="noopener noreferrer"&gt;Blueprint&lt;/a&gt; - I think Blueprint looks great, and to my eyes, better than Bootstrap or Semantic UI. But I haven’t used it myself. One thing that stands out with Blueprint is that it is written in (and supports) TypeScript. It doesn’t &lt;em&gt;require&lt;/em&gt; TypeScript, but if you’re using TS it might be worth a look.&lt;/p&gt;

&lt;p&gt;There are a &lt;em&gt;ton&lt;/em&gt; of CSS frameworks available. Here’s &lt;a href="https://hackernoon.com/the-coolest-react-ui-frameworks-for-your-new-react-app-ad699fffd651" rel="noopener noreferrer"&gt;a list&lt;/a&gt; with more that work with React.&lt;/p&gt;

&lt;p&gt;While frameworks might help you avoid touching much CSS at all, these next two things will let you work more easily with CSS directly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Flexbox
&lt;/h3&gt;

&lt;p&gt;Flexbox layout is a modern way to lay out content using CSS, much easier to use than the &lt;code&gt;float&lt;/code&gt;s of old (or the random stabbing in the dark you were doing 5 minutes ago). It has &lt;a href="https://caniuse.com/#search=flexbox" rel="noopener noreferrer"&gt;good browser support&lt;/a&gt; and makes it dead-simple to do some things that have traditionally been a big pain with CSS, like &lt;strong&gt;vertically centering things&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Take a look at this:&lt;/p&gt;

&lt;p&gt;Look how nicely centered that little red square is! The outer box with the gray border just needs these 3 lines of CSS to make that happen:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;display: flex; /* turn flexbox on */
justify-content: center; /* center horizontally */ 
align-items: center; /* center vertically */
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you right-click it and Inspect Element, you’ll see that it has more than those 3 lines… but they’re not responsible for centering the red box. That additional stuff gives it the gray border, makes it a square, centers it horizontally within this blog post (&lt;code&gt;margin: 0 auto&lt;/code&gt;), and the bottom margin gives it some breathing room from the text below.&lt;/p&gt;

&lt;p&gt;CSS Tricks has a great &lt;a href="https://css-tricks.com/snippets/css/a-guide-to-flexbox/" rel="noopener noreferrer"&gt;Complete Guide to Flexbox&lt;/a&gt; if you’re interested in learning more. I suggest checking it out! Flexbox really helped me get a grip on CSS and it’s my go-to tool for solving most layout problems now.&lt;/p&gt;

&lt;h3&gt;
  
  
  CSS Grid
&lt;/h3&gt;

&lt;p&gt;Grid is an even more modern way to do layout, and more powerful than flexbox. It can handle 2 dimensions (rows and columns) whereas flexbox is better at doing one direction or the other. Browser support is &lt;a href="https://caniuse.com/#feat=css-grid" rel="noopener noreferrer"&gt;pretty good&lt;/a&gt;. Accoding to CSS Tricks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;As of March 2017, most browsers shipped native, unprefixed support for CSS Grid: Chrome (including on Android), Firefox, Safari (including on iOS), and Opera. Internet Explorer 10 and 11 on the other hand support it, but it’s an old implementation with an outdated syntax. The time to build with grid is now!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As I write this, I have only barely fiddled around with CSS grid for layout. Being more powerful than flexbox, it’s a bit more complex, and I’ve found flexbox suits my needs well enough most of the time. It’s on my list to learn though!&lt;/p&gt;

&lt;p&gt;You can read CSS Tricks’ &lt;a href="https://css-tricks.com/snippets/css/complete-guide-grid/" rel="noopener noreferrer"&gt;Complete Guide to CSS Grid&lt;/a&gt; to learn more.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Logical Approach
&lt;/h3&gt;

&lt;p&gt;This is sort of a bonus meta “strategy” for dealing with CSS. As much as you can, try to avoid the random stabbing in the dark and copying-and-pasting from StackOverflow to get your layouts looking right.&lt;/p&gt;

&lt;p&gt;Try taking a more methodical approach.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;get the item into position (flexbox, grid, or maybe absolutely positioned inside a relative container)&lt;/li&gt;
&lt;li&gt;set its margins and padding&lt;/li&gt;
&lt;li&gt;set the border&lt;/li&gt;
&lt;li&gt;set a background color&lt;/li&gt;
&lt;li&gt;then &lt;a href="http://knowyourmeme.com/memes/how-to-draw-an-owl" rel="noopener noreferrer"&gt;draw the rest of the owl&lt;/a&gt; - add box shadows, set :hover/:active/:focus states, etc.&lt;/li&gt;
&lt;/ul&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%2Fdaveceddia.com%2Fimages%2Fdraw-an-owl.jpg" 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%2Fdaveceddia.com%2Fimages%2Fdraw-an-owl.jpg" alt="Draw the rest of the owl"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In some ways, software engineering principles like &lt;a href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself" rel="noopener noreferrer"&gt;DRY (Don’t Repeat Yourself)&lt;/a&gt; and the &lt;a href="https://en.wikipedia.org/wiki/Law_of_Demeter" rel="noopener noreferrer"&gt;Law of Demeter&lt;/a&gt; can apply to styling elements on a page. As an example, consider this layout for a user’s message with their avatar:&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%2Fdaveceddia.com%2Fimages%2Fcss-layout-dry-example.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%2Fdaveceddia.com%2Fimages%2Fcss-layout-dry-example.png" alt="Layout for a message with user avatar"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice that everything is 20 pixels away from the edges of the box. One way to achieve this would be to set the &lt;code&gt;margin&lt;/code&gt; of both elements in the box to &lt;code&gt;20px&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;But that has some downsides. First off, there’s repetition: what happens if that margin needs to change? Gotta change it in 2 places!&lt;/p&gt;

&lt;p&gt;Secondly, shouldn’t it be the box’s “responsibility” to determine how far inset its elements are, rather than leaving it up to each element to decide its own distance from an edge?&lt;/p&gt;

&lt;p&gt;A better way to do this layout would be to set the box’s &lt;code&gt;padding&lt;/code&gt; to &lt;code&gt;20px&lt;/code&gt;, so then the contents can be blissfully unaware of where they need to be. This also makes it easier to add new elements inside the box too – you don’t need to explicitly tell each element where to place itself.&lt;/p&gt;

&lt;p&gt;This is a tiny example just to illustrate the point, which is that a bit of forethought and a logical approach can make styling go much more smoothly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Action Steps!
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Find 3 layouts to copy. These could be small elements of sites you use (a single tweet, a Pinterest card, etc) or they could be physical things like a credit card or a book cover.&lt;/li&gt;
&lt;li&gt;Read the &lt;a href="https://css-tricks.com/snippets/css/a-guide-to-flexbox/" rel="noopener noreferrer"&gt;Complete Guide to Flexbox&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Use flexbox to create the layouts you picked in Step 1.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://daveceddia.com/love-js-hate-css/" rel="noopener noreferrer"&gt;Love JavaScript, but hate CSS?&lt;/a&gt; was originally published by Dave Ceddia at &lt;a href="https://daveceddia.com" rel="noopener noreferrer"&gt;Dave Ceddia&lt;/a&gt; on March 15, 2018.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.codeproject.com" rel="noopener noreferrer"&gt;CodeProject&lt;/a&gt;&lt;/p&gt;

</description>
      <category>css</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Where and When to Fetch Data With Redux</title>
      <dc:creator>Dave Ceddia</dc:creator>
      <pubDate>Fri, 02 Feb 2018 13:19:57 +0000</pubDate>
      <link>https://forem.com/dceddia/where-and-when-to-fetch-data-with-redux-gm1</link>
      <guid>https://forem.com/dceddia/where-and-when-to-fetch-data-with-redux-gm1</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;If a component needs data in order to render, and you want to fetch that data with Redux and keep it in the Redux store, when is the best time to make that API call?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;tl;dr – &lt;strong&gt;Kick off the action in the &lt;code&gt;componentDidMount&lt;/code&gt; lifecycle hook&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How This Works, in Code
&lt;/h2&gt;

&lt;p&gt;Let’s imagine you want to display a list of products. You’ve got a backend API that answers to &lt;code&gt;GET /products&lt;/code&gt;, so you create a Redux action to do the fetching:&lt;/p&gt;

&lt;p&gt;productActions.js&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export function fetchProducts() {
  return dispatch =&amp;gt; {
    dispatch(fetchProductsBegin());
    return fetch("/products")
      .then(handleErrors)
      .then(res =&amp;gt; res.json())
      .then(json =&amp;gt; {
        dispatch(fetchProductsSuccess(json.products));
        return json.products;
      })
      .catch(error =&amp;gt; dispatch(fetchProductsFailure(error)));
  };
}

// Handle HTTP errors since fetch won't.
function handleErrors(response) {
  if (!response.ok) {
    throw Error(response.statusText);
  }
  return response;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Side note: &lt;strong&gt;&lt;code&gt;fetch()&lt;/code&gt; does not throw HTTP errors&lt;/strong&gt;. This is really confusing if you’re used to something like &lt;a href="https://github.com/axios/axios"&gt;axios&lt;/a&gt;. Read &lt;a href="https://www.tjvantoll.com/2015/09/13/fetch-and-errors/"&gt;here&lt;/a&gt; for more about fetch and error handling.&lt;/p&gt;

&lt;p&gt;Redux actions that fetch data will typically be written with begin/success/failure actions surrounding the API call. This isn’t a requirement, but it’s useful because it lets you keep track of what’s happening – say, by setting a “loading” flag &lt;code&gt;true&lt;/code&gt; in response to the Begin action, and then &lt;code&gt;false&lt;/code&gt; after Success or Error. Here’s what those actions look like:&lt;/p&gt;

&lt;p&gt;productActions.js&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const FETCH_PRODUCTS_BEGIN = 'FETCH_PRODUCTS_BEGIN';
export const FETCH_PRODUCTS_SUCCESS = 'FETCH_PRODUCTS_SUCCESS';
export const FETCH_PRODUCTS_FAILURE = 'FETCH_PRODUCTS_FAILURE';

export const fetchProductsBegin = () =&amp;gt; ({
  type: FETCH_PRODUCTS_BEGIN
});

export const fetchProductsSuccess = products =&amp;gt; ({
  type: FETCH_PRODUCTS_SUCCESS,
  payload: { products }
});

export const fetchProductsError = error =&amp;gt; ({
  type: FETCH_PRODUCTS_FAILURE,
  payload: { error }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then we’ll have the reducer save the products into the Redux store when it receives the &lt;code&gt;FETCH_PRODUCTS_SUCCESS&lt;/code&gt; action. It’ll also set a &lt;code&gt;loading&lt;/code&gt; flag to true when the fetch begins, and false when it finishes or fails.&lt;/p&gt;

&lt;p&gt;productReducer.js&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import {
  FETCH_PRODUCTS_BEGIN,
  FETCH_PRODUCTS_SUCCESS,
  FETCH_PRODUCTS_FAILURE
} from './productActions';

const initialState = {
  items: [],
  loading: false,
  error: null
};

export default function productReducer(state = initialState, action) {
  switch(action.type) {
    case FETCH_PRODUCTS_BEGIN:
      // Mark the state as "loading" so we can show a spinner or something
      // Also, reset any errors. We're starting fresh.
      return {
        ...state,
        loading: true,
        error: null
      };

    case FETCH_PRODUCTS_SUCCESS:
      // All done: set loading "false".
      // Also, replace the items with the ones from the server
      return {
        ...state,
        loading: false,
        items: action.payload.products
      };

    case FETCH_PRODUCTS_ERROR:
      // The request failed, but it did stop, so set loading to "false".
      // Save the error, and we can display it somewhere
      // Since it failed, we don't have items to display anymore, so set it empty.
      // This is up to you and your app though: maybe you want to keep the items
      // around! Do whatever seems right.
      return {
        ...state,
        loading: false,
        error: action.payload.error,
        items: []
      };

    default:
      // ALWAYS have a default case in a reducer
      return state;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, we just need to pass the products into a &lt;code&gt;ProductList&lt;/code&gt; component that will display them, and also be responsible for kicking off the data fetching.&lt;/p&gt;

&lt;p&gt;ProductList.js&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
import { connect } from "react-redux";
import { fetchProducts } from "productActions";

class ProductList extends React.Component {
  render() {
    if (error) {
      return &amp;lt;div&amp;gt;Error! {error.message}&amp;lt;/div&amp;gt;;
    }

    if (loading) {
      return &amp;lt;div&amp;gt;Loading...&amp;lt;/div&amp;gt;;
    }

    return (
      &amp;lt;ul&amp;gt;
        {products.map(product =&amp;gt;
          &amp;lt;li key={product.id}&amp;gt;{product.name}&amp;lt;/li&amp;gt;
        )}
      &amp;lt;/ul&amp;gt;
    );
  }
}

const mapStateToProps = state =&amp;gt; ({
  products: state.products.items,
  loading: state.products.loading,
  error: state.products.error
});

export default connect(mapStateToProps)(ProductList);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  But It Will Render Twice!
&lt;/h2&gt;

&lt;p&gt;This is a really common concern. And yes, it &lt;em&gt;will&lt;/em&gt; render more than once.&lt;/p&gt;

&lt;p&gt;It will render in an empty state, then re-render in a loading state, and then re-render &lt;em&gt;again&lt;/em&gt; with products to show. The horror! 3 renders! (you could get it down to 2 if you skip straight to the “loading” state)&lt;/p&gt;

&lt;p&gt;You may be worried about “unnecessary” renders because of performance, but don’t be: single renders are very fast. If you’re working on an app where they are slow enough to notice, do some profiling and figure out why that’s the case.&lt;/p&gt;

&lt;p&gt;Think of it this way: the app needs to show &lt;em&gt;something&lt;/em&gt; when there are no products, or when they’re loading, or when there’s an error. You probably don’t want to just show a blank screen until the data is ready. This gives you an easy opportunity to make those decisions.&lt;/p&gt;

&lt;h2&gt;
  
  
  But The Component Shouldn’t Have to Fetch!
&lt;/h2&gt;

&lt;p&gt;From an architecture standpoint, it would be nicer if there was a parent “thing” (component or function or router or whatever) that automatically fetched data before it loaded the components. Then components could be blissfully unaware of any dirty API nonsense; they could simply wait around to be handed data on a silver platter. What a life!&lt;/p&gt;

&lt;p&gt;There are ways to fix this, but as with everything, there are tradeoffs. Magic data loaders are magic (harder to debug, harder to remember how/when/why they work). They might require &lt;em&gt;more&lt;/em&gt; code instead of less.&lt;/p&gt;

&lt;h2&gt;
  
  
  Many Ways To Skin This Cat
&lt;/h2&gt;

&lt;p&gt;There are many many ways to factor this code. There is no “best way,” because these things exist on a spectrum, and because the “best” for one use case may be the “worst” for another.&lt;/p&gt;

&lt;p&gt;“Fetch the data in &lt;code&gt;componentDidMount&lt;/code&gt;” is not the &lt;em&gt;one true way&lt;/em&gt;, but it’s simple, and it gets the job done.&lt;/p&gt;

&lt;p&gt;If you don’t like the idea of doing it this way, though, here are some things you could try:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Move the API call out of the Redux action and into an &lt;code&gt;api&lt;/code&gt; module, and call it from the action. (better separation of concerns)&lt;/li&gt;
&lt;li&gt;Have the component call the API module directly, and then have it dispatch the action when that data is returned, &lt;a href="https://egghead.io/lessons/javascript-redux-dispatching-actions-with-the-fetched-data"&gt;like Dan Abramov shows in this video&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Use a library like &lt;a href="https://github.com/kouhin/redux-dataloader"&gt;redux-dataloader&lt;/a&gt; or &lt;a href="https://github.com/recruit-tech/redux-async-loader"&gt;redux-async-loader&lt;/a&gt; or &lt;a href="https://github.com/markerikson/redux-ecosystem-links/blob/master/component-data-fetching-preloading.md"&gt;one of the other libraries from Mark Erikson’s list of data fetching libs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Make a wrapper component to do the fetching – in the above example, that might be called &lt;code&gt;ProductListPage&lt;/code&gt;. Then the “Page” takes care of fetching, and the “List” just accepts data and renders it.&lt;/li&gt;
&lt;li&gt;Use &lt;a href="https://github.com/acdlite/recompose"&gt;recompose&lt;/a&gt; to pull the &lt;code&gt;componentDidMount&lt;/code&gt; hook out into its own higher-order wrapper component&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Like I said, there are a lot of ways to do this :)&lt;/p&gt;

&lt;h2&gt;
  
  
  Action Steps
&lt;/h2&gt;

&lt;p&gt;Try implementing this yourself! Practice is the best way to learn.&lt;/p&gt;

&lt;p&gt;If you don’t have your own backend server, just use Reddit – their URLs will return JSON if you append “.json” to the end, e.g. &lt;a href="//www.reddit.com/r/reactjs.json"&gt;www.reddit.com/r/reactjs.json&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Make a tiny React + Redux app that displays the posts from /r/reactjs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://daveceddia.com/where-fetch-data-redux/"&gt;Where and When to Fetch Data With Redux&lt;/a&gt; was originally published by Dave Ceddia at &lt;a href="https://daveceddia.com"&gt;Dave Ceddia&lt;/a&gt; on February 02, 2018.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.codeproject.com"&gt;CodeProject&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Immutable Updates in React and Redux</title>
      <dc:creator>Dave Ceddia</dc:creator>
      <pubDate>Wed, 29 Nov 2017 14:11:06 +0000</pubDate>
      <link>https://forem.com/dceddia/immutable-updates-in-react-and-redux-kg</link>
      <guid>https://forem.com/dceddia/immutable-updates-in-react-and-redux-kg</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;How do you update state when you are not allowed to &lt;em&gt;change&lt;/em&gt; it?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Immutability is kind of hard to wrap your head around at first. It seems like a paradox. Changing the data without changing the data? Huh?&lt;/p&gt;

&lt;p&gt;On top of that, writing code to do immutable state updates is tricky. Below, you will find a few common patterns.&lt;/p&gt;

&lt;p&gt;Try them out on your own, whether in the browser developer console or in a real app. Pay particular attention to the nested object updates, and practice those. I find those to be the trickiest.&lt;/p&gt;

&lt;p&gt;All of this actually applies to React state too, so the things you learn in this guide will apply whether you use Redux or not.&lt;/p&gt;

&lt;p&gt;Finally, I should mention that some of this code can become easier to write by using a library like &lt;a href="https://facebook.github.io/immutable-js/"&gt;Immutable.js&lt;/a&gt;, though it comes with its own tradeoffs. If you recoil at the syntax below, check out Immutable.js.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Spread Operator
&lt;/h2&gt;

&lt;p&gt;These examples make heavy use of the &lt;strong&gt;spread&lt;/strong&gt; operator for arrays and objects. It’s represented by &lt;code&gt;...&lt;/code&gt; and when placed before an object or array, it unwraps the children within.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// For arrays:&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;nums&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&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;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;newNums&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; [1, 2, 3]&lt;/span&gt;
&lt;span class="nx"&gt;nums&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;newNums&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; false! not the same array&lt;/span&gt;

&lt;span class="c1"&gt;// For objects:&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Liz&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;32&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;newPerson&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="nx"&gt;person&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;newPerson&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; false! not the same object&lt;/span&gt;

&lt;span class="c1"&gt;// Internals are left alone:&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;company&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Foo Corp&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;people&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="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Joe&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Alice&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;newCompany&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;company&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="nx"&gt;newCompany&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;company&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; false! not the same object&lt;/span&gt;
&lt;span class="nx"&gt;newCompany&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;people&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;company&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;people&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; true!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When used as shown above, the spread operator makes it easy to create a new object or array that contains the exact same contents as another one. This is useful for creating a copy of an object/array, and then overwriting specific properties that you need to change:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;liz&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Liz&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;location&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;city&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Portland&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Oregon&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;pets&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="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cat&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Redux&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Make Liz one year older, while leaving everything&lt;/span&gt;
&lt;span class="c1"&gt;// else the same:&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;olderLiz&lt;/span&gt; &lt;span class="o"&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;liz&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;33&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The spread operator for objects is a stage 3 draft, which means it’s not officially part of JS yet. You’ll need to use a transpiler like Babel to use it in your code. If you use Create React App, you can already use it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recipes for Updating State
&lt;/h2&gt;

&lt;p&gt;These examples are written in the context of returning state from a Redux reducer: pretend that the &lt;code&gt;state = {whatever}&lt;/code&gt; at the top is the state that was passed in to the reducer, and then the updated version is returned underneath.&lt;/p&gt;

&lt;h4&gt;
  
  
  Applying to React and setState
&lt;/h4&gt;

&lt;p&gt;To apply these examples to plain React state, you just need to tweak a couple things:&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;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;updates&lt;/span&gt; &lt;span class="nx"&gt;here&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// becomes:&lt;/span&gt;
&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;updates&lt;/span&gt; &lt;span class="nx"&gt;here&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here are some common immutable update operations:&lt;/p&gt;

&lt;h3&gt;
  
  
  Updating an Object
&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;const&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;clicks&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="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;clicks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clicks&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="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Updating a Nested Object
&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;const&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;house&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Ravenclaw&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;points&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;17&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Two points for Ravenclaw&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;...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;house&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;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;house&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;points&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;house&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;points&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&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;h3&gt;
  
  
  Updating an Object by Key
&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;const&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;houses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;gryffindor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;points&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;ravenclaw&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;points&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;hufflepuff&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;points&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;slytherin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;points&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Add 3 points to Ravenclaw,&lt;/span&gt;
&lt;span class="c1"&gt;// when the name is stored in a variable&lt;/span&gt;
&lt;span class="kd"&gt;const&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="s2"&gt;ravenclaw&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;houses&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;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;houses&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="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;houses&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="na"&gt;points&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;houses&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;points&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;3&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;h3&gt;
  
  
  Add an element to the beginning of an array
&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;const&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&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;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newItem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="nx"&gt;newItem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Add an element to the end of an array
&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;const&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&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;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newItem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;newItem&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Add an element in the middle of an array
&lt;/h3&gt;

&lt;p&gt;Pro tip: Write unit tests for these things. It’s easy to make off-by-one errors.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&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;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&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;newItem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="c1"&gt;// array is new&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="c1"&gt;// first X items unchanged&lt;/span&gt;
  &lt;span class="nx"&gt;newItem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// last Y items unchanged&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Change an element in the middle of an array
&lt;/h3&gt;

&lt;p&gt;This is the same pattern as adding an item, except that the indexes are different.&lt;/p&gt;

&lt;p&gt;Pro tip: Write unit tests for these things. It’s easy to make off-by-one errors.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&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;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;X&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newItem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="c1"&gt;// array is new&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="c1"&gt;// first X items unchanged&lt;/span&gt;
  &lt;span class="nx"&gt;newItem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// last Y items unchanged&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  All Done
&lt;/h2&gt;

&lt;p&gt;Was this helpful? Did I miss a pattern you wanted to see? Leave a comment below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://daveceddia.com/immutable-updates-react-redux/"&gt;Immutable Updates in React and Redux&lt;/a&gt; was originally published by Dave Ceddia at &lt;a href="https://daveceddia.com"&gt;Dave Ceddia&lt;/a&gt; on November 29, 2017.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.codeproject.com"&gt;CodeProject&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
    </item>
    <item>
      <title>How Does Redux Work?</title>
      <dc:creator>Dave Ceddia</dc:creator>
      <pubDate>Sun, 29 Oct 2017 19:49:54 +0000</pubDate>
      <link>https://forem.com/dceddia/how-does-redux-work-cal</link>
      <guid>https://forem.com/dceddia/how-does-redux-work-cal</guid>
      <description>&lt;p&gt;After learning a bit about React and getting into Redux, it’s really confusing how it all works.&lt;/p&gt;

&lt;p&gt;Actions, reducers, action creators, middleware, pure functions, immutability...&lt;/p&gt;

&lt;p&gt;Most of these terms seem totally foreign.&lt;/p&gt;

&lt;p&gt;So in this post we’re going to demystify &lt;em&gt;how&lt;/em&gt; Redux works with a simple example. As in the &lt;a href="https://dev.to/dceddia/whats-redux-and-when-should-you-use-it-d7f"&gt;last post&lt;/a&gt;, I’ll try to explain Redux in simple terms before tackling the terminology.&lt;/p&gt;

&lt;p&gt;If you’re not yet sure &lt;em&gt;what Redux is for&lt;/em&gt; or why you should use it, read &lt;a href="https://dev.to/dceddia/whats-redux-and-when-should-you-use-it-d7f"&gt;this post first&lt;/a&gt; and then come back here.&lt;/p&gt;

&lt;h2&gt;
  
  
  First: Plain React State
&lt;/h2&gt;

&lt;p&gt;We’ll start with an example of plain old React state, and then add Redux piece-by-piece.&lt;/p&gt;

&lt;p&gt;Here is a counter:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6eijSHH3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://daveceddia.com/images/counter-plain.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6eijSHH3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://daveceddia.com/images/counter-plain.png" alt="Counter component"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And here’s the code (I left out the CSS to keep this simple, so it won’t be as pretty as the image):&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Counter&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;increment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;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="nx"&gt;decrement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;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="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Counter&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;decrement&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;-&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;increment&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;+&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&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;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;Counter&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As a quick review, here’s how this works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;count&lt;/code&gt; state is stored in the top level &lt;code&gt;Counter&lt;/code&gt; component&lt;/li&gt;
&lt;li&gt;When the user clicks “+”, the button’s &lt;code&gt;onClick&lt;/code&gt; handler is called, which is bound to the &lt;code&gt;increment&lt;/code&gt; function in the &lt;code&gt;Counter&lt;/code&gt; component.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;increment&lt;/code&gt; function updates the state with the new count.&lt;/li&gt;
&lt;li&gt;Because state was changed, React re-renders the &lt;code&gt;Counter&lt;/code&gt; component (and its children), and the new counter value is displayed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you need more detail about how state changes work, go read &lt;a href="https://daveceddia.com/visual-guide-to-state-in-react/"&gt;A Visual Guide to State in React&lt;/a&gt; and then come back here. Seriously: if the above was &lt;em&gt;not&lt;/em&gt; review for you, you need to learn how React state works &lt;em&gt;before&lt;/em&gt; you learn Redux.&lt;/p&gt;

&lt;h4&gt;
  
  
  Quick Setup
&lt;/h4&gt;

&lt;p&gt;If you’d like to follow along with the code, create a project now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install create-react-app if you don’t have it (&lt;code&gt;npm install -g create-react-app&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Create a project: &lt;code&gt;create-react-app redux-intro&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Open &lt;code&gt;src/index.js&lt;/code&gt; and replace it with this:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react';
import { render } from 'react-dom';
import Counter from './Counter';

const App = () =&amp;gt; (
  &amp;lt;div&amp;gt;
    &amp;lt;Counter /&amp;gt;
  &amp;lt;/div&amp;gt;
);

render(&amp;lt;App /&amp;gt;, document.getElementById('root'));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Create a &lt;code&gt;src/Counter.js&lt;/code&gt; with the code from the Counter example above.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Now: Add Redux
&lt;/h2&gt;

&lt;p&gt;As &lt;a href="https://dev.to/dceddia/whats-redux-and-when-should-you-use-it-d7f"&gt;discussed in Part 1&lt;/a&gt;, Redux keeps the &lt;strong&gt;state&lt;/strong&gt; of your app in a single &lt;strong&gt;store&lt;/strong&gt;. Then, you can extract parts of that state and plug it into your components as props. This lets you keep data in one global place (the store) and feed it directly to &lt;em&gt;any&lt;/em&gt; component in the app, without the gymnastics of passing props down multiple levels.&lt;/p&gt;

&lt;p&gt;Side note: you’ll often see the words “state” and “store” used interchangably. Technically, the &lt;strong&gt;state&lt;/strong&gt; is the data, and the &lt;strong&gt;store&lt;/strong&gt; is where it’s kept.&lt;/p&gt;

&lt;p&gt;As we go through the steps below, follow along in your editor! It will help you understand how this works (and we’ll get to work through some errors together).&lt;/p&gt;

&lt;p&gt;Add Redux to the project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ yarn add redux react-redux
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  redux vs react-redux
&lt;/h4&gt;

&lt;p&gt;Wait – 2 libraries? “What’s react-redux,” you say? Well, I’ve kinda been lying to you (sorry).&lt;/p&gt;

&lt;p&gt;See, &lt;code&gt;redux&lt;/code&gt; gives you a store, and lets you keep state in it, and get state out, and respond when the state changes. But that’s all it does. It’s actually &lt;code&gt;react-redux&lt;/code&gt; that lets you connect pieces of the state to React components. That’s right: &lt;code&gt;redux&lt;/code&gt; knows nothing about React &lt;em&gt;at all&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;These libraries are like two peas in a pod. 99.999% of the time, when anyone mentions “Redux” in the context of React, they are referring to both of these libraries in tandem. So keep that in mind when you see Redux mentioned on StackOverflow, or Reddit, or &lt;a href="https://dev.to/dceddia/keeping-up-with-the-javascript-world-eh9-temp-slug-5129540"&gt;elsewhere&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Last Things First
&lt;/h2&gt;

&lt;p&gt;Most tutorials start by creating a store, setting up Redux, writing a reducer, and so on. Lots must happen before anything appears on screen.&lt;/p&gt;

&lt;p&gt;I’m going to take a backwards approach, and it will take just as much code to make things appear on screen, but hopefully the motivation behind each step will be clearer.&lt;/p&gt;

&lt;p&gt;Back to the Counter app, let’s just imagine for a second that we moved the component’s state into Redux.&lt;/p&gt;

&lt;p&gt;We’ll remove the state from the component, since we’ll be getting that from Redux soon:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react';

class Counter extends React.Component {
  increment = () =&amp;gt; {
    // fill in later
  }

  decrement = () =&amp;gt; {
    // fill in later
  }

  render() {
    return (
      &amp;lt;div&amp;gt;
        &amp;lt;h2&amp;gt;Counter&amp;lt;/h2&amp;gt;
        &amp;lt;div&amp;gt;
          &amp;lt;button onClick={this.decrement}&amp;gt;-&amp;lt;/button&amp;gt;
          &amp;lt;span&amp;gt;{this.props.count}&amp;lt;/span&amp;gt;
          &amp;lt;button onClick={this.increment}&amp;gt;+&amp;lt;/button&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
    )
  }
}

export default Counter;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Wiring Up The Counter
&lt;/h2&gt;

&lt;p&gt;Notice that &lt;code&gt;{this.state.count}&lt;/code&gt; changed to &lt;code&gt;{this.props.count}&lt;/code&gt;. This won’t work yet, of course, because the Counter is not receiving a &lt;code&gt;count&lt;/code&gt; prop. We’re gonna use Redux to inject that.&lt;/p&gt;

&lt;p&gt;To get the count out of Redux, we first need to import the &lt;code&gt;connect&lt;/code&gt; function at the top:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { connect } from 'react-redux';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we need to “connect” the Counter component to Redux at the bottom:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Add this function:
function mapStateToProps(state) {
  return {
    count: state.count
  };
}

// Then replace this:
// export default Counter;

// With this:
export default connect(mapStateToProps)(Counter);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will fail with an error (more on that in a second).&lt;/p&gt;

&lt;p&gt;Where previously we were exporting the component itself, now we’re wrapping it with this &lt;code&gt;connect&lt;/code&gt; function call.&lt;/p&gt;

&lt;h4&gt;
  
  
  What’s &lt;code&gt;connect&lt;/code&gt;?
&lt;/h4&gt;

&lt;p&gt;You might notice the call looks little… weird. Why &lt;code&gt;connect(mapStateToProps)(Counter)&lt;/code&gt; and not &lt;code&gt;connect(mapStateToProps, Counter)&lt;/code&gt; or &lt;code&gt;connect(Counter, mapStateToProps)&lt;/code&gt;? What’s that doing?&lt;/p&gt;

&lt;p&gt;It’s written this way because &lt;code&gt;connect&lt;/code&gt; is a &lt;em&gt;higher-order function&lt;/em&gt;, which is a fancy way of saying it returns a function when you call it. And then calling &lt;em&gt;that&lt;/em&gt; function with a component returns a new (wrapped) component.&lt;/p&gt;

&lt;p&gt;Another name for this is a &lt;em&gt;higher-order component&lt;/em&gt; (aka “HOC”). HOCs have gotten some bad press lately, but they’re still quite useful, and &lt;code&gt;connect&lt;/code&gt; is a good example of a useful one.&lt;/p&gt;

&lt;p&gt;What &lt;code&gt;connect&lt;/code&gt; does is hook into Redux, pull out the entire state, and pass it through the &lt;code&gt;mapStateToProps&lt;/code&gt; function that you provide. This needs to be a custom function because only &lt;em&gt;you&lt;/em&gt; will know the “shape” of the state in Redux.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;connect&lt;/code&gt; passes the entire state as if to say, “Hey, tell me what you need out of this jumbled mess.”&lt;/p&gt;

&lt;p&gt;The object you return from &lt;code&gt;mapStateToProps&lt;/code&gt; gets fed into your component as props. The example above will pass &lt;code&gt;state.count&lt;/code&gt; as the value of the &lt;code&gt;count&lt;/code&gt; prop: the keys in the object become prop names, and their corresponding values become the props’ values. So you see, this function literally &lt;em&gt;defines a mapping from state into props&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Errors Mean Progress!
&lt;/h2&gt;

&lt;p&gt;If you’re following along, you will see an error like this in the console:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Could not find “store” in either the context or props of “Connect(Counter)”. Either wrap the root component in a , or explicitly pass "store" as a prop to "Connect(Counter)".&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Since &lt;code&gt;connect&lt;/code&gt; pulls data from the Redux store, and we haven’t set up a store or told the app how to find it, this error is pretty logical. Redux has no dang idea what’s going on right now.&lt;/p&gt;

&lt;h2&gt;
  
  
  Provide a Store
&lt;/h2&gt;

&lt;p&gt;Redux holds the global state for the entire app, and by wrapping the entire app with the &lt;code&gt;Provider&lt;/code&gt; component from &lt;code&gt;react-redux&lt;/code&gt;, &lt;em&gt;every component&lt;/em&gt; in the app tree will be able to use &lt;code&gt;connect&lt;/code&gt; to access the Redux store if it wants to.&lt;/p&gt;

&lt;p&gt;This means &lt;code&gt;App&lt;/code&gt;, and children of &lt;code&gt;App&lt;/code&gt; (like &lt;code&gt;Counter&lt;/code&gt;), and children of their children, and so on – all of them can now access the Redux store, but only if they are explicitly wrapped by a call to &lt;code&gt;connect&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I’m not saying to actually do that – &lt;code&gt;connect&lt;/code&gt;ing every single component would be a bad idea (messy design, and slow too).&lt;/p&gt;

&lt;p&gt;This &lt;code&gt;Provider&lt;/code&gt; thing might seem like total magic right now. It is a little bit; it actually uses React’s “context” feature under the hood.&lt;/p&gt;

&lt;p&gt;It’s like a secret passageway connected to every component, and using &lt;code&gt;connect&lt;/code&gt; opens the door to the passageway.&lt;/p&gt;

&lt;p&gt;Imagine pouring syrup on a pile of pancakes, and how it manages to make its way into ALL the pancakes even though you just poured it on the top one. &lt;code&gt;Provider&lt;/code&gt; does that for Redux.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;src/index.js&lt;/code&gt;, import the &lt;code&gt;Provider&lt;/code&gt; and wrap the&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Provider } from 'react-redux';

...

const App = () =&amp;gt; (
  &amp;lt;Provider&amp;gt;
    &amp;lt;Counter/&amp;gt;
  &amp;lt;/Provider&amp;gt;
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We’re still getting that error though – that’s because &lt;code&gt;Provider&lt;/code&gt; needs a store to work with. It’ll take the store as a prop, but we need to create one first.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create the Store
&lt;/h2&gt;

&lt;p&gt;Redux comes with a handy function that creates stores, and it’s called &lt;code&gt;createStore&lt;/code&gt;. Yep. Let’s make a store and pass it to Provider:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { createStore } from 'redux';

const store = createStore();

const App = () =&amp;gt; (
  &amp;lt;Provider store={store}&amp;gt;
    &amp;lt;Counter/&amp;gt;
  &amp;lt;/Provider&amp;gt;
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another error, but different this time:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Expected the reducer to be a function.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, here’s the thing about Redux: it’s not very smart. You might expect that by creating a store, it would give you a nice default value for the state inside that store. Maybe an empty object?&lt;/p&gt;

&lt;p&gt;But no: Redux makes &lt;em&gt;zero&lt;/em&gt; assumptions about the shape of your state. It’s up to you! It could be an object, or a number, or a string, or whatever you need. So we have to provide a function that will return the state. That function is called a &lt;strong&gt;reducer&lt;/strong&gt; (we’ll see why in a minute). So let’s make the simplest one possible, pass it into &lt;code&gt;createStore&lt;/code&gt;, and see what happens:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function reducer() {
  // just gonna leave this blank for now
  // which is the same as `return undefined;`
}

const store = createStore(reducer);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Reducer Should Always Return Something
&lt;/h2&gt;

&lt;p&gt;The error is different now:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Cannot read property ‘count’ of undefined&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It’s breaking because we’re trying to access &lt;code&gt;state.count&lt;/code&gt;, but &lt;code&gt;state&lt;/code&gt; is undefined. Redux expected our &lt;code&gt;reducer&lt;/code&gt; function to return a value for &lt;code&gt;state&lt;/code&gt;, except that it (implicitly) returned &lt;code&gt;undefined&lt;/code&gt;. Things are rightfully broken.&lt;/p&gt;

&lt;p&gt;The reducer is expected to return the state. It’s actually supposed to take the &lt;em&gt;current&lt;/em&gt; state and return the &lt;em&gt;new&lt;/em&gt; state, but nevermind; we’ll come back to that.&lt;/p&gt;

&lt;p&gt;Let’s make the reducer return something that matches the shape we need: an object with a &lt;code&gt;count&lt;/code&gt; property.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function reducer() {
  return {
    count: 42
  };
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hey! It works! The count now appears as “42”. Awesome.&lt;/p&gt;

&lt;p&gt;Just one thing though: the count is forever stuck at 42.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Story So Far
&lt;/h2&gt;

&lt;p&gt;Before we get into how to actually &lt;em&gt;update&lt;/em&gt; the counter, let’s look at what we’ve done up til now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We wrote a &lt;code&gt;mapStateToProps&lt;/code&gt; function that does what the name says: transforms the Redux state into an object containing props.&lt;/li&gt;
&lt;li&gt;We connected the Redux store to our &lt;code&gt;Counter&lt;/code&gt; component with the &lt;code&gt;connect&lt;/code&gt; function from &lt;code&gt;react-redux&lt;/code&gt;, using the &lt;code&gt;mapStateToProps&lt;/code&gt; function to configure how the connection works.&lt;/li&gt;
&lt;li&gt;We created a &lt;code&gt;reducer&lt;/code&gt; function to tell Redux what our state should look like.&lt;/li&gt;
&lt;li&gt;We used the ingeniously-named &lt;code&gt;createStore&lt;/code&gt; function to create a store, and passed it the &lt;code&gt;reducer&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;We wrapped our whole app in the &lt;code&gt;Provider&lt;/code&gt; component that comes with &lt;code&gt;react-redux&lt;/code&gt;, and passed it our store as a prop.&lt;/li&gt;
&lt;li&gt;The app works flawlessly, except the fact that the counter is stuck at 42.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With me so far?&lt;/p&gt;

&lt;h2&gt;
  
  
  Interactivity (Making It Work)
&lt;/h2&gt;

&lt;p&gt;So far this is pretty lame, I know. You could’ve written a static HTML page with the number “42” and 2 broken buttons in 60 seconds flat, yet here you are, reading how to overcomplicate that very same thing with React and Redux and who knows what else.&lt;/p&gt;

&lt;p&gt;I promise this next section will make it all worthwhile.&lt;/p&gt;

&lt;p&gt;Actually, no. I take that back. A simple Counter app is a great teaching tool, but Redux is absolutely overkill for something like this. React state is &lt;em&gt;perfectly fine&lt;/em&gt; for something so simple. Heck, even plain JS would work great. Pick the right tool for the job. Redux is not always that tool. But I digress.&lt;/p&gt;

&lt;h2&gt;
  
  
  Initial State
&lt;/h2&gt;

&lt;p&gt;So we need a way to tell Redux to change the counter.&lt;/p&gt;

&lt;p&gt;Remember the &lt;code&gt;reducer&lt;/code&gt; function we wrote? (of course you do, it was 2 minutes ago)&lt;/p&gt;

&lt;p&gt;Remember how I mentioned it takes the &lt;em&gt;current state&lt;/em&gt; and returns the &lt;em&gt;new state&lt;/em&gt;? Well, I lied again. It actually takes the current state and an &lt;em&gt;action&lt;/em&gt;, and then it returns the new state. We should have written it like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function reducer(state, action) {
  return {
    count: 42
  };
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The very first time Redux calls this function, it will pass &lt;code&gt;undefined&lt;/code&gt; as the &lt;code&gt;state&lt;/code&gt;. That is your cue to return the &lt;em&gt;initial state&lt;/em&gt;. For us, that’s probably an object with a &lt;code&gt;count&lt;/code&gt; of 0.&lt;/p&gt;

&lt;p&gt;It’s common to write the initial state above the reducer, and use ES6’s default argument feature to provide a value for the &lt;code&gt;state&lt;/code&gt; argument when it’s undefined.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const initialState = {
  count: 0
};

function reducer(state = initialState, action) {
  return state;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Try this out. It should still work, except now the counter is stuck at 0 instead of 42. Awesome.&lt;/p&gt;

&lt;h2&gt;
  
  
  Action
&lt;/h2&gt;

&lt;p&gt;We’re finally ready to talk about the &lt;code&gt;action&lt;/code&gt; parameter. What is it? Where does it come from? How can we use it to change the damn counter?&lt;/p&gt;

&lt;p&gt;An “action” is a JS object that describes a change that we want to make. The only requirement is that the object needs to have a &lt;code&gt;type&lt;/code&gt; property, and its value should be a string. Here’s an example of an action:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  type: "INCREMENT"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here’s another one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  type: "DECREMENT"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Are the gears turning in your head? Do you know what we’re gonna do next?&lt;/p&gt;

&lt;h2&gt;
  
  
  Respond to Actions
&lt;/h2&gt;

&lt;p&gt;Remember the reducer’s job is to take the &lt;em&gt;current state&lt;/em&gt; and an &lt;em&gt;action&lt;/em&gt; and figure out the new state. So if the reducer received an action like &lt;code&gt;{ type: "INCREMENT" }&lt;/code&gt;, what might you want to return as the new state?&lt;/p&gt;

&lt;p&gt;If you answered something like this, you’re on the right track:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function reducer(state = initialState, action) {
  if(action.type === "INCREMENT") {
    return {
      count: state.count + 1
    };
  }

  return state;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It’s common to use a &lt;code&gt;switch&lt;/code&gt; statement with &lt;code&gt;case&lt;/code&gt;s for each action you want to handle. Change your reducer to look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function reducer(state = initialState, action) {
  switch(action.type) {
    case 'INCREMENT':
      return {
        count: state.count + 1
      };
    case 'DECREMENT':
      return {
        count: state.count - 1
      };
    default:
      return state;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Always Return a State
&lt;/h4&gt;

&lt;p&gt;You’ll notice that there’s always the &lt;em&gt;fallback&lt;/em&gt; case where all it does is &lt;code&gt;return state&lt;/code&gt;. This is important, because Redux can (will) call your reducer with actions that it doesn’t know what to do with. In fact, the very first action you’ll receive is &lt;code&gt;{ type: "@@redux/INIT" }&lt;/code&gt;. Try putting a &lt;code&gt;console.log(action)&lt;/code&gt; above the &lt;code&gt;switch&lt;/code&gt; and see.&lt;/p&gt;

&lt;p&gt;Remember that the reducer’s job is to return a &lt;em&gt;new state&lt;/em&gt;, even if that state is unchanged from the current one. You never want to go from “having a state” to “state = undefined”, right? That’s what would happen if you left off the &lt;code&gt;default&lt;/code&gt; case. Don’t do that.&lt;/p&gt;

&lt;h4&gt;
  
  
  Never Change State
&lt;/h4&gt;

&lt;p&gt;One more thing to never do: do not &lt;em&gt;mutate&lt;/em&gt; the &lt;code&gt;state&lt;/code&gt;. State is immutable. You must never change it. That means you can’t do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function brokenReducer(state = initialState, action) {
  switch(action.type) {
    case 'INCREMENT':
      // NO! BAD: this is changing state!
      state.count++;
      return state;

    case 'DECREMENT':
      // NO! BAD: this is changing state too!
      state.count--;
      return state;

    default:
      // this is fine.
      return state;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You also can’t do things like &lt;code&gt;state.foo = 7&lt;/code&gt;, or &lt;code&gt;state.items.push(newItem)&lt;/code&gt;, or &lt;code&gt;delete state.something&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Think of it like a game where the only thing you can do is &lt;code&gt;return { ... }&lt;/code&gt;. It’s a fun game. Maddening at first. But you’ll get better at it with practice.&lt;/p&gt;

&lt;h4&gt;
  
  
  All These Rules…
&lt;/h4&gt;

&lt;p&gt;Always return a state, never change state, don’t connect every component, eat your broccoli, don’t stay out past 11… it’s exhausting. It’s like a rules factory, and I don’t even know what that is.&lt;/p&gt;

&lt;p&gt;Yeah, Redux can be like an overbearing parent. But it comes from a place of love. Functional programming love.&lt;/p&gt;

&lt;p&gt;Redux is built on the idea of immutability, because mutating global state is the road to ruin.&lt;/p&gt;

&lt;p&gt;Have you ever kept a global object and used it to pass state around an app? It works great at first. Nice and easy. And then the state starts changing in unpredictable ways and it becomes impossible to find the code that’s changing it.&lt;/p&gt;

&lt;p&gt;Redux avoids these problems with some simple rules. State is read-only, and actions are the only way to modify it. Changes happen one way, and one way only: action -&amp;gt; reducer -&amp;gt; new state. The reducer function must be “pure” – it cannot modify its arguments.&lt;/p&gt;

&lt;p&gt;There are even addon packages that let you log every action that comes through, rewind and replay them, and anything else you could imagine. Time-travel debugging was one of the original motivations for creating Redux.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Do Actions Come From?
&lt;/h2&gt;

&lt;p&gt;One piece of this puzzle remains: we need a way to feed an action into our reducer function so that we can increment and decrement the counter.&lt;/p&gt;

&lt;p&gt;Actions are not born, but they &lt;em&gt;are&lt;/em&gt; &lt;strong&gt;dispatched&lt;/strong&gt; , with a handy function called &lt;code&gt;dispatch&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;dispatch&lt;/code&gt; function is provided by the instance of the Redux store. That is to say, you can’t just &lt;code&gt;import { dispatch }&lt;/code&gt; and be on your way. You can call &lt;code&gt;store.dispatch(someAction)&lt;/code&gt;, but that’s not very convenient since the &lt;code&gt;store&lt;/code&gt; instance is only available in one file.&lt;/p&gt;

&lt;p&gt;As luck would have it, the &lt;code&gt;connect&lt;/code&gt; function has our back. In addition to injecting the result of &lt;code&gt;mapStateToProps&lt;/code&gt; as props, &lt;code&gt;connect&lt;/code&gt; &lt;em&gt;also&lt;/em&gt; injects the &lt;code&gt;dispatch&lt;/code&gt; function as a prop. And with that bit of knowledge, we can finally get the counter working again.&lt;/p&gt;

&lt;p&gt;Here is the final component in all its glory. If you’ve been following along, the only things that changed are the implementations of &lt;code&gt;increment&lt;/code&gt; and &lt;code&gt;decrement&lt;/code&gt;: they now call the &lt;code&gt;dispatch&lt;/code&gt; prop, passing it an action.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react';
import { connect } from 'react-redux';

class Counter extends React.Component {
  increment = () =&amp;gt; {
    this.props.dispatch({ type: 'INCREMENT' });
  }

  decrement = () =&amp;gt; {
    this.props.dispatch({ type: 'DECREMENT' });
  }

  render() {
    return (
      &amp;lt;div&amp;gt;
        &amp;lt;h2&amp;gt;Counter&amp;lt;/h2&amp;gt;
        &amp;lt;div&amp;gt;
          &amp;lt;button onClick={this.decrement}&amp;gt;-&amp;lt;/button&amp;gt;
          &amp;lt;span&amp;gt;{this.props.count}&amp;lt;/span&amp;gt;
          &amp;lt;button onClick={this.increment}&amp;gt;+&amp;lt;/button&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
    )
  }
}

function mapStateToProps(state) {
  return {
    count: state.count
  };
}

export default connect(mapStateToProps)(Counter);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code for the entire project (all two files of it) can be found &lt;a href="https://github.com/dceddia/redux-intro"&gt;on Github&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Now?
&lt;/h2&gt;

&lt;p&gt;With the Counter app under your belt, you are well-equipped to learn more about Redux.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“What?! There’s more?!”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There is much I haven’t covered here, in hopes of making this guide easily digestible – action constants, action creators, middleware, thunks and asynchronous calls, selectors, and on and on. There’s a lot. The &lt;a href="https://redux.js.org/"&gt;Redux docs&lt;/a&gt; are well-written and cover all that and more.&lt;/p&gt;

&lt;p&gt;But you’ve got the basic idea now. Hopefully you understand how data flows in Redux (&lt;code&gt;dispatch(action) -&amp;gt; reducer -&amp;gt; new state -&amp;gt; re-render&lt;/code&gt;), and what a reducer does, and what an action is, and how that all fits together.&lt;/p&gt;

&lt;p&gt;I’m putting together a new course that will cover all of this and more. If you want to know when that’s available, drop your email in the box below and I’ll give you a shout.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://daveceddia.com/how-does-redux-work/"&gt;How Does Redux Work?&lt;/a&gt; was originally published by Dave Ceddia at &lt;a href="https://daveceddia.com"&gt;Dave Ceddia&lt;/a&gt; on October 29, 2017.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
