<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Frontend Armory</title>
        <link>https://frontarm.com/</link>
        <description>Level up your JavaScript through interactive exercises and examples.</description>
        <lastBuildDate>Thu, 10 Sep 2020 00:00:00 GMT</lastBuildDate>
        <docs>http://blogs.law.harvard.edu/tech/rss</docs>
        <generator>Frontend Armory</generator>
        <copyright>Copyright Frontend Armory</copyright>
        <atom:link href="https:/frontarm.com/rss.xml" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Frontend Armory is now Free!]]></title>
            <link>https:/frontarm.com/james-k-nelson/demonetization/</link>
            <guid>https:/frontarm.com/james-k-nelson/demonetization/</guid>
            <pubDate>Thu, 10 Sep 2020 00:00:00 GMT</pubDate>
            <description><![CDATA[No more subscription fees. No more locked content. Everything on Frontend Armory is now free!]]></description>
            <content:encoded><![CDATA[<div class="doc-wrapper doc-Doc-18aNW doc-align-center-when-narrow-2ypbP "><p>So it’s been about a year since the last major update of Frontend Armory and… not particularly much has happened in the meantime. My life outside of the internet has gone through changes which have left me with less time than I’d like to work on content — about a day per week to be exact. And to be honest, I haven’t used that day a week as effectively as I’d like. The result being, well, nothing much of value.</p><p>Nothing much of value is a pretty bad look for a subscription-based site, so I’ve just put through a refund for all subscription fees paid between now and November 29 last year — which was Black Friday, and occurred <em>before</em> I made the last major update.</p><p>I’ve also made all of Frontend Armory’s content free, at least for now. It’s a little out of date, but there’s still a lot to learn from it. Here’s a few of my favorites that used to be behind the paywall:</p><ul><li><a class=" " href="/courses/react-and-bacon/forms/types-of-errors/">The three types of errors</a></li><li><a class=" " href="/courses/react-and-bacon/collecting-fetching-data/communication-state/">Communication state</a></li><li><a class=" " href="/courses/react-fundamentals/events-state-effects/effects/">Effects (with fractal trees)</a></li><li><a class=" " href="/james-k-nelson/vouch/">The “Vouch” source code</a></li></ul><p>I may add more paid content in the future, but if I do, it definitely <em>won’t</em> be subscription-based. Honestly, using a subscription model for this project was a mistake grounded in overly optimistic predictions of the amount of revenue… and the stability of React’s API. I’ll write about that another day, or actually, fuck it, I’ve just written about it at my blog: <a target="_blank" class=" " href="http://jamesknelson.com/react-its-technically-backwards-compatible/">React: it’s technically backwards compatible!</a>.</p><h2 id="where-to-from-here"><a class="doc-headingLink  " href="#where-to-from-here">#</a>Where to from here</h2><p>First, a break. But I do still want to teach programming — at least from what I can see, it’s one of the few ways to get a leg up in this world. And besides, it’s damn interesting.</p><p>I want to finish Vouch, and the React + Bacon course too. If you read my rant on React’s backwards compatibility, you might be surprised to hear that, but yep, I’m still planning on using React. React isn’t what it was, but it’s still a damn good tool. It’s a little like ordering a pizza and getting a steak.</p><p>One thing I’ve learned over the past year is that I can’t teach everything. My big issue with Vouch, React + Bacon was that I wanted to teach everything from the ground up. I wanted to teach people to build their own router, their own authentication, they’re own design system, etc. And… while it may well be possible for an experienced engineer to build an entire app from scratch, teaching it is another matter. I wrote a lot of drafts and code that never saw the light of day because the scope was just too large.</p><p>So, here’s my current goal: I want to create a useful app with working payments, but which <em>you</em> can build in a weekend. Then I want to live stream myself building the app, buying the domain, and deploying it — all in one day-long session. I want the app to be online, making money, providing a real service. And <em>then</em> I want to teach you to make that app.</p><p>I’ve actually been working on this the past few months — basically since I <a target="_blank" class=" " href="http://jamesknelson.com/farewell-twitter-at-least-for-now/">quit Twitter</a>. I thought it’d take me a month or two to get to the point where I can do the stream. It’s taking longer, as it always does. But I’m happy with the direction, and I’m making slow but steady progress. You can see some of it <a target="_blank" class=" " href="https://github.com/jamesknelson/retil">here</a>. For now, I’m going to take a bit of a break — but I do think you’ll hear more about the project at some point in the future.</p><p>Until then, thanks for reading :)</p></div>]]></content:encoded>
            <author>james@jamesknelson.com (James K Nelson)</author>
        </item>
        <item>
            <title><![CDATA[What the this? 5 simple rules to tame JavaScript's most confusing keyword]]></title>
            <link>https:/frontarm.com/james-k-nelson/what-the-this/</link>
            <guid>https:/frontarm.com/james-k-nelson/what-the-this/</guid>
            <pubDate>Fri, 15 May 2020 00:00:00 GMT</pubDate>
            <description><![CDATA[Learn to wield JavaScript's 'this' keyword like a pro – all it takes is 5 simple rules.]]></description>
            <content:encoded><![CDATA[<div class="doc-wrapper doc-Doc-18aNW doc-align-center-when-narrow-2ypbP "><p><code>this</code> may well be the most confusing part of JavaScript you’ll run up against — it sure is for me. And what’s worse, unlike other confusing things (like the <code>arguments</code> fake-array), there’s no modern substitute for it! You <em>need</em> <code>this</code> for classes, and thus for many modern JavaScript libraries. You’re kinda <em>stuck</em> with it.</p><p>It’s no wonder then that I recently received an e-mail with a question about <code>this</code>. In particular, the reader wanted some help understanding the below block of code from my article <a class=" " href="/james-k-nelson/when-to-use-arrow-functions/">When to use arrow functions with React</a>:</p><blockquote><p>Within this <code>render</code> function, the call to <code>handleClick</code> is preceded by <code>this.</code>. The <code>this</code> on line 4 refers to the component instance, so shouldn’t the <code>this</code> on line 7 point to the component instance too?</p></blockquote><pre class="language-jsx"><code>class BrokenButton extends React.Component {
  render() {
    return (
      &lt;button onClick={this.handleClick} style={this.state}&gt;        Set background to red
      &lt;/button&gt;
    )
  }

  handleClick() {
    this.setState({ backgroundColor: &#x27;red&#x27; })  }
}
</code></pre><p>Firstly, thanks for the great question! This is something that most JavaScript developers have struggled with at some point — myself included. To really understand what’s going, there’s no substitute for trying things out, so later in this article I’m going to walk you through a bunch of live demos (after introducing the 5 rules that’ll help you understand <code>this</code>). But I’m getting ahead of myself! Let me start by answering the question:</p><p><strong>If a call to <code>handleClick</code> is preceded by <code>this.</code>, then the value of <code>this</code> within the function <em>will</em> behave as you expect. The issue is, the above example never actually calls <code>handleClick()</code>.</strong></p><p>To put it another way: calling <code>this.handleClick()</code> will <em>change the function’s behavior</em>, setting the value of the <code>this</code> keyword within the <code>handleClick</code> function. In contrast, <em>passing</em> <code>this.handleClick</code> just passes the function as a value — without changing the behavior at all.</p><p>Confused? You’re not alone. But keep reading — we’ll get to the bottom of this together.</p><h2 id="its-all-in-the-call"><a class="doc-headingLink  " href="#its-all-in-the-call">#</a>It’s all in the call</h2><p>When working with JavaScript functions, the value of <code>this</code> depends on the way in which the function was <em>called</em> — as opposed to the way in which the function was <em>defined</em>.</p><p>This can result in some truly boggling behavior. For example, try uncommenting the final two lines in the below example. Like actually try it out. Seeing is believing. I’ll wait here.</p><pre class="language-text"><code>const robot = { 
  dream: &quot;kill all humans&quot;,
  sleepTalk() {
    console.log(`Hey baby, wanna ${this.dream}?`)
  }
}

robot.sleepTalk()

// // You&#x27;d think this would do the same thing as the line above.
// const robotSleepTalk = robot.sleepTalk
// robotSleepTalk()
</code></pre><p>Did you give it a shot? Great! So you’ll have noticed that while calling <code>robot.sleepTalk()</code> prints a classic line from Futurama… calling exactly the same function a couple lines later causes the app to die.</p><p>So what’s going on? Let’s see if you can’t figure it out yourself, using the 5 rules of <code>this</code>.</p><h2 id="the-5-rules-of-this"><a class="doc-headingLink  " href="#the-5-rules-of-this">#</a>The 5 rules of <code>this</code></h2><p>The value of <code>this</code> in a JavaScript function can vary based on how the function was called. There are far too many rules to list them <a target="_blank" class=" " href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this">all</a> right here, but 99% of situations are covered by just <em>three</em> rules:</p><ol><li>When a function is called as a method of an object, e.g. <code>obj.someFunction()</code>, the value of <code>this</code> within that function will be the object on which it was called.</li><li>When a function is called using its <code>call()</code> or <code>apply()</code> methods, the value of <code>this</code> inside the function is provided as the first argument to <code>call()</code> or <code>apply()</code>.</li><li>When a function is called by itself (i.e. <em>without</em> a leading <code>.</code>), the value of <code>this</code> will either be <code>undefined</code> in strict mode, or the global object (e.g. <code>window</code>) outside of strict mode. But you’re probably in strict mode, so it’s probably going to be <code>undefined</code>.</li></ol><p>There are two important exceptions to these rules:</p><ol start="4"><li>You can use a function’s <a target="_blank" class=" " href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind">bind</a> method to return a version of a function where <code>this</code> will <em>always</em> equal the first argument to <code>bind</code>.</li><li>The value of <code>this</code> within an <a target="_blank" class=" " href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions">arrow function</a> will <em>always</em> equal the value of <code>this</code> at the time the function was created.</li></ol><p>These rules and exceptions are a bit of a mouthful, so let’s take a look at some live examples.</p><h3 id="methods-and-this"><a class="doc-headingLink  " href="#methods-and-this">#</a>Methods and <code>this</code></h3><p>The simplest and most obvious way for a function to get a value for <code>this</code> occurs when the function is called as a method. In this case, <code>this</code> is set to the object on which it was called.</p><pre class="language-text"><code>class Counter {
  constructor(initialCount = 0) {
    this.count = initialCount
  }

  increment() {
    return this.count += 1
  }
}

const counter = new Counter()

console.log(&#x27;initial count&#x27;, counter.count)
console.log(&#x27;after increment&#x27;, counter.increment())
console.log(&#x27;and again&#x27;, counter.increment())
</code></pre><p>Keep in mind that it doesn’t matter how a function is defined — only how it is called. This means that there are many different ways to create a counter with the same API as above:</p><pre class="language-text"><code>function increment() {
  return this.count += 1
}

const counter1 = {
  count: 0,
  increment,
}

const counter2 = {
  count: 0
}
counter2.increment = counter1.increment

console.log(&#x27;counter1&#x27;, counter1.increment(), counter1.increment())
console.log(&#x27;counter2&#x27;, counter2.increment(), counter2.increment())
</code></pre><h3 id="this-on-plain-functions"><a class="doc-headingLink  " href="#this-on-plain-functions">#</a><code>this</code> on plain functions</h3><p>When you call a function by itself in a strict-mode application, <code>this</code> will be <code>undefined</code>.</p><pre class="language-text"><code>function increment() {
  return this.count += 1
}

console.log(increment())
</code></pre><p>Obviously, it’s unlikely you’re ever going to write code like the above. But this rule can still cause you all sorts of grief, especially when this rule is applied to functions that were designed to be called as methods.</p><p>For example, say you pass a counter instance’s <code>increment</code> method to a <code>setTimeout()</code> function.</p><pre class="language-text"><code>class Counter {
  constructor(initialCount = 0) {
    this.count = initialCount
  }

  increment() {
    this.count += 1
    console.log(&#x27;value after increment&#x27;, this.count)
  }
}

const counter = new Counter

counter.increment()
setTimeout(counter.increment, 100)
</code></pre><p>See how the call to <code>increment</code> by <code>setTimeout()</code> doesn’t behave as you’d expect? This is because internally, <code>setTimeout()</code> doesn’t have access to the <code>counter</code> <em>object</em> — it only has access to the <code>increment</code> <em>function</em>. As a result, <code>increment</code> is called by itself, and <code>this</code> is <code>undefined</code> for the duration of that call.</p><aside class="doc-Block-3i__D  doc-Beware "><header>Beware</header><p>Be careful when using <code>this</code> in event handlers — the code calling the event handler probably won’t set <code>this</code> to what you want it to be!</p></aside><h3 id="this-on-arrow-functions"><a class="doc-headingLink  " href="#this-on-arrow-functions">#</a><code>this</code> on arrow functions</h3><p>When using arrow functions, you’ll find that the value of <code>this</code> is fixed to whatever it was when the function was defined. When the function is created at the top level, this will usually be <code>undefined</code>. But where things get interesting are when you define arrow functions <em>within</em> other functions. In this case, the value of <code>this</code> within the arrow function will reflect the value of <code>this</code> within the function that created it.</p><p>One place where arrow functions come in handy is class constructors. Any arrow functions defined in a constructor will always have a value of <code>this</code> that points to the class instance, no matter where they’re called from — making them perfect for event handlers.</p><pre class="language-text"><code>class Counter {
  constructor(initialCount = 0) {
    this.count = initialCount
    this.increment = () =&gt; this._increment()
  }

  _increment() {
    this.count += 1
    console.log(&#x27;value after increment&#x27;, this.count)
  }
}

const counter = new Counter

counter.increment()
setTimeout(counter.increment, 100)
</code></pre><p>Arrow functions are also great for event handlers in React’s class components, as they reduce the mental overhead for accessing instance methods like <code>setState()</code>.</p><h3 id="specifying-this-using-bind-call-and-apply"><a class="doc-headingLink  " href="#specifying-this-using-bind-call-and-apply">#</a>Specifying <code>this</code> using <code>bind</code>, <code>call</code> and <code>apply</code></h3><p>If you need to force a specific value of <code>this</code> but can’t use an arrow function, then <a target="_blank" class=" " href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind">bind</a>, <a target="_blank" class=" " href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/call">call</a> and <a target="_blank" class=" " href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/apply">apply</a> are your friends. These functions allow you to specify a function’s arguments and <code>this</code> value programmatically.</p><p>I won’t go into too much detail on how these work — if you’re interested, you can follow the above links to read the details on MDN. For good measure though, here’s a demo using all three:</p><pre class="language-text"><code>function increment() {
  return this.count += 1
}

const counter = { count: 0 }

increment.bind.call(increment, counter).apply()

console.log(&#x27;did it increment?&#x27;, !!counter.count)
</code></pre><p>As <code>bind</code>, <code>call</code> and <code>apply</code> are themselves functions… well, you can use them on each other. But please, don’t do this at home (or especially at work).</p><h2 id="the-this-quiz"><a class="doc-headingLink  " href="#the-this-quiz">#</a>The <code>this</code> quiz</h2><p>Now that you’ve seen <code>this</code> in action, let’s take another look at the broken dreaming bending robot:</p><pre class="language-jsx"><code>const bendingRobot = { 
  dream: &quot;kill all humans&quot;,
  sleepTalk() {
    console.log(`Hey baby, wanna ${this.dream}?`)
  }
}

bendingRobot.sleepTalk()
const bendingRobotSleepTalk = bendingRobot.sleepTalk
bendingRobotSleepTalk()</code></pre><p>Now do you know why the last line throws an error, while calling <code>bendingRobot.sleepTalk()</code> works as expected? Have a think about it, and then check your answer below.</p><section class="doc-Block-3i__D  doc-Spoiler "><header>Spoiler</header><p><code>this</code> doesn’t care about where <code>sleepTalk</code> was defined — it only cares about how it was called. In the case where it’s called using <code>robot.sleepTalk()</code>, the value of <code>this</code> will be <code>robot</code>. However, when called as a bare function, <code>this</code> will be <code>undefined</code>.</p></section><h2 id="exercise-fixing-the-react-component"><a class="doc-headingLink  " href="#exercise-fixing-the-react-component">#</a>Exercise: fixing the React component</h2><p>Let’s finish up by taking another look at the broken React component from the start of this article. Now that you’ve learned about the different ways to control the value of <code>this</code>, can you fix the component so that clicking the button changes the background color?</p><pre class="language-text"><code>import React from &#x27;react&#x27;

export class App extends React.Component {
  render() {
    return (
      &lt;button onClick={this.handleClick} style={this.state}&gt;
        Set background to red
      &lt;/button&gt;
    )
  }

  handleClick() {
    this.setState({ backgroundColor: &#x27;red&#x27; })
  }
}
</code></pre><p>How’d you go — were you able to make the button work?</p><p>Keep in mind that there’s no right ways to do this — I’ve provided one solution on the solution tab, but it’s by no means the only one. If you come up with another solution, I’d love to see it — you can let me know with a <a target="_blank" class=" " href="https://twitter.com/james_k_nelson">tweet</a>!</p><h2 id="the-best-approach-to-this"><a class="doc-headingLink  " href="#the-best-approach-to-this">#</a>The best approach to <code>this</code>?</h2><p>So now that you know all about <code>this</code>, I want to finish up by discussing the <em>best</em> approach to using it:</p><p><strong>In my opinion, the best use of <code>this</code> is <em>no</em> use of <code>this</code>.</strong></p><p>At best, <code>this</code> is confusing. At worst, it can be the cause of obscure and unpredictable bugs. If you have the choice, the easiest thing to do is to just avoid it. And luckily, if you’re using React, hooks make it easier than it’s ever been to avoid <code>this</code> completely!</p><p>With this in mind, in a future article, I want to dive into the workings of a custom hook from one of my production codebases. And I’m looking for your help to decide which one! Here are the options:</p><ul><li><code>useLatestSnapshot()</code> - a hook for integrating with Firebase, simplifying access to the latest <a target="_blank" class=" " href="https://firebase.google.com/docs/reference/js/firebase.firestore.DocumentSnapshot">Snapshot</a> of a Firestore Document or Query.</li><li><code>useMediaQuery()</code> - a hook that returns a boolean reflecting whether the browser currently matches the given media query.</li><li><code>usePopupTrigger()</code> - a hook that manages the state of popup menu, independent of its presentation.</li></ul><p>If you’d like to have a say in which of these I write about, it’s easy — just send a quick <a class=" " href="james@jamesknelson.com/">email</a> or <a target="_blank" class=" " href="https://twitter.com/james_k_nelson">tweet</a> telling me which of the above options you’d like to see. Of course, I’d love to hear any of your other JavaScript questions too! I won’t promise to respond to every message, but I’m always looking for ideas for content that can help give people a leg up. I can’t wait to hear from you — and until next time, happy coding!</p></div>]]></content:encoded>
            <author>james@jamesknelson.com (James K Nelson)</author>
        </item>
        <item>
            <title><![CDATA[Control Components: reuse react components with pseudo-selectors]]></title>
            <link>https:/frontarm.com/james-k-nelson/decoupling-react-pseudo-styles/</link>
            <guid>https:/frontarm.com/james-k-nelson/decoupling-react-pseudo-styles/</guid>
            <pubDate>Fri, 08 May 2020 00:00:00 GMT</pubDate>
            <description><![CDATA[Learn to use control components -- a pattern that facilitates composition of pseudo-selectors.]]></description>
            <content:encoded><![CDATA[<div class="doc-wrapper doc-Doc-18aNW doc-align-center-when-narrow-2ypbP "><p>So you’ve built yourself a <code>&lt;Button&gt;</code> component, and it’s a darn good button at that. It’s got props to configure everything you’d ever need - the label, icon, colors, and even a loading spinner. It has beautiful styles for hover, active and focus states, and it <em>even</em> works well with screen readers.</p><p>Your button component can take anything the world throws at it! And then you realize that you don’t actually need a button after all. What you <em>really</em> needed was a link that <em>looks</em> like a button.</p><p>Luckily, you can fix this without even resorting to copy and paste! Because after a bit of searching, you stumble across the concept of <code>as</code> props…</p><h2 id="as-props-considered-harmful"><a class="doc-headingLink  " href="#as-props-considered-harmful">#</a><code>as</code> props (considered harmful)</h2><p>When you first see an <code>as</code> prop, it can be something of an epiphany. <em>Props can be anything, even components!</em> <strong>JSX elements can have variable types!</strong></p><p>Here’s what a simple <code>&lt;Button&gt;</code> with an <code>as</code> prop looks like in practice:</p><pre class="language-text"><code>import React from &#x27;react&#x27;

export function Button(props) {
  const {
    as: Component = &#x27;button&#x27;,
    className = &#x27;&#x27;,
    icon: Icon,
    label,
    ...rest
  } = props
  
  return (
    &lt;Component className={`Button ${className}`} {...rest}&gt;
      {Icon &amp;&amp; &lt;Icon /&gt;}
      &lt;span className=&quot;label&quot;&gt;{label}&lt;/span&gt;
    &lt;/Component&gt;
  )
}
</code></pre><p>Make sense? If not, it’s probably worth taking a look at the first few free lessons in my <a class=" " href="/courses/react-fundamentals/">React Fundamentals</a> course — especially the bits on JSX and props. But to give you a two-sentence explanation: the above <code>&lt;Button&gt;</code> component returns an element with a variable <code>type</code>. By default, it uses the string <code>&quot;button&quot;</code> as its type — but by passing an <code>as</code> prop, you can set that to <code>&quot;a&quot;</code>, <code>Link</code>, or anything else that strikes your fancy.</p><p>If you work with React on a regular basis, you’ll probably have seen <code>as</code> props in the wild. For instance, <a target="_blank" class=" " href="https://styled-components.com/">Styled Components</a> supports them. You might also have seen them used with custom <code>&lt;Button&gt;</code> components, allowing them to be somewhat hackily connected up to your router of choice’s <code>&lt;Link&gt;</code> component (and thus improving response time when clicking the links):</p><pre class="language-text"><code>import React from &#x27;react&#x27;
import styled from &#x27;styled-components&#x27;

export const Button = styled.button`
  align-items: center;
  background-color: transparent;
  border: 2px solid deepskyblue;
  border-radius: 8px;
  color: white;
  display: inline-flex;
  font-family: sans-serif;
  font-size: inherit;
  line-height: 1.4rem;
  margin: 0 4px;
  padding: 8px 12px 8px 4px;
  position: relative;
  text-decoration: none;
  transition:
    border-color 150ms ease-out,
    transform 150ms ease-out;

  &amp;:not([disabled]) {
    cursor: pointer;
  }
  &amp;:not([disabled]):hover {
    border-color: white;
  }
  &amp;:not([disabled]):active {
    transform: scale(0.95);
  }
  &amp;:focus {
    outline: none;
  }
  &amp;:focus::after {
    content: &#x27; &#x27;;
    position: absolute;
    left: 2px;
    right: 2px;
    top: 2px;
    bottom: 2px;
    border: 2px solid white;    
    border-radius: 5px;
  }
  &amp;[disabled] {
    opacity: 0.5;
  }
}
`
</code></pre><p>You saw me make up the word <em>hackily</em>, so now you’re thinking — <em>what’s so hackily about this?</em> Well, assuming you don’t want well-typed components (hint: you <em>do</em> want well-typed components), I guess it does kinda work in this particular case.</p><p>But let me throw you a new requirement.</p><h2 id="active-margins"><a class="doc-headingLink  " href="#active-margins">#</a>Active margins</h2><p>So you’ve got a button, and it’s got beautiful, animated hover styles. You nudge your mouse over the button, and it lights up like a christmas tree.</p><pre class="language-text"><code>import React from &#x27;react&#x27;
import styled, { keyframes } from &#x27;styled-components&#x27;

const rotate = keyframes`
  0% {
    transform: rotate(0deg);
  }
  
  100% {
    transform: rotate(360deg);
  }
`

export const Button = styled.button`
  align-items: center;
  background-color: #223344;
  box-sizing: border-box;
  background-clip: content-box;
  border: 2px solid transparent;
  border-radius: 8px;
  border-top-left-radius: 7px;
  border-bottom-right-radius: 7px;
  color: white;
  cursor: pointer;
  display: flex;
  font-family: sans-serif;
  font-size: inherit;
  justify-content: center;
  height: 40px;
  width: 100px;
  outline: none;
  overflow: hidden;
  padding: 2px;
  position: relative;
  transition: background-color 150ms ease-out, padding 150ms ease-out;
  
  &amp;::before {
    content: &#x27;&#x27;;
    position: absolute;
    top: 0; right: 0; bottom: 0; left: 0;
    z-index: -1;
    margin: -40px;
    border-radius: inherit;
    background: linear-gradient(45deg, deepskyblue, fuchsia);
  }
  
  &amp;:hover {
    background-color: #223344CC;
  }
  
  &amp;:hover::before {
    background: linear-gradient(200deg, red, lightgreen) !important;
    animation: ${rotate} 2s linear infinite;
  }
  
  &amp;:active {
    padding: 4px;
  }
  &amp;:focus::after {
    content: &#x27; &#x27;;
    position: absolute;
    left: 5px;
    right: 5px;
    top: 5px;
    bottom: 5px;
    border: 1px dotted rgba(255, 255, 255, 0.5);
    border-radius: 2px;
  }
}
`
</code></pre><p>In fact, this button is looking so darn pneumatic that why wouldn’t we want a whole bar full of them?</p><pre class="language-text"><code>import React from &#x27;react&#x27;
import styled, { keyframes } from &#x27;styled-components&#x27;

import { Button } from &#x27;./button&#x27;
import { PreviousIcon, NextIcon, RefreshIcon } from &#x27;./icons&#x27;

export function App() {
  return (
    &lt;Bar&gt;
      &lt;Button&gt;&lt;PreviousIcon /&gt;&lt;/Button&gt;
      &lt;Button&gt;&lt;NextIcon /&gt;&lt;/Button&gt;
      &lt;Button&gt;&lt;RefreshIcon width={18} height={18} /&gt;&lt;/Button&gt;
    &lt;/Bar&gt;
  )
}

const Bar = styled.div`
  background-color: #223344;
  box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.2);
  border-radius: 6px;
  display: flex;
  align-items: stretch;
  flex-wrap: wrap;
  height: 58px;
  padding: 8px;
  width: 150px;
  z-index: 0;
  
  &gt; * {
    flex: 1;
  }
`
</code></pre><p>Beautiful. There’s just one problem. When your boss comes along and tests everything on a tiny phone after you’ve been happily developing it on your vintage 2013 15&quot; Macbook Pro and what a beautiful machine it is… well anyway, your boss doesn’t like the fact that he had to press the button 3 or 4 times to finally hit the target. <strong>The touch targets are too small.</strong> And by golly gosh, he <em>shouldn’t</em> be happy about that — it’s awful for user experience.</p><p>Those margins around the buttons? They need to be <em>active</em>. Despite being outside of the button <em>body</em>, they still need to be part of the button <em>control</em>. But it’s not like you can just add <code>margin</code> or <code>padding</code> to your <code>&lt;Button&gt;</code> element — margins are inactive, and padding is internal.</p><p>Here’s the problem: your styles and behavior are all defined on one big, monolithic <code>&lt;Button&gt;</code> component. And while <code>as</code> props let you modify the behavior of that styled component, what you <em>really</em> want is <em>two separate components</em>: one which handles behaviors, and a <em>separate</em> one to handle the styles.</p><h2 id="the-solution-control-components"><a class="doc-headingLink  " href="#the-solution-control-components">#</a>The solution: Control Components</h2><p>You know how when you render a <code>&lt;button&gt;</code> or an <code>&lt;a&gt;</code>, by default, the browser applies a bunch of styles to make them look like buttons and links?</p><pre class="language-text"><code>&lt;p&gt;
  &lt;button&gt;A vanilla HTML button&lt;/button&gt;
&lt;/p&gt;
&lt;p&gt;
  &lt;a href=&quot;#&quot;&gt;Followed by a vanilla HTML link&lt;/a&gt;
&lt;/p&gt;
</code></pre><p>My thesis is: <strong>in the React world, the browser`s default styles are just getting in the way</strong>. It’d make far more sense for components like <code>&lt;button&gt;</code> and <code>&lt;a&gt;</code> to be unstyled wrappers, with the button styles rendered as children.</p><p>So instead of:</p><pre class="language-jsx"><code>&lt;Button as={Link} href=&#x27;/&#x27; style={{ margin: 8 }}&gt;
  Home
&lt;/Button&gt;
</code></pre><p>You want:</p><pre class="language-jsx"><code>&lt;UnstyledLinkControl href=&#x27;/&#x27;&gt;
  &lt;ButtonBody style={{ margin: 8 }}&gt;
    Home
  &lt;/ButtonBody&gt;
&lt;/UnstyledLinkControl&gt;
</code></pre><p>Looks simple enough, right? But there’s a trick: the hover styles for <code>&lt;ButtonBody&gt;</code> need to be activated when the mouse hovers over <code>&lt;LinkControl&gt;</code>. Or <code>&lt;AControl&gt;</code>. Or <code>&lt;ButtonControl&gt;</code>. Or <em>any other control</em>.</p><p>As it happens, there are three ways to achieve this: the naive way, the clunky way, and the best way. Let’s take a look at each.</p><h2 id="styled-component-selectors"><a class="doc-headingLink  " href="#styled-component-selectors">#</a>Styled component selectors</h2><p>One of the less-known features of the Styled Components library, is that it lets you <a target="_blank" class=" " href="https://styled-components.com/docs/advanced#referring-to-other-components">use your styled components themselves as selectors</a>. Combined with nested styles and the <code>&amp;</code> selector, this means that <strong>components can declare styles that’ll only apply when a parent is being hovered over</strong> — as in the above example.</p><p>For example, here’s how you’d add hover styles for <code>&lt;ButtonBody&gt;</code> that activate when the mouse hovers over an <code>&lt;AControl&gt;</code> <em>or</em> a <code>&lt;ButtonControl&gt;</code>:</p><pre class="language-jsx"><code>export const AControl = styled.a`
  /* ... reset styles ... */
`
export const ButtonControl = styled.a`
  /* ... reset styles ... */
`

export const ButtonBody = styled.span`
  background-color: #223344;

  ${AControl}:hover &amp;, ${ButtonControl}:hover &amp; {
    background-color: #223344CC;
  }
`
</code></pre><p>Here’s the full example:</p><pre class="language-text"><code>import React from &#x27;react&#x27;
import styled, { keyframes } from &#x27;styled-components&#x27;

import { AControl, ButtonBody, ButtonControl } from &#x27;./control&#x27;
import { PreviousIcon, NextIcon, RefreshIcon } from &#x27;./icons&#x27;

const currentPage = parseInt(
  window.location.search.split(&#x27;?page=&#x27;)[1] || 1,
  10
)

export function App() {
  return (
    &lt;&gt;
      &lt;Bar&gt;
        &lt;AControl
          disabled={currentPage === 1}
          href={currentPage &gt; 1 ? `/?page=${currentPage - 1}` : undefined}
          onClick={currentPage === 1 ? (event) =&gt; event.preventDefault() : undefined}&gt;
          &lt;ButtonBody&gt;
            &lt;PreviousIcon /&gt;
          &lt;/ButtonBody&gt;
        &lt;/AControl&gt;
        &lt;AControl href={`/?page=${currentPage + 1}`}&gt;
          &lt;ButtonBody&gt;
            &lt;NextIcon /&gt;
          &lt;/ButtonBody&gt;
        &lt;/AControl&gt;
        &lt;ButtonControl onClick={() =&gt; alert(&#x27;refresh!&#x27;)}&gt;
          &lt;ButtonBody&gt;
            &lt;RefreshIcon width={18} height={18} /&gt;
          &lt;/ButtonBody&gt;
        &lt;/ButtonControl&gt;
      &lt;/Bar&gt;
      &lt;h1&gt;Page {currentPage}&lt;/h1&gt;
    &lt;/&gt;
  )
}

const Bar = styled.div`
  background-color: #223344;
  box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.2);
  border-radius: 6px;
  display: flex;
  align-items: stretch;
  flex-wrap: wrap;
  height: 58px;
  padding: 0 8px;
  width: 150px;
  z-index: 0;
  
  &gt; * {
    flex: 1;
  }
`
</code></pre><p>If you try hovering over the buttons on this version of the toolbar, you’ll see that the margins are now <em>active</em>; they cause the inner button’s hover styles to be activated! Of course, this approach doesn’t <em>really</em> solve the problem, because the <code>&lt;ButtonBody&gt;</code> component still needs to explicitly specify each and every control that it can be used with; it’s <em>tightly coupled</em>.</p><p>For example, the above <code>&lt;ButtonBody&gt;</code> component only works with standard <code>&lt;a&gt;</code> tags — it <em>doesn’t</em> work with <code>&lt;Link&gt;</code> components from your favorite routing library. And while you <em>could</em> fix this by creating a <code>&lt;LinkControl&gt;</code> component and adding it to the css for <code>&lt;ButtonBody&gt;</code>, it turns out there’s a better way…</p><h2 id="control-context"><a class="doc-headingLink  " href="#control-context">#</a>Control Context</h2><p>One of the neat things about Styled Components it allows your styles to reference a <code>theme</code> object. This is often used to set colors based on a global theme:</p><pre class="language-jsx"><code>const Button = styled.button`
  background-color: ${props =&gt; props.theme.buttonBackgroundColor};
`
</code></pre><p>As it happens, Styled Components also lets individual components merge <em>new</em> values into that <code>theme</code> object, which will apply only for that component’s children.</p><div class="doc-AsideTop-1wzdz "><pre class="language-jsx"><code>export const ButtonControl = () =&gt; {
  const theme = useContext(ThemeContext)
  const patchedTheme = {
    ...theme,
    // ... merged values
  }

  return (
    &lt;ThemeContext.Provider value={patchedTheme}&gt;
      ...
    &lt;/ThemeContext.Provider&gt;
  )
}
</code></pre><aside class="doc-Aside-QiMiD "><aside class="doc-Block-3i__D  doc-Details "><header></header><p>For a real-world implementation, you’ll want to memoize the patched theme to prevent render thrashing.</p></aside></aside></div><p>By feeding the Control Component’s <em>styled component</em> into context, it becomes possible for child components to create selectors that are <em>specific to whatever control they’re being used in</em>.</p><p>For example, here’s the <code>:hover</code> example from before, with the <code>:hover</code> selector being applied to whatever component has been added to the <code>parentStyledComponent</code> property of the theme object:</p><pre class="language-jsx"><code>export const ButtonBody = styled.span`
  background-color: #223344;

  ${({ theme }) =&gt; theme.parentStyledControl}:hover &amp; {
    background-color: #223344CC;
  }
`
</code></pre><p>Here’s a full example taking this approach — I’ve even connected it up to <a target="_blank" class=" " href="/navi/">Navi</a>&#x27;s <code>&lt;Link&gt;</code> component for good measure!</p><pre class="language-text"><code>import { route } from &#x27;navi&#x27;
import React from &#x27;react&#x27;
import styled, { keyframes } from &#x27;styled-components&#x27;

import { ButtonBody, ButtonControl, LinkControl } from &#x27;./control&#x27;
import { PreviousIcon, NextIcon, RefreshIcon } from &#x27;./icons&#x27;

export function Page({ currentPage }) {
  return (
    &lt;&gt;
      &lt;Bar&gt;
        &lt;LinkControl
          disabled={currentPage === 1}
          href={currentPage &gt; 1 ? `/${currentPage - 1}` : undefined}
          onClick={currentPage === 1 ? (event) =&gt; event.preventDefault() : undefined}&gt;
          &lt;ButtonBody&gt;
            &lt;PreviousIcon /&gt;
          &lt;/ButtonBody&gt;
        &lt;/LinkControl&gt;
        &lt;LinkControl href={`/${currentPage + 1}`}&gt;
          &lt;ButtonBody&gt;
            &lt;NextIcon /&gt;
          &lt;/ButtonBody&gt;
        &lt;/LinkControl&gt;
        &lt;ButtonControl onClick={() =&gt; alert(&#x27;refresh!&#x27;)}&gt;
          &lt;ButtonBody&gt;
            &lt;RefreshIcon width={18} height={18} /&gt;
          &lt;/ButtonBody&gt;
        &lt;/ButtonControl&gt;
      &lt;/Bar&gt;
      &lt;h1&gt;Page {currentPage}&lt;/h1&gt;
    &lt;/&gt;
  )
}

const Bar = styled.div`
  background-color: #223344;
  box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.2);
  border-radius: 6px;
  display: flex;
  align-items: stretch;
  flex-wrap: wrap;
  height: 58px;
  padding: 0 8px;
  width: 150px;
  z-index: 0;
  
  &gt; * {
    flex: 1;
  }
`

export default route({
  getView: ({ params }) =&gt; &lt;Page currentPage={parseInt(params.number, 10)} /&gt;
})
</code></pre><p>You can see how this pattern opens up a whole new world of possibilities… but you can also see how manually fiddling with context, nested selectors and default styles can get old fast. And that’s why there’s now a package for that!</p><h2 id="react-utilities-for-controls"><a class="doc-headingLink  " href="#react-utilities-for-controls">#</a>React Utilities for Controls</h2><p>The <code>@retil/control</code> package exports everything you need to start using control components, including:</p><ul><li><code>&lt;AControl&gt;</code> and <code>&lt;ButtonControl&gt;</code> components for Styled Components</li><li>Template functions for <code>active</code>, <code>disabled</code>, <code>focus</code> and <code>hover</code> selectors, which can be used within your <code>styled</code> components and <code>css</code> template strings</li><li>A higher-order <code>control()</code> function that turns any Styled Component into a context-providing Control Component</li><li>The raw css strings used to reset the browser default styles</li></ul><p>Here’s how to refactor the above example using <code>@retil/control</code></p><pre class="language-text"><code>import {
  ButtonControl,
  active,
  control,
  disabled,
  focus,
  hover,
  resetACSS
} from &#x27;@retil/control&#x27;
import React from &#x27;react&#x27;
import { Link } from &#x27;react-navi&#x27;
import styled, { keyframes } from &#x27;styled-components&#x27;

const StyledLinkControl = styled(Link)(resetACSS)
export const LinkControl = control(StyledLinkControl)
export { ButtonControl }

const rotate = keyframes`
  0% {
    transform: rotate(0deg);
  }
  
  100% {
    transform: rotate(360deg);
  }
`

export const ButtonBody = styled.span`
  align-items: center;
  background-color: #223344;
  box-sizing: border-box;
  background-clip: content-box;
  border: 2px solid transparent;
  border-radius: 8px;
  border-top-left-radius: 7px;
  border-bottom-right-radius: 7px;
  color: white;
  cursor: pointer;
  display: flex;
  flex: 1;
  font-family: sans-serif;
  font-size: inherit;
  justify-content: center;
  margin: 12px 4px;
  outline: none;
  overflow: hidden;
  padding: 2px;
  position: relative;
  transition: background-color 150ms ease-out;
  
  &amp;::before {
    content: &#x27;&#x27;;
    position: absolute;
    top: 0; right: 0; bottom: 0; left: 0;
    z-index: -1;
    margin: -10px;
    border-radius: inherit;
    background-image: linear-gradient(45deg, deepskyblue, fuchsia);
    transition: opacity 100ms ease-out;
    animation: ${rotate} 2s linear infinite;
    animation-play-state: paused;
  }

  ${disabled`
    ::before {
      opacity: 0.5;
    }
  `}
  
  ${hover`
    background-color: #223344CC;

    &amp;::before {
      background-image: linear-gradient(200deg, red, lightgreen);
      animation-play-state: running;
    }
  `}

  ${active`
    ::before {
      opacity: 0.5;
    }
  `}

  ${focus`
    ::after {
      content: &#x27; &#x27;;
      position: absolute;
      left: 5px;
      right: 5px;
      top: 5px;
      bottom: 5px;
      border: 1px dotted rgba(255, 255, 255, 0.5);
      border-radius: 2px;
    }
  `}
}
`
</code></pre><p>The package also exports a bunch of more advanced utilities:</p><ul><li>A <code>createTemplateHelper()</code> function, in case the default template helpers (e.g. <code>hover</code>) don’t suit your needs</li><li>A <code>useControlContext()</code> hook that returns the raw Control Context (internally, it’s stored within your Styled Components theme)</li><li><code>AControlProps</code> and <code>ButtonControlProps</code> types for TypeScript projects</li></ul><h2 id="give-it-a-whirl"><a class="doc-headingLink  " href="#give-it-a-whirl">#</a>Give it a whirl</h2><p>I’d love to see what you build with <code>@retil/control</code>. I’d also love to show the world — if you give it a whirl, make sure to send a [Pull Request] adding yourself to the <em>apps using @retil/control`</em> section in the README!</p><p>One more thing — I want to thank everyone who contributed to the discussion about this idea on Twitter!</p><div>Unimplemented.</div><p>You might be able to guess from the package name — but <code>@retil/control</code> is the first React Utility that I’ll be publishing under the “retil” brand, and there’ll almost certainly be more. If <em>you’ve</em> got some code and you’re somehow convinced that there’s <em>gotta be a better way</em> of doing it, then you’re in good company. <a class=" " href="">Send me a Tweet</a>, and let’s nut out how to make a utility that can improve <em>everyone’s</em> React experience.</p><p>That’s it for today — happy coding! And if I don’t see you on the Twitters, I’ll see you at the next post!</p></div>]]></content:encoded>
            <author>james@jamesknelson.com (James K Nelson)</author>
        </item>
        <item>
            <title><![CDATA[Is a Redux Store Observable?]]></title>
            <link>https:/frontarm.com/james-k-nelson/is-a-redux-store-observable/</link>
            <guid>https:/frontarm.com/james-k-nelson/is-a-redux-store-observable/</guid>
            <pubDate>Fri, 01 May 2020 00:00:00 GMT</pubDate>
            <description><![CDATA[Redux stores and RxJS Observables both have a subscribe method with a similar signature – but are they really the same thing?]]></description>
            <content:encoded><![CDATA[<div class="doc-wrapper doc-Doc-18aNW doc-align-center-when-narrow-2ypbP "><p>If you’ve been using JavaScript for a while, then you’ve probably heard of observables. They’re at the core of <a target="_blank" class=" " href="https://www.apollographql.com/docs/react/v3.0-beta/api/core/ObservableQuery/">Apollo Client</a>, <a target="_blank" class=" " href="https://angular.io/guide/rx-library">Angular JS</a>, and there’s even a <a target="_blank" class=" " href="https://github.com/tc39/proposal-observable">proposal</a> to add them to JavaScript itself.</p><p>Of course, for many people, the first thing that comes to mind when you hear the word <em>observables</em> is the enormous <a target="_blank" class=" " href="https://rxjs-dev.firebaseapp.com/">RxJS</a> library. And because of this, it can seem like observables are big, complicated things. But in truth, they can be as simple as a plain object with a <code>subscribe</code> method.</p><pre class="language-typescript"><code>interface Observable&lt;T&gt; {
  subscribe(onNext: (value: T) =&gt; void): () =&gt; void
}
</code></pre><p>While slightly different to the RxJS Observable, the above interface accomplishes exactly the same thing. It says: an <code>Observable</code> is an object with a <code>subscribe()</code> method, that takes an <code>onNext(value)</code> callback, and returns a function (which can be used to cancel the subscription). Simple, right? In fact, if you’ve ever used a Redux store, you might have seen something similar.</p><h2 id="reduxs-store"><a class="doc-headingLink  " href="#reduxs-store">#</a>Redux’s Store</h2><p>When you create a store using Redux’s <code>createStore()</code> function, you’ll get an object with a <code>subscribe()</code> method. In fact, this looks a lot like an Observable’s <code>subscribe()</code> method — but there’s an important difference.</p><pre class="language-typescript"><code>interface ReduxStore {
  subscribe(onChange: () =&gt; void): () =&gt; void
}
</code></pre><p>Can you see what the difference is? Check your answer by clicking the spoiler below.</p><section class="doc-Block-3i__D  doc-Spoiler "><header>Spoiler</header><p>The callback that you pass to a Redux store’s <code>subscribe()</code> method does not receive any arguments!</p></section><p>Where an observable’s <code>subscribe()</code> function notifies you of each value <em>as it occurs</em>, Redux’s subscribe function only tells you that <em>something</em> changed… <em>probably</em>. To find out <em>what</em> changed, you’ll need to call another method on the <code>store</code> object: <code>getState()</code>.</p><pre class="language-typescript"><code>interface ReduxStore&lt;T&gt; {
  getState(): T
}
</code></pre><h2 id="a-trick-question"><a class="doc-headingLink  " href="#a-trick-question">#</a>A trick question</h2><p>Say that you have an observable, and you want to log every value that it produces to the console. Here’s how you’d do it:</p><pre class="language-typescript"><code>observable.subscribe((value) =&gt; {
  console.log(value)
})
</code></pre><p>Makes sense, right? So the next question is: how would you log every state of a <em>Redux</em> store to the console? Let’s do this as an exercise!</p><p><strong>Your task is is to log every state of the below store to the console.</strong></p><p><em>Remember: you can get the current state with <code>store.getState()</code>.</em></p><p>You may think that this exercise looks far too simple, but give it a try anyway — you’ll see why when you’re done.</p><pre class="language-text"><code>import { store } from &#x27;./store&#x27;

console.log(&#x27;Your task: log each new store state to the console.&#x27;)

store.subscribe(() =&gt; {
  // TODO
})

for (let i = 0; i &lt; 5; i++) {
  store.dispatch({ type: &#x27;next&#x27; })
}
</code></pre><p>How’d you go? Did you find something odd, where the console displayed every even number between 2 and 10 — <em>twice</em>? Let me explain why.</p><section class="doc-Block-3i__D  doc-Spoiler "><header>Spoiler</header><p>While <code>index.js</code> only dispatches 5 actions, <code>store.js</code> also has a <code>subscribe()</code> handler — and this one dispatches a second <code>next</code> action whenever the current state is an odd number.</p><pre class="language-jsx"><code>store.subscribe(() =&gt; { 
  if (store.getState() % 2 === 1) {
    store.dispatch({
      type: &#x27;next&#x27;,
    })
  }
})
</code></pre></section><h2 id="sources"><a class="doc-headingLink  " href="#sources">#</a>Sources</h2><p>There’s an important difference between Observables and Redux-like stores — which I’m going to start calling <strong>Sources</strong>, and which I’m going to define as having a <code>getCurrentValue()</code> function in place of <code>getState()</code>.</p><pre class="language-typescript"><code>interface Source&lt;T&gt; {
  subscribe(onChange: () =&gt; void): () =&gt; void
  getCurrentValue(): T
}
</code></pre><p>While an Observable passes <em>every</em> value to <em>every</em> subscribe callback, a Source makes no such guarantee; it can <em>skip</em> values. This makes Sources less capable than Observables in some ways; for example, you can’t <code>reduce</code> over a Source’s values. Interestingly though, this limitation actually makes Sources a much better fit for building UIs with React, because it allows for an interesting possibility.</p><p><strong>What if there is <em>no</em> current value?</strong></p><p>What if <code>getCurrentValue()</code> throws an Error? What if it throws a Promise? <em>What if you pass a source that throws an Error or Promise to React’s <a target="_blank" class=" " href="https://github.com/facebook/react/tree/master/packages/use-subscription">useSubscription</a> hook?</em> <strong>You’ll get Suspense and Error Boundaries support without writing a single line of component or hook-based code.</strong></p><p><em>Okay James, but what’s your point?</em></p><p>Let me be clear: I’m <em>not</em> suggesting you throw out Apollo Client and switch back to Redux — after all, Redux’s <code>getState()</code> can’t throw promises. But it <em>is</em> <a target="_blank" class=" " href="https://github.com/jamesknelson/retil/tree/monorepo/packages/source">food for thought</a>.</p></div>]]></content:encoded>
            <author>james@jamesknelson.com (James K Nelson)</author>
        </item>
        <item>
            <title><![CDATA[The big 2019 Frontend Armory update]]></title>
            <link>https:/frontarm.com/james-k-nelson/update-2019/</link>
            <guid>https:/frontarm.com/james-k-nelson/update-2019/</guid>
            <pubDate>Sun, 24 Nov 2019 00:00:00 GMT</pubDate>
            <description><![CDATA[It's been a big year for Frontend Armory – with new lessons, code, videos, a new mission and a new price.]]></description>
            <content:encoded><![CDATA[<div class="doc-wrapper doc-Doc-18aNW doc-align-center-when-narrow-2ypbP "><p>G’day there! It’s been about a year since my last status update, and a <em>big</em> year at that. I’ve released a bunch of new lessons and code, a couple new videos, a new direction for the site, <em>and</em> a much lower price. But before talking about any of this, let’s rewind to earlier this year.</p><p><em>React hooks were released.</em></p><p>Hooks promised to completely change the way you’d write React apps. Which at the time, sounded like a whole lot of work. It meant that you’d need to learn new patterns, new ways of thinking, and new libraries. Given this reality, it took some time before I was truly convinced about the merit of hooks — but after using them in the real world for some months, you can consider me convinced. Hooks <em>are</em> pretty great.</p><p>At least, hooks are great <em>as a developer</em>. As someone who’d just gone full time on Frontend Armory and spent months writing a course on React with class components, hooks were pretty bad timing for me. They’re a completely different beast to class components, and I needed time to get comfortable with them before I could teach them. This left Frontend Armory in a slightly different position than I expected it would be just one year back — so let’s talk about what has changed.</p><h2 id="new-lessons-and-code"><a class="doc-headingLink  " href="#new-lessons-and-code">#</a>New lessons and code</h2><h3 id="react-fundamentals"><a class="doc-headingLink  " href="#react-fundamentals">#</a>React Fundamentals</h3><p>When I launched Frontend Armory last year, it had just one course: <a class=" " href="/courses/learn-raw-react/basics/one-file-react-app/">React (without the buzzwords)</a>. And then like a week later, I heard the first news about React Hooks. <em>Doh.</em></p><p>The thing about hooks is that they’re <em>not</em> just a different way of writing class components — they’re a completely different way of thinking about state and effects. Basically, I needed to rewrite a large part of the course. So in 2019, that’s what I did.</p><p>The updated course is called <a class=" " href="/courses/react-fundamentals/">React Fundamentals</a>. It now:</p><ul><li>Introduces Create React App near the beginning of the course.</li><li>Uses JSX for most of the examples.</li><li><strong>Teaches state and effects using hooks.</strong></li><li>Teaches you to build a fancy pancy hooks-based fractal tree that reacts to mouse movements and clicks. <em>Go ahead</em>, try it below!</li></ul><pre class="language-text"><code>import React, { useEffect, useState } from &#x27;react&#x27;
import ReactDOM from &#x27;react-dom&#x27;
import FractalTreeBranch from &#x27;./FractalTreeBranch&#x27;

// The height and width of the entire window
const { innerHeight, innerWidth } = window

const FractalTree = () =&gt; {
  let [time, setTime] = useState(() =&gt; Date.now())
  let [mousePosition, setMousePosition] = useState({
    x: innerWidth / 2,
    y: innerHeight / 2,
  })
  useEffect(() =&gt; {
    let requestId = window.requestAnimationFrame(() =&gt; {
      setTime(Date.now())
    })
    return () =&gt; {
      window.cancelAnimationFrame(requestId)
    }
  })
  let fromHorizontalCenter = (innerWidth / 2 - mousePosition.x) / innerWidth
  let fromVerticalCenter = (innerHeight / 2 - mousePosition.y) / innerHeight
  let lean = 0.03 * Math.sin(time / 2000) + fromHorizontalCenter / 4
  let sprout =
    0.3 +
    0.05 * Math.sin(time / 1300) +
    fromVerticalCenter / 5 -
    0.2 * Math.abs(0.5 - fromHorizontalCenter / 2)

  return (
    &lt;div
      style={{
        position: &#x27;absolute&#x27;,
        top: 0,
        left: 0,
        bottom: 0,
        right: 0,
        overflow: &#x27;hidden&#x27;,
      }}
      onMouseMove={event =&gt; {
        setMousePosition({
          x: event.clientX,
          y: event.clientY,
        })
      }}&gt;
      &lt;FractalTreeBranch lean={lean} size={150} sprout={sprout} /&gt;
    &lt;/div&gt;
  )
}

ReactDOM.render(&lt;FractalTree /&gt;, document.getElementById(&#x27;root&#x27;))
</code></pre><p><em>React fundamentals</em> is a huge improvement on the earlier <em>React (without the buzzwords)</em> course. There’s just a few outstanding issues:</p><ul><li>It only includes <a class=" " href="/courses/react-fundamentals/basics/one-file-react-app/">one</a> video. I’ve recorded a few other videos this year, but ran into some issues on this front — I’ll go into more detail later in the update.</li><li>Some of the later lessons in React Fundamentals are works in progress in that they’re still based around the older <em>React (without the buzzwords)</em> course.</li></ul><p>I plan on updating the later lessons in the coming year, but for now you’ll find more details on building practical apps in…</p><h3 id="react-firebase--bacon"><a class="doc-headingLink  " href="#react-firebase--bacon">#</a>React, Firebase &amp; Bacon</h3><p>In recent years, it’s become much easier to learn advanced React features — mostly due to the massibe imporvements in the React docs themselves. But at the same time, there are now more concepts and tools to learn, and more ways that the various pieces can fit together.</p><p>As a result, while <em>React itself</em> has become easier to learn, it’s also become less clear how to put it to use in real world apps. And that’s where <a target="_blank" class=" " href="/courses/react-and-bacon/">React, Firebase &amp; Bacon</a> comes in.</p><p>This <strong>work-in-progress</strong> course aims to be a step-by-step guide to building a real world app from the ground up. So far, it includes lessons on:</p><ul><li>Setting up your Create React App &amp; Firebase project</li><li>Fetching and submitting data</li><li>Working with simple forms</li><li>Styling your app with <a target="_blank" class=" " href="https://www.styled-components.com/">styled-components</a>, a popular CSS-in-JS library</li></ul><p>Each of these lesson covers one step in the process towards building this landing page:</p><pre class="language-text"><code>import { createBrowserHistory } from &#x27;history&#x27;
import React, { useEffect, useState } from &#x27;react&#x27;

import { NarrowCardLayout, StyledHaiku } from &#x27;./components&#x27;
import Landing from &#x27;./landing&#x27;

const history = createBrowserHistory()
const navigate = path =&gt; history.push(path)

function getRoute(location) {
  switch (normalizePathname(location.pathname)) {
    case &#x27;/&#x27;:
      return &lt;Landing navigate={navigate} /&gt;

    case &#x27;/privacy&#x27;:
      return &lt;Privacy navigate={navigate} /&gt;

    case &#x27;/thanks&#x27;:
      return &lt;Thanks navigate={navigate} /&gt;

    default:
      return &lt;NotFound navigate={navigate} /&gt;
  }
}

export default function App() {
  const [location, setLocation] = useState(history.location)

  useEffect(() =&gt; history.listen(setLocation), [])

  return getRoute(location)
}

function NotFound({ navigate }) {
  return (
    &lt;NarrowCardLayout navigate={navigate}&gt;
      &lt;StyledHaiku&gt;
        I couldn&#x27;t find it
        &lt;br /&gt;
        The page probably hates me
        &lt;br /&gt;
        I&#x27;m really depressed
      &lt;/StyledHaiku&gt;
    &lt;/NarrowCardLayout&gt;
  )
}

function Privacy({ navigate }) {
  return (
    &lt;NarrowCardLayout navigate={navigate}&gt;
      &lt;StyledHaiku&gt;
        Your privacy is
        &lt;br /&gt;
        Very important to us
        &lt;br /&gt;I wrote a poem
      &lt;/StyledHaiku&gt;
    &lt;/NarrowCardLayout&gt;
  )
}

function Thanks({ navigate }) {
  return (
    &lt;NarrowCardLayout navigate={navigate}&gt;
      &lt;StyledHaiku&gt;
        Thanks for joining in!
        &lt;br /&gt;
        When we&#x27;re ready to wow you,
        &lt;br /&gt;
        You&#x27;ll get an email.
      &lt;/StyledHaiku&gt;
    &lt;/NarrowCardLayout&gt;
  )
}

function normalizePathname(pathname) {
  if (pathname === &#x27;/&#x27; || pathname === &#x27;&#x27;) {
    return &#x27;/&#x27;
  }

  // Add leading slash
  pathname = pathname[0] !== &#x27;/&#x27; ? &#x27;/&#x27; + pathname : pathname

  // Strip trailing slash
  pathname =
    pathname[pathname.length - 1] === &#x27;/&#x27; ? pathname.slice(0, -1) : pathname

  return pathname
}</code></pre><p>In fact, the above landing page is <a target="_blank" class=" " href="https://github.com/frontarm/react-firebase-bacon">open source</a>, with separate branches for each step — including the ones that aren’t yet covered in the course.</p><p>Okay, okay but… why <em>bacon?</em></p><p>Before answering this, I need to stress that this course is currently a <em>work in progress</em>. I’ll be releasing updates on a when-they’re-done basis — but the <em>direction</em> of the course is set in stone. Let me explain: once the course is complete, <strong>it’ll teach you to build a real-world app that makes bacon (money)</strong>. The app you’ll be building is called Vouch, and <strong>Pro members already have access to a significant chunk of the source for the finished product.</strong></p><h3 id="vouch"><a class="doc-headingLink  " href="#vouch">#</a>Vouch</h3><p><a target="_blank" class=" " href="https://beta.vouch.chat">Vouch</a> is the companion app to React, Firebase &amp; Bacon. It’s an advertising-free social network, and as with the course, it’s a work in progress — but it’s a lot further along than the course content itself. It’s <a class=" " href="/james-k-nelson/vouch/">source</a> is exclusively available to Frontend Armory Pro members, including:</p><ul><li>Working payments (with Stripe)</li><li>Server rendering (with Create Universal React App)</li><li>Authentication (with Firebase)</li><li>Onboarding flow</li><li>Responsive layout</li></ul><p>The main missing feature? <em>Posting</em>. Yep, it’s a social network that doesn’t let you post anything. There’s a reason for this, though: I want Vouch to eventually be a real, useful, open-source app — not just a demo. And to make that happen, Vouch is going to let you post JavaScript demos using the same <em>Demoboard</em> component that the course’s exercises currently use. This means that Demoboard needs to be a reusable component. And as of a few weeks ago, it actually is!</p><h3 id="demoboard"><a class="doc-headingLink  " href="#demoboard">#</a>Demoboard</h3><p>I’m often asked the question: <em>why does Frontend Armory use its own Demoboard component?</em> Why not just use CodeSandbox? It’s a great question, and honestly, there are a lot of ways I could answer it. To start with, CodeSandbox didn’t even exist when I started work on <a target="_blank" class=" " href="https://reactarmory.com/guides/learn-react-by-itself/react-basics">the first version of Frontend Armory</a>. But there’s another, more important reason.</p><p>CodeSandbox is designed to let you edit real world code in the browser. It’s amazing at what it does, but Demoboard — the editor that runs the fractal and landing page examples above — does something different. It lets you quickly throw together small demos. And moreover, it lets you render a <em>lot</em> of those demos on a single page.</p><p><strong>Demoboard is designed to be lightweight.</strong> It loads quickly, and loads <em>even quicker</em> when you have multiple demoboards on a page (as they’ll share the build worker). It’s also server-renderable, speeding up the time to initial content. It also works without a server <em>at all</em> — it can read everything it needs from a JavaScript CDN like <a target="_blank" class=" " href="https://unpkg.com/">UNPKG</a>.</p><p><strong>As of a few weeks ago, Demoboard is now <a target="_blank" class=" " href="https://github.com/frontarm/demoboard">open source</a>.</strong></p><p>Documentation is still to come, and the API is subject to change — but even in its current state, you can embed Demoboards in your site or docs with a simple <code>yarn add @frontarm/demoboard</code>. You can see how to do so at <a target="_blank" class=" " href="https://demoboard.io">demoboard.io</a> — where the open-source demoboard project will be living from here on out.</p><p>Demoboard is the engine that drives Frontend Armory, and it’ll be the engine that drives Vouch too. But why Demoboard and Vouch? And why <em>bacon</em>?</p><h2 id="the-mission"><a class="doc-headingLink  " href="#the-mission">#</a>The mission</h2><p>Without going into the details, I grew up in a place with a rather low socioeconomic rank. Remote work on the internet was a ladder up for me — and it’s a ladder that I want to help keep open for others. But actually, when I started Frontend Armory, I hadn’t yet realized this. All I knew was that I wanted to <em>teach</em>.</p><p><em>But what should I teach?</em> The obvious thing to teach was JavaScript and React. I <em>know</em> JavaScript and React. But there’s been something that’s made me increasingly uncomfortable about teaching web tech just for the sake of it: <em>the advertising economy</em>. I’m not a huge fan of ads. And that’s why I want to teach people to build apps without them.</p><div class="doc-AsideTop-1wzdz "><p><strong>My mission for Frontend Armory is to teach people the skills they need to build apps that charge money.</strong> </p><aside class="doc-Aside-QiMiD "><aside class="doc-Block-3i__D  doc-Details "><header></header><p>Rest assured, I understand the irony in taking this as a mission while relying on a Facebook funded product. But what am I gonna do, teach a Google funded product instead?</p></aside></aside></div><p>Each piece of new content this year has been one step towards this mission:</p><ul><li>Demoboard helps teachers make quality material by simplifying the process of embedding exercises</li><li>Vouch will encourage learning <a target="_blank" class=" " href="https://www.swyx.io/writing/learn-in-public/"><em>in public</em></a></li><li>React, Firebase &amp; Bacon is the roadmap to get where students are going</li></ul><p>This mission has helped give better direction to Frontend Armory’s content over the past few months — and it’s also resulted in another important change.</p><h2 id="a-more-accessible-price"><a class="doc-headingLink  " href="#a-more-accessible-price">#</a>A more accessible price</h2><p>Pricing is hard.</p><p>On one hand, for a service like Frontend Armory to be sustainable, it needs to cost money — because I need to be able to feed and house my family. On the other hand, if the price is too high for the people that actually need it, then I’m basically just wasting my time. The price needs to be <em>sustainable</em>, but it also needs to be <em>accessible</em>.</p><p>When I first launched Frontend Armory, the price was $40/month or $250/year. However, it soon became apparent that this put it out of reach for a lot of people who needed it most. To try and strike a better balance with accessibility, <em>I’ve cut Frontend Armory Pro’s monthly price by more than half.</em></p><p>Frontend Armory Pro is now just $18/month, or $180/year.</p><p><a class=" " href="/pricing/individual/#buy"><strong>Join Frontend Armory Pro Now »</strong></a></p><h2 id="business-and-financials"><a class="doc-headingLink  " href="#business-and-financials">#</a>Business and financials</h2><p>In the interest of transparency and learning in public, here’s some data from the first year of Frontend Armory:</p><ul><li>Revenue for the first year was roughly <strong>USD $20,000</strong> (2,160,000 yen)</li><li>There have been <strong>170</strong> customers in total (and as far as I know, my mum <em>didn’t</em> sign up to pad the numbers!)</li><li>Various hosting and business costs amounted to roughly <strong>USD $3,000</strong></li><li>Which all adds up to a <strong>huge loss</strong> if I value my time at even half of minimum wage</li></ul><p>Let me share a few other business-related things I’ve learned over the first year, in no particular order:</p><ul><li>Curating and editing content from others is hard. It takes almost as much time as writing my own content. While I’d still like to publish other authors, I first need to learn to better market my own content.</li><li>Extolling the virtue of my own content is mostly a waste of time. It’s far more valuable to have others vouch for my product than to do so myself.</li><li>Surprisingly, organic traffic from google has increased significantly, even during periods where I haven’t been regularly blogging… </li><li>But organic traffic doesn’t have a great conversion rate to paying customers.</li><li>GitHub stars don’t pay the bills.</li><li>Real-life workshops <em>do</em> pay the bills, but…</li><li>Marketing and sales take a <em>whole</em> lot of time, which can’t be spent on creating content.</li></ul><p>Initially, my plan was to create content for Frontend Armory full time — and for the better part of a year I managed to do so. However, it turns out I still have a lot to learn about marketing and business. With this in mind, for at least the next half year, I’m aiming to spend only 2–3 days a week on Frontend Armory. I’m treating this as a bit of a time to recharge and try new things <em>without</em> the stress of a limited runway.</p><h2 id="what-else-didnt-go-right"><a class="doc-headingLink  " href="#what-else-didnt-go-right">#</a>What else didn’t go right</h2><p>If you’ve been following along since last year, you might have noticed a few things conspicuously missing from the new lessons and code.</p><h3 id="videos"><a class="doc-headingLink  " href="#videos">#</a>Videos</h3><p>So far, Frontend Armory’s content has mostly been text and demo based — because in my opinion, these are usually the best mediums for building a deep understanding of a topic. But with this said, video <em>does</em> have its place. In particular, I’ve wanted to create video introductions for course topics, and video solutions for the more involved exercises. In fact, early on in the process of planning the React, Firebase &amp; Bacon course, I did create a <a target="_blank" class=" " href="https://www.youtube.com/watch?v=hfwpcGRtyw0">couple</a> <a target="_blank" class=" " href="https://www.youtube.com/watch?v=eTfJFuvfJrc&amp;t=22s">videos</a>. Here’s what I learned:</p><ul><li>Videos take a <em>lot</em> of time to get to the quality I want.</li><li>Unlike text, if the content changes, I can’t easily edit them; I have to start from scratch.</li><li>I can’t take good video with two huge construction sites next door.</li></ul><p>In any case, I <em>have</em> learned a lot about video, and plan on having another go once the text for the first few parts of React, Firebase &amp; Bacon is done — and once the construction next door finishes (or I give up waiting and move).</p><h3 id="navi"><a class="doc-headingLink  " href="#navi">#</a>Navi</h3><p>Towards the beginning of the year, I released a new version of my <a class=" " href="/navi/">Navi</a> router — with hooks, and a bunch of other neat features. Navi has come a long way, and is used in a number of production apps — including Frontend Armory and a number of apps by other contributors.</p><p>Recently though, the React team has been heading in a new direction, which makes me unsure of whether Navi has a future. React itself is gaining more and more responsibility, which makes it less and less certain that external state management solutions like Navi will continue to work well into the future. In particular, I’ve even seen talk of React integrating with bundlers and <a target="_blank" class=" " href="https://github.com/facebook/react/tree/master/packages/react-flight">the server</a> itself. Due to the uncertainty this brings and my limited time, I’ll be pausing work on new features, and continuing only with basic maintenance.</p><h3 id="communication"><a class="doc-headingLink  " href="#communication">#</a>Communication</h3><p>If you’ve read this far in, then thanks for reading! And also, chances are you’re someone who might have noticed that I haven’t been hugely communicative over the past year.</p><p>There are a number of reasons for this, but let me cover a few of the big ones.</p><ol><li>The change from class components to hooks was quite hard on me. I don’t want to teach something that I haven’t had time to become confident with, which means I didn’t really have much to say for the first part of the year — I just didn’t have the experience using hooks in real world code to actually teach them.</li><li>Even after gaining familiarity with hooks, I’ve hesitant to spend much effort teaching many existing patterns, due to the near-certainty that they’ll soon be obsolete. The announcement of <a target="_blank" class=" " href="https://reactjs.org/docs/concurrent-mode-intro.html">Concurrent Mode</a> in October has only reinforced this opinion.</li><li>As a result, for the first part of the year, I wasn’t able to create much that I personally felt had enough value to broadcast to the world.</li></ol><p>Over the past few months however, I felt like I’m gaining my feet again. Instead of teaching React itself, I’ve focused on teaching how to build apps that <em>use</em> React. Instead of teaching the latest React patterns and APIs, I’ve been teaching the tools that I use <em>right now</em> in a real app. And while I’m not going to promise you updates at any specific frequency, I <em>will</em> be more communicative over the coming year.</p><h2 id="one-last-silly-little-thing"><a class="doc-headingLink  " href="#one-last-silly-little-thing">#</a>One last silly little thing</h2><p>Near the beginning of 2019, I bought a big Lego rocket, and I gave myself a rule: one page of the instruction booklet gets built for each major piece of content that goes online.</p><p>Here’s an image I posted just after I got the rocket, on January 23:</p><div>Unimplemented.</div><p>And here’s the rocket now — after building <em>76</em> pages:</p><div>Unimplemented.</div><p>As silly as it sounds, the rocket has been a great motivator for me. Each time I add another brick to the rocket, it means I’ve taken one more meaningful step towards helping people to learn skills that can build them a better life.</p><p><strong>If you’ve already become a Frontend Armory Pro member, then you’ve helped build 76 pages of rocket towards that goal.</strong> And if not, then now’s the perfect time to join! You’ll not only get immediate access to:</p><ul><li>The Vouch source code</li><li>All member-exclusive content</li><li>Early access to new content</li><li>The member’s lounge slack room (where I answer questions a lot more reliably than I do via Twitter or Email)</li></ul><p>If you join in now, you’ll <em>also</em> be helping to move another 100 pages closer to the goal of creating Frontend Armory, Vouch and Demoboard — and helping people teach themselves a valuable skill in the process.</p><p><em>(Oh yeah, and since it’s late November, I’ve dropped the yearly price from $180 to $150 — it’ll stay at that price until November 31.)</em></p><p><a class=" " href="/pricing/individual/#buy"><strong>So join Frontend Armory Pro now »</strong></a></p><p>Thanks so much for reading! Can’t wait to see you again at the next update :-)</p></div>]]></content:encoded>
            <author>james@jamesknelson.com (James K Nelson)</author>
        </item>
        <item>
            <title><![CDATA[A deep dive into React effects]]></title>
            <link>https:/frontarm.com/james-k-nelson/introduction-to-react-effects/</link>
            <guid>https:/frontarm.com/james-k-nelson/introduction-to-react-effects/</guid>
            <pubDate>Sun, 25 Aug 2019 00:00:00 GMT</pubDate>
            <description><![CDATA[Learn all about React's new useEffect hook, with live exercises and fractals.]]></description>
            <content:encoded><![CDATA[<div class="doc-wrapper doc-Doc-18aNW doc-align-center-when-narrow-2ypbP "><aside class="doc-Aside-QiMiD "><aside class="doc-Block-3i__D  doc-Details "><header></header><p>This lesson is based on the effects lesson in my <a class=" " href="/bacon/">React, Firebase &amp; Bacon</a> course.</p></aside></aside><p>Imagine that for some reason, you’ve decided to create a React component that renders an animated fractal tree. In fact, let’s say that you’re already 90% of the way there — you <em>have</em> a fractal tree component, and now you want to animate it.</p><pre class="language-text"><code>import React, { useState } from &#x27;react&#x27;
import FractalTreeFrame from &#x27;./FractalTreeFrame&#x27;

// The height and width of the entire window
const { innerHeight, innerWidth } = window

export default function App() {
  const [mousePosition, setMousePosition] = useState({
    x: innerWidth / 2,
    y: innerHeight / 2,
  })

  return (
    &lt;FractalTreeFrame
      mousePosition={mousePosition}
      onMouseMove={({ clientX: x, clientY: y }) =&gt;
        setMousePosition({ x, y })
      }
      time={Date.now()}
    /&gt;
  )
}
</code></pre><p>If you move the mouse around the preview area, you’ll see that the tree is <em>already</em> somewhat animated, due to the <code>onMouseMove</code> handler:</p><pre class="language-jsx"><code>onMouseMove={({ clientX: x, clientY: y }) =&gt;
  setMousePosition({ x, y })
}
</code></pre><p>Each time the mouse moves over the preview area, React calls this event handler. This in turn updates the component state, triggering a re-render of the component with a new value of the <code>time</code> prop.</p><pre class="language-jsx"><code>time={Date.now()}
</code></pre><div class="doc-AsideTop-1wzdz "><p>Of course, it won’t do to require the user to constantly move their mouse to keep the animation going. Ideally, the component would <em>automatically</em> schedule a new frame after each frame is rendered, using something like the browser’s <code>requestAnimationFrame()</code> function.</p><aside class="doc-Aside-QiMiD "><aside class="doc-Block-3i__D  doc-Details "><header></header><p><code>requestAnimationFrame()</code> requests that the browser calls a specified function before the next repaint — allowing you to render an animation one frame at a time. For more details, <a target="_blank" class=" " href="https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame">see MDN</a>.</p></aside></aside></div><p>As it happens, there’s a pretty obvious way to make this work. Given that updating the state also triggers a re-render, you can store the current time with a <code>useState</code> hook. Then, you can trigger re-render by updating the time in a <code>requestAnimationFrame()</code> callback. To try it out, just uncomment lines 14–17 below:</p><pre class="language-text"><code>import React, { useState } from &#x27;react&#x27;
import FractalTreeFrame from &#x27;./FractalTreeFrame&#x27;

// The height and width of the entire window
const { innerHeight, innerWidth } = window

export default function App() {
  const [time, setTime] = useState(Date.now())
  const [mousePosition, setMousePosition] = useState({
    x: innerWidth / 2,
    y: innerHeight / 2,
  })

  // window.requestAnimationFrame(() =&gt; {
  //   // Update time to trigger a re-render
  //   setTime(Date.now())
  // })

  return (
    &lt;FractalTreeFrame
      mousePosition={mousePosition}
      onMouseMove={({ clientX: x, clientY: y }) =&gt;
        setMousePosition({ x, y })
      }
      time={time}
    /&gt;
  )
}
</code></pre><p>Once you’ve removed the comment above, this animation looks to work pretty well! That is, at least until you try moving the mouse over the tree as well. Go ahead, try quickly moving your mouse over the tree, and see how performance takes a nosedive.</p><p><em>What the hell is going on?</em></p><p>Here’s the problem: if the mouse moves, then React will update the state and re-render the component, thus scheduling <em>another</em> render in addition to the one already scheduled by <code>requestAnimationFrame()</code>. Now you have <em>two</em> scheduled renders, twice the CPU usage, half the frame rate, and everything starts to grind to a halt.</p><h2 id="so-effects"><a class="doc-headingLink  " href="#so-effects">#</a>So… effects?</h2><p>In the above example, the call to <code>window.requestAnimationFrame()</code> is what’s called a <strong>side effect</strong>; it’s something that your component does <em>in addition</em> to returning elements.</p><p>Side effects are what make your application <em>actually useful</em>. They’re responsible for things like:</p><ul><li>Loading data from the server</li><li>Setting and clearing timers</li><li>Interacting with the DOM</li></ul><div class="doc-AsideTop-1wzdz "><p>As you can see from the above example, it’s entirely possible to put effectful code directly in the component function. The thing is, the resulting effects occur <em>each and every</em> time the component function is called — which is rarely the desired behavior. More often, you’ll want the effect to occur in response to specific conditions — and to <em>stop</em> occurring once those conditions are removed.</p><aside class="doc-Aside-QiMiD "><aside class="doc-Block-3i__D  doc-Details "><header></header><p>When using features like <a target="_blank" class=" " href="https://reactjs.org/docs/react-api.html#reactsuspense">React Suspense</a>, it’s possible for component functions to be stopped mid-execution, and repeated later on. This can result in parts of the function being run multiple times, or not being run at all.</p></aside></aside></div><h2 id="the-useeffect-function"><a class="doc-headingLink  " href="#the-useeffect-function">#</a>The <code>useEffect()</code> function</h2><p>This hook function lets you ask React to do something <em>after</em> the component has finished rendering to the DOM. There are a few ways to use it, so let’s start with the simplest:</p><pre class="language-jsx"><code>useEffect(() =&gt; {
  // do stuff after update
})
</code></pre><p>When <code>useEffect()</code> receives a function as its first and only argument, it’ll call that function on <em>every</em> update. You might use this to, for example, validate usernames in a social network’s onboarding sequence. You can see how I’ve approached this below — go ahead, try typing in a username to test it out!</p><pre class="language-text"><code>import React, { useEffect, useState } from &#x27;react&#x27;
import getUsernameAvailability from &#x27;./getUsernameAvailability&#x27;

export default function App() {
  const [username, setUsername] = useState(&#x27;&#x27;)
  const [availability, setAvailability] = useState({})
  const handleChange = event =&gt; setUsername(event.target.value)

  useEffect(() =&gt; {
    if (username &amp;&amp; username !== availability.username) {
      // The promises returned by getUsernameAvailability
      // will always resolve in the same order as they&#x27;re created,
      // so we don&#x27;t have to worry about race conditions here.
      getUsernameAvailability(username).then(
        isAvailable =&gt; setAvailability({ username, isAvailable })
      )
    }
  })

  return (
    &lt;div className=&quot;nametag&quot;&gt;
      &lt;h2&gt;Hello&lt;/h2&gt;
      &lt;label&gt;
        &lt;p&gt;my username is&lt;/p&gt;
        &lt;div className=&quot;field&quot;&gt;
          &lt;span className=&quot;at&quot;&gt;@&lt;/span&gt;
          &lt;input value={username} onChange={handleChange} /&gt;
          &lt;span className=&quot;icon&quot;&gt;
            {username &amp;&amp; availability.username === username &amp;&amp; (
              availability.isAvailable ? &quot;✔️&quot; : &quot;❌&quot;
            )}
          &lt;/span&gt;
        &lt;/div&gt;
      &lt;/label&gt;
    &lt;/div&gt;
  )
}
</code></pre><aside class="doc-Aside-QiMiD "><aside class="doc-Block-3i__D  doc-Details "><header></header><p>Want to know more about Promise objects, like the one in the above example? Check out my <a class=" " href="/courses/async-javascript/">Mastering Async JavaScript</a> course for a detailed introduction.</p></aside></aside><p>In the above example, the effect starts by checking whether validation still needs to be performed for the current username. Then, if validation <em>is</em> still required, it calls <code>getUsernameAvailability()</code> and saves the result to component state.</p><p>While it may seem like a minor (and imperfect) optimization, the <code>if</code> statement inside the above effect is actually <em>incredibly</em> important. Do you know why?</p><section class="doc-Block-3i__D  doc-Spoiler "><header>Spoiler</header><p>Without the <code>if</code> statement, you get an infinite loop.</p></section><p>Saving the validation result to component state triggers another update, which triggers the effect, which triggers the update, which… yeah, you get the idea. </p><p>Effects often need to update component state, and this presents a bit of a problem: if you run these effects in response to <em>every</em> update, you can easily end up with infinite loops. Typically though, you <em>don’t want</em> to run effects in response to every update. You only want them to respond to specific events — and that’s where the second argument of <code>useEffect()</code> comes in.</p><h2 id="conditional-effects"><a class="doc-headingLink  " href="#conditional-effects">#</a>Conditional effects</h2><p>The second argument to <code>useEffect()</code> — called the <strong>dependencies array</strong> — instructs React to <strong>only run the effect if a dependency has changed from its previous value</strong>.</p><div class="doc-AsideTop-1wzdz "><pre class="language-jsx"><code>useEffect(
  () =&gt; {
    // do stuff after specified updates
  },
  [executeWhenThisChanges, orWhenThisChanges]
)
</code></pre><aside class="doc-Aside-QiMiD "><aside class="doc-Block-3i__D  doc-Details "><header>Empty arrays</header><p>If you pass an empty array <code>[]</code> for the dependencies, the effect will only run once — on mount.</p></aside></aside></div><p>The dependencies array gives you a simple way to create effects that respond to specific events, <em>without</em> running into infinite loops. And with that in mind, let’s revisit the username example with an exercise.</p><p><strong>Your task is to refactor the below example with a dependencies array, so that it no longer uses an <code>if</code> statement.</strong></p><p>Be careful to add the dependencies array <em>before</em> removing the <code>if</code> statement though — otherwise you’ll end up with an infinite loop!</p><pre class="language-text"><code>import React, { useEffect, useState } from &#x27;react&#x27;
import getUsernameAvailability from &#x27;./getUsernameAvailability&#x27;

export default function App() {
  const [username, setUsername] = useState(&#x27;&#x27;)
  const [availability, setAvailability] = useState({})
  const handleChange = event =&gt; setUsername(event.target.value)

  useEffect(() =&gt; {
    if (username &amp;&amp; username !== availability.username) {
      // The promises returned by getUsernameAvailability
      // will always resolve in the same order as they&#x27;re created,
      // so we don&#x27;t have to worry about race conditions here.
      getUsernameAvailability(username).then(
        isAvailable =&gt; setAvailability({ username, isAvailable })
      )
    }
  })

  return (
    &lt;div className=&quot;nametag&quot;&gt;
      &lt;h2&gt;Hello&lt;/h2&gt;
      &lt;label&gt;
        &lt;p&gt;my username is&lt;/p&gt;
        &lt;div className=&quot;field&quot;&gt;
          &lt;span className=&quot;at&quot;&gt;@&lt;/span&gt;
          &lt;input value={username} onChange={handleChange} /&gt;
          &lt;span className=&quot;icon&quot;&gt;
            {username &amp;&amp; availability.username === username &amp;&amp; (
              availability.isAvailable ? &quot;✔️&quot; : &quot;❌&quot;
            )}
          &lt;/span&gt;
        &lt;/div&gt;
      &lt;/label&gt;
    &lt;/div&gt;
  )
}
</code></pre><p>Did you have a go? Great! In that case, if you take a look at the solution for the above exercise, you might notice something interesting. Here’s the original:</p><pre class="language-jsx"><code>useEffect(() =&gt; {
  if (username !== availability.username) {
    // ...
  }
})
</code></pre><p>In contrast, here’s the solution with a dependencies array:</p><pre class="language-jsx"><code>useEffect(() =&gt; {
  if (username) {
    // ...
  }
}, [username])
</code></pre><p>At first, there might not seem to really be any point in making this change. Sure, it saved you a couple characters… but if you look a little closer, there’s something far more exciting going on. Do you know what it is? Have a little think about this before checking the box below.</p><section class="doc-Block-3i__D  doc-Spoiler "><header>Spoiler</header><p>Actually, there are two exciting things going on here!</p><p>First, there’s the fact that the number of validations is cut in half — you can confirm this by opening up the console in both of the above examples. This is because the effect is now only being run when the username has changed — as opposed to running when it differs to the <em>last received username</em>. It gives you a better result, despite using less code. Which brings me to the second exciting thing.</p><p>While the condition in the first snippet references <em>two</em> variables: <code>username</code>, and <code>availability.username</code>, the second snippet <em>only needs the <code>username</code></em>. By using the dependencies array, you’ve eliminated the need for an extra piece of state!</p></section><p>The key feature of <code>useEffect()</code> is that it lets you specify not just <em>what</em> effect to run, but also <em>when</em> that effect should occur — and it lets you do this declaratively, without relying on component state at all! In fact, it actually takes this one step further: it lets you declare how the effect should <em>end</em>.</p><h2 id="the-cleanup-function"><a class="doc-headingLink  " href="#the-cleanup-function">#</a>The cleanup function</h2><p>When you return a function from your <code>useEffect()</code> callback, React will call that function when the effect should no longer have any… effect. <small><em>lol, sorry not sorry.</em></small></p><div class="doc-AsideTop-1wzdz "><pre class="language-jsx"><code>useEffect(
  () =&gt; {
    // do stuff after specified updates

    return () =&gt; {
      // finish doing stuff
    }
  },
  [executeWhenThisChanges, orWhenThisChanges]
)
</code></pre><aside class="doc-Aside-QiMiD "><aside class="doc-Block-3i__D  doc-Beware "><header>Effects and async</header><p>The <code>useEffect()</code> hook does <em>not</em> allow you to pass in async callbacks. And when you think about it, this makes sense — async functions always return a promise, which would make it impossible to return a cleanup function.</p></aside></aside></div><p>This function is often called the <strong>cleanup function</strong>, and there are <em>two</em> situations in which React will call it. Do you know what they are? Have a think about it, and when you’re ready, check your answer below.</p><section class="doc-Block-3i__D  doc-Spoiler "><header>Spoiler</header><p>The cleanup function will be called:</p><ol><li>When the component is unmounted</li><li>On the <em>next time</em> that the effect callback is run</li></ol></section><p>The first of these situations is hopefully fairly obvious. But what about the second situation? <em>This is what makes the effect hook so powerful.</em> It lets you declare to React:</p><p><em>Yo React, I want this thing to happen, but only</em> until <em>the next time it happens (or until it no longer</em> can <em>happen).</em></p><p>The cleanup function is particularly important when dealing with data subscriptions — I’ll cover more on this in the routing section of <a class=" " href="/bacon/">React, Firebase &amp; Bacon</a>. For the moment though, let’s jump back to where we started: the animated tree.</p><p>In order to smooth out the tree’s animation, all you need to do is finish off the effect in the demo below. The thing is, there are actually <em>two</em> approaches that you can take. Do you know what they are? If so, try them out in the editor — and then check below to find out which one works best.</p><pre class="language-text"><code>import React, { useEffect, useState } from &#x27;react&#x27;
import FractalTreeFrame from &#x27;./FractalTreeFrame&#x27;

// The height and width of the entire window
const { innerHeight, innerWidth } = window

export default function App() {
  const [time, setTime] = useState(Date.now())
  const [mousePosition, setMousePosition] = useState({
    x: innerWidth / 2,
    y: innerHeight / 2,
  })

  // useEffect(() =&gt; {
  //   window.requestAnimationFrame(() =&gt; {
  //     // Update time to trigger a re-render
  //     setTime(Date.now())
  //   })
  // })

  return (
    &lt;FractalTreeFrame
      mousePosition={mousePosition}
      onMouseMove={({ clientX: x, clientY: y }) =&gt;
        setMousePosition({ x, y })
      }
      time={time}
    /&gt;
  )
}
</code></pre><p>Did you find both approaches?</p><section class="doc-Block-3i__D  doc-Spoiler "><header>Spoiler</header><h5 id="approach-1-conditional-effects"><a class="doc-headingLink  " href="#approach-1-conditional-effects">#</a>Approach 1: conditional effects</h5><p>Given that <code>time</code> is only updated within <code>requestAnimationFrame</code>, you can limit the number of renders by adding <code>time</code> as a dependency.</p><pre class="language-jsx"><code>useEffect(() =&gt; {
  window.requestAnimationFrame(() =&gt; {
    setTime(Date.now())
  })
}, [time])
</code></pre><p>So long as the tree is the top level component, this approach works fine and dandy. Be careful, though — if this component is <em>not</em> at the top level and is then <em>unmounted</em> inside a running application, it would cause a warning, as <code>setTime</code> would still be called after unmount.</p><h5 id="approach-2-cleanup-function"><a class="doc-headingLink  " href="#approach-2-cleanup-function">#</a>Approach 2: cleanup function</h5><p>By calling <a target="_blank" class=" " href="https://developer.mozilla.org/en-US/docs/Web/API/Window/cancelAnimationFrame">cancelAnimationFrame</a> in the cleanup function, you’ll ensure that any scheduled updates are cancelled when you move the mouse.</p><pre class="language-jsx"><code>useEffect(() =&gt; {
  const frame = window.requestAnimationFrame(() =&gt; {
    setTime(Date.now())
  })
  return () =&gt; {
    window.cancelAnimationFrame(frame)
  }
})
</code></pre><p>I’d recommend taking this approach, for two reasons:</p><ol><li>It’ll work just as well if you decide to update <code>time</code> elsewhere</li><li>It’ll work just as well if the component is mounted elsewhere</li></ol></section><h2 id="the-three-rules"><a class="doc-headingLink  " href="#the-three-rules">#</a>The three rules</h2><p>Phew, that was a lot of info on effects! It’s okay if you didn’t take it all in — as you keep using effects in your day-to-day (or in my <a class=" " href="/course/">React, Firebase &amp; Bacon</a> course), you’ll gradually build intuition for them. But to start with? All you need to remember is these three rules:</p><ol><li><code>useEffect()</code> schedules an update <em>after</em> the DOM has been updated</li><li>By passing a dependencies array, that update will only occur if a dependency has changed</li><li>If you return a cleanup function, it’ll be called when the effect should should no longer apply</li></ol><p>Got these three rules down? Good. Let’s see if we can’t put &#x27;em all into practice with an exercise.</p><h2 id="exercise-debounce-the-username-form"><a class="doc-headingLink  " href="#exercise-debounce-the-username-form">#</a>Exercise: debounce the username form</h2><p>If you take a look at the console for this example, you’ll see that as you type, a separate validation request is made for <em>each and every</em> keystroke. Given that at some level you’re going to be charged per request… well, if your app grows large enough, a little debounce could save a lot of bacon.</p><p>But what do I mean by debouncing? Simple: instead of validating each and every keystroke, you’ll want to delay validation until the user has stopped typing for a short period. Roughly speaking, here’s how to achieve this:</p><ol><li>When the user updates the input, you’ll use <a target="_blank" class=" " href="https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout">setTimeout()</a> to schedule a validation to occur a few hundred milliseconds in the future.</li><li>If the user updates the input <em>again</em> before the previously scheduled validation has occurred, then cancel it with <a target="_blank" class=" " href="https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/clearTimeout">clearTimeout()</a> before scheduling another one.</li></ol><p><strong>Your task is to debounce the username input so that validation runs no more than once every 500ms.</strong></p><p>You can check your work by opening up the console, and watching how many requests are made as you type. Then, once you’re happy with your work (or if you’re stuck but you’ve given the exercise a solid try), compare your work with my solution by clicking the <em>solution</em> button at the bottom left.</p><pre class="language-text"><code>import React, { useEffect, useState } from &#x27;react&#x27;
import getUsernameAvailability from &#x27;./getUsernameAvailability&#x27;

export default function App() {
  const [username, setUsername] = useState(&#x27;&#x27;)
  const [availability, setAvailability] = useState({})

  useEffect(() =&gt; {
    if (username) {
      getUsernameAvailability(username).then(
        isAvailable =&gt; setAvailability({ username, isAvailable })
      )
    }
  }, [username])

  return (
    &lt;div className=&quot;nametag&quot;&gt;
      &lt;h2&gt;Hello&lt;/h2&gt;
      &lt;label&gt;
        &lt;p&gt;my username is&lt;/p&gt;
        &lt;div className=&quot;field&quot;&gt;
          &lt;span className=&quot;at&quot;&gt;@&lt;/span&gt;
          &lt;input
            value={username}
            onChange={event =&gt; setUsername(event.target.value)}
          /&gt;
          &lt;span className=&quot;icon&quot;&gt;
            {username &amp;&amp; availability.username === username &amp;&amp; (
              availability.isAvailable ? &quot;✔️&quot; : &quot;❌&quot;
            )}
          &lt;/span&gt;
        &lt;/div&gt;
      &lt;/label&gt;
    &lt;/div&gt;
  )
}
</code></pre><p><em>This article is based on the <code>useEffect()</code> lesson in <a class=" " href="/bacon/">React, Firebase &amp; Bacon</a>. If you found this lesson useful, then there’s plenty more demos, exercises and in-depth explanations where it came from. Check it out — I think you’ll love it! 🤓</em></p><ul><li><strong><a class=" " href="/bacon/">Check out the React, Firebase &amp; Bacon course »</a></strong></li><li><strong><a class=" " href="/courses/react-fundamentals/">Check out the React Fundamentals course »</a></strong></li></ul></div>]]></content:encoded>
            <author>james@jamesknelson.com (James K Nelson)</author>
        </item>
        <item>
            <title><![CDATA[When to Use Custom React Hooks]]></title>
            <link>https:/frontarm.com/james-k-nelson/react-hooks-intuition/</link>
            <guid>https:/frontarm.com/james-k-nelson/react-hooks-intuition/</guid>
            <pubDate>Wed, 06 Mar 2019 00:00:00 GMT</pubDate>
            <description><![CDATA[Learn how custom hooks are like mixins: a great way to share small bits of functionality between components.]]></description>
            <content:encoded><![CDATA[<div class="doc-wrapper doc-Doc-18aNW doc-align-center-when-narrow-2ypbP "><div class="doc-AsideTop-1wzdz "><p>It’s been almost a month since React Hooks were released, and they already seem to be taking over the world — thanks in no small part to the power of custom hooks.</p><p>Custom hooks do for state and side effects what React components did for views; they make it insanely easy to share and reuse small pieces of code. As a result, all sorts of packages now export custom hooks — <a class=" " href="/navi/en/reference/react-components-hooks/#usecurrentroute">my own package</a> included. <em>But there’s a catch.</em></p><p>Let’s investigate the catch by diving into an example, before building some intuition around when to use custom hooks — and when to use something else.</p><aside class="doc-Aside-QiMiD "><blockquote style="margin-top:0;font-style:italic;font-size:120%">This article is almost my exact experience!<cite style="margin-top:1rem;display:block;font-size:80%">– <a href="https://twitter.com/_eliperkins">Eli Perkins</a></cite></blockquote></aside></div><h2 id="have-you-ever-used-an-app-with-no-lists"><a class="doc-headingLink  " href="#have-you-ever-used-an-app-with-no-lists">#</a>Have you ever used an app with no lists?</h2><p>Imagine that you’re building an app with a contact form. To start out, you may decide to store the form’s state within the Form component itself, using the <code>useState()</code> hook.</p><pre class="language-jsx"><code>let [name, setName] = useState(defaultValue.name || &#x27;&#x27;)
let [email, setEmail] = useState(defaultValue.email || &#x27;&#x27;)
</code></pre><p>To ensure reusability, you put this state management code into a <code>useContactModel()</code> custom hook, that can be used whenever a contact form is required within your app.</p><pre class="language-jsx"><code>function useContactModel({ defaultValue }) {
  let [name, setName] = useState(defaultValue.name || &#x27;&#x27;)
  let [email, setEmail] = useState(defaultValue.email || &#x27;&#x27;)

  return {
    error: name === &#x27;&#x27; ? &#x27;Please enter a name&#x27; : undefined,

    // Contains objects that can be spread onto &lt;input&gt; elements
    inputProps: {
      name: {
        value: name,
        onChange: e =&gt; setName(e.target.value),
      },
      email: {
        value: email,
        onChange: e =&gt; setEmail(e.target.value),
      },
    }
  }
}
</code></pre><p>Simple, huh? Hooks make this kind of thing super-duper easy. But what if the customer then asks you why you only allow for entry of a <em>single</em> contact, as opposed to a <em>list</em> of contacts? No worries, <code>Contact</code> is a component. Turning it into a list is as simple as creating a <code>ContactList</code> component and rendering <code>Contact</code> a few times.</p><pre class="language-text"><code>import React from &#x27;react&#x27;
import { useContactModel, useKeys } from &#x27;./hooks&#x27;

export function Contact({ onRemove }) {
  let model = useContactModel()

  return (
    &lt;div&gt;
      &lt;label&gt;Name: &lt;input {...model.inputProps.name} /&gt;&lt;/label&gt;
      &lt;label&gt;Email: &lt;input {...model.inputProps.email} /&gt;&lt;/label&gt;
      &lt;button onClick={onRemove}&gt;Remove&lt;/button&gt;
      {model.error &amp;&amp; &lt;p&gt;{model.error}&lt;/p&gt;}
    &lt;/div&gt;
  )
}

export function ContactList() {
  let [keys, add, remove] = useKeys(3)

  return (
    &lt;&gt;
      {keys.map(key =&gt;
        &lt;Contact key={key} onRemove={() =&gt; remove(key)} /&gt;
      )}
      &lt;button onClick={add}&gt;Add&lt;/button&gt;
    &lt;/&gt;
  )
}
</code></pre><p>So far, so good. There’s just one problem: you need to be able to <em>save</em> the contacts. And given that your API requires that you send the entire list at once, you’re going to need to have access to an array containing all that data.</p><p>If the state is all stored in child components, then you can’t just access the data from the parent. But no problem — <code>useContactModel()</code> is a hook, so you can just lift the whole thing into the parent component, right?</p><pre class="language-text"><code>import React from &#x27;react&#x27;
import { useContactModel, useKeys } from &#x27;./hooks&#x27;

export function Contact({ model, onRemove }) {
  return (
    &lt;div&gt;
      &lt;label&gt;Name: &lt;input {...model.inputProps.name} /&gt;&lt;/label&gt;
      &lt;label&gt;Email: &lt;input {...model.inputProps.email} /&gt;&lt;/label&gt;
      &lt;button onClick={onRemove}&gt;Remove&lt;/button&gt;
      {model.error &amp;&amp; &lt;p&gt;{model.error}&lt;/p&gt;}
    &lt;/div&gt;
  )
}

export function ContactList() {
  let [keys, add, remove] = useKeys(3)
  let contactModels = keys.map(useContactModel)

  return (
    &lt;&gt;
      {keys.map((key, i) =&gt;
        &lt;Contact
          key={key}
          model={contactModels[i]}
          onRemove={() =&gt; remove(key)}
        /&gt;
      )}
      &lt;button onClick={add}&gt;Add&lt;/button&gt;
    &lt;/&gt;
  )
}
</code></pre><p>Waaait a minute… in the above example, <code>useContactModel()</code> is called from a loop. You can’t see the loop, because it’s happening inside of the call to <code>map()</code>. But I can assure you that there are looping shenanigans taking place.</p><p>Now as you know, hooks aren’t like normal functions. <em>You can’t use them just anywhere in your code.</em> The above code shouldn’t work, and indeed it doesn’t — just try adding or removing a contact…</p><h2 id="hooks-cant-always-be-lifted-up"><a class="doc-headingLink  " href="#hooks-cant-always-be-lifted-up">#</a>Hooks can’t (always) be lifted up</h2><p>At times, you can think of custom hooks as <em>components for state management</em>. But this mental model breaks down after a point: while components can be rendered within loops and conditions, hooks <a target="_blank" class=" " href="https://reactjs.org/docs/hooks-rules.html">can’t</a>. And this has an important side effect:</p><p><strong>Custom hooks can’t be lifted out of components that are rendered inside of conditions or loops.</strong></p><p>Hooks aren’t like reducers; you can’t just compose them together into one big hook that holds the entire application’s state. Instead, you’ll need to call any <code>useState()</code> hooks closer to where the state is actually rendered — and <em>this is by design:</em></p><div>Unimplemented.</div><p>While hooks do let you reuse stateful and effectful code across components, they still <strong>force you to associate that code with a component</strong> — and its associated position in the DOM. As a result, hooks come with many of the same constraints as class components:</p><div class="doc-AsideTop-1wzdz "><ul><li><p><strong>What if you need to call a hook within a loop?</strong></p><p>Then you’ll need to put the hook in a child component and call it there.</p></li><li><p><strong>What if you then want to access the result of those hooks in the parent component?</strong></p><p>Then you’ll need to lift the state back up into the parent component and refactor to avoid calling hooks in loops — e.g. by replacing multiple <code>useState()</code> hooks with a single <code>useReducer()</code>.</p></li><li><p><strong>What if you then want that state to stick around after the component is unmounted?</strong></p><p>Then you’ll need to lift the state up even further — and probably refactor again.</p></li></ul><p>As you can see, custom hooks aren’t really “components for state and side effects” — they’re too dependent on their context to be thought of as components. But if they’re not components, <em>then what are they?</em></p><aside class="doc-Aside-QiMiD "><aside class="doc-Block-3i__D  doc-Details "><header>Multiple useStates, or a useReducer?</header><p>Dan Abramov <a target="_blank" class=" " href="https://twitter.com/dan_abramov/status/1083330668522864640">tweeted</a> a simple answer:</p><blockquote><p>For independent things (isHovering and textInput), multiple useState.</p><p>For things that change together (isFetching and fetchedItems), or if their next state depends on previous (todos), I prefer useReducer.</p></blockquote></aside></aside></div><h2 id="hooks-are-mixins"><a class="doc-headingLink  " href="#hooks-are-mixins">#</a>Hooks are mixins</h2><p>Once upon a time, React had a feature called <em>mixins</em> that let you reuse small groups of lifecycle methods and state across multiple components. React’s mixins had a <a target="_blank" class=" " href="https://reactjs.org/blog/2016/07/13/mixins-considered-harmful.html">number of issues</a> which caused them to be deprecated, but the need for a way to share functionality between components is as a strong as ever. And that’s what hooks are: a way to share stateful and side-effectful functionality between components.</p><aside class="doc-Aside-QiMiD "><aside class="doc-Block-3i__D  doc-Details "><header></header><p>Another tool for thinking about hooks is to understand that a component can have a <em>tree</em> of child components, but it can only have a <em>list</em> of hooks or mixins.</p><p>If you need a tree, then you don’t want to build it out of hooks — but you <em>may</em> want to build it out of components or reducers.</p></aside></aside><p>Ryan Florence actually <a target="_blank" class=" " href="https://reactpodcast.com/31">made this connection</a> before hooks were even announced. But personally speaking, it wasn’t until I started running into the limitations of hooks that the connection really struck.</p><p>Ok, so hooks are mixins. It’s a fun connection to make — but does this mean anything <em>in practice?</em> Actually, I’ve found this to be a good way to intuitively understand whether something <del>can</del> should be done with hooks:</p><ul><li><p><strong>Should I try and create a Redux-like store that holds my entire app’s state by mixing things into a component?</strong> No? Then it doesn’t make sense with hooks either.</p></li><li><p><strong>Should I try to create models that store state for a large form by mixing things into a component?</strong> No? Then hooks probably aren’t a great way to do this either.</p></li><li><p><strong>Would mixins be an appropriate way to make a component subscribe to a global store?</strong> Yes? Then hooks will work for that too!</p></li></ul><p>And we’re not done yet. There’s one more thing that hooks-are-mixins means in practice, and it’s a biggie…</p><h2 id="dont-throw-out-your-state-manager"><a class="doc-headingLink  " href="#dont-throw-out-your-state-manager">#</a>Don’t throw out your state manager.</h2><div class="doc-AsideTop-1wzdz "><p>While hooks are a great way to reuse stateful code across components, <em>they’re still tied to components</em>. Sometimes you’ll need state that <em>isn’t</em> tied to a component — things like:</p><ul><li>A cache of data that has been received from the server (e.g. Apollo)</li><li>The status of any drag-and-drop interactions (e.g. <a target="_blank" class=" " href="https://github.com/react-dnd/react-dnd">react-dnd</a>)</li><li>The current user’s authentication state (e.g. using Firebase or Auth0)</li><li>Any async data that depends on the current URL (e.g. using <a class=" " href="/navi/">Navi</a>)</li></ul><p>While hooks are local, some state is global. And that means that state managers will always be your friend! With that said, <strong>hooks and state managers aren’t mutually exclusive.</strong></p><aside class="doc-Aside-QiMiD "><aside class="doc-Block-3i__D  doc-Details "><header>What about Suspense?</header><p>When <a target="_blank" class=" " href="https://reactjs.org/blog/2018/11/27/react-16-roadmap.html#react-16x-q2-2019-the-one-with-concurrent-mode">Concurrent Mode</a> hits the street, it’ll become even easier to subscribe to async data using Suspense — but that data will still need to be cached somewhere.</p><p>React will provide a <em>simple</em> <a target="_blank" class=" " href="https://www.npmjs.com/package/react-cache">cache</a>, but Apollo (and other tools for managing global state) will provide you with many more features.</p></aside></aside></div><p>In order to render any global state, you’ll first need to subscribe to it and store it in component state — and hooks are a great way to do this. For an example of how to do this, check out Daishi Kato’s recent guide to <a class=" " href="/daishi-kato/redux-custom-hooks/">creating hooks to subscribe to a Redux store (with Proxies)</a>.</p><p>So here’s the thing: hooks are an incredible tool. I feel like they’re the missing piece that React has needed since Mixins were deprecated. But like any tool, hooks don’t suit every situation, and the key to getting the most out of them is to understand when to use them — and when to use something else.</p><p><em>Thanks for reading all the way to the end! If you liked this article and want to read more like it, then now’s a great time to join Frontend Armory’s weekly newsletter. It’s free to join — just click → <a class=" " href="/members/register/">here</a> ←.</em></p><h2 id="more-reading"><a class="doc-headingLink  " href="#more-reading">#</a>More Reading</h2><ul><li><a class=" " href="/james-k-nelson/when-context-replaces-redux/">When Context Replaces Redux</a></li><li><a class=" " href="/daishi-kato/redux-custom-hooks/">Creating a react-redux alternative with Hooks and Proxies</a></li><li><a class=" " href="/swyx/reusable-time-travel-react-hooks-immer/">Reusable Time Travel with React Hooks and Immer</a></li><li><a class=" " href="/james-k-nelson/navi-react-router-hooks-suspense/">A <code>&lt;Router /&gt;</code> with Hooks and Suspense</a></li></ul></div>]]></content:encoded>
            <author>james@jamesknelson.com (James K Nelson)</author>
        </item>
        <item>
            <title><![CDATA[useRef() and Concurrent Mode: how to avoid shooting yourself in the foot]]></title>
            <link>https:/frontarm.com/daishi-kato/use-ref-in-concurrent-mode/</link>
            <guid>https:/frontarm.com/daishi-kato/use-ref-in-concurrent-mode/</guid>
            <pubDate>Tue, 05 Mar 2019 00:00:00 GMT</pubDate>
            <description><![CDATA[React's eaglerly awaited Concurrent Mode can vastly improve user experience, but it requires a stricter way of writing components.]]></description>
            <content:encoded><![CDATA[<div class="doc-wrapper doc-Doc-18aNW doc-align-center-when-narrow-2ypbP "><div class="doc-AsideTop-1wzdz "><p>According to the <a target="_blank" class=" " href="https://reactjs.org/blog/2018/11/27/react-16-roadmap.html">React 16 Roadmap</a>, Concurrent Mode is just over the horizon. Expected to arrive in Q2 2019, here’s what Dan Abramov has to say about Concurrent Mode:</p><blockquote><p>Concurrent Mode lets React apps be more responsive by rendering component trees without blocking the main thread. It is opt-in and allows React to interrupt a long-running render (for example, rendering a new feed story) to handle a high-priority event (for example, text input or hover). Concurrent Mode also improves the user experience of Suspense by skipping unnecessary loading states on fast connections.</p></blockquote><p>While Concurrent Mode is an opt-in feature, enabling it will be simple: just wrap part of your app with a <code>&lt;ConcurrentMode&gt;</code> element:</p><pre class="language-jsx"><code>&lt;ConcurrentMode&gt;
  &lt;Something /&gt;
&lt;/ConcurrentMode&gt;
</code></pre><aside class="doc-Aside-QiMiD "><aside class="doc-Block-3i__D  doc-Details "><header></header><p>ConcurrentMode is already available to try out under <code>&lt;React.unstable_ConcurrentMode&gt;</code>.</p></aside></aside></div><p>But be aware: if your app uses <code>useRef()</code> the wrong way, then Concurrent Mode won’t work correctly. In fact, your <em>entire app</em> won’t work correctly. So to help you prepare, this short article compares some bad code with a good version, and then discusses what you can do to prepare right now.</p><h2 id="the-bad-code"><a class="doc-headingLink  " href="#the-bad-code">#</a>The bad code</h2><blockquote><p>Your render function should be side-effect free.</p></blockquote><p>So it has always been the case that your rendering your component shouldn’t have any side effects, but it hadn’t really been an issue until Concurrent Mode appeared on the scene. In Concurrent Mode, render functions can be invoked multiple times without actually committing (meaning, for example, applying changes to the DOM).</p><p>For example, here’s a simple counter that uses <code>useRef()</code>.</p><aside class="doc-Aside-QiMiD "><aside class="doc-Block-3i__D  doc-Details "><header></header><p>This example is a little contrived — in practice, you’d probably use <code>useState()</code> for a counter. But the example demonstrates the issue well.</p></aside></aside><pre class="language-jsx"><code>import React, { useRef } from &quot;react&quot;;

const BadCounter = () =&gt; {
  const count = useRef(0);
  count.current += 1;
  return &lt;div&gt;count:{count.current}&lt;/div&gt;;
};

export default BadCounter;
</code></pre><p>The above example works as expected in traditional React where the render phase and the commit phase is one-to-one. However, if React invokes the render function multiple time without committing, the counter will increase unexpectedly.</p><h2 id="the-good-code"><a class="doc-headingLink  " href="#the-good-code">#</a>The good code</h2><br/><pre class="language-jsx"><code>import React, { useEffect, useRef } from &quot;react&quot;;

const GoodCounter = () =&gt; {
  const count = useRef(0);
  let currentCount = count.current;
  useEffect(() =&gt; {
    count.current = currentCount;
  });
  currentCount += 1;
  return &lt;div&gt;count:{currentCount}&lt;/div&gt;;
};

export default GoodCounter;
</code></pre><p>This version uses <code>useEffect()</code>, whose argument function is only invoked in the commit phase. <code>currentCount</code> is a local variable within the render function scope, so it will only change the ref count in the commit phase. The ref  is essentially a global variable outside the function scope, hence modifying it is a side effect.</p><h2 id="the-demo"><a class="doc-headingLink  " href="#the-demo">#</a>The demo</h2><pre class="language-text"><code>import React, { useRef } from &quot;react&quot;;

const BadCounter = () =&gt; {
  const count = useRef(0);
  count.current += 1;
  return &lt;div&gt;count:{count.current}&lt;/div&gt;;
};

export default BadCounter;
</code></pre><h2 id="preparing-for-the-future"><a class="doc-headingLink  " href="#preparing-for-the-future">#</a>Preparing for the future</h2><p>The thing about the <em>bad</em> counter in the above example is that it works, <em>until</em> you put it into a <code>&lt;ConcurrentMode&gt;</code>. So how do you know if your code is <em>good</em>?</p><p>This is where React’s <code>&lt;StrictMode&gt;</code> component comes in. Strict Mode intentionally invokes render functions twice, letting you find incorrect behavior during development. And <code>&lt;StrictMode&gt;</code> is available right now. For more details, see to <a target="_blank" class=" " href="https://reactjs.org/docs/strict-mode.html#detecting-unexpected-side-effects">the docs</a>.</p><p>Finally, let me tell you a little about why I wrote this article in the first place. The reason that I’m using <code>useRef()</code> is to develop a bindings library for Redux, called <a target="_blank" class=" " href="https://github.com/dai-shi/react-hooks-easy-redux">react-hooks-easy-redux</a>. The library must subscribe to the global store, and update the component state whenever the store’s state is updated. Refs are used to keep track of the last rendered state — I’ve made sure that they work with <code>&lt;ConcurrentMode&gt;</code>, and I’d like to share what I learned while doing so.
</p></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Creating a react-redux alternative with Hooks and Proxies]]></title>
            <link>https:/frontarm.com/daishi-kato/redux-custom-hooks/</link>
            <guid>https:/frontarm.com/daishi-kato/redux-custom-hooks/</guid>
            <pubDate>Mon, 25 Feb 2019 00:00:00 GMT</pubDate>
            <description><![CDATA[Create a simple React/Redux integration with Hooks, then improve its performance with Proxies.]]></description>
            <content:encoded><![CDATA[<div class="doc-wrapper doc-Doc-18aNW doc-align-center-when-narrow-2ypbP "><div class="doc-AsideTop-1wzdz "><p>Ever since I first learned Redux, I’ve been thinking about alternative ways to integrate it with React. My intuition was that Redux is super simple (which I like a lot), whereas react-redux’s performance optimizations make it complex. And while I’d still recommend that you use the official <a target="_blank" class=" " href="https://github.com/reduxjs/react-redux">react-redux</a> library for business products, if you’re playing with a toy app or you’re just starting to learn Redux, then you might want something more straightforward.</p><p>The React team recently introduced the new Hooks API, allowing for the use of stateful logic in function components. In particular, this allows for custom hooks — reusable chunks of state management logic. As a result, there have been many discussions about how to create hooks-based React bindings for Redux, and many proposals that would replace Redux completely, including <a target="_blank" class=" " href="https://itnext.io/an-alternative-to-react-redux-by-react-hooks-api-for-both-javascript-and-typescript-c5e9a351ba0b">mine</a>.</p><p>But today, I’ll discuss something simpler: instead of replacing Redux, I’ll demonstrate how to develop custom hooks <em>for</em> Redux in a straightforward way. I’ll first describe a naive implementation, and later introduce a <code>Proxy</code>-based approach that seamlessly improves performance.</p><aside class="doc-Aside-QiMiD "><aside class="doc-Block-3i__D  doc-Details "><header>Why not just use <code>useReducer</code>?</header><p>Redux is more than just a Reducer — it also supports middleware, and has excellent Dev Tools.</p></aside></aside></div><h2 id="a-naive-implementation"><a class="doc-headingLink  " href="#a-naive-implementation">#</a>A naive implementation</h2><p>Let’s start with a naive implementation. If you are not familiar with the Context and Hooks APIs, please visit the <a target="_blank" class=" " href="https://reactjs.org/docs/context.html">official</a> <a target="_blank" class=" " href="https://reactjs.org/docs/hooks-intro.html">docs</a> to learn them first. The rest of this article assumes a basic understanding of them.</p><p>First, let’s create a single context that can pass around a Redux store.</p><pre class="language-jsx"><code>const ReduxStoreContext = React.createContext();

const ReduxProvider = ({ store, children }) =&gt; (
  &lt;ReduxStoreContext.Provider value={store}&gt;
    {children}
  &lt;/ReduxStoreContext.Provider&gt;
);
</code></pre><p>We then define two hooks: <code>useReduxDispatch()</code> and <code>useReduxState()</code>. The reason we have two separate hooks is that not all components will use both hooks at the same time, and we want to hide the usage of context within the implementation.</p><p>Incidentally, the implementation of <code>useReduxDispatch()</code> is very simple.</p><pre class="language-jsx"><code>const useReduxDispatch = () =&gt; {
  const store = useContext(ReduxStoreContext);
  return store.dispatch;
};
</code></pre><p>The naive implementation of <code>useReduxState()</code> is a little more complex, and uses four hooks: <code>useContext()</code>, <code>useRef()</code>, <code>useEffect()</code> and <code>useForceUpdate()</code>.</p><pre class="language-jsx"><code>const useReduxState = () =&gt; { 
  const forceUpdate = useForceUpdate();
  const store = useContext(ReduxStoreContext);
  const state = useRef(store.getState());
  useEffect(() =&gt; {
    const callback = () =&gt; {
      state.current = store.getState();
      forceUpdate();
    };
    const unsubscribe = store.subscribe(callback);
    return unsubscribe;
  }, []);
  return state.current;
};
</code></pre><p>Basically, we just subscribe to any changes in the Redux store’s state. (A minor note: this doesn’t support changing the store on the fly, which may be important for testing.)</p><p>We can then implement <code>useForceUpdate()</code> as below.</p><div class="doc-AsideTop-1wzdz "><pre class="language-jsx"><code>const forcedReducer = state =&gt; !state;
const useForceUpdate = () =&gt; useReducer(forcedReducer, false)[1];
</code></pre><aside class="doc-Aside-QiMiD "><aside class="doc-Block-3i__D  doc-Details "><header></header><p>There’s an interesting <a target="_blank" class=" " href="https://github.com/facebook/react/issues/14110#issuecomment-446845886">discussion</a> that goes into the details for why you’d implement <code>useForceUpdate</code> this way.</p></aside></aside></div><h2 id="a-usage-example"><a class="doc-headingLink  " href="#a-usage-example">#</a>A usage example</h2><p>So how would you use <code>useReduxState()</code>, <code>useReduxDispatch()</code> and <code>&lt;ReduxProvider&gt;</code>? Take a look at this simple example to find out.</p><pre class="language-text"><code>import React, { useCallback } from &#x27;react&#x27;;
import store from &#x27;./store&#x27;;
import { ReduxProvider, useReduxState, useReduxDispatch } from &#x27;./redux-bindings&#x27;;

const App = () =&gt; (
  &lt;ReduxProvider store={store}&gt;
    &lt;Counter /&gt;
    &lt;TextBox /&gt;
  &lt;/ReduxProvider&gt;
);

const Counter = () =&gt; {
  const state = useReduxState();
  const dispatch = useReduxDispatch();
  const inc = useCallback(() =&gt; dispatch({ type: &#x27;inc&#x27; }), []);
  return (
    &lt;div&gt;
      &lt;div&gt;Count: {state.count}&lt;/div&gt;
      &lt;button onClick={inc}&gt;+1&lt;/button&gt;
    &lt;/div&gt;
  );
};

const TextBox = () =&gt; {
  const state = useReduxState();
  const dispatch = useReduxDispatch();
  const setText = useCallback(event =&gt; dispatch({
    type: &#x27;setText&#x27;,
    text: event.target.value,
  }), []);
  return (
    &lt;div&gt;
      &lt;div&gt;Text: {state.text}&lt;/div&gt;
      &lt;input value={state.text} onChange={setText} /&gt;
    &lt;/div&gt;
  );
};

export default App;</code></pre><p>If you are familiar with Redux and react-redux, then you’ll probably notice some issues with the above example.</p><p>To start with, if you click the <em>+1</em> button, not only does it re-render the Counter component — it <em>also</em> re-renders the TextBox component. Well, this is not a problem until it is a problem. For small apps, it works just fine. But for larger apps, it may cause problems with performance.</p><p>Really, we’d like to avoid unnecessary rendering if possible. If you were using react-redux, you might supply <code>connect()</code> with a <a target="_blank" class=" " href="https://react-redux.js.org/api/connect#mapstatetoprops-state-ownprops-object"><code>mapStateToProps</code></a> function to achieve this:</p><pre class="language-jsx"><code>mapStateToProps: (state, ownProps?) =&gt; Object
</code></pre><p><code>mapStateToProps</code> allows you to specify which part of the state will be used by a component. But actually defining it is a lot of extra work, and can be troublesome in some cases. It’s easy to add heavy computations in such functions, and I’ve found that beginners have trouble optimizing this due to lack of familiarity with memoization.</p><p>But what if you don’t <em>need</em> to specify a <code>mapStateToProps</code> function? What if you can use <code>Proxy</code> instead?</p><h2 id="improving-usereduxstate-with-proxy"><a class="doc-headingLink  " href="#improving-usereduxstate-with-proxy">#</a>Improving <code>useReduxState()</code> with <code>Proxy</code></h2><p>JavaScript’s new <code>Proxy</code> object makes it possible to automatically detect which part of the state is used during rendering. Then when your component is notified of a new <code>state</code>, it will know if the relevant part has changed, and can re-render only when necessary.</p><p>Let’s modify our <code>useReduxState()</code> hook to implement this feature. For now, we’ll only worry about the first level of the state object (and we’ll ignore state that is deep in the object tree).</p><div class="doc-AsideTop-1wzdz "><pre class="language-jsx"><code>const useReduxState = () =&gt; { 
  const forceUpdate = useForceUpdate();
  const store = useContext(ReduxStoreContext);
  const state = useRef(store.getState());
  const used = useRef({});
  const handler = useMemo(() =&gt; ({
    get: (target, name) =&gt; {
      used.current[name] = true;
      return target[name];
    },
  }), []);
  useEffect(() =&gt; {
    const callback = () =&gt; {
      const nextState = store.getState();
      const changed = Object.keys(used.current)
        .find(key =&gt; state.current[key] !== nextState[key]);
      if (changed) {
        state.current = nextState;
        forceUpdate();
      }
    };
    const unsubscribe = store.subscribe(callback);
    return unsubscribe;
  }, []);
  return new Proxy(state.current, handler);
};
</code></pre><aside class="doc-Aside-QiMiD "><aside class="doc-Block-3i__D  doc-Details "><header></header><p>Want to try out this code? You can edit it into the above editor’s <code>redux-bindings.js</code> file!</p></aside></aside></div><p>Now, the TextBox will not be re-rendered when you click <em>+1</em>, and vice versa.</p><p>This implementation is somewhat limited, and you might think that the shallow comparison is not enough. Indeed, if you already have a concrete design for your state structure, then that may be the case. However, if you start designing a new state structure, you could design it with first-level separation in mind. Also, note that for complex structures where you would need <code>reselect</code> with react-redux, you could use <code>useMemo()</code> in a function component so that it returns a memoized element.</p><h2 id="the-library"><a class="doc-headingLink  " href="#the-library">#</a>The library</h2><p>As it happens, I’ve developed a library called <em>react-hooks-easy-redux</em> that takes this approach. This library actually allows deep comparison thanks to <a target="_blank" class=" " href="https://www.npmjs.com/package/proxyequal">proxyequal</a>. (Still, the shallow comparison described in the previous section may work better in some use cases.)</p><p><a target="_blank" class=" " href="https://github.com/dai-shi/react-hooks-easy-redux"><strong>View react-hooks-easy-redux at GitHub »</strong></a></p><p>The repository contains <a target="_blank" class=" " href="https://codesandbox.io/s/github/dai-shi/react-hooks-easy-redux/tree/master/examples/02_typescript?module=%2Fsrc%2FCounter.tsx&amp;view=preview">several examples</a> — here’s one that you can play with as a live Demoboard:</p><pre class="language-text"><code>import * as React from &#x27;react&#x27;
import { useReduxDispatch, useReduxState } from &#x27;react-hooks-easy-redux&#x27;
import { Action, State } from &#x27;./state&#x27;

const Counter = () =&gt; {
  const state = useReduxState();
  const dispatch = useReduxDispatch();
  return (
    &lt;div&gt;
      {Math.random()}
      &lt;div&gt;
        &lt;span&gt;Count: {state.counter}&lt;/span&gt;
        &lt;button type=&quot;button&quot; onClick={() =&gt; dispatch({ type: &#x27;increment&#x27; })}&gt;+1&lt;/button&gt;
        &lt;button type=&quot;button&quot; onClick={() =&gt; dispatch({ type: &#x27;decrement&#x27; })}&gt;-1&lt;/button&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  );
};

export default Counter;
</code></pre><h2 id="final-notes"><a class="doc-headingLink  " href="#final-notes">#</a>Final notes</h2><p>There could be some edge cases where this approach or the library doesn’t work well. I would love to hear your feedback either by <a target="_blank" class=" " href="https://twitter.com/dai_shi">Twitter</a>, or <a target="_blank" class=" " href="https://github.com/dai-shi/react-hooks-easy-redux/issues">GitHub issues</a>.</p><p>The official react-redux also has a discussion about the Proxy approach. The possibility remains open that they might implement it in the future. <small>Would be nice.</small></p></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[From React Hooks to... Render Props?]]></title>
            <link>https:/frontarm.com/james-k-nelson/hooks-vs-render-props/</link>
            <guid>https:/frontarm.com/james-k-nelson/hooks-vs-render-props/</guid>
            <pubDate>Fri, 22 Feb 2019 00:00:00 GMT</pubDate>
            <description><![CDATA[Even old-school class components allow you to compose component state. Hooks just make your life far, far simpler.]]></description>
            <content:encoded><![CDATA[<div class="doc-wrapper doc-Doc-18aNW doc-align-center-when-narrow-2ypbP "><p>If you’ve been following the news about React lately, then you’ve probably heard about hooks. There’s been a <em>lot</em> of excitement about what you can build with them, and rightly so. Just take a look at all the interesting recipes on <a target="_blank" class=" " href="https://usehooks.com/">Gabe Ragland’s list</a>.</p><p>So hooks are great. But what if I told you that everything on that list can be built <em>without</em> hooks? Would it still be worth learning them?</p><h2 id="hooks-are-like-render-props"><a class="doc-headingLink  " href="#hooks-are-like-render-props">#</a>Hooks are like Render Props</h2><p>If you’ve played with hooks, then you’ve probably discovered that they’re <a class=" " href="/james-k-nelson/usecontext-react-hook/">great for consuming context</a>. To do so, you just use the <code>useContext()</code> hook:</p><pre class="language-jsx"><code>let IsStatic = React.createContext()

function HideDuringStaticRendering({ children }) {
  let isStatic = React.useContext(IsStatic)  return isStatic ? null : children
}
</code></pre><p>Of course, it’s also possible to consume context using <a target="_blank" class=" " href="https://reactjs.org/docs/render-props.html">render props</a>:</p><pre class="language-jsx"><code>function HideDuringStaticRendering({ children }) {
  return (
    &lt;IsStatic.Consumer&gt;      {isStatic =&gt; isStatic ? null : children}    &lt;/IsStatic.Consumer&gt;  )
}
</code></pre><p>As it happens, it’s actually possible to implement almost <em>any</em> hook as a component that takes a render prop. But is the converse true? <strong>Can hooks replace render props?</strong></p><p>Have a little think about this, then click below to see my answer.</p><section class="doc-Block-3i__D  doc-Spoiler "><header>Spoiler</header><p>Hooks can replace <em>some</em> render props, but not <em>all</em> of them.</p><p>Hooks can’t render anything, they can’t set values on context (even though they can consume values), and they can’t implement error boundaries. Given these limitations, you may still find yourself using render props from time to time.</p></section><h2 id="why-hooks"><a class="doc-headingLink  " href="#why-hooks">#</a>Why Hooks?</h2><p>If render props are more flexible than hooks, and have been around for all this time, then why are people so suddenly excited about hooks?</p><p>To answer this, let’s do something a little odd, and reimplement a <em>hooks</em>-based demo with <em>render props</em>.</p><p>Here’s the demo. It’s pretty simple; it just renders some randomly updating data, and performs a row highlight animation after each update — using hooks.</p><pre class="language-text"><code>import React, { useEffect } from &#x27;react&#x27;
import { useData, useDidChange, useLastValue, useTimedToggle } from &#x27;./hooks&#x27;
import { StyledTableRow } from &#x27;./styled&#x27;

function TableRow({ id }) {
  let data = useData(id)
  let last = useLastValue(data)
  let didChange = useDidChange(data)
  let [isHighlighted, highlight] = useTimedToggle(500)

  useEffect(() =&gt; {
    if (didChange) {
      highlight()
    }
  })
  
  let change = last &amp;&amp; (last.price &gt; data.price ? &#x27;down&#x27; : &#x27;up&#x27;)
  
  return (
    &lt;StyledTableRow
      data={data}
      change={isHighlighted &amp;&amp; change}
    /&gt;
  )
}

export default TableRow
</code></pre><p>So how would you implement this demo <em>without</em> hooks? To start, you could reimplement the <code>useData</code> and <code>useTimedToggle</code> hooks as components that accept a render prop, passing their values out as children — just as React’s context consumer component works.</p><pre class="language-jsx"><code>function TableRow({ id }) {
  return (
    &lt;Data id={id} children={data =&gt;
      &lt;TimedToggle
        milliseconds={500}
        children={([isHighlighted, highlight]) =&gt;
          &quot;...&quot;
        }
      /&gt;
    } /&gt;
  )
}
</code></pre><p>As for the <code>useDidChange()</code>, <code>useLastValue()</code> and <code>useEffect()</code>, how would you implement those? Why not give it a try yourself as an exercise!</p><p><strong>Your task is to complete the row highlight animation using render props, so that the below example behaves identically to the above example.</strong></p><p>I’ve provided you with <code>Data</code> and <code>TimedToggle</code> components, you just need to finish off the highlight-on-change functionality. If you get stuck, you can check your answer by clicking on the “solution” button at the bottom of the editor. But please do make sure to give it a go before continuing!</p><pre class="language-text"><code>import React from &#x27;react&#x27;
import { Data, TimedToggle } from &#x27;./controllers&#x27;
import { StyledTableRow } from &#x27;./styled&#x27;

function TableRow({ id }) {
  return (
    &lt;Data id={id} children={data =&gt;
      &lt;TimedToggle
        milliseconds={500}
        children={([isHighlighted, highlight]) =&gt;
          &lt;StyledTableRow isHighlighted={isHighlighted} data={data} /&gt;
        }
      /&gt;
    } /&gt;
  )
}

export default TableRow
</code></pre><p>How’d you go?</p><p>Depending on your experience with React, this exercise may be quite easy, or may feel impossible. In fact, there are a couple ways that you could answer it. But whatever approach you take, it’s going to be a pain-in-the-arse.</p><p><strong>The problem with the above exercise is that you need to react to changes to a value passed via render prop.</strong></p><p>In non-hooks React, reacting to changes is usually accomplished by use of the <code>componentDidUpdate()</code> lifecycle method. But <code>componentDidUpdate()</code> only knows about props and state. It doesn’t know about any values received via render prop. And so typically, if you need to watch a render function’s arguments, you’d pass them to a nested component and watch them there.</p><pre class="language-jsx"><code>function TableRow({ id }) {
  return (
    &lt;Data id={id} children={data =&gt;
      &lt;TimedToggle
        milliseconds={500}
        children={([isHighlighted, highlight]) =&gt;
          &lt;InnerTableRow
            data={data}            highlight={highlight}
            isHighlighted={isHighlighted}
          /&gt;
        }
      /&gt;
    } /&gt;
  )
}

class InnerTableRow extends React.Component {
  state = {
    lastChange: null,
  }

  render() {
    return (
      &lt;StyledTableRow
        data={this.props.data}
        change={this.props.isHighlighted &amp;&amp; this.state.lastChange}
      /&gt;
    )
  }

  componentDidUpdate(prevProps) {
    if (prevProps.data &amp;&amp; prevProps.data !== this.props.data) {      this.props.highlight()
      this.setState({
        lastChange:
          prevProps.data.price &gt; this.props.data.price
            ? &#x27;down&#x27;
            : &#x27;up&#x27;
      })
    }
  }
}
</code></pre><p>Creating a separate component <em>works</em>, but it is a verifiable pain-in-the-arse. <em>Hooks solve all that.</em></p><p>If I was to make a terrible analogy, I’d tell you that the transition from render props to hooks feels a lot like the transition from callbacks to promises. It lets you accomplish the same thing, but you can put more in a single function. <strong>Hooks flatten things out.</strong></p><p>So here’s the thing. React components are composable — with or without hooks. <strong>But with hooks, composing state and reactions to that state becomes far, far simpler.</strong> And that’s why you’re probably going to be using a darn lot of hooks in the not too distant future (if you’re not already, that is!)</p><p>If you need to learn more about hooks? Check out the <a target="_blank" class=" " href="https://reactjs.org/docs/hooks-intro.html">React
Hooks documentation</a>. It’s first class. Or if you’d prefer to learn with live examples and exercises like the ones above, then you may want to join my weekly newsletter to receive more articles like this — just <a class=" " href="/members/login/">login with GitHub or e-mail</a> to do so.</p><p>That’s it for me today. If you have any questions or comments, let me know on twitter at <a target="_blank" class=" " href="https://twitter.com/james_k_nelson">@james_k_nelson</a> or via email at <a class=" " href="mailto:james@frontarm.com">james@frontarm.com</a>. But until next time, happy coding!</p></div>]]></content:encoded>
            <author>james@jamesknelson.com (James K Nelson)</author>
        </item>
        <item>
            <title><![CDATA[A React Router with Hooks and Suspense]]></title>
            <link>https:/frontarm.com/james-k-nelson/navi-react-router-hooks-suspense/</link>
            <guid>https:/frontarm.com/james-k-nelson/navi-react-router-hooks-suspense/</guid>
            <pubDate>Mon, 18 Feb 2019 00:00:00 GMT</pubDate>
            <description><![CDATA[Navi is a new kind of router for React, that lets you declaratively map URLs to (possibly asynchronous) content.]]></description>
            <content:encoded><![CDATA[<div class="doc-wrapper doc-Doc-18aNW doc-align-center-when-narrow-2ypbP "><div class="doc-AsideTop-1wzdz "><p>So the React team just released a new API called <em>Hooks</em>. It’s amazing. It lets you declaratively model state and side effects. You’ve probably read about it elsewhere on the internet, so I’m not going to tell you about hooks themselves, but…</p><p>With a new API comes new possibilities. And to cut to the chase, Navi’s new <code>&lt;Router&gt;</code> component uses Hooks and Suspense to make routing simpler than ever before. It makes all sorts of things possible — you can even add animated loading transitions in <em>just 3 lines of code</em>.</p><p>So how do you use these new superpowered hooks? We’ll get to that in a moment. But before we do, <em>what the hell is a <code>&lt;Router&gt;</code>?</em></p><aside class="doc-Aside-QiMiD "><aside class="doc-Block-3i__D  doc-Details "><header>TL;DR?</header><p>Asynchronous routing has never been this simple.</p><ul><li><a class=" " href="/navi/">View the docs »</a></li><li><a target="_blank" class=" " href="https://github.com/frontarm/navi">View the GitHub repo »</a></li></ul></aside></aside></div><h2 id="how-many-routes-could-abr--router-routes--route"><a class="doc-headingLink  " href="#how-many-routes-could-abr--router-routes--route">#</a>How many routes could a<br/> <code>&lt;Router routes /&gt;</code> route…</h2><div class="doc-AsideTop-1wzdz "><p>It can route as many as you’d like, because Navi lets you dynamically <code>import()</code> entire routing trees on demand. But <em>how</em>?</p><aside class="doc-Aside-QiMiD "><aside class="doc-Block-3i__D  doc-Details "><header></header><p>It could route <strong>over 9000</strong> routes…</p></aside></aside></div><p>The trick is in Navi’s method for declaring routes. For simple routes, you can just use Navi’s <code>mount()</code> and <code>route()</code> functions. But for heavier content, you can declare dependencies on asynchronous data and views using <code>async</code>/<code>await</code> — or you can even split out entire routing trees using <code>lazy()</code>.</p><pre class="language-jsx"><code>&lt;Router routes={
  mount({    &#x27;/&#x27;: route({      title: &#x27;My Shop&#x27;,
      getData: () =&gt; api.fetchProducts(),
      view: &lt;Landing /&gt;,
    }),
    &#x27;/products&#x27;: lazy(() =&gt; import(&#x27;./productsRoutes&#x27;)),  })
} /&gt;
</code></pre><p>If you take a look at this example, you’ll see that you’ve got yourself a <code>&lt;Router&gt;</code> with a couple routes, including a shop’s landing page and a lazily loadable <code>/products</code> URL.</p><p><em>Let’s build the rest of the shop.</em></p><p>For your next step, you’ll need to decide <em>where</em> to render the current route’s <code>view</code> element. And to do that, you just plonk down a <code>&lt;View /&gt;</code> element somewhere inside your <code>&lt;Router&gt;</code>.</p><pre class="language-jsx"><code>ReactDOM.render(
  &lt;Router routes={routes}&gt;
    &lt;Layout&gt;
      &lt;View /&gt;    &lt;/Layout&gt;
  &lt;/Router&gt;,
  document.getElementById(&#x27;root&#x27;)
)
</code></pre><div class="doc-AsideTop-1wzdz "><p>Simple, huh? But waaait a minute… what if you view the lazily loadable <code>/products</code> URL? Then the route will be loaded via an <code>import()</code>, which returns a Promise, and so at first there’ll be nothing to render. Luckily, React’s new <a target="_blank" class=" " href="https://reactjs.org/docs/react-api.html#reactsuspense"><code>&lt;Suspense&gt;</code></a> feature lets you declaratively wait for promises to resolve. So just wrap your <code>&lt;View&gt;</code> in a <code>&lt;Suspense&gt;</code> tag, and you’re off and racing!</p><pre class="language-text"><code>import { mount, route, lazy } from &#x27;navi&#x27;
import React, { Suspense } from &#x27;react&#x27;
import ReactDOM from &#x27;react-dom&#x27;
import { Router, View } from &#x27;react-navi&#x27;
import api from &#x27;./api&#x27;
import Landing from &#x27;./Landing&#x27;
import Layout from &#x27;./Layout&#x27;

const routes =
  mount({
    &#x27;/&#x27;: route({
      title: &quot;Hats &#x27;n&#x27; Flamethrowers &#x27;r&#x27; Us&quot;,
      getData: () =&gt; api.fetchProducts(),
      view: &lt;Landing /&gt;,
    }),
    &#x27;/product&#x27;: lazy(() =&gt; import(&#x27;./product&#x27;)),
  })

ReactDOM.render(
  &lt;Router routes={routes}&gt;
    &lt;Layout&gt;
      &lt;Suspense fallback={null}&gt;
        &lt;View /&gt;
      &lt;/Suspense&gt;
    &lt;/Layout&gt;
  &lt;/Router&gt;,
  document.getElementById(&#x27;root&#x27;)
)</code></pre><aside class="doc-Aside-QiMiD "><aside class="doc-Block-3i__D  doc-Details "><header>Isn&#x27;t <code>&lt;View&gt;</code> part of react-native?</header><p>It is! But react-native apps would be far better served by <a target="_blank" class=" " href="https://github.com/wix/react-native-navigation">react-native-navigation</a> or <a target="_blank" class=" " href="https://reactnavigation.org/">react-navigation</a> than by Navi.</p></aside></aside></div><h2 id="bro-just-give-me-the-hooks"><a class="doc-headingLink  " href="#bro-just-give-me-the-hooks">#</a>Bro, just give me the hooks?</h2><p>Ok, so you’ve seen how to render a route’s view. But did you notice that your route also defines a <code>getData()</code> function?</p><pre class="language-jsx"><code>route({
  title: &#x27;My Shop&#x27;,
  getData: () =&gt; api.fetch(&#x27;/products&#x27;),
  view: &lt;Landing /&gt;,
})
</code></pre><p><em>How do you access the data?</em> With React hooks!</p><p>Navi’s <code>useCurrentRoute()</code> hook can be called from any function component that is rendered within the <code>&lt;Router&gt;</code> tag. It returns a <a class=" " href="/navi/en/reference/data-types/#route"><code>Route</code></a> object that contains everything that Navi knows about the current URL.</p><pre class="language-text"><code>import React from &#x27;react&#x27;
import { Link, useCurrentRoute } from &#x27;react-navi&#x27;

export default function Landing() {
  // useCurrentRoute returns the lastest loaded Route object
  let route = useCurrentRoute()
  let data = route.data
  let productIds = Object.keys(data)

  console.log(&#x27;views&#x27;, route.views)
  console.log(&#x27;url&#x27;, route.url)
  console.log(&#x27;data&#x27;, route.data)
  console.log(&#x27;status&#x27;, route.status)
  
  return (
    &lt;ul&gt;
      {productIds.map(id =&gt; 
        &lt;li key={id}&gt;
          &lt;Link href={`/product/${id}`}&gt;{data[id].title}&lt;/Link&gt;
        &lt;/li&gt;
      )}
    &lt;/ul&gt;
  )
}
</code></pre><p>Ok. So far, so good. But imagine that you’ve just clicked a link to <code>/products</code> — which is dynamically imported. It’s going to take some time to fetch the route, so what are you going to display in the meantime?</p><h2 id="visualizing-loading-routes"><a class="doc-headingLink  " href="#visualizing-loading-routes">#</a>Visualizing loading routes</h2><p>When routes take a long time to load, you’ll want to display some sort of loading indicator to the user — and there a number of approaches that you <em>could</em> take. One option would be to show a fallback with <code>&lt;Suspense&gt;</code>, just as with the initial load. But this looks a bit shit.</p><img src="/static/media/suspense-loading.6edec3cf.gif" alt="terrible looking loading" style="border:1px solid #f0f0f0;border-radius:1rem"/><aside class="doc-Aside-QiMiD "><aside class="doc-Block-3i__D  doc-Details "><header></header><p>Suspense should improve with time, and there are already plans to improve support for cases like this. The caveat is that it <a target="_blank" class=" " href="https://reactjs.org/blog/2018/11/27/react-16-roadmap.html#suspense-for-server-rendering">could be a while</a> before it works on the server.</p></aside></aside><p>What you’d <em>really</em> like to do is to display a loading bar over the current page while the next route loads… well, unless the transition only takes 100ms. Then you probably just want to keep displaying the current page until the next one is ready, because showing a loading bar for only 100ms also looks a bit shit.</p><img src="/static/media/no-delay-loading.c22855b3.gif" alt="loading indicator with no delay" style="border:1px solid #f0f0f0;border-radius:1rem"/><p>There’s just one problem. Doing this with currently available tools is ridiculously hard, right? Well actually… You can add it to the above demo in just 3 lines of code, using the <code>useLoadingRoute()</code> hook and the <code>react-busy-indicator</code> package.</p><pre class="language-text"><code>import BusyIndicator from &#x27;react-busy-indicator@1.0.0&#x27;
import React from &#x27;react&#x27;
import { Link, useLoadingRoute } from &#x27;react-navi&#x27;

export default function Layout({ children }) {
  // If there is a route that hasn&#x27;t finished loading, it can be
  // retrieved with `useLoadingRoute()`.
  let loadingRoute = useLoadingRoute()

  return (
    &lt;div className=&quot;Layout&quot;&gt;
      {/* This component shows a loading indicator after a delay */}
      &lt;BusyIndicator isBusy={!!loadingRoute} delayMs={200} /&gt;
      &lt;header className=&quot;Layout-header&quot;&gt;
        &lt;h1 className=&quot;Layout-title&quot;&gt;
        &lt;Link href=&#x27;/&#x27; prefetch={null}&gt;
          Hats &#x27;n&#x27; Flamethrowers &#x27;r&#x27; Us
        &lt;/Link&gt;
        &lt;/h1&gt;
      &lt;/header&gt;
      &lt;main&gt;
        {children}
      &lt;/main&gt;
    &lt;/div&gt;
  )
}
</code></pre><p>Go ahead and try clicking between these pages a few times. Did you notice how smooth the transition back to the index page is? No? It was so smooth that you didn’t notice that there’s actually a 100ms delay? Great! <em>That’s exactly the experience that your users want.</em></p><p>Here’s how it works: <code>useCurrentRoute()</code> returns the most recent <em>completely loaded</em> route. And <code>useLoadingRoute()</code> returns any requested-but-not-yet-completely-loaded route. Or if the user <em>hasn’t</em> just clicked a link, it returns <code>undefined</code>. </p><p>Want to display a loading bar while pages load? Then just call <code>useLoadingRoute()</code>, check if there’s a value, and render a loading bar if there is! CSS transitions let you do the rest.</p><h2 id="more-neat-tricks"><a class="doc-headingLink  " href="#more-neat-tricks">#</a>More neat tricks</h2><p>I’m not going to drop the entire set of <a class=" " href="/navi/en/guides/getting-started/">guides</a>, <a class=" " href="/navi/en/reference/react-components-hooks/">API reference</a>, and docs on <a class=" " href="/navi/en/integrations/react-router/">integrating with other tools</a> on you right now. You’re reading a blog post, so you might not have time for all that juicy information. But let me ask you a question:</p><p><em>What happens if the route </em>doesn’t<em> load?</em></p><p>One of the things about asynchronous data and views is that sometimes they <em>don’t bloody work</em>. Luckily, React has a great tool for dealing with things that don’t bloody work: Error Boundaries.</p><p>Let’s rewind for a moment to the <code>&lt;Suspense&gt;</code> tag that wraps your <code>&lt;View /&gt;</code>.  When <code>&lt;View /&gt;</code> encounters a not-yet-loaded route, it <em>throws a promise</em>, which effectively asks React to <em>please show the fallback for a moment</em>. You can imagine that <code>&lt;Suspense&gt;</code> catches that promise, and then re-renders its children once the promise resolves.</p><p>Similarly, if <code>&lt;View /&gt;</code> finds that <code>getView()</code> or <code>getData()</code> have thrown an error, then it re-throws that error. In fact, if the router encounters a 404-page-gone-for-a-long-stroll error, then <code>&lt;View /&gt;</code> will throw that, too. These errors can be caught by <a target="_blank" class=" " href="https://reactjs.org/docs/error-boundaries.html">Error Boundary</a> components. For the most part, you’ll need to make your own error boundaries, but Navi includes a <a class=" " href="/navi/en/reference/react-components-hooks/#notfoundboundary"><code>&lt;NotFoundBoundary&gt;</code></a> to show you how its done:</p><pre class="language-text"><code>import BusyIndicator from &#x27;react-busy-indicator@1.0.0&#x27;
import React from &#x27;react&#x27;
import { Link, NotFoundBoundary, useLoadingRoute } from &#x27;react-navi&#x27;

export default function Layout({ children }) {
  // If there is a route that hasn&#x27;t finished loading, it can be
  // retrieved with `useLoadingRoute()`.
  let loadingRoute = useLoadingRoute()

  return (
    &lt;div className=&quot;Layout&quot;&gt;
      {/* This component shows a loading indicator after a delay */}
      &lt;BusyIndicator isBusy={!!loadingRoute} delayMs={200} /&gt;
      &lt;header className=&quot;Layout-header&quot;&gt;
        &lt;h1 className=&quot;Layout-title&quot;&gt;
        &lt;Link href=&#x27;/&#x27;&gt;
          Hats &#x27;n&#x27; Flamethrowers &#x27;r&#x27; Us
        &lt;/Link&gt;
        &lt;/h1&gt;
      &lt;/header&gt;
      &lt;main&gt;
        &lt;NotFoundBoundary render={renderNotFound}&gt;
          {children}
        &lt;/NotFoundBoundary&gt;
      &lt;/main&gt;
    &lt;/div&gt;
  )
}

function renderNotFound() {
  return (
    &lt;div className=&#x27;Layout-error&#x27;&gt;
      &lt;h1&gt;404 - Not Found&lt;/h1&gt;
    &lt;/div&gt;
  )
}
</code></pre><h2 id="but-thats-not-all"><a class="doc-headingLink  " href="#but-thats-not-all">#</a>But that’s not all!</h2><p>Ok, so I think we’re about out of time for this blog post. But there’s a bunch more details in the docs:</p><ul><li><a class=" " href="/navi/en/guides/url-parameters/">Using URL Parameters</a></li><li><a class=" " href="/navi/en/guides/requests-routes-matchers/">Requests, Routes and Matchers</a></li><li><a class=" " href="/navi/en/guides/nested-views/">Nested Routes and Views</a></li><li><a class=" " href="/navi/en/guides/programmatic-navigation/">Programmatic navigation</a></li><li><a class=" " href="/navi/en/guides/authenticated-routes/">Guarding routes with authentication</a></li><li><a class=" " href="/navi/en/guides/static-rendering/">Improving SEO with static rendering</a></li><li><a class=" " href="/navi/en/integrations/react-router/">Using Navi with react-router</a></li><li><a class=" " href="/navi/en/integrations/react-helmet/">Using Navi with react-helmet</a></li><li><a class=" " href="/navi/en/create-react-navi-app/">Get a head start with a create-react-app based starter</a></li></ul><p>You can also check out the <a target="_blank" class=" " href="https://github.com/frontarm/navi/tree/master/examples">examples</a> directory of the Navi repository for full code examples, including:</p><ul><li><a target="_blank" class=" " href="https://github.com/frontarm/navi/tree/master/examples/basic">A basic site with create-react-app</a></li><li><a target="_blank" class=" " href="https://github.com/frontarm/navi/tree/master/examples/basic-static-rendering">A simple site with static rendering</a></li><li><a target="_blank" class=" " href="https://github.com/frontarm/navi/tree/master/examples/blog">A blog with tags, pagination and RSS</a></li><li><a target="_blank" class=" " href="https://github.com/frontarm/navi/tree/master/examples/blog-typescript">That same blog but written in TypeScript</a></li></ul><p>Oh, and did I mention that Navi is build with TypeScript, so the typings are first-class?</p><h2 id="help-me-obi-wan-kenobi-youre-my-only-hope"><a class="doc-headingLink  " href="#help-me-obi-wan-kenobi-youre-my-only-hope">#</a>Help me, Obi-Wan Kenobi. You’re my only hope.</h2><p>Ok, so even if you’re not Obi-Wan Kenobi, I’d really appreciate your help.</p><p>Actually, a lot of little things are way more helpful than they might seem. Can you try Navi out and file an issue for any missing features? <em>Awesome.</em> Can you make tiny improvements to the docs as you learn? <em>Radical.</em> Can you put something small online and add it to the <a target="_blank" class=" " href="https://github.com/frontarm/navi#whos-using-navi">README</a>&#x27;s list of sites using Navi? <em>Phenomenal.</em></p><p>With that said, there are a few big ticket items that I’d love some help with:</p><ul><li><p>Navi needs some dev tools. Internally, all data is represented as simple objects called <a class=" " href="/navi/en/reference/data-types/#chunk">Chunks</a> — which are then reduced into <code>Route</code> objects with a Redux-like reducer. As a result of this design, it should be possible for dev tools to provide a useful window into what’s going on, along with time-travel capability — but I want to leave this task for the community. So if <em>you</em> want to be the person who made Navi’s dev tools, let’s <a target="_blank" class=" " href="https://github.com/frontarm/navi/issues/52">discuss the details</a> 🤓</p></li><li><p>Matcher functions like <code>mount()</code>, <code>lazy()</code> and <code>route()</code> are just Generator Functions. In fact, it’s entirely possible to create <a class=" " href="/navi/en/reference/matchers/#custom-matchers">custom matchers</a>. For instance, you could create a <code>withTimeout()</code> matcher that switches routes based on how long they take to load. And if you <em>do</em> create useful custom matchers, send a tweet or DM to <a target="_blank" class=" " href="https://twitter.com/i/notifications">@james_k_nelson</a> so I can spread the word 🤩</p></li><li><p>If you can provide a translation for even a single page from the docs, I’ll be forever grateful ❤️</p></li><li><p>If you’d like to see this project grow, please give it a <a target="_blank" class=" " href="https://github.com/frontarm/navi">🌟Star on Github</a>!</p></li></ul><h2 id="one-more-thing"><a class="doc-headingLink  " href="#one-more-thing">#</a>One more thing…</h2><p>Navi now has experimental server rendering support. Matchers like <code>route()</code> and <code>mount()</code> have access to an entire <code>Request</code> object, including <code>method</code>, <code>headers</code>, and <code>body</code>. Your routes aren’t limited to matching just a <code>view</code> and <code>data</code> — they can also match a HTTP <code>status</code> and <code>headers</code>.</p><p><strong>You can now handle routing on the client, the server and in serverless functions with <em>exactly</em> the same code.</strong></p><p>Of course, you could already do some of this with <a target="_blank" class=" " href="https://nextjs.org/">Next.js</a> — but if all you need is a router, then Navi is a <em>lot</em> smaller (and more flexible). If you’d like to know more about the difference, take a read through <a class=" " href="/navi/en/comparisons/#navi-vs-nextjs">Navi vs. Next.js</a>. Or if you just want the server rendering demo: </p><pre class="language-text"><code>import { createMemoryNavigation, mount, route, lazy } from &#x27;navi&#x27;
import React, { Suspense } from &#x27;react&#x27;
import ReactDOMServer from &#x27;react-dom/server&#x27;
import { NaviProvider, View } from &#x27;react-navi&#x27;
import api from &#x27;./api&#x27;
import Landing from &#x27;./Landing&#x27;
import Layout from &#x27;./Layout&#x27;

async function main() {
  const routes =
    mount({
      &#x27;/&#x27;: route({
        title: &quot;Hats &#x27;n&#x27; Flamethrowers &#x27;r&#x27; Us&quot;,
        getData: (request) =&gt; {
          console.log(&#x27;headers&#x27;, request.headers)
          return api.fetchProducts()
        },
        view: &lt;Landing /&gt;,
        status: 200,
      }),
      &#x27;/product&#x27;: lazy(() =&gt; import(&#x27;./product&#x27;)),
    })

  // Creates a &quot;navigation&quot; object, which contains the same functionality
  // as the browser `&lt;Router&gt;` object, but handled in-memory.
  const navigation = createMemoryNavigation({
    routes,
    request: {
      headers: {
        &#x27;authorization-token&#x27;: &#x27;123&#x27;,
      },
      url: window.location.pathname
    }
  })

  // Wait for the navigation object to stabilise, so it can be rendered
  // immediately.
  await navigation.steady()

  console.log(&#x27;status&#x27;, navigation.getCurrentValue().status)

  // As `renderToString()` doesn&#x27;t support `&lt;Suspense&gt;`, instead of using
  // a `&lt;Router&gt;` with a `&lt;Suspense&gt;`, you&#x27;ll need to manually pass your
  // navigation object to a `&lt;NaviProvider&gt;` component.
  let html = ReactDOMServer.renderToString(
    &lt;NaviProvider navigation={navigation}&gt;
      &lt;Layout&gt;
        &lt;View /&gt;
      &lt;/Layout&gt;
    &lt;/NaviProvider&gt;
  )

  document.body.innerHTML = html
}

main()
</code></pre><p>As of right now, there’s no official package for integrating Navi with Express. There should be one. Please make one. I’ll tell the world about it.</p><p>But seriously, I <em>will</em> tell the world about anything you make with Navi. Here’s how I’ll do it: the Frontend Armory weekly newsletter. Want to hear about awesome React shit that other readers are making? Join it. You know you want to.</p><p><strong><a class=" " href="/members/register/">Join Frontend Armory for Free »</a></strong></p><p>But that’s it from me today. Thanks <em>so</em> much for reading. I’ve poured my heart into this project because I believe that it’ll make <em>your</em> life as a React developer so much easier. Now go build something amazing!</p><p><em>P.S. I haven’t forgotten about the React in Practice course — I’m working on it right now, and it’ll include hooks. I’ll have more more details real soon.</em></p><h2 id="related-links"><a class="doc-headingLink  " href="#related-links">#</a>Related Links</h2><ul><li><a class=" " href="/navi/">Navi’s Documentation</a></li><li><a target="_blank" class=" " href="https://github.com/frontarm/navi">Navi on GitHub</a></li><li><a target="_blank" class=" " href="https://twitter.com/james_k_nelson">Follow @james_k_nelson on Twitter</a></li></ul></div>]]></content:encoded>
            <author>james@jamesknelson.com (James K Nelson)</author>
        </item>
        <item>
            <title><![CDATA[useContext(): a React hook that's an obvious win]]></title>
            <link>https:/frontarm.com/james-k-nelson/usecontext-react-hook/</link>
            <guid>https:/frontarm.com/james-k-nelson/usecontext-react-hook/</guid>
            <pubDate>Wed, 06 Feb 2019 00:00:00 GMT</pubDate>
            <description><![CDATA[Don't let the hype around hooks fool you - useContext() is actually incredibly useful.]]></description>
            <content:encoded><![CDATA[<div class="doc-wrapper doc-Doc-18aNW doc-align-center-when-narrow-2ypbP "><div class="doc-AsideTop-1wzdz "><p>Earlier today, the React team released React 16.8, and along with it the eagerly awaited <strong>hooks</strong> API.</p><p>If you haven’t yet heard, React’s hooks API opens a up a whole new way of writing components - and the internet is abuzz with talk of the possibilities. Of course, with such a major change, many people are also asking the question: do we really need this new API?</p><p>In this article, I’m going to skip this question and instead try to answer something simpler and more useful: are there any situations where hooks are just <em>obviously better</em>? My answer is <em>yes</em>, and I think you’ll agree after seeing just how much <code>useContext</code> improves readability.</p><aside class="doc-Aside-QiMiD "><aside class="doc-Block-3i__D  doc-Details "><header></header><p>As of today, typing <code>import React from &#x27;react&#x27;</code> in Frontend Armory’s <a class=" " href="/demoboard/">Demoboard</a> will load React 16.8, with full hooks support!</p></aside></aside></div><h2 id="context-"><a class="doc-headingLink  " href="#context-">#</a>Context 😕</h2><p>Since React’s beginnings, one of the least satisfying parts of using it has been has been the process of passing data through many levels of your component tree. Initially, this could only be accomplished by <em>prop drilling</em>, i.e. manually passing props through every level of your tree. This was obviously cumbersome, so the React team give us an experimental Context API to work with, before releasing an official Context API early last year. The thing is, even the official Context API has its quirks.</p><p>After consuming data from a Context, you’ll typically only have access to the consumed data within a render function, as seen in this example.</p><pre class="language-text"><code>import React from &#x27;react&#x27;

const CurrentRoute = React.createContext({ path: &#x27;/welcome&#x27; })

export default function App() {
  return (
    &lt;CurrentRoute.Consumer&gt;
      {currentRoute =&gt; 
        currentRoute.path === &#x27;/welcome&#x27; &amp;&amp;
        &quot;Welcome!&quot;
      }
    &lt;/CurrentRoute.Consumer&gt;
  )
}
</code></pre><p>In the above example, only a single piece of data is being consumed. And honestly, this looks ok. It’s easy enough to understand what’s going on. But imagine for minute that you want to consume values from <em>three</em> Context objects:</p><pre class="language-text"><code>import React from &#x27;react&#x27;

const CurrentRoute = React.createContext({ path: &#x27;/welcome&#x27; })
const CurrentUser = React.createContext(undefined)
const IsStatic = React.createContext(false)

export default function App() {
  return (
    &lt;CurrentRoute.Consumer&gt;
      {currentRoute =&gt;
        &lt;CurrentUser.Consumer&gt;
          {currentUser =&gt;
            &lt;IsStatic.Consumer&gt;
              {isStatic =&gt;
                !isStatic &amp;&amp;
                currentRoute.path === &#x27;/welcome&#x27; &amp;&amp;
                (currentUser
                  ? `Welcome back, ${currentUser.name}!`
                  : &#x27;Welcome!&#x27;
                )
              }
            &lt;/IsStatic.Consumer&gt;
          }
        &lt;/CurrentUser.Consumer&gt;
      }
    &lt;/CurrentRoute.Consumer&gt;
  )
}
</code></pre><p>While this second example <em>works</em>, it’s starting to look unwieldy. You can see that there’s a callback pyramid starting to form – and the more context you consume, the worse it’s gonna get. Unless, that is, you use the new <code>useContext()</code> hook.</p><h2 id="usecontext-"><a class="doc-headingLink  " href="#usecontext-">#</a><code>useContext()</code> 😆</h2><p>Starting with React 16.8, you now have <code>useContext()</code>: a new, simpler way to consume data from multiple contexts. Here’s how you’d use it to simplify the above example:</p><pre class="language-text"><code>import React, { useContext } from &#x27;react&#x27;

const CurrentRoute = React.createContext({ path: &#x27;/welcome&#x27; })
const CurrentUser = React.createContext(undefined)
const IsStatic = React.createContext(false)

export default function App() {
  let currentRoute = useContext(CurrentRoute)
  let currentUser = useContext(CurrentUser)
  let isStatic = useContext(IsStatic)

  return (
    !isStatic &amp;&amp;
    currentRoute.path === &#x27;/welcome&#x27; &amp;&amp;
    (currentUser
      ? `Welcome back, ${currentUser.name}!`
      : &#x27;Welcome!&#x27;
    )
  )
}
</code></pre><p>Neat, huh? But before moving on, I want you to try and imagine something for a minute.</p><p><strong>Imagine that <em>both</em> of the above code examples are boring old APIs that you’ve been using for years.</strong></p><p>Have you gotten in that frame of mind? Great! So I want to ask you a question:</p><p><strong>Which API is clearer?</strong></p><p>To me, the answer seems obvious. The second example wins the readability contest <em>hands down</em>. To bring back an old React cliché - it’s much easier to reason about.</p><p>Ok, so let’s come back to the read world for a moment (thanks for going through this exercise with me!) It’s February 2019, and hooks are <em>brand spankin&#x27; new.</em> They’re a big change, and there’s going to be a lot of uncertainty around them. But you now have at least <em>one</em> solid answer: hooks are definitely an improvement for consuming context.</p><p>So the next question is, what else are hooks good for? I’m as keen to find out as you are, and I’ll be making sure to share what I learn on this blog. Don’t want to miss it? <a class=" " href="/members/register/">Join Frontend Armory</a> now to stay in the loop — it’s free!</p><p>In the meantime, if you’re interested in learning hooks then there’s a few resources you can check out:</p><ul><li>The <a target="_blank" class=" " href="https://reactjs.org/docs/hooks-intro.html">official hooks documentation</a> is incredibly informative, and I highly recommend you take a look.</li><li>For a tutorial with live editors, take a look at @swyx’s guide to <a class=" " href="/swyx/reusable-time-travel-react-hooks-immer/">Reusable Time Travel with React Hooks and Immer</a>.</li><li>If you’d like to see how <code>useContext()</code> can be used in real world code, take a look at <a target="_blank" class=" " href="https://github.com/frontarm/navi/blob/6a3fcb9834e9d3efb2e4178210817c06f2e2f535/examples/basic/src/App.js">this commit</a> for <a class=" " href="/navi/">Navi</a>, the router that drives Frontend Armory.</li></ul><p>Thanks so much for reading — it’s great to know that there are people like you who find this useful enough to read all the way to the end 😊 So until next time, happy engineering!</p></div>]]></content:encoded>
            <author>james@jamesknelson.com (James K Nelson)</author>
        </item>
        <item>
            <title><![CDATA[Will it finally: a try/catch quiz]]></title>
            <link>https:/frontarm.com/james-k-nelson/will-finally-run-quiz/</link>
            <guid>https:/frontarm.com/james-k-nelson/will-finally-run-quiz/</guid>
            <pubDate>Mon, 04 Feb 2019 00:00:00 GMT</pubDate>
            <description><![CDATA[You know try and catch, but how well do you know finally? Find out with 4 live examples.]]></description>
            <content:encoded><![CDATA[<div class="doc-wrapper doc-Doc-18aNW doc-align-center-when-narrow-2ypbP "><p>With the advent of <code>async</code>/<code>await</code>, I’ve recently found myself using a lot more <code>try</code>/<code>catch</code>/<code>finally</code> in my code. But honestly, I’m a little out of practice with <code>finally</code>. When I went to actually use it, I was a little unsure of its finer details. So I put together a few examples.</p><h2 id="when-you-throw-a-catch"><a class="doc-headingLink  " href="#when-you-throw-a-catch">#</a>When you <code>throw</code> a <code>catch</code></h2><p>Consider the case where you throw an exception <em>within</em> a <code>catch</code> block. There’s nothing to catch your <code>throw</code> before it exits the function. Does <code>finally</code> run?</p><p>To find out, just uncomment the <code>example()</code> call at the bottom of the editor!</p><pre class="language-text"><code>function example() {
  try {
    fail()
  }
  catch (e) {
    console.log(&quot;Will finally run?&quot;)
    throw e
  }
  finally {
    console.log(&quot;FINALLY RUNS!&quot;)
  }
  console.log(&quot;This shouldn&#x27;t be called eh?&quot;)
}

// example()
</code></pre><section class="doc-Block-3i__D  doc-Spoiler "><header>Spoiler</header><p>The finally runs, even though the last log statement doesn’t!</p><p>You can see that <code>finally</code> is a little special; it lets you run things between throwing an error and leaving the function, even if that error was thrown inside a <code>catch</code> block.</p></section><h2 id="try-without-catch"><a class="doc-headingLink  " href="#try-without-catch">#</a>Try without catch</h2><p>Did you know that if you supply a <code>finally</code> block, you don’t need to supply a <code>catch</code> block too? You probably did, but it was worth asking!</p><p>So next question: does that <code>finally</code> block get called even if nothing goes wrong in the <code>try</code> block? If you’re not sure, uncomment the <code>example()</code> at the bottom of the editor to find out.</p><pre class="language-text"><code>function example() {
  try {
    console.log(&quot;Hakuna matata&quot;)
  }
  finally {
    console.log(&quot;What a wonderful phrase!&quot;)
  }
}

// example()
</code></pre><section class="doc-Block-3i__D  doc-Spoiler "><header>Spoiler</header><p>Yep, <code>finally</code> is called even when nothing goes wrong. Of course, it also gets called when something <em>does</em> go wrong.</p><p>That’s the idea behind <code>finally</code> — it lets you handle both cases, as you can see in this example:</p></section><pre class="language-text"><code>function example() {
  try {
    console.log(&quot;I shall try and fail&quot;);
    fail();
  }
  catch (e) {
    console.log(&quot;Then be caught&quot;);
  }
  finally {
    console.log(&quot;And finally something?&quot;);
  }
}

// example()
</code></pre><h2 id="return-and-finally"><a class="doc-headingLink  " href="#return-and-finally">#</a>Return and finally</h2><p>So finally lets you clean up after yourself when exceptions occur. But what about when nothing goes wrong and you just <code>return</code> from the function like normal… in a <code>try</code> block?</p><p>Take a look at the below example. Is it possible that the <code>finally</code> block within <code>example()</code> can run <em>after</em> you’ve already hit a <code>return</code> statement? Uncomment the <code>example()</code> at the bottom of the editor to find out!</p><pre class="language-text"><code>function example() {
  try {
    console.log(&quot;I&#x27;m picking up my ball and going home.&quot;)
    return
  }
  finally {
    console.log(&#x27;Finally?&#x27;)
  }
}

// example()
</code></pre><h2 id="the-rule"><a class="doc-headingLink  " href="#the-rule">#</a>The Rule</h2><p><strong>The <code>finally</code> block on a <code>try</code>/<code>catch</code>/<code>finally</code> will <em>always</em> run</strong> — even if you bail early with an exception or a <code>return</code>.</p><p>This is what makes it so useful; it’s the perfect place to put code that <em>needs</em> to run regardless of what happens, like cleanup code for error-prone IO. In fact, that’s what inspired this article.</p><h2 id="i-used-finally-for"><a class="doc-headingLink  " href="#i-used-finally-for">#</a>I used <code>finally</code> for…</h2><p>Frontend Armory is a statically rendered website; it’s built with a tool called <a target="_blank" class=" " href="/navi/">Navi</a>, which lets you configure a <code>renderPageToString()</code> function that will be used to render each page.</p><p>In order to make sure each call to <code>renderPageToString()</code> is independent of the previous one, Navi uses <code>try</code>/<code>catch</code>/<code>finally</code> and some obscure node-fu to unload any modules that are loaded during the rendering process.</p><aside class="doc-Aside-QiMiD "><aside class="doc-Block-3i__D  doc-Details "><header></header><p>You can take a look at the <a target="_blank" class=" " href="https://github.com/frontarm/navi/tree/master/packages/navi-scripts/lib">full source</a> for Navi’s static renderer on GitHub</p></aside></aside><pre class="language-jsx"><code>let oldCacheKeys = new Set(Object.keys(require.cache))
try {
  html = await renderPageToString(options)
}
catch (e) {
  throw e
}
finally {
  process.env.NODE_ENV = nodeEnv

  for (let key of Object.keys(require.cache)) {
    if (!oldCacheKeys.has(key)) {
      delete require.cache[key]
    }
  }
}
</code></pre><p>As you can see from the above example, <code>try</code>/<code>catch</code>/<code>finally</code> also work great with JavaScript’s new <code>async</code>/<code>await</code> syntax. So if this has reminded you that you need to brush up on <code>async</code>/<code>await</code>, now’s the time to mosey on over to my <a class=" " href="/courses/async-javascript/">Mastering Asynchronous JavaScript</a> course!</p><p>But that’s it for today. Thanks so much for reading! If you have any questions or comments, shoot me a Tweet or DM at <a target="_blank" class=" " href="https://twitter.com/james_k_nelson">@james_k_nelson</a>. And until next time, happy coding :-)</p></div>]]></content:encoded>
            <author>james@jamesknelson.com (James K Nelson)</author>
        </item>
        <item>
            <title><![CDATA[CSS-in-JS and Static Rendering]]></title>
            <link>https:/frontarm.com/james-k-nelson/css-in-js-static-rendering/</link>
            <guid>https:/frontarm.com/james-k-nelson/css-in-js-static-rendering/</guid>
            <pubDate>Sat, 02 Feb 2019 00:00:00 GMT</pubDate>
            <description><![CDATA[CSS-in-JS can be a huge win for maintainability. But plain CSS still has its place.]]></description>
            <content:encoded><![CDATA[<div class="doc-wrapper doc-Doc-18aNW doc-align-center-when-narrow-2ypbP "><div class="doc-AsideTop-1wzdz "><p>More and more developers are switching to CSS-in-JS, including big names like Microsoft, Atlassian, and… the Eurovision song contest! And while I <a class=" " href="/james-k-nelson/how-can-i-use-css-in-js-securely/">haven’t</a> always been a huge fan of CSS-in-JS, even <em>I’m</em> coming around to its benefits:</p><ul><li>It lets you easily share variables between JavaScript and CSS <a class=" " href="/james-k-nelson/how-can-i-use-css-in-js-securely/"><small>(just don’t forget to escape them)</small></a>.</li><li>It’s a boon for tooling, making it easier to remove dead code, and to send the minimum amount of CSS possible.</li><li>And most importantly, it encourages writing CSS in a composable fashion.</li></ul><aside class="doc-Aside-QiMiD "><aside class="doc-Block-3i__D  doc-Details "><header></header><p>This article is based on a recent <a target="_blank" class=" " href="https://twitter.com/james_k_nelson/status/1090862989647831040">twitter thread</a>. Speaking of twitter, if you have any questions about Static Rendering, you’re always welcome to shoot a tweet or DM at <a target="_blank" class=" " href="https://twitter.com/james_k_nelson">@james_k_nelson</a>!</p></aside></aside></div><p>It looks like CSS-in-JS will dominate the styling of web apps for the foreseeable future. But web <em>apps</em> only make up a fraction of the web, because content is still king — as the meteoric rise of Gatsby has made apparent.</p><p>As a React developer, there’s as good a chance as any that you’ll be working on statically rendered web <em>sites</em>. And as I discovered while building <a target="_blank" class=" " href="https://github.com/frontarm/create-react-blog">create-react-blog</a> and Frontend Armory, using CSS-in-JS for statically rendered sites still comes with a few caveats…</p><aside class="doc-Aside-QiMiD "><aside class="doc-Block-3i__D  doc-Details "><header></header><p>What’s the difference between <a class=" " href="/james-k-nelson/static-vs-server-rendering/">static and server rendering?</a></p></aside></aside><h2 id="avoiding-flashes-of-unstyled-content"><a class="doc-headingLink  " href="#avoiding-flashes-of-unstyled-content">#</a>Avoiding Flashes Of Unstyled Content</h2><p>The idea behind static rendering is to speed up a site by pre-rendering the HTML for each page, which can then be displayed to users before the JavaScript finishes loading. Of course, with CSS-in-JS, your styles are in, well, the JavaScript. And this presents a problem — the initial HTML will be unstyled until the JavaScript finished loading.</p><p>Luckily, the teams maintaining <a target="_blank" class=" " href="https://www.styled-components.com/">styled-components</a> and <a target="_blank" class=" " href="https://emotion.sh/">emotion</a> allow you to solve this with a little extra code. For instance, styled-components provides the <code>ServerStyleSheet</code> object, which allows you to statically render your styles at the same time as you statically render your HTML. Then, you just send the statically rendered <code>&lt;style&gt;</code> tag as part of your HTML:</p><pre class="language-text"><code>import React from &#x27;react@next&#x27;
import { renderToString } from &#x27;react-dom@next/server&#x27;
import styled, { ServerStyleSheet } from &#x27;styled-components&#x27;

// A styled component
const Button = styled.a`
  border: 2px solid palevioletred;
  border-radius: 3px;
  color: palevioletred;
  display: inline-block;
  font-family: sans-serif;
  padding: 0.5rem 1rem;
  margin: 0.5rem 1rem;
`

// The React element that will be statically rendered
const pageContent = (
  &lt;Button
    as={&#x27;a&#x27;}
    href=&#x27;https://www.youtube.com/watch?v=FpBJih02aYU&#x27;
    target=&#x27;_blank&#x27;&gt;
    Not my Gumdrop Buttons!
  &lt;/Button&gt;
)

// `ServerStyleSheet` can collect styles from your statically rendered
// HTML, and then output them as a string of `&lt;style&gt;` tags.
const sheet = new ServerStyleSheet()
const html = renderToString(sheet.collectStyles(pageContent))
const styleTags = sheet.getStyleTags()

console.log(&#x27;Static stylesheet:\n&#x27;, styleTags)

document.getElementById(&#x27;root&#x27;).innerHTML = styleTags+html
</code></pre><p>By pre-rendering a <code>&lt;style&gt;</code> tag and sending it with your HTML, you’ll avoid the flash of unstyled content — but there’s a catch. As <code>ServerStyleSheet</code> only produces styles for the <em>initial</em> props, any use of component state, <code>componentDidMount</code> or <code>componentDidUpdate</code> will not be reflected in the server rendered styles. Given that your pre-rendered HTML has the same constraint, this shouldn’t be a problem. But if you do need a little help fetching the initial data for each of your app’s URLs, take a look at <a class=" " href="/navi/">Navi</a> — a router that was built with static/server rendering in mind. But I digress.</p><p>Statically rendering your styles has another benefit: it reduces the amount of CSS that’s required on each page’s initial load. This is because the rendered <code>&lt;style&gt;</code> tags only contain the <strong>critical CSS</strong> that is required for the pre-rendered HTML. The rest of the CSS is still managed with JavaScript, letting you split it out via dynamic <code>import()</code>. This can be great for performance… or it can result in many megabytes of CSS that is invalidated on every update — even for updates that <em>don’t</em> touch the content.</p><h2 id="inline-vs-external-stylesheets"><a class="doc-headingLink  " href="#inline-vs-external-stylesheets">#</a>Inline vs. External Stylesheets</h2><p>If you take a look at the generated <code>&lt;style&gt;</code> tag in the above example, you’ll notice that it has a <code>data-styled</code> attribute. This is important, because it shows that styled-components is tied to that <code>&lt;style&gt;</code> tag. You can’t reliably extract the contents of that <code>&lt;style&gt;</code> tag into a CSS file referenced by <code>&lt;link&gt;</code>. Which is… maybe not that much of a problem?</p><p>I mean, why would you want to put your styles in a separate file anyway? </p><p>To answer this question, consider <a class=" " href="/james-k-nelson/static-vs-server-rendering/">the main reason that you’d statically render</a> in the first place: it lets you serve JavaScript from a CDN. Now the thing about assets served from a CDN is that they’re often cached with expiry dates in the far future. As such, changes to these assets require new filenames in order to bypass the cache.</p><p>Naturally, changes to the names of JavaScript files will require corresponding changes to the HTML that references them. As a result, your app’s HTML files can’t be cached as heavily — and neither can the <code>&lt;style&gt;</code> tags that are embedded in them. And due to the design of Webpack, changes to <em>any</em> JavaScript file in your project will usually require a change to <em>every</em> <code>&lt;script&gt;</code> tag, and thus HTML file, in your app. </p><pre class="language-markup"><code>&lt;!-- For example, this script tag: --&gt;
&lt;script src=&quot;/static/js/runtime~main-47df755c101a4.js&quot;&gt;&lt;/script&gt;

&lt;!-- Might change to this after fixing a typo: --&gt;
&lt;script src=&quot;/static/js/runtime~main-55ce84a0cc19b.js&quot;&gt;&lt;/script&gt;
</code></pre><div class="doc-AsideTop-1wzdz "><p>For apps with few pages, little traffic, or small <code>&lt;style&gt;</code> tags, this is a non-issue. But for content-focused websites, the numbers can start to add up. For example, say that you’re running a site with 1000 pages, and with 25kb of critical CSS on each. Across all your HTML files, you’ll now have 25mb of CSS in <code>&lt;style&gt;</code> tags; and <em>all</em> of that CSS needs to be pushed to the CDN with every change to your site — even if your only change is to fix a typo!</p><aside class="doc-Aside-QiMiD "><aside class="doc-Block-3i__D  doc-Details "><header>25kb of critical CSS?!</header><p>The critical CSS only contains global styles, and styles for components in a single page’s initial render. But some components can contain a lot of styles!</p><p>For example, consider a <code>&lt;MarkdownDocument&gt;</code> component that contains all possible styles for any possible document.</p></aside></aside></div><h2 id="you-can-still-use-css-in-js-though"><a class="doc-headingLink  " href="#you-can-still-use-css-in-js-though">#</a>You can still use CSS-in-JS, though.</h2><p>Is it a problem to have to push all of your inline CSS to a CDN with every change? Is it a problem if users can’t cache the critical CSS? The answer is — of course — <em>it depends</em>. In particular, there are three conditions which can cause issues:</p><ol><li>If you have many pages with a large amount of critical CSS</li><li>If your content is frequently updated</li><li>If your site gets a lot of traffic</li></ol><p>In particular, if your site meets <em>all three</em> of these conditions, then there’s a good chance that you can improve performance (and save on hosting costs) by moving some of your CSS out to separate CSS files. Keep in mind that you can continue using CSS-in-JS alongside plain CSS or CSS Modules — you’ll just want to keep the size of your critical CSS manageable.</p><p>Of course, <a target="_blank" class=" " href="https://www.styled-components.com/">styled-components</a> isn’t the only kid on the block. The next most popular tool, <a target="_blank" class=" " href="https://emotion.sh/">emotion</a>, has much the same story as styled-components. But there’s also <a target="_blank" class=" " href="https://linaria.now.sh/">linaria</a> — a CSS-in-JS tool that is more focused towards static rendering. If you want to use CSS-in-JS, but styled-components doesn’t suit your requirements, then linaria is definitely worth checking out!</p><p>But maybe your heart is set on styled-components — after all, it’s got an all-star team and a huge community. And importantly, it’s open source, so you can help out! The styled-components team is currently working to make it possible to extract cacheable CSS — so if you’d like to chip in, take a look at <a target="_blank" class=" " href="https://github.com/styled-components/styled-components/pull/2357">this Pull Request</a>.</p><p>Lastly, it must be said that while CSS-in-JS is a great option, it’s <em>not</em> a necessity. CSS Modules and SASS solve most of the same issues while working out of the box with create-react-app and <a target="_blank" class=" " href="https://github.com/frontarm/create-react-blog">create-react-blog</a>. Both CSS-in-JS and plain CSS have their place, and knowing the ins and outs of both will help you pick the right tool for the job.</p><hr/><p><em>Have you noticed how ridiculously fast Frontend Armory is? While building it, I’ve spent gobs of time learning the ins and outs of static rendering and code splitting, and now I want to save you the trouble of doing the same. So. If you’re building a React app and speed affects your bottom line (or you just want a snappy UI), then you need to see my upcoming course: <strong>React in Practice</strong>. More details are coming soon; <a class=" " href="/members/register/">join Frontend Armory</a> now to be the first to find out — it’s free!</em></p></div>]]></content:encoded>
            <author>james@jamesknelson.com (James K Nelson)</author>
        </item>
        <item>
            <title><![CDATA[Reusable Time Travel with React Hooks and Immer]]></title>
            <link>https:/frontarm.com/swyx/reusable-time-travel-react-hooks-immer/</link>
            <guid>https:/frontarm.com/swyx/reusable-time-travel-react-hooks-immer/</guid>
            <pubDate>Wed, 30 Jan 2019 00:00:00 GMT</pubDate>
            <description><![CDATA[Learn how and why to make a useTimeTravel React hook that we can use to make Tolerant User Interfaces.]]></description>
            <content:encoded><![CDATA[<div class="doc-wrapper doc-Doc-18aNW doc-align-center-when-narrow-2ypbP "><p><strong>Bottom Line Up Front</strong>: You’ll learn how to build this demo — with a <code>useTimeTravel</code> React hook.</p><pre class="language-text"><code>import React from &#x27;react&#x27;;
import { useTimeTravel } from &#x27;./useTimeTravel&#x27;;

const initialState = { x: 0, y: 0 };

function reducer(state, action) {
  switch (action.type) {
    case &#x27;RESET&#x27;:
      return initialState;
    case &#x27;MOVE&#x27;:
      state.x += action.x;
      state.y += action.y;
      state.x = Math.min(Math.max(state.x, 0), 9);
      state.y = Math.min(Math.max(state.y, 0), 9);
  }
}

export default function App() {
  const { state, dispatch, timeline, doUndo, doRedo, doReset } = useTimeTravel(
    reducer,
    initialState
  );
  const createMove = (x, y) =&gt; () =&gt; dispatch({ type: &#x27;MOVE&#x27;, x, y });
  return (
    &lt;div&gt;
      &lt;h1&gt;Move the green box around&lt;/h1&gt;
      &lt;div id=&quot;App&quot;&gt;
        &lt;div className=&quot;redBox&quot; style={{ &#x27;--stateX&#x27;: `${state.x}0px`, &#x27;--stateY&#x27;: `${state.y}0px` }}&gt;
          &lt;div className=&quot;greenBox&quot; /&gt;
        &lt;/div&gt;
        &lt;div className=&quot;arrows&quot;&gt;
          &lt;div /&gt;
          &lt;button onClick={createMove(0, -1)}&gt;🔼&lt;/button&gt;
          &lt;div /&gt;
          &lt;button onClick={createMove(-1, 0)}&gt;⬅️&lt;/button&gt;
          &lt;div&gt;⭐&lt;/div&gt;
          &lt;button onClick={createMove(1, 0)}&gt;➡️&lt;/button&gt;
          &lt;div /&gt;
          &lt;button onClick={createMove(0, 1)}&gt;🔽&lt;/button&gt;
          &lt;div /&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      &lt;hr /&gt;
      &lt;button onClick={doUndo} disabled={timeline.past.length === 0}&gt;
        Undo
      &lt;/button&gt;
      &lt;button onClick={doRedo} disabled={timeline.future.length === 0}&gt;
        Redo
      &lt;/button&gt;
      &lt;button
        onClick={doReset}
        disabled={timeline.past.length === 0 &amp;&amp; timeline.future.length === 0}
      &gt;
        Reset
      &lt;/button&gt;
      &lt;hr /&gt;
      &lt;ul&gt;
        &lt;li&gt;Past: {JSON.stringify(timeline.past)}&lt;/li&gt;
        &lt;li&gt;Present: {JSON.stringify(timeline.present)}&lt;/li&gt;
        &lt;li&gt;Future: {JSON.stringify(timeline.future)}&lt;/li&gt;
      &lt;/ul&gt;
    &lt;/div&gt;
  );
}</code></pre><hr/><p><a target="_blank" class=" " href="https://reactjs.org/docs/hooks-overview.html">React Hooks</a> are a fundamentally simpler way to encapsulate custom behavior in user interfaces. </p><p>If stateful React components are like an atom, hooks are the subatomic particles. We are given primitives like <code>useState</code> and <code>useReducer</code>, and we can compose and remix them in various quantities to create new elements with the exact properties we want.</p><p>Where <code>useState</code> is useful for reading and mutating atomic values, <code>useReducer</code> is better for updating collections (arrays and objects) of data that represent more complex states. It borrows heavily from Redux patterns in dispatching typed actions and passing through simple state machines. I will refer the reader to <a target="_blank" class=" " href="https://reactjs.org/docs/hooks-reference.html#usereducer">the docs</a> rather than repeat them here.</p><h2 id="tolerant-user-interfaces"><a class="doc-headingLink  " href="#tolerant-user-interfaces">#</a>Tolerant User Interfaces</h2><p>My favorite of the <a target="_blank" class=" " href="https://en.wikipedia.org/wiki/Principles_of_user_interface_design">six principles of User Interface Design</a> is <strong>Tolerance</strong>, which asks the UI designer to limit the cost of mistakes by the user. By giving the user an implicit assurance that their work won’t be lost without intention, they encourage play and discovery of everything else in the UI, which enables more serendipity with lower cognitive load. Many apps I see don’t pass this simple test, and don’t offer undo/redo capability even in UI that doesn’t interact with a backend, probably because it is extra work.</p><p>We should make it easier to write Tolerant User Interfaces.</p><p>One easy way to reduce the number of irreversible actions is to make more things reversible. Implementing this with typical state primitives in React is troublesome, because those APIs tend to discard past state in favor of new state.</p><h2 id="implementing-a-timeline"><a class="doc-headingLink  " href="#implementing-a-timeline">#</a>Implementing a Timeline</h2><p>So how do we implement tolerance in our React apps? We can stick historical state in another piece of state, or a global variable, but those solutions are problematic too. Better to treat state history just like another part of state:</p><pre class="language-jsx"><code>  const timeline = {
    past: [],
    present: initialState,
    future: []
  };
</code></pre><p>Because we’re working with objects and arrays, we’d like to avoid defensive copying and use local mutability with structural sharing, so we introduce <a target="_blank" class=" " href="https://github.com/mweststrate/immer">immer</a>:</p><pre class="language-jsx"><code>import produce from &#x27;immer&#x27;
</code></pre><p>(seriously, <a target="_blank" class=" " href="https://github.com/mweststrate/immer">go read the docs</a>)</p><p>And now we can write reducer methods to add new states:</p><pre class="language-jsx"><code>function _addNewPresent(timeline, newPresent) {
  return produce(timeline, draft =&gt; {
    draft.past.push(draft.present);
    draft.present = newPresent;
    draft.future = [];
  });
}
</code></pre><p>and move back in time:</p><pre class="language-jsx"><code>function _doUndo(timeline) {
  return produce(timeline, draft =&gt; {
    if (!draft.past.length) return;
    const newPresent = draft.past.pop();
    draft.future.unshift(draft.present);
    draft.present = newPresent;
  });
}
</code></pre><p>and Redo and Reset and so on.</p><h2 id="proxying-usereducer-with-the-timeline"><a class="doc-headingLink  " href="#proxying-usereducer-with-the-timeline">#</a>Proxying <code>useReducer</code> with the Timeline</h2><p>Now that we’ve scoped out our Timeline data structure, we can think a bit about the reusability of it, and try to build it in to an idiomatic custom React Hook.</p><p>The <code>useReducer</code> API looks like this:</p><pre class="language-jsx"><code>const [state, dispatch] = useReducer(reducer, initialState);
</code></pre><p>Wouldn’t it be nice if we could pass in a similar <code>reducer</code> to a different hook?</p><pre class="language-jsx"><code>const { state, dispatch, timeline, doUndo } = useTimeTravel(reducer, initialState);
</code></pre><p>And we could write the reducer in a locally mutable style?</p><pre class="language-jsx"><code>function reducer(state, action) {
  switch (action.type) {
    case &#x27;RESET&#x27;:
      return initialState;
    case &#x27;MOVE&#x27;:
      state.x += action.x;
      state.y += action.y;
  }
}
</code></pre><p>In order to accomplish this, we need to transform <code>reducer</code> and <code>initialState</code> into the <code>timeline</code> data structure, and then return nicely named, easy to work with variables in the result. This is trivial in custom hooks:</p><pre class="language-jsx"><code>export function useTimeTravel(reducer, initialState) {
  const timeline = {
    past: [],
    present: initialState,
    future: []
  };
  const proxiedReducer = (tl, action) =&gt; {
    if (action === UNDO) return _doUndo(tl);
    if (action === REDO) return _doRedo(tl);
    if (action === RESET) return _doReset(tl);
    // else
    const newState = produce(tl.present, draft =&gt; reducer(draft, action));
    return _addNewPresent(tl, newState);
  };
  const [_timeline, _dispatch] = useReducer(proxiedReducer, timeline);
  return {
    state: _timeline.present,
    timeline: _timeline,
    dispatch: _dispatch,
    doUndo: () =&gt; _dispatch(UNDO), // nice to wrap action type
    doRedo: () =&gt; _dispatch(REDO), // nice to wrap action type
    doReset: () =&gt; _dispatch(RESET) // nice to wrap action type
  };
}
</code></pre><p>So working backwards from the API that we <em>want</em> to use, we were able write the custom hook logic in just a few lines of code.</p><p>We can use the destructured artefacts in our UI easily:</p><pre class="language-jsx"><code>const createMove = (x, y) =&gt; () =&gt; dispatch({ type: &#x27;MOVE&#x27;, x, y });
// later on...
&lt;button onClick={createMove(0, -1)}&gt;🔼&lt;/button&gt;
&lt;button onClick={createMove(-1, 0)}&gt;⬅️&lt;/button&gt;
&lt;button onClick={createMove(1, 0)}&gt;➡️&lt;/button&gt;
&lt;button onClick={createMove(0, 1)}&gt;🔽&lt;/button&gt;
&lt;button onClick={doUndo} disabled={timeline.past.length === 0}&gt;
  Undo
&lt;/button&gt;
&lt;button onClick={doRedo} disabled={timeline.future.length === 0}&gt;
  Redo
&lt;/button&gt;
&lt;button
  onClick={doReset}
  disabled={timeline.past.length === 0 &amp;&amp; timeline.future.length === 0}
&gt;
  Reset
&lt;/button&gt;
</code></pre><p>And you can play with it here:</p><pre class="language-text"><code>import React from &#x27;react&#x27;;
import { useTimeTravel } from &#x27;./useTimeTravel&#x27;;

const initialState = { x: 0, y: 0 };

function reducer(state, action) {
  switch (action.type) {
    case &#x27;RESET&#x27;:
      return initialState;
    case &#x27;MOVE&#x27;:
      state.x += action.x;
      state.y += action.y;
      state.x = Math.min(Math.max(state.x, 0), 9);
      state.y = Math.min(Math.max(state.y, 0), 9);
  }
}

export default function App() {
  const { state, dispatch, timeline, doUndo, doRedo, doReset } = useTimeTravel(
    reducer,
    initialState
  );
  const createMove = (x, y) =&gt; () =&gt; dispatch({ type: &#x27;MOVE&#x27;, x, y });
  return (
    &lt;div&gt;
      &lt;h1&gt;Move the green box around&lt;/h1&gt;
      &lt;div id=&quot;App&quot;&gt;
        &lt;div className=&quot;redBox&quot; style={{ &#x27;--stateX&#x27;: `${state.x}0px`, &#x27;--stateY&#x27;: `${state.y}0px` }}&gt;
          &lt;div className=&quot;greenBox&quot; /&gt;
        &lt;/div&gt;
        &lt;div className=&quot;arrows&quot;&gt;
          &lt;div /&gt;
          &lt;button onClick={createMove(0, -1)}&gt;🔼&lt;/button&gt;
          &lt;div /&gt;
          &lt;button onClick={createMove(-1, 0)}&gt;⬅️&lt;/button&gt;
          &lt;div&gt;⭐&lt;/div&gt;
          &lt;button onClick={createMove(1, 0)}&gt;➡️&lt;/button&gt;
          &lt;div /&gt;
          &lt;button onClick={createMove(0, 1)}&gt;🔽&lt;/button&gt;
          &lt;div /&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      &lt;hr /&gt;
      &lt;button onClick={doUndo} disabled={timeline.past.length === 0}&gt;
        Undo
      &lt;/button&gt;
      &lt;button onClick={doRedo} disabled={timeline.future.length === 0}&gt;
        Redo
      &lt;/button&gt;
      &lt;button
        onClick={doReset}
        disabled={timeline.past.length === 0 &amp;&amp; timeline.future.length === 0}
      &gt;
        Reset
      &lt;/button&gt;
      &lt;hr /&gt;
      &lt;ul&gt;
        &lt;li&gt;Past: {JSON.stringify(timeline.past)}&lt;/li&gt;
        &lt;li&gt;Present: {JSON.stringify(timeline.present)}&lt;/li&gt;
        &lt;li&gt;Future: {JSON.stringify(timeline.future)}&lt;/li&gt;
      &lt;/ul&gt;
    &lt;/div&gt;
  );
}</code></pre></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[4 ways to pass children to React elements]]></title>
            <link>https:/frontarm.com/james-k-nelson/4-ways-pass-children-react-elements/</link>
            <guid>https:/frontarm.com/james-k-nelson/4-ways-pass-children-react-elements/</guid>
            <pubDate>Mon, 28 Jan 2019 00:00:00 GMT</pubDate>
            <description><![CDATA[Do you know all 4 ways to pass children to React elements?]]></description>
            <content:encoded><![CDATA[<div class="doc-wrapper doc-Doc-18aNW doc-align-center-when-narrow-2ypbP "><p>Did you know that React gives you no less than <strong>four</strong> different ways to specify the children for a new React Element?</p><h2 id="1-nesting-jsx"><a class="doc-headingLink  " href="#1-nesting-jsx">#</a>1. Nesting JSX</h2><p>To start with, there’s the obvious way: nesting the elemen’s between its start and end tags, like the blue div in this example:</p><pre class="language-text"><code>ReactDOM.render(
  &lt;div className=&quot;red&quot;&gt;
    &lt;div className=&quot;blue&quot; /&gt;
  &lt;/div&gt;,
  document.querySelector(&#x27;#root&#x27;)
)
</code></pre><p>The obvious approach is… kinda obvious. But it gives you a hint to approach number two. Given that JSX compiles to JavaScript, there must be a pure JavaScript way to do the same thing. And while there’s a good chance that you already know the corresponding vanilla JavaScript, if you don’t, you can find out by clicking on the <em>Compiled</em> button in the above editor.</p><p>And if you <em>do</em> click on the <em>Compiled</em> button, you’ll see a couple calls to…</p><h2 id="2-createelement"><a class="doc-headingLink  " href="#2-createelement">#</a>2. <code>createElement()</code></h2><p>JSX elements in a React project are transformed at build time into calls to <code>React.createElement()</code>. This function’s first two arguments represent the elment’s <code>type</code> and <code>props</code>, while any subsequent arguments represent the element’s child nodes.</p><pre class="language-jsx"><code>React.createElement(
  type,
  props,

  // You can pass as many children as you need - or none at all.
  childNode1,
  childNode2,
)
</code></pre><p>For example, the two elements in the above JSX transpile to two separate calls to <code>React.createElement()</code>:</p><pre class="language-jsx"><code>React.createElement(
  &quot;div&quot;,
  { className: &quot;red&quot; },
  React.createElement(&quot;div&quot;, { className: &quot;blue&quot; })
)
</code></pre><p>There are three important things to understand about <code>React.createElement()</code>:</p><ol><li>It returns a plain old JavaScript object that contains all of the information that you passed into it.</li><li>It’s first two arguments represent <code>type</code> and <code>props</code>, and any further arguments represent its <code>children</code>.</li><li>You can pass as many children as you’d like… or none at all.</li></ol><p>Simple, huh? But there’s one curious thing about the object returned by <code>React.createElement()</code>. While the returned object has properties corresponding to the <code>type</code> and <code>props</code> arguments, it <em>doesn’t</em> have a <code>children</code> property. Instead, the children are stored on <code>props.children</code>.</p><pre class="language-text"><code>console.log(
  React.createElement(
    &quot;div&quot;,
    { className: &quot;red&quot; },
    &quot;Hello, friend!&quot;
  )
)
</code></pre><p>So what happens if you pass <code>React.createElement()</code> both a <code>children</code> <strong>prop</strong> along with the <code>children</code> <strong>argument</strong>? Let’s find out!</p><pre class="language-text"><code>console.log(
  React.createElement(
    &quot;div&quot;,
    {
      children: &quot;Props win!&quot;,
      className: &quot;red&quot;,
    },
    undefined
  )
)
</code></pre><p>As you can see in the above editor’s console, <strong>the <code>children</code> prop is ignored in favor of the value passed via argument</strong> — which happens to be <code>undefined</code>. But this raises a question: what would happen if you <em>didn’t</em> pass a third argument?</p><p>This leads us to the third way to specify an element’s <code>children</code>.</p><h2 id="3-pass-a-children-prop-to-createelement"><a class="doc-headingLink  " href="#3-pass-a-children-prop-to-createelement">#</a>3. Pass a <code>children</code> prop to <code>createElement()</code></h2><p>When you pass a <code>children</code> prop to <code>createElement()</code>, <em>without</em> passing third (or subsequent) arguments, then that will become the element’s children.</p><pre class="language-text"><code>ReactDOM.render(
  React.createElement(&#x27;div&#x27;, {
    children: React.createElement(&#x27;div&#x27;, {className: &quot;blue&quot; }),
    className: &quot;red&quot;,
  }),
  document.querySelector(&#x27;#root&#x27;)
)
</code></pre><p>This has an interesting corollary: you can also pass elements via props <em>other</em> than <code>children</code>. In fact, you can pass <em>multiple</em> elements to a component using multiple props. This pattern is sometimes called slots — and you can learn more about it with <a target="_blank" class=" " href="https://daveceddia.com/pluggable-slots-in-react-components/">Dave Ceddia’s guide to slots</a>.</p><p>Of course, you don’t have to use raw JavaScript to pass a <code>children</code> prop — which leads to the 4th and final way to specify an element’s children…</p><h2 id="4-pass-a-children-prop-with-jsx"><a class="doc-headingLink  " href="#4-pass-a-children-prop-with-jsx">#</a>4. Pass a <code>children</code> prop with JSX</h2><p>Just as we started by transforming a JSX element into a call to <code>createElement()</code>, let’s finish by rewriting the above with JSX:</p><pre class="language-text"><code>ReactDOM.render(
  &lt;div
    children={&lt;div className=&quot;white&quot; /&gt;}
    className=&quot;black&quot;
  /&gt;,
  document.querySelector(&#x27;#root&#x27;)
)
</code></pre><h2 id="ok-but-whhhy"><a class="doc-headingLink  " href="#ok-but-whhhy">#</a>Ok, but… whhhy?</h2><p>Putting aside the question of whether you <em>can</em> pass children via <code>props</code> <em><small>(you can)</small></em>, let’s ask a perhaps more important question: <em>should you?</em></p><p>It goes without saying that <em>usually</em>, it’s clearer to specify a JSX element’s children the standard way. But with that said, there are a couple situations where the ability to specify <code>children</code> as a prop comes in handy.</p><h3 id="1-consuming-contexts"><a class="doc-headingLink  " href="#1-consuming-contexts">#</a>1. Consuming Contexts</h3><p>When working with React context, you’ll run into a small problem when you need to consume values from multiple contexts: you need to nest context consumers within each other to access multiple values. And so just when you thought that <a class=" " href="/courses/async-javascript/">Promises and async/await</a> had banished callback pyramids from the idyllic land of JavaScript <em>forever</em>, you end up with this:</p><pre class="language-jsx"><code>function InvoiceScreen(props) {
  return (
    &lt;RouteContext.Consumer&gt;
      {route =&gt;
        &lt;AuthContext.Consumer&gt;
          {auth =&gt;
            &lt;DataContext.Consumer&gt;
              {data =&gt;
                &lt;InvoiceScreenImpl
                  route={route}
                  auth={auth}
                  data={data}
                  {...props}
                /&gt;
              }
            &lt;/DataContext.Consumer&gt;
          }
        &lt;/AuthContext.Consumer&gt;
      }
    &lt;/NavRoute&gt;
  )
}
</code></pre><p>The above code can be shortened by using the <code>children</code> prop, instead of nesting JSX elements:</p><pre class="language-jsx"><code>function InvoiceScreen(props) {
  return (
    &lt;RouteContext.Consumer children={route =&gt;
      &lt;AuthContext.Consumer children={auth =&gt;
        &lt;DataContext.Consumer children={data =&gt;
          &lt;InvoiceScreenImpl
            route={route}
            auth={auth}
            data={data}
            {...props}
          /&gt;
        } /&gt;
      } /&gt;
    } /&gt;
  )
}
</code></pre><p>Of course, this still isn’t perfect. For perfection, you’ll need to wait for the new React <a target="_blank" class=" " href="https://reactjs.org/docs/hooks-reference.html">Hooks API</a>, which will make consuming context a breeze.</p><h3 id="2-passing-through-props"><a class="doc-headingLink  " href="#2-passing-through-props">#</a>2. Passing Through Props</h3><div class="doc-AsideTop-1wzdz "><p>Suppose that you have a component that just wraps another component — possibly transforming the props in some way,  before passing them through to a child component.</p><p>In fact, you may have just seen such a component. To see what I mean, let me transform the previous <code>InvoiceScreen</code> example into plain JavaScript.</p><pre class="language-jsx"><code>function InvoiceScreen(props) {
  return (
    createElement(RouteContext.Consumer, { children: route =&gt;
      createElement(AuthContext.Consumer, { children: auth =&gt;
        createElement(DataContext.Consumer, { children: data =&gt;
          createElement(InvoiceScreenImpl, {
            route,
            auth,
            data,
            ...props
          })
        })
      })
    })
  )
}
</code></pre><p>You’ll notice that each calls to <code>createElement()</code> in the above example only uses <em>two</em> arguments, so any value for <code>props.children</code> will be passed through to <code>&lt;InvoiceScreenImpl&gt;</code>.</p><p>When you think about this, it makes a lot of sense. It would be confusing to have to specifically pass the <code>children</code> prop through. And luckily, you don’t have to — because React lets you specify children in an appropriate way for the situation!</p></div><hr/><p><em>Have anything to add to this article? Let me know in the <a href="https://mobile.twitter.com/search?q=https%3A%2F%2Ffrontarm.com%2Fjames-k-nelson%2F4-ways-pass-children-react-elements%2F">Twitter discussion</a>!</em></p></div>]]></content:encoded>
            <author>james@jamesknelson.com (James K Nelson)</author>
        </item>
        <item>
            <title><![CDATA[React Fragments in Practice – 4 real-world examples]]></title>
            <link>https:/frontarm.com/james-k-nelson/react-fragments-in-practice/</link>
            <guid>https:/frontarm.com/james-k-nelson/react-fragments-in-practice/</guid>
            <pubDate>Wed, 23 Jan 2019 00:00:00 GMT</pubDate>
            <description><![CDATA[Learn to group React elements without unnecessary markup – using React Fragments.]]></description>
            <content:encoded><![CDATA[<div class="doc-wrapper doc-Doc-18aNW doc-align-center-when-narrow-2ypbP "><p>When working with React, there are times when you’ll want to pass around <em>groups</em> of React elements. And while it used to be that doing so required you to add useless container components or confusing arrays, React solved this last year by introducing <strong>Fragments</strong> — a simple way to group elements without adding any extra markup.</p><pre class="language-text"><code>ReactDOM.render(
  &lt;ul&gt;
    &lt;React.Fragment&gt;
      &lt;li&gt;The fragment element is not rendered to the DOM.&lt;/li&gt;
      &lt;li&gt;
        You can confirm this by right clicking on one of these items
        in the preview pane, and inspecting the markup in the browser
        dev tools.
      &lt;/li&gt;
    &lt;/React.Fragment&gt;
  &lt;/ul&gt;,
  document.querySelector(&quot;#root&quot;)
)
</code></pre><p><code>React.Fragment</code> — as used in the above example — is like a markupless component. When rendered to the DOM, <strong>its children will be rendered by themselves</strong>, making it possible to pass around groups of elements without introducing unnecessary markup. Fragments are also great for working with table and list markup (like the above), where it’s just not possible to add an extra <code>&lt;div&gt;</code>.</p><h2 id="fragment-syntax"><a class="doc-headingLink  " href="#fragment-syntax">#</a><code>&lt;&gt;Fragment syntax&lt;/&gt;</code></h2><p>After using fragments for a while, you may run into an eensy-weensy issue: typing out <code>&lt;React.Fragment&gt;</code> is <em>bothersome</em> compared to typing <code>&lt;div&gt;</code>. And while this won’t get in the way when fragments are truly necessary, it certainly can slow down adoption. Which is why, I suppose, fragments also come with a concise new syntax:</p><pre class="language-text"><code>ReactDOM.render(
  &lt;&gt;
    &lt;h1&gt;Yo Dawg,&lt;/h1&gt;
    &lt;p&gt;
      I heard you like fragments so
      I &lt;&gt;put a &lt;&gt;fragment&lt;/&gt; in your fragment&lt;/&gt;.
    &lt;/p&gt;
  &lt;/&gt;,
  document.querySelector(&quot;#root&quot;)
)
</code></pre><p>As you can see, the <code>&lt;&gt;</code> and <code>&lt;/&gt;</code> tags in JSX now correspond to <code>&lt;React.Fragment&gt;</code> and <code>&lt;/React.Fragment&gt;</code>. There’s nothing else special about them — they compile down to the same thing as any other React element, with a <code>type</code> of <code>React.Fragment</code>:</p><div class="doc-AsideTop-1wzdz "><aside class="doc-Aside-QiMiD "><aside class="doc-Block-3i__D  doc-Details "><header></header><p>Want to learn more about elements, components and props? Check out my <a class=" " href="/courses/react-fundamentals/">React fundamentals</a> course.</p></aside></aside><pre class="language-jsx"><code>React.createElement(
  React.Fragment,
  null,
  ...childElements
)
</code></pre></div><hr/><div class="doc-Float-SLyV6 " style="min-width:calc(45% + 32px*2);width:calc(100% - 602px - 32px + 0px);text-align:center"><div class="doc-Block-3i__D  "><img src="/static/media/rover.9843bce4.svg" alt="rover" style="width:300px" class="doc-Image"/></div></div><p>When fragments were first released, there wasn’t much support for this syntax. But now that a year has passed, most major tools support it, including:</p><ul><li>Babel 7+</li><li>TypeScript 2.6+</li><li>Prettier 1.9+</li><li>ESLint 3+ (along with babel-eslint 7)</li></ul><p>Of course, you don’t have to worry about any of this if you’re using <a target="_blank" class=" " href="https://facebook.github.io/create-react-app/">create-react-app</a>, because it has supported fragments from when they were first released!</p><h2 id="typical-uses"><a class="doc-headingLink  " href="#typical-uses">#</a>Typical uses</h2><p>Fragments have now had plenty of time for them to make their way into real world codebases. I’ve taken a look through a few open source projects to see how Fragments are being used in practice — and found a number of common use cases:</p><h3 id="1-returning-groups-of-elements"><a class="doc-headingLink  " href="#1-returning-groups-of-elements">#</a>1. Returning groups of elements</h3><p>You can use fragments to create components that return a list of elements without wrapping them in a container or array. This is useful for components that return form and text markup — as wrapping the result in a container <code>&lt;div&gt;</code> can cause headaches when styling things.</p><p><a target="_blank" class=" " href="http://spectrum.chat">Spectrum</a>&#x27;s source frequently uses fragment-returning components for this purpose. For example, take a look at the e-mail confirmation component:</p><div class="doc-AsideTop-1wzdz "><pre class="language-jsx"><code>class UserEmailConfirmation extends React.Component {
  render() {
    const { emailError, email, isLoading } = this.state;
    const { user } = this.props;

    return (
      &lt;React.Fragment&gt;        &lt;EmailForm
          defaultValue={email}
          loading={isLoading}
          onChange={this.handleEmailChange}
          onSubmit={this.init}
          style={{ marginTop: &#x27;8px&#x27;, marginBottom: &#x27;8px&#x27; }}
        /&gt;

        {user.pendingEmail &amp;&amp; (
          &lt;Notice&gt;
            A confirmation link was sent to {user.pendingEmail}. Click
            the confirmation link and then return to this page. You can
            resend the confirmation here, or enter a new email address.
          &lt;/Notice&gt;
        )}

        {emailError &amp;&amp; &lt;Error&gt;{emailError}&lt;/Error&gt;}
      &lt;/React.Fragment&gt;    )
  }
}
</code></pre><aside class="doc-Aside-QiMiD "><aside class="doc-Block-3i__D  doc-Details "><header></header><p>Spectrum was recently acquired by GitHub, but they’re still open source!</p><p><a target="_blank" class=" " href="https://github.com/withspectrum/spectrum/blob/181cf90f8d1c49aeb97f0dbb80359daa0a1343a3/src/components/userEmailConfirmation/index.js#L89">See this example at GitHub</a></p></aside></aside></div><p>Similarly, you can use fragments to return groups of elements from render functions. Wordpress’ <a target="_blank" class=" " href="https://github.com/Automattic/wp-calypso/">Calypso</a> frontend frequently uses this pattern to inject a <code>translate</code> function for internationalization:</p><div class="doc-AsideTop-1wzdz "><pre class="language-jsx"><code>&lt;Step name=&quot;my-sites&quot; target=&quot;my-sites&quot; placement=&quot;below&quot; arrow=&quot;top-left&quot;&gt;
  { ( { translate } ) =&gt; (
    &lt;Fragment&gt;      &lt;p&gt;
        { translate(
          &quot;{{strong}}First things first.{{/strong}} Up here, you&#x27;ll &quot; +
            &quot;find tools for managing your site&#x27;s content and design.&quot;,
          {
            components: {
              strong: &lt;strong /&gt;,
            },
          }
        ) }
      &lt;/p&gt;
      &lt;Continue click icon=&quot;my-sites&quot; step=&quot;sidebar&quot; target=&quot;my-sites&quot; /&gt;
    &lt;/Fragment&gt;  ) }
&lt;/Step&gt;
</code></pre><aside class="doc-Aside-QiMiD "><aside class="doc-Block-3i__D  doc-Details "><header></header><p>Note that Wordpress imports <code>Fragment</code> from the <code>react</code> package and uses it by itself, without qualifying it as <code>React.Fragment</code>.</p><p><a target="_blank" class=" " href="https://github.com/Automattic/wp-calypso/blob/59bdfeeb97eda4266ad39410cb0a074d2c88dbc8/client/layout/guided-tours/tours/jetpack-basic-tour.js#L68">See this example at GitHub</a></p><br/></aside></aside></div><h3 id="2-conditionally-rendering-groups-of-elements"><a class="doc-headingLink  " href="#2-conditionally-rendering-groups-of-elements">#</a>2. Conditionally rendering groups of elements</h3><p>Fragments make it far easier to conditionally render whole groups of elements without adding unnecessary markup. For example, they can be used with the ternary operator to switch an element’s content depending on the value of a prop:</p><pre class="language-jsx"><code>export function ResetPasswordScreen({ hasPassword, name, ...formProps }) {
  return (
    &lt;Layout&gt;
      {hasPassword ? (
        &lt;&gt;          &lt;h3&gt;Reset your password&lt;/h3&gt;
          &lt;p&gt;
            To finish resetting your password, enter your new password
            here and hit the &quot;Reset&quot; button.
          &lt;/p&gt;
        &lt;/&gt;      ) : (
        &lt;&gt;          &lt;h3&gt;Hi {name}!&lt;/h3&gt;
          &lt;p&gt;Thanks for joining!&lt;/p&gt;
          &lt;p&gt;
            Just one more step - please pick a password for your account:
          &lt;/p&gt;
        &lt;/&gt;      )}
      &lt;ResetPasswordForm {...formProps} /&gt;
    &lt;/Layout&gt;
  )
}
</code></pre><h2 id="fragments-with-arrays"><a class="doc-headingLink  " href="#fragments-with-arrays">#</a>Fragments with arrays</h2><p>Fragments have one more powerful feature, which I’ve saved until last as it is rarely used. But when you <em>do</em> need this feature, it is invaluable:</p><p><strong>Fragments can have <code>key</code> props!</strong></p><div class="doc-AsideTop-1wzdz "><pre class="language-jsx"><code>&lt;React.Fragment key=&#x27;somevalue&#x27;&gt;
  ...
&lt;/React.Fragment&gt;
</code></pre><aside class="doc-Aside-QiMiD "><aside class="doc-Block-3i__D  doc-Details "><header></header><p>To specify a <code>key</code> for a fragment, you’ll need to use the standard JSX element syntax; you can’t use the new <code>&lt;&gt;&lt;/&gt;</code> syntax.</p></aside></aside></div><p>Why would you want to give a Fragment a key? Well, it allows fragments to be used as items in arrays. Which in turn makes it possible to splice elements into text — and all without introducing any unnecessary markup.</p><p>For example, the console view in Frontend Armory’s <a class=" " href="/demoboard/">Demoboard</a> editor uses keyed fragments to replace newline characters with <code>&lt;br&gt;</code> elements… and the resulting code is small enough that it would make for a great exercise!</p><p><strong>See if you can use React Fragments to render the newline characters in the below string as <code>&lt;br&gt;</code> tags, without introducing any extra markup.</strong></p><p><em>Once you’ve given it a try, you can take a look at my solution by clicking the </em>Solution<em> tab at the bottom of the editor.</em></p><pre class="language-text"><code>let message = `
  Hello, there!
  HTML doesn&#x27;t render new line characters by default,
  but you can add them back in as &lt;br&gt; tags!
`

// You&#x27;ll need to replace the line break characters in this string
// with `&lt;br&gt;` elements.
let messageWithLineBreaks = message

ReactDOM.render(
  &lt;div&gt;{messageWithLineBreaks}&lt;/div&gt;,
  document.querySelector(&#x27;#root&#x27;)
)
</code></pre><p>Thanks so much for reading! And if you know of any more uses for React Fragments, make sure to let everyone know in the <a href="https://mobile.twitter.com/search?q=https%3A%2F%2Ffrontarm.com%2Fjames-k-nelson%2Freact-fragments-in-practice%2F">twitter discussion</a>!</p></div>]]></content:encoded>
            <author>james@jamesknelson.com (James K Nelson)</author>
        </item>
        <item>
            <title><![CDATA[Using MDX with create-react-app 2]]></title>
            <link>https:/frontarm.com/james-k-nelson/mdx-with-create-react-app/</link>
            <guid>https:/frontarm.com/james-k-nelson/mdx-with-create-react-app/</guid>
            <pubDate>Sun, 16 Dec 2018 00:00:00 GMT</pubDate>
            <description><![CDATA[Learn how to get the succinct syntax of Markdown, the power of JSX, and all with the simplicity of create-react-app 2.]]></description>
            <content:encoded><![CDATA[<div class="doc-wrapper doc-Doc-18aNW doc-align-center-when-narrow-2ypbP "><p>MDX is a wonderful way to write content for React-based apps. It gives you the succinct syntax of Markdown, with all the power of raw JSX. And while MDX <a target="_blank" class=" " href="http://jamesknelson.com/introducing-mdxc/">started out</a> as an obscure little package, it’s grown to be supported by everything from <a target="_blank" class=" " href="https://mdxjs.com/getting-started/next">Next.js</a>, to <a target="_blank" class=" " href="https://mdxjs.com/getting-started/gatsby">Gatsby</a>, to <a target="_blank" class=" " href="https://github.com/jxnblk/mdx-deck">mdx-deck</a>.</p><p>But there’s one place where support has been conspicuously missing: <em>create-react-app 2</em>. Here’s why.</p><h2 id="configuring-create-react-app"><a class="doc-headingLink  " href="#configuring-create-react-app">#</a>Configuring create-react-app</h2><p>While create-react-app 1 allowed for slight modifications to configuration through <a target="_blank" class=" " href="https://github.com/timarney/react-app-rewired">react-app-rewired</a>, this wasn’t supported by the create-react-app team itself.</p><p>With create-react-app 2, official support was added for some extensions through <a target="_blank" class=" " href="https://github.com/kentcdodds/babel-plugin-macros">babel-plugin-macros</a>. In fact, it’s possible to get <em>some</em> MDX support with babel-plugin-macros through the <a target="_blank" class=" " href="https://www.npmjs.com/package/mdx.macro">mdx.macro</a> package (by yours truly). However, this package has a <a target="_blank" class=" " href="https://github.com/facebook/create-react-app/issues/5580">major drawback</a>: you’ll need to manually restart the server each time you change an <code>.mdx</code> file.</p><p>In order to implement proper MDX support through babel-plugin-macros, babel itself will need a <a target="_blank" class=" " href="https://github.com/babel/babel/issues/8497">new feature</a>. But this feature doesn’t exist yet. So how are you going to get the benefit of MDX without ejecting from create-react-app?</p><h2 id="react-scripts-mdx"><a class="doc-headingLink  " href="#react-scripts-mdx">#</a>react-scripts-mdx</h2><p>One of the great things about create-react-app is that it doesn’t force you to use the official scripts. It makes it <em>dead easy</em> to use a fork. And given that there’s now a <a target="_blank" class=" " href="https://github.com/jamesknelson/create-react-app-mdx">react-scripts-mdx</a> fork, this means that getting started with MDX and create-react-app is a one-liner:</p><div>Unimplemented.</div><p>Simple, huh? Or if you’ve already got a create-react-app generated project, you can add MDX support by just switching out <code>react-scripts</code> with <code>react-scripts-mdx</code> in your <code>dependencies</code> and running <code>yarn install</code> or <code>npm install</code>. Then, you’ll be able to add MDX files like this to your project:</p><pre class="language-markdown"><code># I&#x27;m a Markdown file

And I can use &lt;em className=&quot;jsx&quot;&gt;JSX!&lt;/em&gt;
</code></pre><p>Then <code>import</code> and use your MDX file, just as you would with any other React component:</p><pre class="language-jsx"><code>import React, { Component } from &#x27;react&#x27;;
import &#x27;./App.css&#x27;;
import MDXDocument from &#x27;./test.md&#x27;;

class App extends Component {
  render() {
    return (
      &lt;div className=&quot;App&quot;&gt;
        &lt;MDXDocument /&gt;
      &lt;/div&gt;
    );
  }
}

export default App;
</code></pre><p>Neat, huh? But while adding MDX support is super easy, is it really ok to use a fork?</p><h2 id="what-the-fork-changes"><a class="doc-headingLink  " href="#what-the-fork-changes">#</a>What the fork changes</h2><p>The <code>react-scripts-mdx</code> fork makes a single change to <code>react-scripts</code>:</p><p><strong><code>react-scripts-mdx</code> will transform <code>.md</code> and <code>.mdx</code> files with <a target="_blank" class=" " href="https://www.npmjs.com/package/mdx-loader">mdx-loader</a>.</strong></p><p>The fork is <a target="_blank" class=" " href="https://github.com/jamesknelson/create-react-app-mdx/blob/2.1.1-mdx/packages/react-scripts/fixtures/kitchensink/src/features/webpack/MdxInclusion.test.js">tested</a>, and is only a tiny patch on the main create-react-app project — making maintenance easy. Of course, the fork shouldn’t be necessary forever! Once babel-plugin-macros gains live reload support, it’ll be simple to transition over to that instead.</p><p>But for the moment, if you need MDX and create-react-app? Give react-scripts-mdx a try!</p><p>Thanks for reading! And if you have any questions, give me a shout on twitter at <a target="_blank" class=" " href="https://twitter.com/james_k_nelson">@james_k_nelson</a>. And until next time, happy mdxing!</p></div>]]></content:encoded>
            <author>james@jamesknelson.com (James K Nelson)</author>
        </item>
        <item>
            <title><![CDATA[Static vs. Server Rendering]]></title>
            <link>https:/frontarm.com/james-k-nelson/static-vs-server-rendering/</link>
            <guid>https:/frontarm.com/james-k-nelson/static-vs-server-rendering/</guid>
            <pubDate>Sat, 15 Dec 2018 00:00:00 GMT</pubDate>
            <description><![CDATA[Static rendering and server rendering both involve rendering HTML for each of your app's pages – but there's one major difference between them...]]></description>
            <content:encoded><![CDATA[<div class="doc-wrapper doc-Doc-18aNW doc-align-center-when-narrow-2ypbP "><p>So you’ve heard the terms static and server rendering. You know that they both improve SEO and involve generating HTML for your website or app. And given that you’re using React, then <a target="_blank" class=" " href="https://reactjs.org/docs/react-dom-server.html#rendertostring"><code>ReactDOMServer.renderToString()</code></a> lets you accomplish either.</p><p>So they’re basically the same thing, right? Well, they’re aaalllmost the same. Let me explain.</p><h2 id="static-rendering-is-eager-server-rendering-is-lazy"><a class="doc-headingLink  " href="#static-rendering-is-eager-server-rendering-is-lazy">#</a>Static rendering is eager, server rendering is lazy</h2><p>Both static and server rendering involve generating HTML for each of your site’s URLs. The difference is that <strong>static rendering happens once at build time</strong>, while <strong>server rendering happens on-demand</strong>, as the user requests each file.</p><h3 id="static-rendering"><a class="doc-headingLink  " href="#static-rendering">#</a>Static rendering</h3><p>With <strong>static rendering</strong>, you’ll need to generate a single HTML file for every page that the user can access ahead of time. You’ll then serve these pages from a cloud service like S3, or from a server running something like nginx.</p><img src="/static/media/static-rendering.ac5d510c.png" alt="static rendering diagram"/><p>Static rendering has the advantage of being able to serve requests stupidly fast, because nothing needs to be generated on the fly. In fact, since your site’s responses are all generated ahead of time, you can store the files all over the world on a CDN (on the <em>edge</em>). This gives your site <em>ridiculously</em> fast response times. But there’s a catch.</p><p>With static rendering, you need to generate responses for <em>every possible request</em> ahead of time. For websites  focussed on high quality content, this is fine — static renderers like <a class=" " href="/navi/">Navi</a> can generate hundreds of pages in mere seconds. But what if you’re building something where you can’t predict all possible requests, like a search engine? Or what if you have a lot of user generated contend, and the response changes on every request? In that case, you’ll need server rendering.</p><h3 id="server-rendering"><a class="doc-headingLink  " href="#server-rendering">#</a>Server rendering</h3><p>In the React world, <strong>server rendering</strong> refers to the process of generating HTML on demand for each request. Usually, you’ll accomplish this by setting up a server running something like <a target="_blank" class=" " href="https://expressjs.com/">express</a> or <a target="_blank" class=" " href="https://nextjs.org/">Next.js</a> that renders your React app with each request — just as with a more traditional PHP or Rails based website.</p><img src="/static/media/server-rendering.c64da2e3.png" alt="server rendering diagram"/><p>Server rendering is <em>always</em> slower than serving static content. However, you’d need to mess things up pretty badly for the slowdown to be anything greater than a second — and whether this kind of delay matters really depends on your business requirements.</p><p>Of course, for what server rendering lacks in speed, it makes up for in flexibility. It allows you to:</p><ul><li>Respond to <em>any</em> request that the user makes — even ones you might not have expected.</li><li>Pull the most recent content from a database, instead of server older static files.</li><li>Selectively hide content from unauthenticated users.</li></ul><h2 id="so-which-should-i-use"><a class="doc-headingLink  " href="#so-which-should-i-use">#</a>So which should I use?</h2><p>The answer is — of course — <em>it depends.</em></p><p>If <strong>static</strong> rendering is possible, it’ll give you a faster, cheaper, simpler solution. However, if your site needs to serve HTML that meets any of these requirements, then you’ll need <strong>server</strong> rendering:</p><ul><li>If you can’t predict all possible requests</li><li>If the response changes depending on who is viewing it</li><li>If responses quickly go out of date</li></ul><p>Keep in mind that these requirements will only make server rendering necessary <strong>if you need to serve specific HTML for each page for SEO purposes</strong>. For example, a social network or online marketplace would best be built as a server rendered site.</p><p>On the other hand, if you’re building something where SEO is irrelevant — e.g. an app that lives behind a login screen — then your app only needs a single HTML file. It used to be that this was by far the simplest option, as it meant that you could just use stock create-react-app. However, recent improvements in static and server rendering tooling have mostly closed the simplicity gap.</p><h2 id="rendering-tooling"><a class="doc-headingLink  " href="#rendering-tooling">#</a>Rendering tooling</h2><p>When I first started building websites with React a couple years ago, static/server rendering was <em>fucking hard</em>. I even wrote an article telling you <a target="_blank" class=" " href="http://jamesknelson.com/universal-react-youre-doing-it-wrong/"><em>don’t do it</em></a>. But things have changed <em>a lot</em>.</p><p>There are a growing number of tools for statically rendering React-based websites and apps. <a target="_blank" class=" " href="https://www.gatsbyjs.org/">Gatsby</a> is a popular, heavy-duty option. For something simpler, you can try <a class=" " href="/navi/">Navi</a>, which drives this website and works alongside create-react-app.</p><p>As for server rendering, you have two options: the Next.js way, and the Express way. With <a target="_blank" class=" " href="https://nextjs.org/learn/">Next.js</a>, you get an entire framework and a hosting solution that works out of the box — but you tie your project to Next.js (who have stated that they <a target="_blank" class=" " href="https://github.com/zeit/next.js/issues/1691">will not provide an option to eject</a>). If this doesn’t work for you, then you can always set up a more traditional <a target="_blank" class=" " href="https://expressjs.com/">Express</a> app (and Navi’s router makes this easier than ever!)</p><h2 id="a-little-trivia"><a class="doc-headingLink  " href="#a-little-trivia">#</a>A little trivia</h2><p>Let me close by explaining how the site that you’re reading right now works. Frontend Armory is statically rendered. Each time the content changes, the site is re-built using <a class=" " href="/navi/">Navi</a>, then pushed to S3. Then, when you send a request, it first checks for a cached version that is geographically close to you with CloudFront, before requesting it from S3 if that fails.</p><p>And that’s why Frontend Armory feels so snappy — it’s all about routing and static rendering!</p><p><em>Want to build a blinding fast website with great SEO? I’ll be launching a new course walking you through the process of building and deploying a statically rendered site with Navi and create-react-app later this month. <a class=" " href="/members/register/">Sign up</a> to make sure you don’t miss it!</em></p></div>]]></content:encoded>
            <author>james@jamesknelson.com (James K Nelson)</author>
        </item>
        <item>
            <title><![CDATA[Navi: SEO & routing with vanilla create-react-app]]></title>
            <link>https:/frontarm.com/james-k-nelson/announcing-navi/</link>
            <guid>https:/frontarm.com/james-k-nelson/announcing-navi/</guid>
            <pubDate>Wed, 12 Dec 2018 00:00:00 GMT</pubDate>
            <description><![CDATA[Build big, fast, CDN-delivered websites with great SEO & SMO, and all with vanilla create-react-app!]]></description>
            <content:encoded><![CDATA[<div class="doc-wrapper doc-Doc-18aNW doc-align-center-when-narrow-2ypbP "><p>Businesses live and die on their web traffic, most which comes from search engines and social media. If you’re getting paid to build websites or web apps, then you <em>need</em> to think about SEO and SMO — it’s just how the world works.</p><p>Now if you were building an old-school PHP or Rails app, SEO would be free and SMO would be easy — you’d just add some meta tags to the <code>&lt;head&gt;</code> of your HTML files. But the future belongs to serverless React, and this presents a problem. <strong>You want to build a beautiful, interactive site, but you <em>don’t</em> want to have to eject from create-react-app to do it.</strong></p><p><em>TL;DR? Jump to <a class=" " href="/navi/">the docs</a> or <a target="_blank" class=" " href="https://github.com/frontarm/navi">the code</a>.</em></p><p>The thing is, React just wasn’t built to do SEO by itself. Sure, it has a <code>renderToString()</code> method… but it doesn’t support most lifecycle methods. And while server-side Suspense is coming, it’s been coming for a year and there’s <em>still</em> no release date.</p><p>So here’s the deal: you’re getting paid to build websites. You need to build traffic <em>now</em> — but you don’t want to reimplement everything <em>yet again</em> 6 months down the track. And you’re not alone, <em>so let’s do something about it.</em></p><h2 id="have-your-cake-and-eat-it-too"><a class="doc-headingLink  " href="#have-your-cake-and-eat-it-too">#</a>Have your cake and eat it too</h2><p>Today I’m releasing Navi: the router and static renderer that drives Frontend Armory. <strong>Navi lets you create big, fast, CDN-delivered websites with great SEO &amp; SMO, and all with vanilla create-react-app.</strong> Of course, Navi also works great <em>after</em> ejecting, or even with an express-based app. No matter how you use it, you’ll save gobs of time with:</p><p>🔥 Simple loading transitions for async content<br/>
🗺️ JSON site maps that can be built at runtime or build time<br/>
⚠️ Console warnings when a <code>&lt;Link&gt;</code> points to a 404<br/>
📜 Scroll management that just works<br/>
♿️ Page <code>&lt;title&gt;</code> management for accessibility<br/>
🏷️ Great TypeScript support<br/>
👌 A dead-simple API<br/></p><h2 id="many-hands-make-light-work"><a class="doc-headingLink  " href="#many-hands-make-light-work">#</a>Many hands make light work</h2><p>Navi has around 2 years of history behind it, and its overarching design has barely changed over that time. It’s React integration was designed to work great with React Suspense - so when it arrives, your app will spontaneously grow a number of new features. And of course, Navi is 100% open source and open to contributions. Here are a few ways you could help:</p><ul><li>Try it out and <a target="_blank" class=" " href="https://github.com/frontarm/navi/issues">open an issue</a> with your feedback 😄</li><li>Build the <a target="_blank" class=" " href="https://github.com/frontarm/navi/issues/18">Vue integration</a> (The <code>navi</code> package itself is vanilla JavaScript, and it’ll work just as well with Vue as it does with React)</li><li>Use the <em>edit this page</em> links to improve pages in <a class=" " href="/navi/">the documentation</a></li></ul><p>Speaking of documentation — the Navi website is 100% open source, and built with Navi and React itself. If you want to run it locally, just clone the <a target="_blank" class=" " href="https://github.com/frontarm/navi-website">navi-website</a> repository, then run <code>yarn install</code> and <code>yarn start</code> and you’ll be good to go! But if you view them on Frontend Armory, you’ll get an extra special feature…</p><h2 id="all-i-want-for-christmas-is-amazing-documentation"><a class="doc-headingLink  " href="#all-i-want-for-christmas-is-amazing-documentation">#</a>All I want for Christmas is amazing documentation</h2><p>Navi’s docs are choc-full of example code. And when viewing the docs as a Frontend Armory Pro member, many of these examples will be interactive <a class=" " href="/articles/announcing-demoboard/">demoboards</a> — allowing you to quickly try out new things, and easily share the result with colleagues and friends. Pro members will also gain access to docs on niche topics like integrating Navi with react-router or react-helmet — helping to support development, and giving you peace of mind about the project’s sustainability into the future.</p><p>Of course, <em>all</em> of the documentation will still be completely open source, and available for you to fork and edit at your pleasure. In fact, the first three docs are already available, and I’ll be releasing a new page each day until Christmas. Here’s the plan:</p><ul><li>Wednesday 12th: <a class=" " href="/navi/guides/minimal-example/">A Minimal Example</a>, <a class=" " href="/navi/reference/declarations/">Declaring Pages</a> and <a class=" " href="/navi/guides/static-rendering/">Static Rendering</a></li><li>Thursday 13th: <a class=" " href="/navi/integrations/react/">Integrating with React</a> and Launch! 🚀</li><li>Friday 14th: <a class=" " href="/navi/guides/authenticated-routes/">Authenticated Routes</a>, more live examples</li><li>Saturday 15th: <a class=" " href="/navi/reference/navigation/">The <code>navigation</code> object</a>, <a class=" " href="/navi/reference/navigation/"><code>history</code> object</a></li><li>Sunday 16th: <a class=" " href="/navi/reference/route-and-segment/"><code>Route</code> and <code>Segment</code></a> and <a class=" " href="/navi/reference/url-descriptor/"><code>URLDescriptor</code></a> types</li></ul><ul><li>Monday 17th: <a class=" " href="/navi/create-react-navi-app/">create-react-navi-app</a></li><li>Tuesday 18th: <a class=" " href="/navi/integrations/react-router/">Integrating with react-router</a></li><li>Wednesday 19th: <a target="_blank" class=" " href="https://www.youtube.com/watch?v=PkIS_Xgf1zc">Video Introduction</a></li><li>Thursday 20th: <a class=" " href="/navi/integrations/react-helmet/">Integrating with react-helmet</a> <small>(pro exclusive)</small></li><li>Friday 21st: <a class=" " href="/navi/reference/router/">The <code>router</code> object</a></li><li>Saturday 22nd: <a class=" " href="/navi/guides/layouts-nested-content/">Layouts and nested content</a></li><li>Sunday 23rd: <a target="_blank" class=" " href="https://github.com/frontarm/navi/tree/master/examples/blog">Blog example</a></li></ul><ul><li><em>Coming soon</em>: <em>Generating JSON site maps</em> <small>(pro exclusive)</small></li><li>🎄 Christmas Day: it’s a surprise 😉</li></ul><p>I’ll be linking each of these pages as they’re released, so check back each day to get a brand new link! ⏱ </p><p>Thanks so much for reading! Given that you’ve read all this way, you really should give Navi a try — just head on through to <a class=" " href="/navi/guides/minimal-example/">A Minimal Example</a> in the docs to try it out within the browser. And once you’re done, let me know your thoughts! Just <a target="_blank" class=" " href="https://github.com/frontarm/navi/issues">open an issue</a>, or send me a tweet at <a target="_blank" class=" " href="https://twitter.com/james_k_nelson">@james_k_nelson</a>. Finally, if you decide to use Navi in your project, make sure to <a class=" " href="/pricing/individual/">join Frontend Armory Pro</a> to unlock access to the demoboards and integration docs.</p><p>See you again on Christmas Day with a Navi surprise! 🎁</p></div>]]></content:encoded>
            <author>james@jamesknelson.com (James K Nelson)</author>
        </item>
    </channel>
</rss>