<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Kyle Shevlin&apos;s Blog RSS Feed</title><description>Kyle Shevlin is a software engineer who specializes in JavaScript, TypeScript, React and frontend web development.</description><link>https://kyleshevlin.com/</link><item><title>&lt;code&gt;AsyncData&lt;/code&gt;</title><link>https://kyleshevlin.com/async-data/</link><guid isPermaLink="true">https://kyleshevlin.com/async-data/</guid><description>We&apos;ve talked about enumerating states. We&apos;ve talked about using state machines. Now let&apos;s talk about functors. For managing state, that is.</description><pubDate>Sun, 11 Jan 2026 18:14:40 GMT</pubDate><content:encoded>&lt;p&gt;Over the years, I&apos;ve had an interest in modeling state problems as accurately as possible. I submit posts like &lt;a href=&quot;/enumerate-dont-booleanate&quot;&gt;Enumerate, Don&apos;t Booleanate&lt;/a&gt; and my many posts on &lt;a href=&quot;/tags/state-machines&quot;&gt;state machines&lt;/a&gt; as evidence. I can&apos;t stand allowing impossible states or &lt;a href=&quot;/multiple-boolean-props-are-a-code-smell&quot;&gt;leaking implementation details&lt;/a&gt; when there&apos;s a better way.&lt;/p&gt;
&lt;p&gt;I thought I had reached the zenith of my state representation journey, but I was wrong.&lt;/p&gt;
&lt;p&gt;I recently decided to revisit functional programming and really dove into understanding monads, functors, etc. even more than I have in the past. I&apos;ve been learning &lt;a href=&quot;https://gleam.run&quot;&gt;Gleam&lt;/a&gt; for fun, and writing my own little beginner&apos;s functional programming library to help ingrain the concepts. &amp;lt;Marker content=&quot;I haven&apos;t published it yet. It&apos;s not even at version 0.1.0.&quot; /&amp;gt; As part of my research, I&apos;ve been closely studying the &lt;a href=&quot;https://boxed.cool&quot;&gt;Boxed library&lt;/a&gt; and the data types it implements. That&apos;s how I came across the &lt;code&gt;AsyncData&lt;/code&gt; data type.&lt;/p&gt;
&lt;p&gt;There is some context that I think would be very helpful for you to understand why I find &lt;code&gt;AsyncData&lt;/code&gt; so interesting, but including it here would take a lot of words. Instead, I&apos;m going to list the concepts here for you to look up: &amp;lt;Marker content=&quot;Hopefully, I get around to writing my own posts about them some day.&quot; /&amp;gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Discriminated unions, check out &lt;a href=&quot;https://www.typescriptlang.org/docs/handbook/2/narrowing.html#discriminated-unions&quot;&gt;here&lt;/a&gt; and &lt;a href=&quot;/discriminated-unions-and-destructuring-in-typescript&quot;&gt;here&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Functors, check out &lt;a href=&quot;https://mostly-adequate.gitbook.io/mostly-adequate-guide/ch08#my-first-functor&quot;&gt;here&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Representing async data, imperatively&lt;/h3&gt;
&lt;p&gt;I&apos;m going to assume that most of you reading this have used the &lt;code&gt;fetch&lt;/code&gt; method to get some data from an API.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function getData() {
  return fetch(&apos;/some/url&apos;).then(res =&amp;gt; res.json())
}

const result = await getData()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When we fetch data, we generally need to manage some state about that data fetch so that we can respond to the various states it&apos;s in. I&apos;m going to keep using plain JavaScript for my example, but you can imagine what it might look like for your framework of choice.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let loading = false
let error = null
let data = null

async function getData() {
  // reset state from previous fetch
  error = null

  // start managing this loading state
  loading = true

  fetch(&apos;/some/url&apos;)
    .then(res =&amp;gt; res.json())
    .then(d =&amp;gt; {
      data = d
    })
    .catch(err =&amp;gt; {
      error = err
    })
    .finally(() =&amp;gt; {
      loading = false
    })
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This works, but it&apos;s a lot of manual setup (often repeated many times in a codebase) and it allows for possible impossible states if written poorly. The fact that there are three variables to manage the state means that somewhere in our code we might check for &lt;code&gt;loading&lt;/code&gt;, &lt;code&gt;data&lt;/code&gt;, or &lt;code&gt;error&lt;/code&gt; in some incorrect way that leads to us showing an &lt;code&gt;error&lt;/code&gt; when we should be &lt;code&gt;loading&lt;/code&gt; or already have some &lt;code&gt;data&lt;/code&gt;. &amp;lt;Marker content=&quot;Notice I didn&apos;t reset the data. Maybe you do or don&apos;t want to do that.&quot; /&amp;gt; It&apos;s prone to human error and can be avoided.&lt;/p&gt;
&lt;p&gt;We can make this better by enumerating the states. I won&apos;t go so far as using a state machine, though I could. Instead, I&apos;ll use a discriminated union to represent the possible states instead.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type State&amp;lt;Data&amp;gt; =
  | { status: &apos;not-asked&apos; }
  | { status: &apos;loading&apos; }
  | { status: &apos;failure&apos;; message: string }
  | { status: &apos;success&apos;; data: Data }

let state: State = { status: &apos;not-asked&apos; }

async function getData&amp;lt;Data&amp;gt;() {
  state = { status: &apos;loading&apos; }

  fetch(&apos;/some/url&apos;)
    .then(res =&amp;gt; res.json())
    .then(d =&amp;gt; {
      state = { status: &apos;success&apos;, data: d as Data }
    })
    .catch(err =&amp;gt; {
      state = { status: &apos;failure&apos;, message: err.message }
    })
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is way better than before. We only have one variable that manages all our state. We never have to reset state before fetching, and we can&apos;t possibly have an impossible state downstream. The use of the discriminated union also means TypeScript will narrow our types for us based on &lt;code&gt;status&lt;/code&gt;, too.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if (state.status === &apos;success&apos;) {
  // TypeScript knows state.data is the type Data here
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you stopped at this point, that would be great. Your codebase would improve just from this step. But there&apos;s a subtle way that this is inaccurate that I hadn&apos;t noticed.&lt;/p&gt;
&lt;p&gt;But this is where &lt;code&gt;AsyncData&lt;/code&gt; and its friend, &lt;code&gt;Result&lt;/code&gt;, come in.&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;AsyncData&lt;/code&gt; and &lt;code&gt;Result&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;What if instead of a type, we used a functor to represent our discriminated union? And what if we separated the concerns of the async process from the concerns of which &quot;data&quot; we received at the same time? That could be pretty cool.&lt;/p&gt;
&lt;p&gt;Let&apos;s start by implementing &lt;code&gt;AsyncData&lt;/code&gt;. It&apos;s a Sum type made up of three sub-types: &lt;code&gt;NotAsked&lt;/code&gt;, &lt;code&gt;Loading&lt;/code&gt; and &lt;code&gt;Done&lt;/code&gt;. We can setup some classes &amp;lt;Marker content=&quot;Ironic. I know.&quot; /&amp;gt; to make this work:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type Tag = &apos;NotAsked&apos; | &apos;Loading&apos; | &apos;Done&apos;

class AsyncData&amp;lt;T&amp;gt; {
  #tag: Tag
  #value: T

  constructor(tag: Tag, value: T) {
    this.#tag = tag
    this.#value = value
  }

  static NotAsked() {
    return new NotAsked()
  }

  static Loading() {
    return new Loading()
  }

  static Done&amp;lt;U&amp;gt;(value: U) {
    return new Done(value)
  }
}

class NotAsked extends AsyncData&amp;lt;never&amp;gt; {
  constructor() {
    super(&apos;NotAsked&apos;, undefined as never)
  }
}

class Loading extends AsyncData&amp;lt;never&amp;gt; {
  constructor() {
    super(&apos;Loading&apos;, undefined as never)
  }
}

class Done&amp;lt;T&amp;gt; extends AsyncData&amp;lt;T&amp;gt; {
  constructor(value: T) {
    super(&apos;Done&apos;, value)
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That&apos;s not our full implementation, but let&apos;s see how we&apos;d use this instead in our &lt;code&gt;fetch&lt;/code&gt; example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let state = AsyncData.NotAsked()

function getData() {
  state = AsyncData.Loading()

  fetch(&apos;/some/url&apos;)
    .then(res =&amp;gt; res.json())
    .then(data =&amp;gt; {
      state = AsyncData.Done(data)
    })
    .catch(error =&amp;gt; {
      state = AsyncData.Done(error)
    })
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, if you&apos;re paying attention, you might think, &quot;Kyle, that&apos;s objectively worse. You&apos;re passing &lt;code&gt;data&lt;/code&gt; and &lt;code&gt;error&lt;/code&gt; to the &lt;code&gt;Done&lt;/code&gt; state and we can&apos;t discriminate between the two.&quot; You&apos;d be right, but stay with me. We&apos;re going to make two more changes that will set your mind at ease.&lt;/p&gt;
&lt;p&gt;Now, I called &lt;code&gt;AsyncData&lt;/code&gt; a functor because it is. We could implement &lt;code&gt;map&lt;/code&gt; and &lt;code&gt;map&lt;/code&gt; would only interact with the &lt;code&gt;value&lt;/code&gt; when it&apos;s &lt;code&gt;Done&lt;/code&gt;, otherwise it&apos;s a noop. But more interesting to our purposes is &lt;a href=&quot;/pattern-matching&quot;&gt;pattern matching&lt;/a&gt;. We&apos;re going to implement a &lt;code&gt;match&lt;/code&gt; method.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class AsyncData&amp;lt;T&amp;gt; {
  // same as before... new stuff below
  isNotAsked(): this is NotAsked {
    this.#tag === &apos;NotAsked&apos;
  }

  isLoading(): this is Loading {
    this.#tag === &apos;Loading&apos;
  }

  isDone(): this is Done&amp;lt;T&amp;gt; {
    this.#tag === &apos;Done&apos;
  }

  // Here&apos;s the good stuff
  match&amp;lt;A, B, C&amp;gt;({
    NotAsked,
    Loading,
    Done,
  }: {
    NotAsked: () =&amp;gt; A
    Loading: () =&amp;gt; B
    Done: (value: T) =&amp;gt; C
  }): A | B | C {
    if (this.isNotAsked()) NotAsked()
    if (this.isLoading()) Loading()
    if (this.isDone()) Done(this.#value)
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Our &lt;code&gt;match&lt;/code&gt; method takes an object with three keys that match our possible sub-types, whose value is the function to call if the data happens to be in that particular state. Now we have a rock-solid way of responding to &lt;code&gt;AsyncData&lt;/code&gt; as it changes, such as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type State = AsyncData&amp;lt;Result&amp;lt;Data, Error&amp;gt;&amp;gt;

function MyDataDisplay() {
  const [state, setState] = React.useState&amp;lt;State&amp;gt;(AsyncData.NotAsked())

  React.useEffect(() =&amp;gt; {
    function getData() {
      setState(AsyncData.Loading())

      fetch(&apos;/some/url&apos;)
        .then(res =&amp;gt; res.json())
        .then(data =&amp;gt; {
          setState(AsyncData.Done(Result.Ok(data)))
        })
        .catch(error =&amp;gt; {
          setState(AsyncData.Done(Result.Error(error)))
        })
    }

    getData()
  }, [])

  return state.match({
    NotAsked: () =&amp;gt; null,
    Loading: () =&amp;gt; &amp;lt;div&amp;gt;Loading...&amp;lt;/div&amp;gt;,
    Done: result =&amp;gt;
      result.match({
        Ok: data =&amp;gt; &amp;lt;DataViz data={data} /&amp;gt;,
        Error: error =&amp;gt; (
          &amp;lt;div&amp;gt;Whoops! Something went wrong: {error.message}&amp;lt;/div&amp;gt;
        ),
      }),
  })
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;See what I did there?! Sure, I threw a curveball at you with the &lt;code&gt;Result&lt;/code&gt; data type, but I bet you can figure it out. We&apos;ve now completely separated the async process from that state of the data or error that was returned. That&apos;s a wholly separate concern, nicely managed with the &lt;code&gt;Result&lt;/code&gt; type. And the pattern matching is just so clean (not to mention type-safe).&lt;/p&gt;
&lt;p&gt;Now we have a singular, reusable data type that we can use whenever we have an async process. No more imperative variables or states to setup, and no discriminated TypeScript unions to write either. Just our one, singular &lt;code&gt;AsyncData&lt;/code&gt; state. I think that&apos;s really cool.&lt;/p&gt;
&lt;h3&gt;Do I expect to ever use this?&lt;/h3&gt;
&lt;p&gt;In one of my projects? Sure. But in my day-to-day work, no.&lt;/p&gt;
&lt;p&gt;What I find cool and interesting doesn&apos;t often make it into the product I&apos;m working on. I find it pretty difficult to convince people to try something like this, so I wouldn&apos;t stress about it if you like the pattern and can&apos;t use it either. Take satisfaction in knowing an &lt;em&gt;even better way&lt;/em&gt; to represent some of the state in your app.&lt;/p&gt;
&lt;p&gt;If you do want to try using this, I recommend checking out &lt;a href=&quot;https://boxed.cool&quot;&gt;Boxed&lt;/a&gt;. It has the &lt;code&gt;AsyncData&lt;/code&gt; and &lt;code&gt;Result&lt;/code&gt; types you need as well as some examples. Check it out.&lt;/p&gt;
&lt;p&gt;If I ever finish that library I&apos;m writing, I&apos;ll let you know.&lt;/p&gt;
</content:encoded><category>Functional Programming</category><category>TypeScript</category><category>JavaScript</category><category>React</category></item><item><title>Nothing is Something</title><link>https://kyleshevlin.com/nothing-is-something/</link><guid isPermaLink="true">https://kyleshevlin.com/nothing-is-something/</guid><description>If this, do that; else, do nothing. A programmer&apos;s story as old as time. But what if doing nothing is actually doing something. And what if our code can get a lot simpler by recognizing that?</description><pubDate>Sat, 20 Dec 2025 00:14:23 GMT</pubDate><content:encoded>&lt;p&gt;I really need more people to watch &lt;a href=&quot;https://www.youtube.com/watch?v=OMPfEXIlTVE&quot;&gt;&quot;Nothing is Something&quot; by Sandi Metz&lt;/a&gt; so I don&apos;t get weird looks when I apply its lessons to my code.&lt;/p&gt;
&lt;p&gt;I was dealing with a problem like the following today. Imagine you got an object of key/value pairs, where the key is a bit of state and the value transforms that state somehow.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Just some arbitrary state for our example
type State = {
  count: number
  createdAt: Date
  isActive: boolean
  name: string
}

type Transform = &amp;lt;T&amp;gt;(x: T) =&amp;gt; T

const STATE_TRANSFORMS: Partial&amp;lt;Record&amp;lt;keyof State, Transform&amp;gt;&amp;gt; = {
  count: x =&amp;gt; x * 2,
  name: x =&amp;gt; x.toUpperCase(),
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The transforms themselves aren&apos;t terribly important, but notice that I don&apos;t have a transformation for every key in the &lt;code&gt;State&lt;/code&gt; type.&lt;/p&gt;
&lt;p&gt;Now, if you were to make a function to run those transforms, you might be tempted to do:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function transformStates(state: State) {
  const nextState: State = {}

  for (const key of state) {
    const transform = STATE_TRANSFORMS[key]

    // This handles the condition at the last possible moment
    // and it results in two separate ways of managing the state
    if (transform) {
      nextState[key] = transform(state[key])
    } else {
      nextState[key] = state[key]
    }
  }

  return nextState
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But I prefer to do this instead:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const identity = x =&amp;gt; x

function transformStates(state) {
  const nextState = {}

  for (const key of state) {
    // Condition is handled a step earlier and we&apos;ve narrowed
    // the type of `transform` from `Transform | undefined`
    // to just `Transform`, simplifying the next step
    const transform = STATE_TRANSFORMS[key] ?? identity

    nextState[key] = transform(state[key])
  }

  return nextState
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Because, as the title of the talk suggests, doing nothing &lt;em&gt;is&lt;/em&gt; doing something.&lt;/p&gt;
&lt;p&gt;You might argue that I&apos;m making unnecessary function calls here, but I think it&apos;s a worthwhile trade-off for simpler code.&lt;/p&gt;
&lt;p&gt;We can use this pattern of identifying the &quot;nothing&quot;, aka the default behavior, and providing the functionality for it as a way to simplify our code, primarily by reducing excessive conditionals which tends to be the source of complexity.&lt;/p&gt;
&lt;p&gt;Please watch the talk. You&apos;ll be a better programmer for it.&lt;/p&gt;
</content:encoded><category>JavaScript</category><category>TypeScript</category></item><item><title>&lt;code&gt;data&lt;/code&gt; Attributes for Testing</title><link>https://kyleshevlin.com/data-attributes-for-testing/</link><guid isPermaLink="true">https://kyleshevlin.com/data-attributes-for-testing/</guid><description>Sometimes our tests are too imperative and know too much about the implementation details of the component. Learn how `data` attributes might be able to help you out.</description><pubDate>Fri, 21 Nov 2025 18:37:54 GMT</pubDate><content:encoded>&lt;p&gt;I don&apos;t know if this is the world&apos;s best idea, but given the situation I&apos;m faced with, it&apos;s the best one I&apos;ve got.&lt;/p&gt;
&lt;p&gt;At my place of work, we have a design system partially built with custom web components. Given how web components are implemented, occasionally there&apos;s an attribute or piece of data we would like to test for that is in the shadow DOM. This poses a small problem for testing.&lt;/p&gt;
&lt;p&gt;I want to keep my tests as declarative as possible, but to get that information I have to imperatively reach into the shadow DOM. I don&apos;t like this. Especially if there&apos;s any chance we might change the implementation of the component. I want the tests to keep passing, so long as we haven&apos;t changed the public interface.&lt;/p&gt;
&lt;p&gt;As it stands, we sometimes have to search through the shadow DOM to find the right shadow part of an element we want to test. This requires making a special selector for those parts, and means our tests can be break if we make a change to the implementation.&lt;/p&gt;
&lt;p&gt;For example, we have a button component that can be passed an &lt;code&gt;href&lt;/code&gt; or &lt;code&gt;to&lt;/code&gt; prop and it will render as an &lt;code&gt;a&lt;/code&gt; tag in the shadow DOM. If I want to look at the resulting &lt;code&gt;href&lt;/code&gt;, I have to use our custom &lt;code&gt;shadowPart&lt;/code&gt; selector to get that element. I&apos;d rather not have to do that.&lt;/p&gt;
&lt;p&gt;The way I&apos;ve gotten around this is by lifting important attributes that otherwise would be buried in the shadow DOM as &lt;code&gt;data-*&lt;/code&gt; attributes on the root element. In the case of that &lt;code&gt;href&lt;/code&gt;, I lift it to a &lt;code&gt;data-href&lt;/code&gt; attribute.&lt;/p&gt;
&lt;p&gt;The dev uses the component like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;OurButton href=&quot;/some/url&quot;&amp;gt;Click me&amp;lt;/OurButton&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the DOM looks something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;our-button data-href=&quot;/some/url&quot;&amp;gt;
  &amp;lt;!-- in the shadow DOM --&amp;gt;
  &amp;lt;a href=&quot;/some/url&quot; part=&quot;base&quot;&amp;gt;Click me&amp;lt;/a&amp;gt;
&amp;lt;/our-button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The tests go from looking like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;expect(wrapper.getByTestId(&apos;our-button&apos;).shadowPart(&apos;base&apos;)).toHaveAttribute(
  &apos;href&apos;,
  &apos;/some/url&apos;,
)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;expect(wrapper.getByTestId(&apos;our-button&apos;)).toHaveAttribute(
  &apos;data-href&apos;,
  &apos;/some/url&apos;,
)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice I don&apos;t need the &lt;code&gt;shadowPart&lt;/code&gt; selector anymore. If, like we&apos;re considering, we drop the custom web component and revert to regular DOM elements, the test will still pass.&lt;/p&gt;
&lt;p&gt;You can do this on a number of components for any number of attributes or props. For example, our button has the following &lt;code&gt;data-*&lt;/code&gt; attributes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;data-loading&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;data-href&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;data-variant&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;data-size&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And there are more, but that&apos;s enough for you to see how the pattern can be implemented.&lt;/p&gt;
&lt;p&gt;These data attributes remain stable while other implementation details change. I&apos;ll give you another example that might apply to you.&lt;/p&gt;
&lt;p&gt;Before I added the &lt;code&gt;data-variant&lt;/code&gt; and &lt;code&gt;data-size&lt;/code&gt; attributes, our tests would look for specific classnames on the button to ensure that a prop was applied properly. The problem with this was if we migrate our system to use something like Tailwind, then all of these tests would break, even if the public interface hadn&apos;t changed.&lt;/p&gt;
&lt;p&gt;By verifying that the data attribute is correct (and assuming all functionality remains the same), we can keep our tests passing even if we make changes under the hood.&lt;/p&gt;
&lt;p&gt;So give it a try. If you&apos;re in a situation where you have some challenging components to test, you might find the &lt;code&gt;data-*&lt;/code&gt; attributes pattern to be helpful.&lt;/p&gt;
</content:encoded><category>React</category><category>Vue</category></item><item><title>Prefer Gaps To Margins</title><link>https://kyleshevlin.com/prefer-gaps-to-margins/</link><guid isPermaLink="true">https://kyleshevlin.com/prefer-gaps-to-margins/</guid><description>Prefer using gaps to margins when it comes to your component layouts.</description><pubDate>Mon, 23 Jun 2025 15:20:35 GMT</pubDate><content:encoded>&lt;p&gt;Preferring gaps to margins is so obvious to me that it&apos;s honestly challenging to write about it. What is there to argue? It just makes sense.&lt;/p&gt;
&lt;p&gt;Yet experience has taught me that it doesn&apos;t &quot;just make sense&quot; to many others, so I&apos;m going to try and make my case.&lt;/p&gt;
&lt;p&gt;Margins and gaps are two different ways to space apart adjacent elements, however there are some key differences to note.&lt;/p&gt;
&lt;p&gt;Margins are applied to an element, either thru CSS or composition, and create a boundary around it such that the element itself can get no closer to any other element than the boundary. We can think of this relationship as child-to-sibling or child-to-outside-world layout strategy.&lt;/p&gt;
&lt;p&gt;Gaps, on the other hand, are a way for a Flex or Grid container to space out the children it contains. Each gap is applied between adjacent sibling elements. We can think of this as a parent-to-children layout strategy.&lt;/p&gt;
&lt;p&gt;Both can be used to space out elements, but whether we choose one or the other really depends on how you answer the following question: &lt;strong&gt;whose responsibility is it for spacing, the parent or the child&lt;/strong&gt;?&lt;/p&gt;
&lt;p&gt;I&apos;ll make no qualms, I fall entirely in the &quot;parents should control the layout of children&quot; camp. I make heavy use of composition in my apps for this very purpose, and I&apos;m perfectly comfortable doing this either with layout components or with utility classes.&lt;/p&gt;
&lt;h3&gt;Why I dislike margins&lt;/h3&gt;
&lt;p&gt;There are a few reasons I think margins are a poor choice for laying out sibling components. Let&apos;s set aside the fact that any layout achieved with margins can be achieved with Flex + gaps instead and let&apos;s focus on issues with margins themselves.&lt;/p&gt;
&lt;p&gt;First, margins require us to wrap each child individually, and often with excessive care. Let&apos;s say I have three items I want to have in vertical column:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;div&amp;gt;
  &amp;lt;Item1 class=&quot;mb-4&quot; /&amp;gt;
  &amp;lt;Item2 class=&quot;mb-4&quot; /&amp;gt;
  &amp;lt;Item3 /&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It may not seem like a lot of code, but we&apos;ve had to manually add classes &lt;em&gt;and&lt;/em&gt; we have to remember not to add it to the final element.&lt;/p&gt;
&lt;p&gt;The issue arises should we ever need to add, remove, or move elements in this list. We now have to manually move classes.&lt;/p&gt;
&lt;p&gt;But let&apos;s say we get wise and instead of hand-writing these components, we choose to derive them from data instead. We&apos;ll programmatically render the list, but we&apos;ll still have to make a caveat for not adding the final margin:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;div&amp;gt;
  {items.map((item, idx) =&amp;gt; (
    &amp;lt;Item
      key={item.id}
      class={idx !== items.length - 1 ? &quot;mb-4&quot; : &quot;&quot;}
      item={item}
    /&amp;gt;
  )}
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What a completely unnecessary bit of code to write when we can use gaps instead?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;div class=&quot;flex flex-col gap-4&quot;&amp;gt;
  {items.map(item =&amp;gt; (
    &amp;lt;Item key={item.id} item={item} /&amp;gt;
  ))}
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Better still, let&apos;s say that list of items should be in a row at a different breakpoint. What&apos;s easier? Manually removing and replacing all the margin classes, or simply changing the direction of the parent container?&lt;/p&gt;
&lt;p&gt;What code would you prefer, this?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;div&amp;gt;
  {items.map((item, idx) =&amp;gt; (
    &amp;lt;Item
      key={item.id}
      // At the medium break point, items should have a right
      // margin now. Ignoring the fact that we&apos;d have to change
      // them to be inline-block or the parent div to a flex
      // row to get them to layout side by side
      class={idx !== items.length - 1 ? &quot;mb-4 md:mb-0 md:mr-4&quot; : &quot;&quot;}
      item={item}
    /&amp;gt;
  )}
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or this?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;div class=&quot;flex flex-col gap-4 md:flex-row&quot;&amp;gt;
  {items.map(item =&amp;gt; (
    &amp;lt;Item key={item.id} item={item} /&amp;gt;
  ))}
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The answer should be glaringly obvious.&lt;/p&gt;
&lt;p&gt;Let&apos;s add one more wrinkle to margins: &quot;vertical margin collapse&quot;. I&apos;m not going to spend a lot of time explaining what it is, &lt;a href=&quot;https://www.joshwcomeau.com/css/rules-of-margin-collapse/&quot;&gt;Josh W. Comeau wrote a fantastic article about it you can read&lt;/a&gt;, but I&apos;m not a big fan of relying upon it in component systems.&lt;/p&gt;
&lt;p&gt;It&apos;s true, you can build systems that use margin collapse as a way to &quot;create sane default spacing&quot;, but I&apos;d argue you spend more time making compensatory classes or CSS to undo the margins than having the defaults are worth. If you find yourself writing CSS classes setting margins to &lt;code&gt;0&lt;/code&gt; or writing a bunch of &lt;code&gt;my-0&lt;/code&gt; classes in your code, you probably have a component system that&apos;s really difficult to compose.&lt;/p&gt;
&lt;h3&gt;Why I love gaps&lt;/h3&gt;
&lt;p&gt;I don&apos;t even think this sections needs a lot of exposition, so I&apos;ll give you the bullet points.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Gaps are automatic. No matter how many items you add, they just keep getting added in the right spot. &lt;strong&gt;Even if your list is of length 1, you never have to worry about an incorrect gap getting applied.&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Gaps are literally less code to write, added once on a parent, no need for children to share classes to share a margin top or bottom, no need for nth-selectors, etc.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Gaps work for both vertical and horizontal spacing. If your items wrap, there&apos;s no need to add additional margin classes to make sure they align on rows correctly. And you never need outer negative margins to ensure inner spacing works!&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Final thoughts&lt;/h3&gt;
&lt;p&gt;Gaps are superior to margins in pretty much every way. I&apos;d rather an app be full of tiny stacks and rows with gaps than deal with margins any day of the week. Combine this concept with my &lt;a href=&quot;/no-outer-margin&quot;&gt;No Outer Margin&lt;/a&gt; post to make your component system more robust.&lt;/p&gt;
</content:encoded><category>Frontend</category><category>Design Systems</category><category>CSS</category><category>Prefer</category></item><item><title>&amp;ldquo;Refactor&amp;rdquo; is Not a Scary Word</title><link>https://kyleshevlin.com/refactor-is-not-a-scary-word/</link><guid isPermaLink="true">https://kyleshevlin.com/refactor-is-not-a-scary-word/</guid><description>At some point, &amp;ldquo;refactor&amp;rdquo; became a scary word, striking fear into the hearts of any manager who hears it. Let&amp;apos;s reclaim the word, remove that fear, and recognize we cannot be good software engineers without developing an ability to refactor code effectively.</description><pubDate>Thu, 27 Feb 2025 16:45:58 GMT</pubDate><content:encoded>&lt;p&gt;One thing I&apos;ve struggled with throughout my life is using a word with a specific definition that gets interpreted differently. It causes me a great deal of frustration. &amp;lt;Marker content={&lt;code&gt;In my childhood, I read the book &quot;The Giver&quot; by Lois Lowry. At one point, the main character makes an exaggerated statement, to which the parents admonish him with, &quot;Precision of language!&quot; I felt understood when I read that.&lt;/code&gt;} /&amp;gt; It might be unreasonable to expect people to walk around with a Merriam-Webster&apos;s dictionary in their pocket, &amp;lt;Marker content=&quot;Actually, I can. 📱&quot; /&amp;gt; so mistakes are bound to happen.&lt;/p&gt;
&lt;p&gt;I recently lost a potential client and I&apos;m convinced the reason why is because we had different definitions for a single word: “refactor”.&lt;/p&gt;
&lt;p&gt;“I&apos;ll need to refactor some of these components to support your new use cases.” This was a benign, workaday statement using common jargon for software engineers, yet I could tell it struck fear in this client. I never had a chance after that.&lt;/p&gt;
&lt;p&gt;I don&apos;t know when it happened, but “refactor” became a &lt;strong&gt;scary&lt;/strong&gt; word, and we need to get it back.&lt;/p&gt;
&lt;h3&gt;Why is it a scary word?&lt;/h3&gt;
&lt;p&gt;I have no research to back up what I&apos;m about to claim, but my suspicion is that people recoil at the word “refactor” because it&apos;s caused them trauma, primarily in the way of costs.&lt;/p&gt;
&lt;p&gt;I think somehow it has become an ambiguous term in the industry roughly meaning &quot;large, time-consuming, and potentially dangerous changes to code.&quot; I find this deeply upsetting as it&apos;s essentially the &lt;em&gt;opposite&lt;/em&gt; of what the word means, which I will discuss shortly.&lt;/p&gt;
&lt;p&gt;Without adherence to a strict definition, I imagine there have been many instances where an engineer mentioned &quot;we need to refactor this&quot; to a manager, and next thing you know, the roadmap ends up derailed, or the project is a failure, or even worse, the company goes out of business.&lt;/p&gt;
&lt;p&gt;These outcomes shouldn&apos;t be the result of refactoring, and we should really get on the same page about the word to avoid this from happening.&lt;/p&gt;
&lt;h3&gt;What does the word actually mean?&lt;/h3&gt;
&lt;p&gt;When I use the word “refactor” or &quot;refactoring&quot;, I mean these two specific definitions that come from the book &quot;Refactoring&quot; by Martin Fowler:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Refactoring&lt;/strong&gt; (noun): a change made to the internal structure of software to make it easier to understand and cheaper to modify without changing its observable behavior.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Refactoring&lt;/strong&gt; (verb): to restructure software by applying a series of refactorings without changing its observable behavior.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The key part of the definition here is &lt;strong&gt;“without changing observable behavior”&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;If you are refactoring, it does not mean rewriting the code from scratch. It does not mean making some changes &lt;em&gt;while&lt;/em&gt; adding new features. It doesn&apos;t even mean changing the structure and &lt;em&gt;hoping&lt;/em&gt; it&apos;s the same. &lt;strong&gt;It means changing the structure of the code &lt;em&gt;knowing&lt;/em&gt; it&apos;s the same.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;There should be &lt;em&gt;no&lt;/em&gt; equivocation about this.&lt;/p&gt;
&lt;h3&gt;Implications of the proper definition&lt;/h3&gt;
&lt;p&gt;The only way to make changes while knowing the observable behavior hasn&apos;t changed is to have a testing suite that can confirm or deny this. Honestly, if you&apos;ve avoided writing tests in your career, you&apos;re doing yourself a disservice. Coding is one of the few industries where we can cheaply and easily verify our work is correct. All it takes is writing a few lines of code. Imagine doing something similar in the physical world, where testing might cost just as much as the actual implementation.&lt;/p&gt;
&lt;p&gt;Extrapolating from this, if we must keep the tests green as we make our changes, I think it suggests two things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The changes we make should be small, incremental steps to our goal&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We should be able to make each change to our code in an understandable fashion. The way we accomplish big changes is through the composition of many small ones. With each small change, we should keep the tests green.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;These small changes reveal algorithmic patterns, aka refactorings, that are repeatable&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We can define what are essentially &quot;recipes&quot; for restructuring code, and for those keen on reading the book, they provide over 60 of them to get started. There are more that can be defined as well.&lt;/p&gt;
&lt;p&gt;This means that when we&apos;re doing a refactoring properly, we should be doing the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Tests related to the code we are changing should be running in a watch mode&lt;/li&gt;
&lt;li&gt;We should be able to make an atomic commit with each step &amp;lt;Marker content=&quot;Some changes, such as &amp;lt;em&amp;gt;Rename Variable&amp;lt;/em&amp;gt; are so small it might not warrant a commit, but it&apos;s hopefully obvious how one could do so.&quot; /&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;An example&lt;/h3&gt;
&lt;p&gt;I&apos;m going to make a rudimentary example to demonstrate how we might refactor a function, without changing it&apos;s behavior, that will make it much easier to enhance in the future.&lt;/p&gt;
&lt;p&gt;Here we have a &lt;code&gt;getTicketPrice&lt;/code&gt; function. It receives a &lt;code&gt;Show&lt;/code&gt; as an argument. Members get a 15% discount on ticket prices, while non-members pay the full price. Our function looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type Show = {
  name: string
  /**
   * The price in cents. Typically it&apos;s better to store money as an object, but
   * here we&apos;ll make the assumption we&apos;re working with US currency.
   */
  price: number
}

function getTicketPrice(show: Show, isMember: boolean) {
  return isMember ? show.price * 0.85 : show.price
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The tests for a function like this are fairly straightforward. I&apos;ll write them in a style that&apos;s compatible with Vitest or Jest:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;describe(&apos;getTicketPrice&apos;, () =&amp;gt; {
  const show: Show = {
    name: &apos;Test show&apos;,
    price: 1000,
  }

  it(&apos;should give members a 15% discount&apos;, () =&amp;gt; {
    expect(getTicketPrice(show, true)).toEqual(850)
  })

  it(&apos;should give non-members the full price&apos;, () =&amp;gt; {
    expect(getTicketPrice(show, false)).toEqual(1000)
  })
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Running our tests shows that they&apos;re working.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Let&apos;s say we learn that we now offer different levels of memberships. A member might be a basic member or a &lt;code&gt;premium&lt;/code&gt; one. Members of &lt;code&gt;premium&lt;/code&gt; status will get an even greater discount of 25%. What does this mean for our function?&lt;/p&gt;
&lt;p&gt;The first obvious thing we&apos;ll need to refactor is the &lt;code&gt;isMember&lt;/code&gt; boolean. Simply put, we won&apos;t be able to represent three possible membership levels with a boolean. I haven&apos;t come across a name for the refactoring we&apos;ll do, but I think &lt;em&gt;Boolean to Variant&lt;/em&gt; might be a good one. As we make this change, remember
we&apos;re trying to keep the same observable behavior.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type Show = {
  name: string
  price: number
}

// We&apos;ll add a membership type and represent our two current states
type Membership = &apos;member&apos; | &apos;non-member&apos;

// We&apos;ll use that type instead of the boolean
function getTicketPrice(show: Show, membership: Membership) {
  // We&apos;ll update our implementation to use our membership instead
  switch (membership) {
    case &apos;member&apos;:
      return show.price * 0.85
    case &apos;non-member&apos;:
      return show.price
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We&apos;ll need to make a small change to our tests, but we&apos;ll see that they continue to pass. An added benefit is we removed a &lt;a href=&quot;https://martinfowler.com/bliki/FlagArgument.html&quot;&gt;flag argument&lt;/a&gt; in the process:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;describe(&apos;getTicketPrice&apos;, () =&amp;gt; {
  const show: Show = {
    name: &apos;Test show&apos;,
    price: 1000,
  }

  it(&apos;should give members a 15% discount&apos;, () =&amp;gt; {
    expect(getTicketPrice(show, &apos;member&apos;)).toEqual(850)
  })

  it(&apos;should give non-members the full price&apos;, () =&amp;gt; {
    expect(getTicketPrice(show, &apos;non-member&apos;)).toEqual(1000)
  })
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Our tests are still green with that change. I won&apos;t share a picture, it&apos;s exactly the same as before.&lt;/p&gt;
&lt;p&gt;That said, I think we&apos;re at a place we can add our new feature. Given the nature of this function, we can write the additional test first, then get it passing:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;it(&apos;should give premium members a 25% discount&apos;, () =&amp;gt; {
  expect(getTicketPrice(show, &apos;premium&apos;)).toEqual(750)
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Our test fails, so let&apos;s get it passing. To do so, we&apos;ll add a &lt;code&gt;premium&lt;/code&gt; variant to &lt;code&gt;Membership&lt;/code&gt; and account for it in our function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type Show = {
  name: string
  price: number
}

type Membership = &apos;member&apos; | &apos;non-member&apos; | &apos;premium&apos;

function getTicketPrice(show: Show, membership: Membership) {
  switch (membership) {
    case &apos;premium&apos;:
      return show.price * 0.75
    case &apos;member&apos;:
      return show.price * 0.85
    case &apos;non-member&apos;:
      return show.price
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And our tests are passing again.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;There might be more that we can do to this function. We could even argue a bit about the best way to do its implementation, but hopefully it gave you some insight into the process of changing code with safe refactorings.&lt;/p&gt;
&lt;h3&gt;Final thoughts&lt;/h3&gt;
&lt;p&gt;We need to reclaim “refactor” because this process of restructure, verify, add feature, verify is simply just doing the job. I don&apos;t want to have to use euphimisms to describe my work just so managers don&apos;t freak out when changes are necessary. I think if refactors remain scary, then we actually make our work more dangerous for ourselves. Avoiding making changes only makes the code more complex and likely more error prone as well.&lt;/p&gt;
&lt;p&gt;If we can embrace refactoring as a safe, atomic way to change code and recognize that it&apos;s just a part of the day to day work, I think we can drop the stigma and start improving the codebases we work in.&lt;/p&gt;
</content:encoded><category>Refactoring</category><category>Software Engineering</category><category>Thoughts</category></item><item><title>Fun Coding Exercise: Pyramid Slide Down</title><link>https://kyleshevlin.com/fun-coding-exercise-pyramid-slide-down/</link><guid isPermaLink="true">https://kyleshevlin.com/fun-coding-exercise-pyramid-slide-down/</guid><description>Sharing a fun coding exercise I came across and what the solution taught me. Plus, a few bonus steps you can take in the solution, too.</description><pubDate>Mon, 27 Jan 2025 17:15:10 GMT</pubDate><content:encoded>&lt;p&gt;I was doing some more interview prep this past week, this time using an app called &lt;a href=&quot;https://codewars.com&quot;&gt;Codewars&lt;/a&gt;, when I came across a &quot;kata&quot; &amp;lt;Marker content=&quot;That&apos;s what they call the exercises.&quot; /&amp;gt; that stood out to me.&lt;/p&gt;
&lt;p&gt;The reason it caught my eye is not only that the solution is far simpler than I originally thought, but it also involves a little &quot;divergent thinking&quot; (not to be confused with &quot;neurodivergent thinking&quot;). Let&apos;s look at the problem. Then I&apos;ll give you my original thoughts on the problem, followed by the solution.&lt;/p&gt;
&lt;h3&gt;The problem&lt;/h3&gt;
&lt;p&gt;If you want to try out the problem before reading this article, you can find it at: &lt;a href=&quot;https://www.codewars.com/kata/551f23362ff852e2ab000037/train/javascript&quot;&gt;https://www.codewars.com/kata/551f23362ff852e2ab000037/train/javascript&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You are given a &lt;code&gt;pyramid&lt;/code&gt;. That is a two-dimensional array of length &lt;code&gt;n&lt;/code&gt;, where the length of each row is 1 more than the previous row. An example would look like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const pyramid = [[3], [7, 4], [2, 4, 6], [8, 5, 9, 3]]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If we &quot;center&quot; those, we can see the pyramid a bit better&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;   3
  7 4
 2 4 6
8 5 9 3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Our goal is to calculate the greatest sum of numbers from &quot;sliding&quot; down the pyramid. The slide can only reach adjacent numbers and must always go down one row at a time. In our example here, the best path is &lt;code&gt;3, 7, 4, 9&lt;/code&gt;, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  /3/
  \7\ 4
 2 \4\ 6
8 5 \9\ 3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;How do we solve this?&lt;/p&gt;
&lt;h3&gt;My initial thoughts&lt;/h3&gt;
&lt;p&gt;When I first saw the problem, because the structure of the values resembled a graph or a tree, I thought perhaps the answer was to use &lt;a href=&quot;https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm&quot;&gt;Djikstra&apos;s algorithm&lt;/a&gt; on a graph of the numbers. We could use sums as the weights on the node&apos;s edges. Seems clever enough.&lt;/p&gt;
&lt;p&gt;While this approach would eventually work, there are a couple problems with it. First, we&apos;d have to run the algorithm from the top node to every bottom node. Taking up at least &lt;code&gt;n&lt;/code&gt;, where &lt;code&gt;n&lt;/code&gt; is the length of the last array, time.&lt;/p&gt;
&lt;p&gt;It&apos;s also likely that we would be recalculating many of the same routes over and over, so we&apos;d need to take extra steps with caching to ensure we had an optimal solution.&lt;/p&gt;
&lt;p&gt;But it turns out the solution is much simpler than all of that.&lt;/p&gt;
&lt;h3&gt;The solution&lt;/h3&gt;
&lt;p&gt;There&apos;s a common strategy in these types of problems called &quot;dynamic programming&quot;. It&apos;s an intimidating name, but it really means breaking the problem down into much smaller sub-problems, solving them, and then using those solutions to arrive at the solution for our big problem.&lt;/p&gt;
&lt;p&gt;In regards to pyramid, what&apos;s the smaller problem we need to solve? Hint: this is where &quot;divergent thinking&quot; comes into play.&lt;/p&gt;
&lt;p&gt;I&apos;ll give you a moment...&lt;/p&gt;
&lt;p&gt;The key insight is to realize we don&apos;t have to &lt;em&gt;slide down&lt;/em&gt; the pyramid like the problem title suggests. We&apos;re not actually skiing it. Instead, we can think divergently, coming up with multiple ways to examine and think about the same problem, and realize something can come &lt;em&gt;up&lt;/em&gt; the pyramid instead.&lt;/p&gt;
&lt;p&gt;Rather than start at the top, what if we break the problem down into solving the greatest sums &lt;em&gt;up&lt;/em&gt; the mountain at each level. So our sub problem becomes, &quot;What are the greatest sums we can achieve between the last two rows?&quot;&lt;/p&gt;
&lt;p&gt;Let&apos;s write this out:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function greatestSlide(pyramid) {
  // We&apos;re going to start at the second to last row,
  // By decrementing, we&apos;ll work our way _up_ the pyramid rows
  for (let row = pyramid.length - 2; row &amp;gt;= 0; row--) {}
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then with each row, we&apos;re going to replace the current value with the greatest sum achieved by adding the two possible values from the row below. That looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function greatestSlide(pyramid) {
  for (let row = pyramid.length - 2; row &amp;gt;= 0; row--) {
    // Iterate over each item in the row
    for (let col = 0; col &amp;lt; pyramid[row].length; col++) {
      // Replace the value with the greatest sum possible
      pyramid[row][col] += Math.max(
        // This is the item down to the left (has the same column index)
        pyramid[row + 1][col],
        // This is the item down to the right
        pyramid[row + 1][col + 1],
      )
    }
  }

  // By the time we&apos;ve done this for the entire pyramid, the very top
  // is now the value of the greatest sum possible
  return pyramid[0][0]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And that&apos;s our solution. By finding the greatest sums possible going up the pyramid, by the time we hit the peak, we&apos;re guaranteed the answer.&lt;/p&gt;
&lt;p&gt;I just love that the solution was simple and literally required flipping the problem on its head.&lt;/p&gt;
&lt;p&gt;Sometimes the hardest step in solving a problem is just figuring out how to think about it correctly, and this problem is a good reminder to look at it from all angles.&lt;/p&gt;
&lt;h3&gt;Optional steps&lt;/h3&gt;
&lt;p&gt;One of the first things I &lt;em&gt;don&apos;t&lt;/em&gt; like about this solution is that we modify the &lt;code&gt;pyramid&lt;/code&gt; passed in. Assuming your program allowed for it, I would copy the &lt;code&gt;pyramid&lt;/code&gt; before doing the work:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function greatestSlide(pyramid) {
  const copy = pyramid.map(row =&amp;gt; row.slice())
  // ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Another thing that could be fun if you were building a visualization, or simply trying to debug it would be to turn &lt;code&gt;greatestSlide&lt;/code&gt; into a &lt;a href=&quot;/generator-functions&quot;&gt;generator function&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;By turning it into a generator function, we&apos;re able to &lt;code&gt;yield&lt;/code&gt; out our pyramid and different stages and see the transformation. Like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function* greatestSlide(pyramid) {
  const copy = pyramid.map(row =&amp;gt; row.slice())
  yield copy

  for (let row = copy.length - 2; row &amp;gt;= 0; row--) {
    for (let col = 0; col &amp;lt; copy[row].length; col++) {
      copy[row][col] += Math.max(copy[row + 1][col], copy[row + 1][col + 1])
    }

    // This will just show us the modified portion of the pyramid,
    // making it easy to see the sums work their way up from the bottom
    yield copy.slice(0, row + 1)
  }

  return copy[0][0]
}

const generator = greatestSlide([[3], [7, 4], [2, 4, 6], [8, 5, 9, 3]])

for (const state of generator) {
  console.log(state)
}

// [[3], [7, 4], [2, 4, 6], [8, 5, 9, 3]]
// [[3], [7, 4], [10, 13, 15]]
// [[3], [20, 19]]
// [[23]]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Hopefully you can see how the values sum their way up the pyramid.&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;I recognize that perhaps you might not find that as interesting as I did, but hopefully I didn&apos;t bore you either. We don&apos;t often face problems quite like this in web development, so I find it a good exercise to stretch the brain from time to time. You never know what you might learn.&lt;/p&gt;
</content:encoded><category>Data Structures and Algorithms</category><category>JavaScript</category><category>TypeScript</category></item><item><title>Algorithm: Sliding Window</title><link>https://kyleshevlin.com/algorithm-sliding-window/</link><guid isPermaLink="true">https://kyleshevlin.com/algorithm-sliding-window/</guid><description>Let&apos;s learn a technique useful in string or array problems called the &apos;sliding window&apos;, where we use two pointers to expand and contract a subview of our data.</description><pubDate>Thu, 16 Jan 2025 18:32:25 GMT</pubDate><content:encoded>&lt;p&gt;import { SlidingWindowVisual } from &apos;./_components&apos;&lt;/p&gt;
&lt;p&gt;I&apos;ve decided to go back on the job hunt and this has me getting prepared for technical interviews. To do this, I&apos;ve been practicing &lt;a href=&quot;https://leetcode.com&quot;&gt;Leetcode&lt;/a&gt; problems. Yes, I&apos;m not a big fan of this style of interviewing either, but you have to be prepared for whatever might come.&lt;/p&gt;
&lt;p&gt;I recently ran into a problem that used a technique I&apos;ve never used before, a &quot;sliding window&quot;, and I wanted to write a quick post about it, both to solidify it in my memory and hopefully teach you something new.&lt;/p&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;SlidingWindowVisual client:load /&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;h3&gt;The Problem&lt;/h3&gt;
&lt;p&gt;I&apos;m going to borrow this &lt;a href=&quot;https://leetcode.com/problems/longest-substring-without-repeating-characters/description/?envType=study-plan-v2&amp;amp;envId=top-interview-150&quot;&gt;straight from their site&lt;/a&gt;: Given a string &lt;code&gt;s&lt;/code&gt;, find the length of the longest substring without repeating characters. Here&apos;s an example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Input: s = &quot;abcabcbb&quot;
Output: 3
Explanation: The answer is &quot;abc&quot;, once we get to &quot;a&quot; at index 3, we have a repeating character, and no other substring is longer
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Hopefully that makes sense. They have other examples at the link above. Don&apos;t scroll down if you want to go and try it for yourself first.&lt;/p&gt;
&lt;h3&gt;The Solution&lt;/h3&gt;
&lt;p&gt;We&apos;re going to implement a &quot;sliding window&quot;. That is, we&apos;re going to look at a slice of our string, tracking the left and right sides of our &quot;window&quot; as we go through it. We move the left and right edges of our window to adjust how much of the string we can &quot;view&quot;. You can also do this trick with items in an array.&lt;/p&gt;
&lt;p&gt;The key is to manage two pointers, a &lt;code&gt;start&lt;/code&gt; index and an &lt;code&gt;end&lt;/code&gt; index. We&apos;re going to loop over the &lt;code&gt;end&lt;/code&gt; with a &lt;code&gt;for&lt;/code&gt; loop, and then check if we need to advance our &lt;code&gt;start&lt;/code&gt; within that loop. This way, the right side of our window keeps expanding, and when necessary, we shrink the left side, too.&lt;/p&gt;
&lt;p&gt;Let&apos;s write our function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function lengthOfLongestSubstring(str) {
  // We&apos;ll make a map of character and track the index we last saw them
  const lastSeen = new Map()

  // We need to track the longest substring we&apos;ve found so far that meets our conditions
  let maxLength = 0

  // initialize our start index
  let start = 0

  // Our loop will advance the right side of our window
  for (let end = 0; end &amp;lt; str.length; end++) {
    // get the character at the rightmost side of our window
    // we&apos;ve already looked at anything left of it
    const char = str[end]

    // We&apos;re going to check our Map and see if we have that character
    // And if the index we found it at is inside the left side of our window
    if (lastSeen.has(char) &amp;amp;&amp;amp; lastSeen.get(char) &amp;gt;= start) {
      // If we found that character in our window, that&apos;s a repeat
      // Because it&apos;s a repeat, we can shrink the left side of our window to the
      // index just past that character
      start = lastSeen.get(char) + 1
    }

    // We need to track our current character now
    lastSeen.set(char, end)

    // And we can update our maxLength, keep it if our current length is less
    maxLength = Math.max(maxLength, end - start + 1)
  }

  return maxLength
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Why is this the best way to handle this solution?&lt;/h3&gt;
&lt;p&gt;A naive approach might be something like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Start at the first letter&lt;/li&gt;
&lt;li&gt;Expand until we hit a duplicate&lt;/li&gt;
&lt;li&gt;Track the &lt;code&gt;maxLength&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Something like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function lengthOfLongestSubstring(str) {
  let maxLength = 0

  for (let i = 0; i &amp;lt; str.length; i++) {
    for (let j = i + 1; j &amp;lt; str.length; j++) {
      const sub = str.slice(i, j)

      // let&apos;s at least check a substring longer than our max so far
      if (sub.length &amp;lt; maxLength) continue

      // fastest way I know to get unique characters
      const charsSet = new Set(sub.split(&apos;&apos;))

      // Unequal sizes means a repeated character
      if (sub.length !== charsSet.size) {
        // This breaks the inner loop, advancing the outer one
        break
      }

      maxLength = Math.max(maxLength, j - i)
    }
  }

  return maxLength
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;While this will eventually solve our problem, it&apos;s inefficient. The issue with this algorithm is that it cycles through substrings we&apos;ve checked before. Ones that we know won&apos;t yield better results.&lt;/p&gt;
&lt;p&gt;For example, if I was testing the string &lt;code&gt;abcb&lt;/code&gt; using this approach, we&apos;d start at &lt;code&gt;a&lt;/code&gt; and get a length of &lt;code&gt;3&lt;/code&gt; when we hit the second &lt;code&gt;b&lt;/code&gt;. Then we would move the &lt;code&gt;i&lt;/code&gt; index, starting at the first &lt;code&gt;b&lt;/code&gt; and check &lt;code&gt;b&lt;/code&gt;, &lt;code&gt;bc&lt;/code&gt; and &lt;code&gt;bcb&lt;/code&gt; again, failing at the same spot.&lt;/p&gt;
&lt;p&gt;With the sliding window technique, we&apos;re able to move the left side of our window all the way &lt;em&gt;past&lt;/em&gt; the repeated character, ensuring we&apos;re never checking a substring we have already seen before.&lt;/p&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;Some problems benefit from checking a &quot;window&quot; of the string or array. Manage two pointers. Use a loop for the &lt;code&gt;end&lt;/code&gt; pointer, and advance the &lt;code&gt;start&lt;/code&gt; pointer as necessary within that loop.&lt;/p&gt;
&lt;p&gt;Hope this technique helps you out some time, maybe even lands you a job! Wish me luck on my interviews, too.&lt;/p&gt;
</content:encoded><category>Data Structures and Algorithms</category><category>JavaScript</category><category>TypeScript</category></item><item><title>The Consciousness Lottery</title><link>https://kyleshevlin.com/consciousness-lottery/</link><guid isPermaLink="true">https://kyleshevlin.com/consciousness-lottery/</guid><description>For years now, I&apos;ve been using the phrase &amp;ldquo;the consciousness lottery&amp;rdquo; in conversation and I wanted to put it into writing finally. Come learn what it is and why you should add it to your vernacular.</description><pubDate>Tue, 19 Nov 2024 16:24:07 GMT</pubDate><content:encoded>&lt;p&gt;This will be a departure from my typical topic of writing, but it&apos;s something I&apos;ve been thinking about for well over a decade and would like to finally put into some words. With no better place to publish this, here will have to do. Do not be surprised if I publish more content in a similar vein in the future.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;None of us are born of &lt;em&gt;our&lt;/em&gt; will. That is, not one of us &lt;em&gt;chose&lt;/em&gt; to be born. Rather, each of us is born &lt;em&gt;against&lt;/em&gt; our will. We each had parents that conceived us, a mother that birthed us, and here we are, each participating in a world we had no say in entering.&lt;/p&gt;
&lt;p&gt;Not only this, but we had no choice in &lt;em&gt;who&lt;/em&gt; we came into this world as. One day, &quot;you&quot; suddenly were &quot;you&quot;. &quot;You&quot; were a consciousness embodied in a &lt;em&gt;particular&lt;/em&gt; physical form. This is the &quot;consciousness lottery&quot;.&lt;/p&gt;
&lt;p&gt;There&apos;s no reason &quot;you&quot; could not have been &quot;you&quot; differently. No reason &quot;you&quot; could not have gained consciousness at a different time in history, a different geographic location, a different sex, a different ethnicity, of a different social and economic class, etc. No reason at all.&lt;/p&gt;
&lt;p&gt;Yet, one day, a particular corporeal form gained &quot;you&quot;-ness and there &quot;you&quot; were.&lt;/p&gt;
&lt;p&gt;Think about this for a moment.&lt;/p&gt;
&lt;p&gt;Why are you &lt;em&gt;you&lt;/em&gt;?&lt;/p&gt;
&lt;p&gt;There&apos;s no sufficient answer, but it doesn&apos;t make the question less worthwhile to ask. In fact, because there is no answer, it makes the question all the more &lt;em&gt;important&lt;/em&gt; to ask.&lt;/p&gt;
&lt;p&gt;If each of us is &quot;us&quot; against our will, through the sheer luck of an invisible universal lottery, awakening conscious in a body one day, this should vastly increase our empathy towards one another.&lt;/p&gt;
&lt;p&gt;Just as there is no good reason that you are you, there is no good reason they are them.&lt;/p&gt;
&lt;p&gt;The consciousness lottery is why I find patriotism and nationalism confusing. No one chooses where they are born, so what are you actually proud of? Unless you immigrated and chose to take citizenship, what did you actually do?&lt;/p&gt;
&lt;p&gt;The consciousness lottery is why I find racism, sexism, homophobia and transphobia confusing. None of us chose our skin color. None of us chose our sexual orientation. Almost none of us chose our sex, and those who do, can you imagine how difficult a life must be to have gained consciousness in a body that never feels like your own? How are we not empathetic to that plight?&lt;/p&gt;
&lt;p&gt;Or what if we examine our own lives through the lens of the consciousness lottery. In my case, in some ways I won the lottery. I was born a white, cisgender, heterosexual male in a country where other white, cisgender, heterosexual males hold an excess of power. I have above average intelligence. I am athletic and coordinated. For a portion of my life, reasonably handsome, etc. None of these &quot;wins&quot; can really be ascribed to anything I consciously chose, but are rather emergent properties of the particular genetics that I was lucky enough to gain consciousness in.&lt;/p&gt;
&lt;p&gt;In other ways, I may have lost the lottery. I have autism and ADHD and perpetually struggle in personal relationships and work because of this neurodivergence. I was not born to a well-to-do family which has financially impacted my entire life. My parents suffered from alcholism, various mental health disorders, were abusive or completely dysfunctional. I haven&apos;t had familial support in over 25 years. We could even count going bald at a young age, in a world that values &lt;em&gt;hair&lt;/em&gt;, as a literal loss. I didn&apos;t consciously choose any of that either.&lt;/p&gt;
&lt;p&gt;What about you? Have you asked yourself in what ways have you won and loss the consciousness lottery?&lt;/p&gt;
&lt;p&gt;My hope is you have, and if you haven&apos;t, that you will. But when you do so, I want you to remember, the point of the exercise isn&apos;t to feel guilt, shame or pride. It is to recognize the complete &lt;em&gt;arbitrariness&lt;/em&gt; of some of your wins and losses. You are &lt;em&gt;you&lt;/em&gt; by nothing more than chance.&lt;/p&gt;
&lt;p&gt;This doesn&apos;t mean you haven&apos;t worked hard, or haven&apos;t made the most of the &quot;hand you were dealt&quot;. This takes nothing away from conscious choices you have made. &amp;lt;Marker content=&quot;The discussion on free will versus determinism will have to be another day.&quot; /&amp;gt; But it does ask you to consider what was out of your power to control entirely and to think of others in the same way.&lt;/p&gt;
&lt;p&gt;So please, add this concept to your vernacular. See how it changes how you view yourself and others.&lt;/p&gt;
</content:encoded><category>Thoughts</category><category>Philosophy</category></item><item><title>How I Built &amp;ldquo;Test Your Focus&amp;rdquo;</title><link>https://kyleshevlin.com/how-i-built-test-your-focus/</link><guid isPermaLink="true">https://kyleshevlin.com/how-i-built-test-your-focus/</guid><description>In my previous post, I used a &quot;Test Your Focus&quot; mini-game as a metaphor for describing my ADHD. Let&amp;apos;s learn how to build it using React.</description><pubDate>Fri, 15 Nov 2024 03:13:17 GMT</pubDate><content:encoded>&lt;p&gt;import { TestYourFocus } from &apos;./_components&apos;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/what-adhd-feels-like-to-me&quot;&gt;In my previous post&lt;/a&gt;, I use a mini-game as a metaphor for how it feels to have ADHD. I thought we could learn how to build that game with React. Let&apos;s get started.&lt;/p&gt;
&lt;p&gt;Let&apos;s start with defining our component and building out some of the UI. I&apos;m going to break out the parts more than I usually would just for the sake of making it clear which piece is which.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { Button, Heading } from &apos;~/ui&apos;

const METER_HEIGHT = 300 // Adjust to your liking

function Wrap({ children }: { children: React.ReactNode }) {
  return (
    &amp;lt;div
      style={{
        alignItems: &apos;center&apos;,
        display: &apos;flex&apos;,
        flexDirection: &apos;column&apos;,
        gap: 16,
      }}
    &amp;gt;
      {children}
    &amp;lt;/div&amp;gt;
  )
}

function Meter({ height, value }: { height: number; value: number }) {
  return (
    &amp;lt;div
      style={{
        border: &apos;2px solid #e5e5e5&apos;,
        // We want a defined height so that we can use
        // a percentage height on the child div
        height,
        position: &apos;relative&apos;,
        width: 50,
      }}
    &amp;gt;
      {/**
       * This is the part of the meter that will grow
       * We anchor it to the bottom of the wrapping div
       */}
      &amp;lt;div
        style={{
          backgroundColor: &apos;#33a1cc&apos;,
          bottom: 0,
          height: `${value}%`,
          left: 0,
          position: &apos;absolute&apos;,
          transition: &apos;height 66ms ease&apos;,
          width: &apos;100%&apos;,
        }}
      /&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}

function TestYourFocus() {
  return (
    &amp;lt;Wrap&amp;gt;
      &amp;lt;Heading&amp;gt;Test Your Focus&amp;lt;/Heading&amp;gt;

      &amp;lt;Meter height={METER_HEIGHT} value={0} /&amp;gt;

      &amp;lt;Button onClick={() =&amp;gt; {}}&amp;gt;Click&amp;lt;/Button&amp;gt;
    &amp;lt;/Wrap&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here, we&apos;ve established the basic units of our mini-game, the power meter that will display the level and the button we&apos;ll use to try and move the meter above the threshold.&lt;/p&gt;
&lt;p&gt;Now let&apos;s try and design the state management of our game. I&apos;m a big fan of using &lt;a href=&quot;/why-use-use-reducer&quot;&gt;&quot;event-driven&quot; state management in situations like this&lt;/a&gt;, so we&apos;ll use &lt;code&gt;useReducer&lt;/code&gt;. It may seem like overkill, given we won&apos;t be adding all the actions and state I used in the previous post, so feel free to replace this with whatever state management you prefer. The concepts will be roughly the same.&lt;/p&gt;
&lt;p&gt;The first thing we need for our game is to track a &lt;code&gt;value&lt;/code&gt;. This value will translate to the current height of the powered up portion of the meter. To that end, you could just as easily name it &lt;code&gt;power&lt;/code&gt; or &lt;code&gt;level&lt;/code&gt; or whatever makes sense to you.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type State = {
  /**
   * The current value of the meter
   */
  value: number
}

// I always write my &quot;initialState&quot; as a factory function
// so as to ensure I get a new object any time I call it
// and don&apos;t accidentally reference the same object in
// different components
const getInitialState = () =&amp;gt; ({
  value: 0,
})

// We&apos;ll add these soon
type Action = any

function reducer(state: State, action: Action): State {
  return state
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can add that to our component like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function TestYourFocus() {
  const [state, dispatch] = React.useReducer(getInitialState())

  return (
    &amp;lt;Wrap&amp;gt;
      &amp;lt;Heading&amp;gt;Test Your Focus&amp;lt;/Heading&amp;gt;

      &amp;lt;Meter height={METER_HEIGHT} value={state.value} /&amp;gt;

      &amp;lt;Button onClick={() =&amp;gt; {}}&amp;gt;Click&amp;lt;/Button&amp;gt;
    &amp;lt;/Wrap&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now that we have our &lt;code&gt;value&lt;/code&gt; wired up, we need to consider how that value changes. We know that when the user clicks the button, the &lt;code&gt;value&lt;/code&gt; should increase, but how and how much? We also know that we need that value to decay, but what&apos;s the mechanism for triggering that?&lt;/p&gt;
&lt;p&gt;We&apos;re going to use a concept I covered in my &lt;a href=&quot;/simulation-pattern&quot;&gt;post on simulations&lt;/a&gt; and implement a &lt;code&gt;TICK&lt;/code&gt; action. With each &lt;code&gt;TICK&lt;/code&gt;, we&apos;ll calculate the next &lt;code&gt;value&lt;/code&gt;, and utilize &lt;code&gt;impulse&lt;/code&gt; and &lt;code&gt;decay&lt;/code&gt; states to do so.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type State = {
  /**
   * The rate the value will be decreased each tick
   */
  decay: number
  /**
   * How much the value will be increased with each input
   */
  impulse: number
  /**
   * The current value of the meter
   */
  value: number
}

function getInitialState({
  decay,
  impulse,
}: Pick&amp;lt;State, &apos;decay&apos; | &apos;impulse&apos;&amp;gt;): State {
  return {
    decay,
    impulse,
    value: 0,
  }
}

type Action = { type: &apos;TICK&apos; }

function reducer(state: State, action: Action) {
  switch (action.type) {
    case &apos;TICK&apos;: {
      // We want to clamp the bottom range of our values to 0
      const nextValue = Math.max(0, state.value - state.decay)

      return { state, value: nextValue }
    }

    default:
      return state
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And with this change to &lt;code&gt;getInitialState&lt;/code&gt;, we can now add &lt;code&gt;decay&lt;/code&gt; and &lt;code&gt;impulse&lt;/code&gt; as props to our component, so that we can fiddle with them and make different tests of focus.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type Props = Pick&amp;lt;State, &apos;decay&apos; | &apos;impulse&apos;&amp;gt;

function TestYourFocus({ decay, impulse }: Props) {
  const [state, dispatch] = React.useReducer(
    getInitialState({ decay, impulse }),
  )

  //...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So far, we&apos;ve added the &lt;code&gt;decay&lt;/code&gt; to our &lt;code&gt;value&lt;/code&gt;, but we didn&apos;t add anything that dispatches our &lt;code&gt;TICK&lt;/code&gt; action, so let&apos;s do that next. We want our &lt;code&gt;TICK&lt;/code&gt; to occur on an interval, so we&apos;ll use &lt;code&gt;setInterval&lt;/code&gt; in a &lt;code&gt;useEffect&lt;/code&gt; hook to make this happen.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// This will be our interval in ms. You can adjust the
// denominator to increase or decrease the TICK rate
const FPS = 1000 / 15

// In case you&apos;re a real stickler about not recreating
// new objects all the time, you can do this
const TICK = { type: &apos;TICK&apos; }

// ...

function TestYourFocus({ decay, impulse }: Props) {
  //...

  React.useEffect(() =&amp;gt; {
    const id = setInterval(() =&amp;gt; {
      dispatch(TICK)
    }, FPS)

    return () =&amp;gt; clearInterval(id)
  }, [])

  // ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, at a rate of roughly 15 times a second, our &lt;code&gt;TICK&lt;/code&gt; is dispatched and our state updated. The last piece we need to add is an &lt;code&gt;Action&lt;/code&gt; to add the &lt;code&gt;impulse&lt;/code&gt; to our value.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type Action = { type: &apos;TICK&apos; } | { type: &apos;CLICK&apos; }

function reducer(state: State, action: Action): State {
  switch (action.type) {
    // ...

    case &apos;CLICK&apos;: {
      // Let&apos;s clamp the max value at the full height of the meter
      const nextValue = Math.min(100, state.value + state.impulse)

      return { ...state, value: nextValue }
    }

    // ...
  }
}

// ...

function TestYourFocus({ decay, impulse }: Props) {
  // ...

  const handleClick = React.useCallback(() =&amp;gt; {
    dispatch({ type: &apos;CLICK&apos; })
  }, [])

  // ...
  return (
    // ...

    &amp;lt;Button onClick={handleClick}&amp;gt;Click&amp;lt;/Button&amp;gt;

    // ...
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And now we can play the most rudimentary form of our game.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;TestYourFocus decay={1.5} impulse={10} /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;TestYourFocus client:load decay={1.5} impulse={10} /&amp;gt;&lt;/p&gt;
&lt;h3&gt;Optimizations&lt;/h3&gt;
&lt;p&gt;There are a few quick optimizations we can make to our game. First, as it stands, our &lt;code&gt;Meter&lt;/code&gt; is re-rendering with every &lt;code&gt;TICK&lt;/code&gt;, even if we&apos;re not playing the game. Let&apos;s memoize the component, that way when the &lt;code&gt;value&lt;/code&gt; is pegged at &lt;code&gt;0&lt;/code&gt; because we aren&apos;t playing, it won&apos;t rerender.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const Meter = React.memo(function Meter({
  height,
  value,
}: {
  height: number
  value: number
}) {
  //... same implementation
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Second, we&apos;re currently sending &lt;code&gt;TICK&lt;/code&gt;s to our &lt;code&gt;reducer&lt;/code&gt; 15 times a second, regardless if we are playing or not. Let&apos;s add a game &lt;code&gt;status&lt;/code&gt; to our state and stop &lt;code&gt;TICK&lt;/code&gt;ing unless it&apos;s &lt;code&gt;running&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type Status = &apos;idle&apos; | &apos;running&apos;

type State = {
  decay: number
  impulse: number
  status: Status
  value: number
}

function getInitialState({
  decay,
  impulse,
}: Pick&amp;lt;State, &apos;decay&apos; | &apos;impulse&apos;&amp;gt;): State {
  return {
    decay,
    impulse,
    status: &apos;idle&apos;,
    value: 0,
  }
}

// ...

function reducer(state: State, action: Action): State {
  switch (action.type) {
    case &apos;TICK&apos;: {
      const nextValue = Math.min(0, state.value - state.decay)

      return {
        ...state,
        status: nextValue ? &apos;running&apos; : &apos;idle&apos;,
        value: nextValue,
      }
    }

    case &apos;CLICK&apos;: {
      const nextValue = Math.max(100, state.value + state.impulse)

      return {
        ...state,
        status: &apos;running&apos;,
        value: nextValue,
      }
    }

    default:
      return state
  }
}

// ...

function TestYourFocus({ decay, impulse }: Props) {
  const [state, dispatch] = React.useReducer(
    reducer,
    getInitialState({ decay, impulse }),
  )
  const { status } = state

  // ...

  React.useEffect(() =&amp;gt; {
    if (status === &apos;idle&apos;) return

    const id = setInterval(() =&amp;gt; {
      dispatch(TICK)
    }, FPS)

    return () =&amp;gt; clearInterval(id)
  }, [status])

  // ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we no longer &lt;code&gt;TICK&lt;/code&gt; unless the game is &lt;code&gt;running&lt;/code&gt;, which should reduce re-renders as well.&lt;/p&gt;
&lt;h3&gt;Next steps&lt;/h3&gt;
&lt;p&gt;Here&apos;s a non-exhaustive list of ideas you could implement next:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add a &lt;code&gt;threshold&lt;/code&gt; and determine if the game has been &lt;code&gt;won&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Add a &lt;code&gt;timer&lt;/code&gt; and &lt;code&gt;countdown&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Add multiplayer with something like &lt;a href=&quot;https://www.partykit.io/&quot;&gt;PartyKit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Add &quot;modifiers&quot; like I did in my ADHD post&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I&apos;m sure you can think of even more.&lt;/p&gt;
&lt;h3&gt;Full code&lt;/h3&gt;
&lt;p&gt;As with everything in my blog, the code for this is open source and &lt;a href=&quot;https://github.com/kyleshevlin/blog/blob/main/src/content/posts/how-i-built-test-your-focus/_components.tsx&quot;&gt;you can find it here&lt;/a&gt;.&lt;/p&gt;
</content:encoded><category>React</category><category>JavaScript</category><category>TypeScript</category></item><item><title>What ADHD Feels Like to Me</title><link>https://kyleshevlin.com/what-adhd-feels-like-to-me/</link><guid isPermaLink="true">https://kyleshevlin.com/what-adhd-feels-like-to-me/</guid><description>While we have made great progress in understanding ADHD, it can still be difficult for some to grasp the impact it has on those who struggle with it. Let me show you what having ADHD sometimes feels like to me with a simple interactive game.</description><pubDate>Mon, 11 Nov 2024 16:48:05 GMT</pubDate><content:encoded>&lt;p&gt;import { TestYourMight } from &apos;./_components&apos;&lt;/p&gt;
&lt;p&gt;When I was a kid, I used to go to my neighbor&apos;s house to play Mortal Kombat on their Sega Genesis. Occasionally between fights, you&apos;d get to play a mini-game called &quot;Test Your Might&quot;. I&apos;ve been thinking about this game a lot.&lt;/p&gt;
&lt;p&gt;In the game, your character stood before a block of material, such as wood, stone, or diamond, and attempted to break it in half. Your &quot;might&quot; was a power bar, and your job was to mash the buttons fast enough to charge the power bar before the time limit expired and your character slammed their fist into the material. As the materials got harder, the difficulty of charging the bar got harder.&lt;/p&gt;
&lt;p&gt;It dawned on me, that this is a pretty good metaphor for &lt;strong&gt;working with ADHD&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;A non-exhaustive primer on ADHD&lt;/h3&gt;
&lt;p&gt;For those of you who don&apos;t know much about ADHD, it stands for &lt;a href=&quot;https://en.wikipedia.org/wiki/Attention_deficit_hyperactivity_disorder&quot;&gt;&quot;Attention Deficit Hyperactivity Disorder&quot;&lt;/a&gt;. It&apos;s not really an accurate name anymore given what we understand about the disorder now. A more apt name might be &quot;Dopamine Dysregulation Disorder&quot;. Fundamentally, the ADHD brain has lower levels of dopamine and struggles to regulate what little dopamine it has.&lt;/p&gt;
&lt;p&gt;We all need certain amounts of dopamine to function. Most brains produce an adequate amount of this on their own, which enables them to function with relative ease. There&apos;s a task to do, they do it. There isn&apos;t much need for inputs such as interest or deadlines (more about those later). The brain has what it needs to focus on, begin, and execute the task.&lt;/p&gt;
&lt;p&gt;Since the ADHD brain has so little dopamine, it must constantly seek out stimulation in an attempt to trigger itself to produce more so that it can meet the threshold required to function. This is why almost all ADHD medication is a stimulant. It works by activating your brain to produce more dopamine, which allows you to focus because you no longer need to manually produce it yourself.&lt;/p&gt;
&lt;p&gt;ADHD has been unfortunately portrayed in media and culture as a disorder that leads to easy distraction. Who hasn&apos;t heard someone yell, &quot;Squirrel!&quot; as a joke about those with ADHD? In reality, people with ADHD aren&apos;t distracted because they are undisciplined. Our brains are distracted because our base levels of dopamine are not sufficient enough, and so our brains are constantly seeking new stimuli to achieve the levels we need.&lt;/p&gt;
&lt;p&gt;Let&apos;s imagine the &quot;Test Your Might&quot; game is a human brain, and we have a task to do. If the game was a neurotypical brain, it might look like the following. Give the button a few clicks to watch the meter grow:&lt;/p&gt;
&lt;p&gt;&amp;lt;TestYourMight
client:load
decay={0.1}
impulse={100}
subtitle=&quot;Neurotypical Brain&quot;
/&amp;gt;&lt;/p&gt;
&lt;p&gt;The meter quickly has sufficient dopamine to begin the task, plenty above the threshold. Very little effort was required to get started, and the rate of decay is quite slow.&lt;/p&gt;
&lt;p&gt;Let&apos;s consider the same situation with the ADHD brain.&lt;/p&gt;
&lt;p&gt;&amp;lt;TestYourMight client:load decay={2.5} impulse={5} subtitle=&quot;ADHD Brain&quot; /&amp;gt;&lt;/p&gt;
&lt;p&gt;Notice the brain struggles to get to the threshold and falls quickly below it. We need to keep clicking the button in order to keep stimulating the brain above the focus threshold.&lt;/p&gt;
&lt;h3&gt;Understimulated&lt;/h3&gt;
&lt;p&gt;Sometimes the ADHD brain gets in a mode where it&apos;s desperately seeking stimulation, but there&apos;s no guarantee that whatever is tried will produce the dopamine desired.&lt;/p&gt;
&lt;p&gt;The person might have a number of go-to activities that they find stimulating, but their effectiveness varies often. Something that brought them a lot of joy and focus yesterday might not work today, and there&apos;s no way to know for how long the activity will do the trick.&lt;/p&gt;
&lt;p&gt;The game below represents this understimulation. Imagine each button as an activity a person might do to find stimulation. Eat some food, scroll their phone, play a video game, do a workout, etc. Which button will work, and for how long before it stops working? Try it out.&lt;/p&gt;
&lt;p&gt;&amp;lt;TestYourMight
client:load
decay={2.5}
impulse={5}
subtitle=&quot;ADHD Brain Understimulated&quot;
understimulated={true}
/&amp;gt;&lt;/p&gt;
&lt;h3&gt;Stimulation Modifiers&lt;/h3&gt;
&lt;p&gt;There are four ways we can &quot;encourage&quot; an ADHD brain to get focused, some positive, some negative: &lt;strong&gt;novelty, intrinsic interest, challenge, and urgency&lt;/strong&gt;. &amp;lt;Marker content=&quot;I remember this with the mnemonic NICU.&quot; /&amp;gt; In the context of our game, we can think of these as &quot;stimulation modifiers&quot;. We can tweak and adjust them and watch how it changes our ability to stimulate the brain across the threshold.&lt;/p&gt;
&lt;p&gt;&amp;lt;TestYourMight
client:load
decay={2.5}
impulse={5}
simulationModifiers={true}
subtitle=&quot;ADHD Brain with Stimulation Modifiers&quot;
/&amp;gt;&lt;/p&gt;
&lt;p&gt;Accumulating modifiers has a positive impact on our ability to reach the threshold and reduce the decay of our dopamine loss. However, we have to be really careful how we deploy these. For people with ADHD, the damage of living in a state of constant urgency to get things done can be significant.&lt;/p&gt;
&lt;h3&gt;Executive Dysfunction&lt;/h3&gt;
&lt;p&gt;There are times where no amount of modifiers will do anything. Nothing will allow the ADHD brain to focus, &lt;strong&gt;even if it desperately wants to focus&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&amp;lt;TestYourMight
client:load
decay={80}
executiveDysfunction={true}
impulse={2}
simulationModifiers={true}
subtitle=&quot;ADHD Brain in Executive Dysfunction&quot;
/&amp;gt;&lt;/p&gt;
&lt;p&gt;If you encounter someone in executive dysfunction, you need to understand they aren&apos;t just being lazy. The brain is in a physical state that is not allowing for executive function. It is very likely this person is in a shame-cycle, and only the urgency of the situation might get so dire they finally can do the task.&lt;/p&gt;
&lt;h3&gt;Hyperfocus&lt;/h3&gt;
&lt;p&gt;Many of you have probably heard of &quot;hyperfocus&quot;, and perhaps heard it called a super power. In the right scenario, it can certainly lead to prodigous amounts of productivity, but it often comes with some severe negative side effects as well.&lt;/p&gt;
&lt;p&gt;It might not be obvious, especially to those obsessed with productivity, but a certain amount of attention decay is a good thing. You need to remember to do things like eat, go to the bathroom, manage your life, etc. A person in hyperfocus forgets to do all of those things. Full disclosure, when I&apos;m in that state, it feels downright violent to be asked to context switch.&lt;/p&gt;
&lt;p&gt;Hyperfocus occurs when our system gets stuck. Yes, it&apos;s pegged above the threshold, but there is no reset button. The only way for it to decay is for the system to run out of resources and crash.&lt;/p&gt;
&lt;p&gt;&amp;lt;TestYourMight
client:load
decay={-10}
impulse={100}
subtitle=&quot;ADHD Brain in Hyperfocus&quot;
/&amp;gt;&lt;/p&gt;
&lt;p&gt;I might suggest you refresh the page now. That bar &lt;em&gt;will&lt;/em&gt; grow forever.&lt;/p&gt;
&lt;h3&gt;Closing thoughts&lt;/h3&gt;
&lt;p&gt;As with any metaphor, this one is imperfect, but I hope it provides some context for the people in your life struggling with ADHD. Imagine having to &quot;test your focus&quot; each and every day. It might help you understand why people with ADHD are far more likely to be clinically depressed. We don&apos;t just have less dopamine, but unless we&apos;re fortunate enough to find work that aligns with our stimulation modifiers, we spend most of our lives fighting with ourselves to get stimulated enough to do what we need to do.&lt;/p&gt;
&lt;p&gt;I may update this post in the future, or write something about how I built this little game with React, or how to work with your neurodivergent teammates better, but this is all the focus I have for now. Hope you understand.&lt;/p&gt;
</content:encoded><category>Thoughts</category><category>Productivity</category></item><item><title>Prefer Explicit Maps</title><link>https://kyleshevlin.com/prefer-explicit-maps/</link><guid isPermaLink="true">https://kyleshevlin.com/prefer-explicit-maps/</guid><description>Sometimes we write unnecessary complexity without realizing it. Let&apos;s see how we often do this with ternaries and learn how using a map will remove complexity and improve maintainability.</description><pubDate>Wed, 30 Oct 2024 16:19:36 GMT</pubDate><content:encoded>&lt;p&gt;This tip is a bit of a weird one. I genuinely don&apos;t think others will like it, but I hope you&apos;ll hear me out. At the very least, it might make you think a bit.&lt;/p&gt;
&lt;p&gt;I&apos;m a big fan of &lt;a href=&quot;/enumerate-dont-booleanate&quot;&gt;enumerated states&lt;/a&gt;. In TypeScript, a great way to represent this is a union of strings. Let&apos;s start with a basic one.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type Theme = &apos;light&apos; | &apos;dark&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It might be tempting to make this a boolean, given that there are only two states, but bear with me.&lt;/p&gt;
&lt;p&gt;Now, let&apos;s make a &lt;code&gt;ThemeContext&lt;/code&gt; we could use throughout our app.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const ThemeContext = React.createContext&amp;lt;Theme&amp;gt;(&apos;light&apos;)

function ThemeProvider({ children }: { children: React.ReactNode }) {
  const [theme, setTheme] = React.useState&amp;lt;Theme&amp;gt;(&apos;light&apos;)

  return &amp;lt;ThemeContext.Provider value={theme}&amp;gt;{children}&amp;lt;/ThemeContext.Provider&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So far, so good. Now, let&apos;s add a &lt;code&gt;toggleTheme&lt;/code&gt; function to the context and export that. We&apos;ll need to make some adjustments.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type ThemeContextValue = {
  theme: Theme
  toggleTheme: () =&amp;gt; void
}

// ...

function ThemeProvider({ children }: { children: React.ReactNode }) {
  // ...

  const toggleTheme = React.useCallback(() =&amp;gt; {
    // Here&apos;s the line to pay attention to
    setTheme(currentTheme === &apos;light&apos; ? &apos;dark&apos; : &apos;light&apos;)
  })

  return (
    &amp;lt;ThemeContext.Provider value={{ theme, toggleTheme }}&amp;gt;
      {children}
    &amp;lt;/ThemeContext.Provider&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Do you see this line?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;setTheme(currentTheme === &apos;light&apos; ? &apos;dark&apos; : &apos;light&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To use the parlance of the kids, I lowkey hate this line.&lt;/p&gt;
&lt;p&gt;I&apos;m not opposed to ternaries, but not all ternaries are the same. Some ternaries represent legitimate binary choices: &lt;code&gt;if&lt;/code&gt; this, &lt;code&gt;else&lt;/code&gt; that. But some ternaries are really &quot;implicit maps&quot;.&lt;/p&gt;
&lt;p&gt;A &quot;map&quot; is a data structure that pairs keys to values with a one-to-one relationship. This &lt;code&gt;key&lt;/code&gt; always gives me this &lt;code&gt;value&lt;/code&gt;. For example, we could create a &lt;code&gt;THEME_LABEL_MAP&lt;/code&gt; if we needed to associate strings with our themes, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const THEME_LABEL_MAP: Record&amp;lt;Theme, string&amp;gt; = {
  dark: &apos;Dark&apos;,
  light: &apos;Light&apos;,
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can see we&apos;ve established a one-to-one relationship between the key, a &lt;code&gt;Theme&lt;/code&gt;, and a string. Our ternary from above does this, too, but not explicitly. If you squint hard enough, you can maybe see the &lt;code&gt;NEXT_THEME&lt;/code&gt; map hidden in there. &amp;lt;Marker content=&quot;Astute readers might realize that we&apos;ve created the world&apos;s smallest cyclical graph with &amp;lt;code&amp;gt;NEXT_THEME&amp;lt;/code&amp;gt;, and I just think that&apos;s fun.&quot; /&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const NEXT_THEME: Record&amp;lt;Theme, Theme&amp;gt; = {
  dark: &apos;light&apos;,
  light: &apos;dark&apos;,
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And this is actually how I prefer to write this code. Now our &lt;code&gt;toggleTheme&lt;/code&gt; function will look a bit different:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const toggleTheme = () =&amp;gt; {
  setTheme(currentTheme =&amp;gt; NEXT_THEME[currentTheme])
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Doesn&apos;t that read nicely? Our map is practically a function, it&apos;s so elegant.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&quot;But why, Kyle? This seems like overkill!&quot;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Maybe it is. But let&apos;s say I had to add a third &lt;code&gt;Theme&lt;/code&gt;: &lt;code&gt;high-contrast&lt;/code&gt;. What does our ternary look like then?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const toggleTheme = () =&amp;gt; {
  setTheme(currentTheme =&amp;gt;
    currentTheme === &apos;light&apos;
      ? &apos;dark&apos;
      : currentTheme === &apos;dark&apos;
        ? &apos;high-contrast&apos;
        : &apos;light&apos;,
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I mean, to be fair, we could probably ditch the ternary and make it a bit nicer:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const toggleTheme = () =&amp;gt; {
  setTheme(currentTheme =&amp;gt; {
    if (currentTheme === &apos;light&apos;) return &apos;dark&apos;
    if (currentTheme === &apos;dark&apos;) return &apos;high-contrast&apos;
    return &apos;light&apos;
  })
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But why go through all of that, when we could just update the map?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const NEXT_THEME: Record&amp;lt;Theme, Theme&amp;gt; = {
  dark: &apos;high-contrast&apos;,
  &apos;high-contrast&apos;: &apos;light&apos;,
  light: &apos;dark&apos;,
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Our &lt;code&gt;toggleTheme&lt;/code&gt; function doesn&apos;t have to change at all. &lt;code&gt;NEXT_THEME[currentTheme]&lt;/code&gt; just keeps working. &amp;lt;Marker content=&quot;Although, perhaps it should be called &amp;lt;code&amp;gt;cycleTheme&amp;lt;/code&amp;gt; to be more accurate.&quot; /&amp;gt; &lt;strong&gt;Bonus points&lt;/strong&gt;: we didn&apos;t change the &lt;a href=&quot;/managing-cyclomatic-complexity&quot;&gt;cyclomatic complexity&lt;/a&gt; of our code at all either.&lt;/p&gt;
&lt;p&gt;If we learn to pay attention, we can start to recognize situations where using an explicit map might be a simpler way for us to write and maintain our code.&lt;/p&gt;
&lt;h3&gt;Key takeaways&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Consider when enumerating states might serve you better than a boolean&lt;/li&gt;
&lt;li&gt;Consider using explicit maps to reduce complexity and improve maintainability&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&quot;Why didn&apos;t you use &lt;code&gt;new Map()&lt;/code&gt;?&quot;&lt;/h3&gt;
&lt;p&gt;Just to address anyone who might ask this: Yes, we could use &lt;code&gt;new Map()&lt;/code&gt; to create &quot;real&quot; maps. However, I find the most compelling reason to use a &lt;code&gt;Map&lt;/code&gt; is if you need to use something other than a string for a &lt;code&gt;key&lt;/code&gt;s. Given that we were using strings for &lt;code&gt;key&lt;/code&gt;s, I think its more appropriate and simple to just use an object literal.&lt;/p&gt;
</content:encoded><category>TypeScript</category><category>JavaScript</category><category>Prefer</category></item><item><title>My &lt;code&gt;git&lt;/code&gt; Workflow for Refactoring</title><link>https://kyleshevlin.com/my-git-workflow-for-refactoring/</link><guid isPermaLink="true">https://kyleshevlin.com/my-git-workflow-for-refactoring/</guid><description>Refactoring is a key part of my development process. Let me show you the &lt;code&gt;git&lt;/code&gt; workflow I use to make refactoring just another step in building features or other code changes.</description><pubDate>Sun, 29 Sep 2024 16:34:56 GMT</pubDate><content:encoded>&lt;p&gt;import Image from &apos;../../../components/Image.astro&apos;
import { ExampleButton, ExampleButtonWithVariant } from &apos;./_components&apos;&lt;/p&gt;
&lt;p&gt;If you&apos;ve followed me for any significant amount of time, then you might know that &lt;a href=&quot;https://martinfowler.com/books/refactoring.html&quot;&gt;Refactoring by Martin Fowler&lt;/a&gt; is the most influential book on writing software I have ever read. It fundamentally changed my approach towards writing code.&lt;/p&gt;
&lt;p&gt;The book influenced me so greatly that it led to a change in my &lt;code&gt;git&lt;/code&gt; workflow. Adopting the strategy I&apos;m about to show you made it easier for me to refactor code, build upon that change, and get it reviewed quicker than ever. If you work in an organization that uses pull requests and code reviews, I believe this workflow will help you do the same.&lt;/p&gt;
&lt;p&gt;The gist of my workflow is this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Make a branch for only the refactoring work, submit the PR&lt;/li&gt;
&lt;li&gt;Then, make a branch &lt;em&gt;off of the refactoring branch, not &lt;code&gt;main&lt;/code&gt;&lt;/em&gt; for your feature work, and &lt;em&gt;set the base to the refactoring branch&lt;/em&gt; when you submit the PR&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Some groundwork first&lt;/h3&gt;
&lt;p&gt;Before we get into the finer details of this workflow, I want to provide a little more context as to why I think it&apos;s a good idea to make changes this way.&lt;/p&gt;
&lt;p&gt;First, I think it&apos;s a really bad habit to refactor &lt;em&gt;and&lt;/em&gt; make changes in the same pull request. This practice is extremely common, but it comes with some major downsides:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It&apos;s not really a refactor, by definition &amp;lt;Marker content=&quot;The definition of a refactor requires that the functionality of the program &amp;lt;em&amp;gt;doesn&apos;t&amp;lt;/em&amp;gt; change. Thus, adding changes to the same PR breaks this definition. You&apos;ve really just made two changes, which goes to my next point.&quot; /&amp;gt;&lt;/li&gt;
&lt;li&gt;It&apos;s harder to differentiate between what was refactored vs. what was added, what was necessary to change and what wasn&apos;t&lt;/li&gt;
&lt;li&gt;It creates large PRs, which are more likely to be &quot;rubber stamped&quot; and therefore, more error prone &amp;lt;Marker content=&quot;I realize for some devs this is a &amp;lt;em&amp;gt;feature&amp;lt;/em&amp;gt;. Creating big PRs to might make it easier to get PR approval due to human laxity, but that doesn&apos;t make it right.&quot; /&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Second, I recognize that many organizations&apos; processes are designed to incentivize large PRs. Anything from compliance requiring separate tickets for every change (so you just stuff it all into one ticket), to the overwhelming pressure to pump out features. I understand there are factors working against you sometimes. My hope is that this strategy fits in that system, as it has for me.&lt;/p&gt;
&lt;p&gt;So without further ado, let&apos;s break this bad habit and explore this workflow now.&lt;/p&gt;
&lt;h3&gt;Our example&lt;/h3&gt;
&lt;p&gt;I figured it would be best to work through an example to demonstrate the process. Our codebase has a rudimentary &lt;code&gt;Button&lt;/code&gt; component. It currently has two implicit variants, a &lt;code&gt;primary&lt;/code&gt; and &lt;code&gt;secondary&lt;/code&gt; style. Let&apos;s look at how it was implemented.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const SHARED_STYLES = {
  borderRadius: 9999,
  fontFamily: &apos;sans-serif&apos;,
  padding: &apos;0.35em 1em&apos;,
}

const PRIMARY_STYLES = { backgroundColor: &apos;blue&apos;, color: &apos;white&apos; }
const SECONDARY_STYLES = { backgroundColor: &apos;lightGray&apos;, color: &apos;black&apos; }

type Props = {
  children: React.ReactNode
  onClick: () =&amp;gt; void
  isSecondary?: boolean
  type?: &apos;button&apos; | &apos;submit&apos; | &apos;reset&apos;
}

function Button({
  children,
  onClick,
  isSecondary = false,
  type = &apos;button&apos;,
}: Props) {
  const variantStyles = isSecondary ? SECONDARY_STYLES : PRIMARY_STYLES

  return (
    &amp;lt;button
      onClick={onClick}
      style={{ ...SHARED_STYLES, ...variantStyles }}
      type={type}
    &amp;gt;
      {children}
    &amp;lt;/button&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can use our &lt;code&gt;Button&lt;/code&gt; component like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;Button onClick={() =&amp;gt; {}}&amp;gt;Primary Button&amp;lt;/Button&amp;gt;
&amp;lt;Button onClick={() =&amp;gt; {}} isSecondary&amp;gt;Secondary Button&amp;lt;/Button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And it looks like:&lt;/p&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;div class=&quot;stack sm:row gap-4 sm:justify-center&quot;&amp;gt;
&amp;lt;ExampleButton client:load&amp;gt;Primary button&amp;lt;/ExampleButton&amp;gt;
&amp;lt;ExampleButton client:load isSecondary&amp;gt;
Secondary button
&amp;lt;/ExampleButton&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;p&gt;Now that we know our starting point, let&apos;s consider our task. We need to add a third variant, the &lt;code&gt;danger&lt;/code&gt; button, without regressions. &lt;strong&gt;How should we do this?&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;Step 0: Write some tests&lt;/h3&gt;
&lt;p&gt;In the &lt;a href=&quot;https://martinfowler.com/books/refactoring.html&quot;&gt;Refactoring book&lt;/a&gt;, Fowler makes it clear that a proper refactor changes the organization and structure of the code without changing its functionality. In order to verify that no functionality has changed, we need tests in place that can assert the correct behavior.&lt;/p&gt;
&lt;p&gt;In the case of our buttons, we&apos;d have functional tests ensuring the button worked when clicked, or didn&apos;t when disabled, etc. We&apos;d also be well served to have visual regression tests, perhaps with something like &lt;a href=&quot;https://storybook.js.org/&quot;&gt;Storybook&lt;/a&gt;. So before we go refactoring, make sure you can verify that everything works exactly as it did before.&lt;/p&gt;
&lt;p&gt;If you do need to write some tests, I recommend making this PR first. You can then build your refactor branch off of the testing branch, similar to how we&apos;re going to make our feature branch off of our refactoring branch later on.&lt;/p&gt;
&lt;h3&gt;Step 1: Refactor&lt;/h3&gt;
&lt;p&gt;Assuming we have tests ready to go in our &lt;code&gt;main&lt;/code&gt; branch, we&apos;ll start by creating a branch off of &lt;code&gt;main&lt;/code&gt; for our refactor:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git checkout -b refactor-button
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now that we&apos;re on new branch, we can make our changes. Adding a &lt;code&gt;danger&lt;/code&gt; variant will be very cumbersome if we have to deal with booleans. &lt;a href=&quot;/multiple-boolean-props-are-a-code-smell&quot;&gt;Booleans are a poor choice for representing finite states&lt;/a&gt; and could lead to weird situations that leak implementation details.&lt;/p&gt;
&lt;p&gt;A better choice than an &lt;code&gt;isSecondary&lt;/code&gt; prop, is a &lt;code&gt;variant&lt;/code&gt; prop that takes a string. We&apos;ll use TypeScript to define this string as a union of our variants, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type Variant = &apos;primary&apos; | &apos;secondary&apos;

type Props = {
  children: React.ReactNode
  onClick: () =&amp;gt; void
  type?: &apos;button&apos; | &apos;submit&apos; | &apos;reset&apos;
  variant?: Variant
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now that we&apos;ve added &lt;code&gt;Variant&lt;/code&gt; to our types, we can make objects that use &lt;code&gt;Variant&lt;/code&gt; as a key to create maps for our styles, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const VARIANT_TO_STYLES: Record&amp;lt;Variant, React.CSSProperties&amp;gt; = {
  primary: { backgroundColor: &apos;blue&apos;, color: &apos;white&apos; },
  secondary: { backgroundColor: &apos;lightGray&apos;, color: &apos;black&apos; },
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And we can now use that map in our component:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Button({
  children,
  onClick,
  type = &apos;button&apos;,
  variant = &apos;primary&apos;,
}: Props) {
  const variantStyles = VARIANT_TO_STYLES[variant]

  return (
    &amp;lt;button
      onClick={onClick}
      style={{ ...SHARED_STYLES, ...variantStyles }}
      type={type}
    &amp;gt;
      {children}
    &amp;lt;/button&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;From this point, we can &lt;code&gt;git add&lt;/code&gt; our changes and &lt;code&gt;commit&lt;/code&gt; them.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git add .
git commit -m &quot;refactor button with variants&quot;
git push origin refactor-button
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After pushing our branch to remote, we can make a PR for our changes.&lt;/p&gt;
&lt;h3&gt;Step 2: Adding our &lt;code&gt;danger&lt;/code&gt; variant&lt;/h3&gt;
&lt;p&gt;Before we make our additional changes, we&apos;re going to make a new branch &lt;em&gt;off of our refactoring branch&lt;/em&gt;. So ensuring we are currently on the &lt;code&gt;refactor-button&lt;/code&gt; branch, we can then make our new on:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git checkout -b update-button-with-danger-variant
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Our work is fairly straightforward from here. We&apos;ll add &lt;code&gt;&apos;danger&apos;&lt;/code&gt; to our &lt;code&gt;Variant&lt;/code&gt; type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type Variant = &apos;danger&apos; | &apos;primary&apos; | &apos;secondary&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We&apos;ll add &lt;code&gt;danger&lt;/code&gt; styles to our style map:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const VARIANT_TO_STYLES: Record&amp;lt;Variant, React.CSSProperties&amp;gt; = {
  danger: { backgroundColor: &apos;red&apos;, color: &apos;white&apos; },
  primary: { backgroundColor: &apos;blue&apos;, color: &apos;white&apos; },
  secondary: { backgroundColor: &apos;lightGray&apos;, color: &apos;black&apos; },
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And we&apos;re done! That&apos;s literally all we have to do to add our new variant.&lt;/p&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;div class=&quot;stack md:row gap-4 md:justify-center&quot;&amp;gt;
&amp;lt;ExampleButtonWithVariant client:load&amp;gt;
Primary button
&amp;lt;/ExampleButtonWithVariant&amp;gt;
&amp;lt;ExampleButtonWithVariant client:load variant=&quot;secondary&quot;&amp;gt;
Secondary button
&amp;lt;/ExampleButtonWithVariant&amp;gt;
&amp;lt;ExampleButtonWithVariant client:load variant=&quot;danger&quot;&amp;gt;
Danger button
&amp;lt;/ExampleButtonWithVariant&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;p&gt;From here, we can &lt;code&gt;add&lt;/code&gt;, &lt;code&gt;commit&lt;/code&gt; and &lt;code&gt;push&lt;/code&gt; our changes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git add .
git commit -m &quot;add danger variant to button&quot;
git push origin update-button-with-danger-variant
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Up to now, all of this work has been the same, but we need to make a key change with our PR. We need to change the base from the &lt;code&gt;main&lt;/code&gt; branch to our &lt;code&gt;refactor-button&lt;/code&gt; branch.&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-8&quot;&amp;gt;
&amp;lt;Image
src=&quot;/images/git-workflow/changing-base-for-pr.jpg&quot;
alt=&quot;The Github PR interface with a circle and arrow pointing to the dropdown you would use to change the base for a PR.&quot;
caption=&quot;Change the base to your refactoring branch&quot;
/&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;Take a look at the &quot;Files Changed&quot; tab when we do. Notice, only the changes we&apos;ve made &lt;em&gt;since the refactor&lt;/em&gt; are there.&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-8&quot;&amp;gt;
&amp;lt;Image
src=&quot;/images/git-workflow/git-diff.jpg&quot;
alt=&quot;The git diff in the PR of our addition&quot;
caption=&quot;Notice the small diff because we changed the base&quot;
/&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;If we had kept the &lt;code&gt;main&lt;/code&gt; branch as base, then we&apos;d see changes from both the refactoring and our &lt;code&gt;danger&lt;/code&gt; addition. This makes sense because we made our updates on a branch that was made from the &lt;code&gt;refactor-button&lt;/code&gt; branch. But by changing the base, we&apos;re able to only see the diff between the &lt;code&gt;refactor-button&lt;/code&gt; branch and our current branch. We&apos;ve shrunk the &lt;code&gt;git diff&lt;/code&gt; considerably, and hopefully shrunk the time to review each PR considerably, too.&lt;/p&gt;
&lt;p&gt;I should be clear, if there are any tests we need to add for our new feature, we should add them now as well.&lt;/p&gt;
&lt;h3&gt;Step 3: Review &amp;amp; Merge&lt;/h3&gt;
&lt;p&gt;At this point, we&apos;ve submitted two PRs, which may seem like twice the work for code reviewers, but I would say it&apos;s actually less than the amount of work of a single PR.&lt;/p&gt;
&lt;p&gt;If both of these changes were in a single PR, you&apos;d have to verify that both the refactor was done correctly, and that the addition worked correctly. There&apos;s additional work of review buried in this integration.&lt;/p&gt;
&lt;p&gt;When we split them into 2 PRs, they become simple verifications. The refactoring PR simply asks us to verify the tests continue to pass. If they do, then we&apos;re ok (assuming the quality of the tests).&lt;/p&gt;
&lt;p&gt;The second PR simply asks if we&apos;ve implemented the new feature. It would be easy to spot if we made an unrelated or additional changes at this stage that need to be addressed.&lt;/p&gt;
&lt;p&gt;In the review process, you may realize that there are updates you need to make to the refactoring branch. This is not a problem. Checkout your refactoring branch, make your changes, commit and push. Once you&apos;ve done that, you can switch to your feature branch, and &lt;code&gt;git rebase&lt;/code&gt; the refactoring branch on to it. This will move the commits of your feature branch to after the commits of the refactoring branch, maintaining the correct history. You can fix any conflicts that arise here, though they should be relatively small and few.&lt;/p&gt;
&lt;p&gt;Once your PRs have been reviewed, merge the refactoring branch first. This will automatically update the base of your feature branch back to &lt;code&gt;main&lt;/code&gt;, allowing you to easily merge that branch in as well.&lt;/p&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;Refactoring is a part of writing quality code, and while our processes might not make it as easy to do as we like, there are strategies we can take to make them as easy on ourselves and others to review.&lt;/p&gt;
&lt;p&gt;If we can build the habit of making our refactoring PR first, and building our feature on top of that branch, we can start to make code changes and reviews easier for everyone we work with.&lt;/p&gt;
&lt;p&gt;I hope you find this &lt;code&gt;git&lt;/code&gt; workflow useful. Let me know if you or your team starts to adopt something like this.&lt;/p&gt;
&lt;h3&gt;Additional resources&lt;/h3&gt;
&lt;p&gt;While I believe they have recently changed their product offering a bit, their is a tool out there that can do a lot of this automatically for you. It&apos;s called &lt;a href=&quot;https://graphite.dev/&quot;&gt;Graphite&lt;/a&gt; and I encourage you to check it out. I&apos;m not the most persuasive person, so I&apos;ve never tried to convince a team to try it, but I think it could be very useful to a team willing to adopt it.&lt;/p&gt;
</content:encoded><category>Git</category><category>Software Engineering</category><category>Productivity</category></item><item><title>Never Call &lt;code&gt;new Date()&lt;/code&gt; Inside Your Components</title><link>https://kyleshevlin.com/never-call-new-date-inside-your-components/</link><guid isPermaLink="true">https://kyleshevlin.com/never-call-new-date-inside-your-components/</guid><description>Calling impure functions with side effects like &lt;code&gt;new Date()&lt;/code&gt; or &lt;code&gt;Math.random()&lt;/code&gt; is a disaster waiting to happen. Learn what to do instead.</description><pubDate>Tue, 20 Aug 2024 19:12:27 GMT</pubDate><content:encoded>&lt;p&gt;import { DiceRoll, Form1 } from &apos;./_components.tsx&apos;&lt;/p&gt;
&lt;p&gt;As I&apos;ve gotten older, I find myself arguing less often and discussing code more in terms of preferences than absolutes. That should indicate how strongly I feel about this.&lt;/p&gt;
&lt;p&gt;I need our community as a whole to stop calling &lt;code&gt;new Date()&lt;/code&gt; and other impure functions inside our components, especially when setting initial state. &amp;lt;Marker content=&quot;Yes, there are probably times where it is safe to do so, but you should have a really good understanding of pure and impure functions before you do.&quot; /&amp;gt; You&apos;re making life harder for yourself.&lt;/p&gt;
&lt;p&gt;I have a simple React component, a single date input that defaults to today&apos;s date.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// A simple way to set a new Date() to &apos;YYYY-MM-DD&apos; format
// but use whatever method or lib you prefer
function formatDate(date: Date) {
  return date.toISOString().split(&apos;T&apos;)[0]
}

function MyDateInput() {
  const today = formatDate(new Date())
  const [date, setDate] = React.useState(today)

  return (
    &amp;lt;label&amp;gt;
      &amp;lt;span&amp;gt;Date&amp;lt;/span&amp;gt;

      &amp;lt;input
        type=&quot;date&quot;
        onChange={e =&amp;gt; {
          setDate(e.target.value)
        }}
        value={date}
      /&amp;gt;
    &amp;lt;/label&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can see it in action here:&lt;/p&gt;
&lt;p&gt;&amp;lt;Form1 client:load /&amp;gt;&lt;/p&gt;
&lt;p&gt;Ask yourself a question: &lt;strong&gt;How would you visually regression test this?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The answer is &lt;strong&gt;you don&apos;t&lt;/strong&gt;. Not in its current state.&lt;/p&gt;
&lt;p&gt;Every time this component is first rendered for testing, the date will (potentially) be different. This is the definition of a flaky test. When I first arrived at one of my previous companies, they had a date input similar to this that they simply updated &lt;em&gt;every single time the Chromatic visual regression test ran&lt;/em&gt;. It was extremely disappointing to see.&lt;/p&gt;
&lt;p&gt;The reason this changes should be obvious, but for the sake of providing all context possible, it happens because &lt;code&gt;new Date()&lt;/code&gt; is an impure function. Every time we call it, we get a different response. That&apos;s essentially the opposite of what we want to have happen in a test. In a test, we want the same inputs to always produce the same outputs.&lt;/p&gt;
&lt;p&gt;Because we&apos;re calling an impure function in our component, our component itself has become impure. How do we fix this?&lt;/p&gt;
&lt;p&gt;By passing the impure function (or the result of the impure function) in as a prop instead.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function MyDateInput({ today }) {
  const [date, setDate] = React.useState(today)

  return (
    &amp;lt;label&amp;gt;
      &amp;lt;span&amp;gt;Date&amp;lt;/span&amp;gt;

      &amp;lt;input
        type=&quot;date&quot;
        onChange={e =&amp;gt; {
          setDate(e.target.value)
        }}
        value={date}
      /&amp;gt;
    &amp;lt;/label&amp;gt;
  )
}

function MyForm() {
  return (
    &amp;lt;form&amp;gt;
      &amp;lt;MyDate today={formatDate(new Date())} /&amp;gt;
    &amp;lt;/form&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, testing is dead simple, just pass any formatted date into it.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;test(&apos;MyDateInput&apos;, () =&amp;gt; {
  const result = render(&amp;lt;MyDateInput today=&quot;2024-08-20&quot; /&amp;gt;)
  const input = result.getByLabelText(&apos;Date&apos;)

  expect(input.value).toEqual(&apos;2024-08-20&apos;)
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; that this allows us to pass in a &lt;em&gt;static&lt;/em&gt; date into a visual regression test, eliminating the issue of a new date being rendered each time we build the suite.&lt;/p&gt;
&lt;h3&gt;A step further&lt;/h3&gt;
&lt;p&gt;I like to take this pattern a step further and use &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters&quot;&gt;default parameters&lt;/a&gt; in this situation. The most common use case of our input will be passing in &lt;code&gt;formatDate(new Date())&lt;/code&gt;, so we should just bake it in for a better developer experience.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function MyDateInput({ today = formatDate(new Date()) }) {
  const [date, setDate] = React.useState(today)

  return (
    &amp;lt;label&amp;gt;
      &amp;lt;span&amp;gt;Date&amp;lt;/span&amp;gt;

      &amp;lt;input
        type=&quot;date&quot;
        onChange={e =&amp;gt; {
          setDate(e.target.value)
        }}
        value={date}
      /&amp;gt;
    &amp;lt;/label&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, we have the best of both worlds. We have a component we can treat as a pure function by passing the &lt;code&gt;today&lt;/code&gt; prop in, or we can make use of the default. I think of this as a form of &lt;a href=&quot;/dependency-injection-and-default-parameters&quot;&gt;dependency injection&lt;/a&gt; and have covered the topic before.&lt;/p&gt;
&lt;h3&gt;Let&apos;s make another example&lt;/h3&gt;
&lt;p&gt;Another common impure function you might see in components (or functions in general) is &lt;code&gt;Math.random()&lt;/code&gt;. For these instances, I like to use a &lt;code&gt;randomizer&lt;/code&gt; argument, with &lt;code&gt;Math.random&lt;/code&gt; set to the default. Consider a &lt;code&gt;DiceRoll&lt;/code&gt; component.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const rollDice = () =&amp;gt; Math.ceil(Math.random() * 6)

function DiceRoll() {
  const [state, setState] = React.useState(rollDice())

  const roll = () =&amp;gt; {
    setState(rollDice())
  }

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;button onClick={roll}&amp;gt;Roll dice&amp;lt;/button&amp;gt;
      &amp;lt;Dice number={state} /&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, I&apos;ve made this component with a bit of indirection, extracting the &lt;code&gt;rollDice&lt;/code&gt; function, but our same principles apply. &lt;code&gt;rollDice&lt;/code&gt; is an impure function because of &lt;code&gt;Math.random&lt;/code&gt;, therefore &lt;code&gt;DiceRoll&lt;/code&gt; is an impure component because of &lt;code&gt;rollDice&lt;/code&gt;. Let&apos;s make both &lt;code&gt;rollDice&lt;/code&gt; and our component pure functions with default parameters.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const rollDice = (randomizer = Math.random) =&amp;gt; Math.ceil(randomizer() * 6)

function DiceRoll({ randomizer = Math.random }) {
  const [state, setState] = React.useState(rollDice(randomizer))

  const roll = () =&amp;gt; {
    setState(rollDice(randomizer))
  }

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;button onClick={roll}&amp;gt;Roll dice&amp;lt;/button&amp;gt;
      &amp;lt;Dice number={state} /&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, we could easily write unit and integration tests for our functions.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;test(&apos;rollDice&apos;, () =&amp;gt; {
  // We do need to pass in a `randomizer` that returns values
  // in the range of Math.random
  expect(rollDice(() =&amp;gt; 0.01)).toEqual(1)
  expect(rollDice(() =&amp;gt; 0.99)).toEqual(6)
})

test(&apos;DiceRoll&apos;, () =&amp;gt; {
  const result = render(&amp;lt;DiceRoll randomizer={() =&amp;gt; 0.99} /&amp;gt;)

  // `getByText` or whatever way we need to check the value of the dice
  expect(result.getByText(6)).toBeInTheDocument()
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;DiceRoll client:load /&amp;gt;&lt;/p&gt;
&lt;h3&gt;Wrap up&lt;/h3&gt;
&lt;p&gt;We don&apos;t want to set initial state with impure functions in our components. It makes testing difficult. Instead, pass in the impure function (or its result) as an argument/prop. This will will give us the ability to pass in a pure function as a substitute in a test.&lt;/p&gt;
</content:encoded><category>React</category><category>JavaScript</category><category>TypeScript</category><category>Functional Programming</category></item><item><title>Composable Flourishes</title><link>https://kyleshevlin.com/composable-flourishes/</link><guid isPermaLink="true">https://kyleshevlin.com/composable-flourishes/</guid><description>Learn how we can use composition to create subtle, pleasant animations that can be used on any component in our applications.</description><pubDate>Fri, 02 Aug 2024 02:28:47 GMT</pubDate><content:encoded>&lt;p&gt;If you&apos;ve read my blog in recent history, then you&apos;re probably aware that I&apos;m a big fan of composition. There&apos;s almost nothing you can&apos;t solve with enough wrapping HTML elements, functions, or components. &amp;lt;Marker content=&quot;Depending on what you&apos;re working on, of course.&quot; /&amp;gt;&lt;/p&gt;
&lt;p&gt;One way that composition really shines is in adding &quot;flourishes&quot; around your UI, subtle animations that make the site feel less static and flat. Look at the boxes below fade in. Refresh the page if necessary to retrigger the animation.&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-8 grid grid-cols-3 gap-4&quot;&amp;gt;
{[0, 1, 2].map(num =&amp;gt; (
&amp;lt;FadeIn delay={num * 200}&amp;gt;
&amp;lt;div class=&quot;aspect-square rounded-xl bg-accent&quot; /&amp;gt;
&amp;lt;/FadeIn&amp;gt;
))}
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;Let&apos;s build this effect as an &lt;a href=&quot;https://astro.build&quot;&gt;Astro component&lt;/a&gt; to demonstrate how easy it can be. &amp;lt;Marker content=&quot;You can easily do the same in React, but I leave that as an exercise for the reader.&quot; /&amp;gt;&lt;/p&gt;
&lt;h3&gt;Our component&lt;/h3&gt;
&lt;p&gt;We&apos;re going to build a composable &lt;code&gt;FadeIn&lt;/code&gt; component. We&apos;ll be able to wrap &lt;em&gt;any&lt;/em&gt; UI we want with it, and fade it in to view as it comes into the viewport. Let&apos;s start by setting up the markup portion of the Astro component.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;div class=&quot;fade-in-element&quot;&amp;gt;
  &amp;lt;slot /&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Yep. That&apos;s it!&lt;/p&gt;
&lt;p&gt;All we want to do is create a wrapping element for our content. Now, we&apos;ll add a some styles to it that will be our animation.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;div class=&quot;fade-in-element&quot;&amp;gt;
  &amp;lt;slot /&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;style&amp;gt;
  .fade-in-element {
    opacity: 0;
    transform: translateY(20px);
    transition:
      opacity 0.5s ease-out,
      transform 0.5s ease-out;
  }

  .fade-in-element.visible {
    opacity: 1;
    transform: translateY(0);
  }
&amp;lt;/style&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;By default, our component isn&apos;t visible. We&apos;ll need to add the &lt;code&gt;.visible&lt;/code&gt; class to it to change that. Let&apos;s do that now.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/* same markup and styles... */

&amp;lt;script&amp;gt;
  const fadeInElements = document.querySelectorAll(&apos;.fade-in-element&apos;)

  const observer = new IntersectionObserver(
    entries =&amp;gt; {
      entries.forEach(entry =&amp;gt; {
        if (entry.isIntersecting) {
          entry.target.classList.add(&apos;visible&apos;)
          observer.unobserve(entry.target)
        }
      })
    },
    {
      threshold: 0.1,
    },
  )

  fadeInElements.forEach(element =&amp;gt; {
    observer.observe(element)
  })
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With this script, we gather all the &lt;code&gt;FadeIn&lt;/code&gt; components, observe them for intersecting the viewport, and add the &lt;code&gt;.visible&lt;/code&gt; class when they come into view. We can tweak the threshold to adjust how much of the element must be in view to animate, and we can play with the styles to achieve different animations.&lt;/p&gt;
&lt;p&gt;One last touch we might like to add is a &lt;code&gt;delay&lt;/code&gt; for when several items are next to each other and we want their animations to cascade a bit.&lt;/p&gt;
&lt;p&gt;To do this, we can add a &lt;code&gt;delay&lt;/code&gt; prop to our component.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
type Props = {
  delay?: number
}

const { delay = 0 } = Astro.props
---

&amp;lt;div class=&quot;fade-in-element&quot; style={`transition-delay: ${delay}ms;`}&amp;gt;
  &amp;lt;slot /&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, we can literally wrap anything in our app and get that subtle fade in animation. For example, the code for boxes at the top of this post looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;div class=&quot;grid grid-cols-3 gap-4&quot;&amp;gt;
  {
    [0, 1, 2].map(num =&amp;gt; (
      &amp;lt;FadeIn delay={num * 200}&amp;gt;
        &amp;lt;div class=&quot;aspect-square rounded-xl bg-accent&quot; /&amp;gt;
      &amp;lt;/FadeIn&amp;gt;
    ))
  }
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It&apos;s not hard to imagine how you could replace the inner &lt;code&gt;div&lt;/code&gt; with other components in your application.&lt;/p&gt;
&lt;h3&gt;Additional things to consider&lt;/h3&gt;
&lt;p&gt;I don&apos;t always love being absolutely thorough in my blog posts. I think it can detract from the lesson to go down all the rabbit holes available. That said, I think there are two things to consider with these flourishes that are pretty important:&lt;/p&gt;
&lt;h4&gt;&lt;code&gt;prefers-reduced-motion&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;We can make the flourishes more accessible to those who don&apos;t like screen motion by making a small change to our styles.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;style&amp;gt;
  .fade-in-element {
    opacity: 1;
    transform: translateY(0);
  }

  @media (prefers-reduced-motion: no-preference) {
    .fade-in-element {
      opacity: 0;
      transform: translateY(20px);
      transition:
        opacity 0.5s ease-out,
        transform 0.5s ease-out;
    }

    .fade-in-element.visible {
      opacity: 1;
      transform: translateY(0);
    }
  }
&amp;lt;/style&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This makes the element visible by default, but if they have no preference, applies the styles in the media query.&lt;/p&gt;
&lt;h4&gt;No JavaScript&lt;/h4&gt;
&lt;p&gt;This ones a bit more tricky, but you want to make sure your content is still visible if the user has JavaScript turned off. Here are the steps I would take to do that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add the class &lt;code&gt;no-js&lt;/code&gt; to the &lt;code&gt;html&lt;/code&gt; element&lt;/li&gt;
&lt;li&gt;In the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; element, add a small &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; that removes the &lt;code&gt;no-js&lt;/code&gt; class&lt;/li&gt;
&lt;li&gt;Update styles that would be affected by the presence of a &lt;code&gt;no-js&lt;/code&gt; class&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Wrap up&lt;/h3&gt;
&lt;p&gt;Composition gives us the opportunity to make some simple reusable flourishes that can add some pleasant movement to our sites. I encourage you to experiment with this technique for other things. Perhaps you can try scaling or rotations. The possibilities are almost endless, so have fun.&lt;/p&gt;
</content:encoded><category>Astro</category><category>JavaScript</category><category>CSS</category></item><item><title>Prefer Alphabetized Object Keys</title><link>https://kyleshevlin.com/prefer-alphabetized-object-keys/</link><guid isPermaLink="true">https://kyleshevlin.com/prefer-alphabetized-object-keys/</guid><description>Small efforts can add up to big gains, given enough time. That&apos;s how I feel about alphabetizing my object keys. By always sorting them, I increase the speed at which I can read, and even write, code.</description><pubDate>Tue, 30 Jul 2024 15:27:23 GMT</pubDate><content:encoded>&lt;p&gt;When it&apos;s been a while since I&apos;ve written a post and I need to get back at it, I like to pick something I can write really quickly and publish right away. So here&apos;s one of the quickest tips I have for you: whenever order is not important, &lt;strong&gt;prefer to alphabetize the keys of your objects&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;As a dev, you spend a lot of time reading code. Anything we can do to increase the speed and efficiency of reading and scanning the code can have a big return on investment in the long run. Alphabetizing the keys of your objects is one of the simplest and easiest ways you can do this.&lt;/p&gt;
&lt;p&gt;This shouldn&apos;t really be controversial, especially for developers with any knowledge of algorithms and data structures. What&apos;s the fastest way to search through an array? &lt;strong&gt;Have it pre-sorted&lt;/strong&gt;. That&apos;s what alphabetizing does. It&apos;s a default sort for every object in your codebase.&lt;/p&gt;
&lt;p&gt;But it&apos;s more than scanning, it also speeds up writing. If you always alphabetize your keys, you never have to ask yourself, &quot;Where should I add this?&quot; You pick a name, and you slot it in. You keep the keys sorted.&lt;/p&gt;
&lt;p&gt;Now, imagine you&apos;ve done this for an entire codebase. Every prop, every object type, interface, map, and dictionary is alphabetically sorted. Because of this order, you save a second or two every time you have to look for a key. You do this multiple times a day, you do this for a full year. It sounds silly, but you might have saved a few hours over the course of a year.&lt;/p&gt;
&lt;h3&gt;What about logical groupings?&lt;/h3&gt;
&lt;p&gt;There&apos;s a reason I use the word &quot;prefer&quot; in the title of these posts. There may be a time where the order of keys matters, or putting them in a &quot;logical&quot; grouping might be better. If that is the case, I like to indicate that with a comment and possibly some whitespace.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// WARNING: ORDER HERE MATTERS!
const obj = {
  foo: 1,
  bar: 2,
  baz: 3,
}

// Or

const styles = {
  backgroundColor: &apos;papayawhip&apos;,
  color: &apos;black&apos;,
  fontSize: &apos;1em&apos;,

  // Positioning
  position: &apos;absolute&apos;,
  top: 0,
  left: 0,
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The point is, exceptions can be made, but they should be &lt;em&gt;exceptions&lt;/em&gt;.&lt;/p&gt;
&lt;h3&gt;How do I make this easy to do?&lt;/h3&gt;
&lt;p&gt;There are ESLint rules you can use to enforce and fix this, but I&apos;ve never been on a team that used it, and I&apos;m not sure this is a hill I&apos;d care to die on either. Instead, I just alphabetize keys as I do my work &lt;strong&gt;with a simple key combination&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Now, if you use VSCode, I think it might have a default sorting key combo, but I have mine bound to &lt;code&gt;cmd + shift + a&lt;/code&gt; (&lt;code&gt;a&lt;/code&gt; is for &quot;alphabetize&quot;). Like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;key&quot;: &quot;cmd+shift+a&quot;,
  &quot;command&quot;: &quot;editor.action.sortLinesAscending&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;All I have to do is highlight a group of key/value pairs, hit the key combo, and it&apos;s done.&lt;/p&gt;
&lt;p&gt;&amp;lt;Gif
alt=&quot;Keys of an object getting highlighted, then alphabetized&quot;
gifSrc=&quot;/images/alphabetizeKeys.gif&quot;
staticSrc=&quot;/images/alphabetizeKeysStatic.jpg&quot;
/&amp;gt;&lt;/p&gt;
&lt;h3&gt;Wrap up&lt;/h3&gt;
&lt;p&gt;I don&apos;t think is a life-altering tip. If you never alphabetize an object in your life, you&apos;ll be fine. But for me, it saves a good amount of time and energy reading and writing code.&lt;/p&gt;
&lt;p&gt;We don&apos;t talk a lot about code style guidelines these days. Not since Prettier came on to the scene. In general, that&apos;s a good thing, but having some small rules &amp;amp; principles like this one, even if they&apos;re only for you with no real impact to others, can make your code more consistent, and consistency leads to speed over time.&lt;/p&gt;
</content:encoded><category>JavaScript</category><category>TypeScript</category><category>React</category><category>Prefer</category></item><item><title>Responsive Design and Composition</title><link>https://kyleshevlin.com/responsive-design-and-composition/</link><guid isPermaLink="true">https://kyleshevlin.com/responsive-design-and-composition/</guid><description>Responsive UI can be very challenging to write well and can often lead to some of the nastiest code you have ever encountered. Learn how to use multiple compositions to make responsive design a whole lot cleaner and easier.</description><pubDate>Sat, 15 Jun 2024 02:34:01 GMT</pubDate><content:encoded>&lt;p&gt;import { Presenter } from &apos;./_components.tsx&apos;&lt;/p&gt;
&lt;p&gt;Do me a favor. Change the width of your browser while watching the UI below. Go really narrow, and go really wide.&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-8&quot;&amp;gt;
&amp;lt;OffsetWrap&amp;gt;
&amp;lt;Presenter
client:only=&quot;react&quot;
name=&quot;Kyle Shevlin&quot;
description=&quot;Kyle is the founder and lead engineer of Agathist, a software firm dedicated to building good software with good people.&quot;
role=&quot;Founder &amp;amp; Lead Engineer&quot;
image=&quot;/images/kyle-headshot.jpg&quot;
/&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;You see what changed? The spatial relationship between the &lt;code&gt;image&lt;/code&gt;, &lt;code&gt;description&lt;/code&gt;, and &lt;code&gt;role&lt;/code&gt; changed. Some font sizes and weights changed. The amount of border radius on the image changed, too.&lt;/p&gt;
&lt;p&gt;I recently came across this exact responsive layout in a client&apos;s codebase. The UI changes aren&apos;t unreasonable. I can agree that it&apos;s a better layout given the size constraints. But if you try and achieve this with a single composition of elements and classes, you&apos;re going to have to do some wild CSS shenanigans to make it work.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;And that&apos;s exactly what they had done.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Here&apos;s a pared down version of what I came across in the codebase. I&apos;ve removed a lot of the stylistic classes, and left you mostly with the classes needed for the UI changes across breakpoints. Hope you&apos;re good at reading Tailwind classes (which isn&apos;t the problem at all; this would be a CSS mess, too):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Presenter({ description, image, name, role }) {
  return (
    &amp;lt;figure className=&quot;grid grid-cols-[auto,1fr] items-center gap-x-4 gap-y-8 sm:grid-cols-12 sm:grid-rows-[1fr,auto,auto,1fr] sm:gap-x-10&quot;&amp;gt;
      &amp;lt;div className=&quot;col-span-2 text-xl sm:col-span-7 sm:col-start-6 sm:row-start-2&quot;&amp;gt;
        {description}
      &amp;lt;/div&amp;gt;

      &amp;lt;div className=&quot;col-start-1 row-start-2 overflow-hidden rounded-xl sm:col-span-5 sm:row-span-full sm:rounded-3xl&quot;&amp;gt;
        &amp;lt;Image
          src={image}
          className=&quot;h-12 w-12 object-cover sm:h-auto sm:w-full&quot;
        /&amp;gt;
      &amp;lt;/div&amp;gt;

      &amp;lt;figcaption className=&quot;text-sm sm:col-span-7 sm:row-start-3 sm:text-base&quot;&amp;gt;
        &amp;lt;span className=&quot;font-bold&quot;&amp;gt;{name}&amp;lt;/span&amp;gt;
        &amp;lt;span className=&quot;hidden font-bold sm:inline&quot;&amp;gt;, &amp;lt;/span&amp;gt;
        &amp;lt;br className=&quot;sm:hidden&quot; /&amp;gt;
        &amp;lt;span className=&quot;sm:font-bold&quot;&amp;gt;{role}&amp;lt;/span&amp;gt;
      &amp;lt;/figcaption&amp;gt;
    &amp;lt;/figure&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So yeah... &lt;strong&gt;do you want to maintain this?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Yeah, I didn&apos;t think so.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Now look&lt;/strong&gt;, I understand why this happens. It&apos;s really easy to empathize with the challenge the original dev or devs faced in making this work. Let&apos;s give them some credit. They were clever enough to come up with a grid layout that could accommodate their needs.&lt;/p&gt;
&lt;p&gt;That said, cleverness is not the answer. &amp;lt;Marker content=&quot;It rarely is.&quot; /&amp;gt; They made this way harder than it has to be. But how could they have known there is an easier way hidden just below the surface? There are two clues here that make it clear what we should do instead.&lt;/p&gt;
&lt;p&gt;First, the layout of the elements changes. It would be one thing if all their spatial relationships remained the same. The &lt;code&gt;name&lt;/code&gt; stays above the &lt;code&gt;image&lt;/code&gt;. The &lt;code&gt;description&lt;/code&gt; always has &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;role&lt;/code&gt; beneath it. But it doesn&apos;t. The layout changes. I mean, they went so far as to have a &lt;code&gt;br&lt;/code&gt; element that is removed from the page! You know we&apos;re up to something weird if that&apos;s happening. All of this should be a signal that maybe we want to solve this with &lt;a href=&quot;/prefer-multiple-compositions&quot;&gt;multiple compositions&lt;/a&gt; instead.&lt;/p&gt;
&lt;p&gt;Second, there are lots of &quot;little conditionals&quot; here if you look closely. Just because you don&apos;t see the keyword &lt;code&gt;if&lt;/code&gt;, doesn&apos;t mean they aren&apos;t there. Everywhere we see &lt;code&gt;sm:&lt;/code&gt;, we can think of that as a conditional. &quot;If we are at a breakpoint larger than &lt;code&gt;sm&lt;/code&gt;, do this&quot;. I see 17 conditionals in the code example. That&apos;s way too many!&lt;/p&gt;
&lt;p&gt;What if I told you we only need two?&lt;/p&gt;
&lt;h3&gt;Multiple compositions to the rescue&lt;/h3&gt;
&lt;p&gt;When we have the same condition many times lower in our tree of components and elements, we can often lift it up higher and reduce how many times it needs to be checked. &amp;lt;Marker content=&quot;That trick applies to a lot more than just components, too. Use it in your functions and watch them get simpler.&quot; /&amp;gt;&lt;/p&gt;
&lt;p&gt;In our case, we can turn &lt;code&gt;Presenter&lt;/code&gt; into a &lt;a href=&quot;facade-pattern&quot;&gt;facade&lt;/a&gt;, that renders either a &lt;code&gt;PresenterNarrow&lt;/code&gt; or &lt;code&gt;PresenterWide&lt;/code&gt; composition.&lt;/p&gt;
&lt;p&gt;First, the facade:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Presenter(props) {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;div className=&quot;sm:hidden&quot;&amp;gt;
        &amp;lt;PresenterNarrow {...props} /&amp;gt;
      &amp;lt;/div&amp;gt;

      &amp;lt;div className=&quot;hidden sm:block&quot;&amp;gt;
        &amp;lt;PresenterWide {...props} /&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Isn&apos;t that simpler?!&lt;/strong&gt; Now that we can guarantee what context each sub-composition will render in, we can arrange the elements without all the wild grid shenanigans to get the job done, and make a few reusable pieces we can use across compositions as well.&lt;/p&gt;
&lt;p&gt;First, our shared pieces. The bigger &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;description&lt;/code&gt; components:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Name({ children }) {
  return &amp;lt;h2 className=&quot;font-sans text-2xl font-bold&quot;&amp;gt;{children}&amp;lt;/h2&amp;gt;
}

function Description({ children }) {
  return &amp;lt;div className=&quot;font-sans text-lg&quot;&amp;gt;{children}&amp;lt;/div&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, our &lt;code&gt;PresenterNarrow&lt;/code&gt; composition:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function PresenterNarrow({ description, image, name, role }) {
  return (
    &amp;lt;div className=&quot;flex flex-col gap-4&quot;&amp;gt;
      &amp;lt;Name&amp;gt;{name}&amp;lt;/Name&amp;gt;
      &amp;lt;Description&amp;gt;{description}&amp;lt;/Description&amp;gt;

      &amp;lt;div className=&quot;flex flex-col gap-2&quot;&amp;gt;
        &amp;lt;img className=&quot;h-12 w-12 rounded-xl&quot; src={image} alt={name} /&amp;gt;

        &amp;lt;div&amp;gt;
          &amp;lt;div className=&quot;font-sans text-sm font-bold&quot;&amp;gt;{name}&amp;lt;/div&amp;gt;
          &amp;lt;div className=&quot;font-sans text-sm&quot;&amp;gt;{role}&amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And finally our &lt;code&gt;PresenterWide&lt;/code&gt; composition:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function PresenterWide({ description, image, name, role }) {
  return (
    &amp;lt;div className=&quot;flex items-center gap-12&quot;&amp;gt;
      &amp;lt;div className=&quot;flex w-[40%] shrink-0 flex-col gap-4&quot;&amp;gt;
        &amp;lt;Name&amp;gt;{name}&amp;lt;/Name&amp;gt;
        &amp;lt;img className=&quot;w-full rounded-3xl&quot; src={image} alt={name} /&amp;gt;
      &amp;lt;/div&amp;gt;

      &amp;lt;div className=&quot;flex grow flex-col gap-4&quot;&amp;gt;
        &amp;lt;Description&amp;gt;{description}&amp;lt;/Description&amp;gt;
        &amp;lt;div className=&quot;font-sans font-bold&quot;&amp;gt;
          {name}, {role}
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;How much easier is that code to read, understand, and maintain?! &lt;strong&gt;Bonus&lt;/strong&gt;, if you need to make a change, you can go directly to the component that needs it. You don&apos;t have to figure out where in the single composition you have to tweak to get it to work correctly.&lt;/p&gt;
&lt;p&gt;So the next time you&apos;re struggling with a component that is challenging to make responsive, consider making multiple compositions, one for each layout, and then move the responsive condition up the tree to render the appropriate sub-composition when necessary. I think you&apos;ll find your life got a little bit easier doing it that way.&lt;/p&gt;
</content:encoded><category>React</category><category>CSS</category><category>Tailwind</category><category>Refactoring</category></item><item><title>Design System Retrospective</title><link>https://kyleshevlin.com/design-system-retrospective/</link><guid isPermaLink="true">https://kyleshevlin.com/design-system-retrospective/</guid><description>I built a cross platform (React &amp; React Native) design system at my last company. I&apos;m in the middle of building another one for a client. Let me tell you what I learned, decisions I regret, and what I&apos;m doing differently this time.</description><pubDate>Thu, 23 May 2024 15:51:54 GMT</pubDate><content:encoded>&lt;p&gt;import { Button } from &apos;../../../components/Button.tsx&apos;&lt;/p&gt;
&lt;p&gt;Before starting &lt;a href=&quot;https://agath.ist&quot;&gt;Agathist&lt;/a&gt;, I worked for a couple years at a healthcare startup on the &quot;Frontend Platform&quot; team. My job was to build and design the tooling and internal libraries we would use to develop all of the frontend clients for the company.&lt;/p&gt;
&lt;p&gt;All of my work involved one unique constraint: everything has to work on both React web &lt;em&gt;and&lt;/em&gt; React Native.&lt;/p&gt;
&lt;p&gt;This presents a lot of challenges and I could write a lot of blog posts about them, but today I want to share what I think was my biggest mistake with the design system, why I think so, and what I&apos;d do differently.&lt;/p&gt;
&lt;h3&gt;What problems were we solving?&lt;/h3&gt;
&lt;p&gt;Before we get into the design system, I think it&apos;s important to discuss what problems we were trying to solve by making one.&lt;/p&gt;
&lt;p&gt;Here were the main issues:&lt;/p&gt;
&lt;h4&gt;Inconsistency&lt;/h4&gt;
&lt;p&gt;None of their products were visually consistent. You could easily see 4 different eras of styling throughout their products. It was visually unappealing. They wanted a system that could be used across their apps to unify their feel and user experience.&lt;/p&gt;
&lt;h4&gt;Developer velocity&lt;/h4&gt;
&lt;p&gt;The developers were very slow to build and release features. One of the reasons &amp;lt;Marker content=&quot;Though honestly, not remotely the biggest reason&quot; /&amp;gt; is that new features were written with bespoke CSS, via &lt;code&gt;styled-components&lt;/code&gt;, and none of it was type-safe or systematized. When you&apos;re manually writing styles for everything, you&apos;re going to be slow.&lt;/p&gt;
&lt;h4&gt;A dumpster fire of an existing &quot;design system&quot;&lt;/h4&gt;
&lt;p&gt;An attempt at a design system already existed. It started off with the intentions of being a small UI library, but quickly became the place all code was developed. &amp;lt;Marker content=&quot;This is because it was too painful to build in the apps themselves. There was a lot of work that needed to be done to modernize the infrastructure of the apps and get to a better, faster developer experience.&quot; /&amp;gt; There were several problems with this model, but most notably it became tightly coupled. There were data fetching calls in the library, there was business logic every where. It was no longer a library, but an awkward, vestigial appendage of the existing apps.&lt;/p&gt;
&lt;p&gt;There were more problems to be solved by the new design system, but those are the main ones.&lt;/p&gt;
&lt;h3&gt;My solution&lt;/h3&gt;
&lt;p&gt;I could solve all three of these problems by making a new design system that eliminated any need for bespoke CSS, was completely type-safe, and never tightly coupled.&lt;/p&gt;
&lt;p&gt;The way I chose to do this was to develop a set of components in the same vein as &lt;a href=&quot;https://v2.chakra-ui.com/&quot;&gt;Chakra UI&lt;/a&gt;. If you&apos;re unfamiliar with Chakra, it is a set of composable components, all built on a base primitive of a &lt;code&gt;Box&lt;/code&gt;. &lt;code&gt;Box&lt;/code&gt; has a large set of props that are mappable to styles. Props regarding margin, padding, background color, etc.&lt;/p&gt;
&lt;p&gt;I, too, built us a &lt;code&gt;Box&lt;/code&gt; on top of the &lt;a href=&quot;https://necolas.github.io/react-native-web/&quot;&gt;React Native Web project&lt;/a&gt;, but I made all of the props conform to our design system. For example, we had a palette of &lt;code&gt;colors&lt;/code&gt;, and rather than have you pass the color value to the &lt;code&gt;Box&lt;/code&gt;, I had you write the color &lt;em&gt;key&lt;/em&gt; and did the mapping under the hood for you. Like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;Box backgroundColor=&quot;gray-300&quot;&amp;gt;
  &amp;lt;Text&amp;gt;I am some example text.&amp;lt;/Text&amp;gt;
&amp;lt;/Box&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We mapped &lt;em&gt;every&lt;/em&gt; prop to keys so you could never deviate. Border radiuses, border thicknesses, padding sizes, gap sizes, etc. Everything had to be done thru the props system. It was awesome because you got Intellisense autocomplete and type errors when you did something wrong.&lt;/p&gt;
&lt;p&gt;We made many other components on top of &lt;code&gt;Box&lt;/code&gt;. Components like &lt;code&gt;Row&lt;/code&gt; and &lt;code&gt;Stack&lt;/code&gt; and &lt;code&gt;Button&lt;/code&gt;, &lt;code&gt;Input&lt;/code&gt;, &lt;code&gt;Textarea&lt;/code&gt;, etc. The entire system was built around composing &lt;code&gt;Box&lt;/code&gt;es and other primitives like &lt;code&gt;Pressable&lt;/code&gt; and &lt;code&gt;Text&lt;/code&gt;. It was a rock solid foundation. It was robust. You could not break it or screw it up. It was very fast to use and scaled exceptionally well.&lt;/p&gt;
&lt;p&gt;It just had one problem.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Lots of people struggle to build things compositionally.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The company severely lacked frontend talent, as it had historically over indexed on fullstack devs who were really backend devs. So many of these people just couldn&apos;t wrap their head around how to properly arrange and compose these components to get the layouts they needed. They were so used to solving everything with some truly tragic CSS that they were quagmired by composition, incapable of seeing alternative ways to achieve the layouts they needed.&lt;/p&gt;
&lt;p&gt;Let me give you an overly simple example to explain.&lt;/p&gt;
&lt;h3&gt;Using composition to design&lt;/h3&gt;
&lt;p&gt;In a world where you must support React and React Native, you only have one layout mechanism: Flexbox. Flexbox is an inherently compositional system. The styles of the parent affect the styles of the children. Composition is how we change the layout of children.&lt;/p&gt;
&lt;p&gt;When I first arrived, the designers had the idea of having a &lt;code&gt;width&lt;/code&gt; variant on the &lt;code&gt;Button&lt;/code&gt;. They wanted &lt;code&gt;Button&lt;/code&gt;s that were just a little bigger than the text, we could call it an &lt;code&gt;inline-block&lt;/code&gt; button, and they wanted &lt;code&gt;Button&lt;/code&gt;s that expanded the full width of their parent. They were adamant that they needed two sizes.&lt;/p&gt;
&lt;p&gt;&quot;No, you don&apos;t. You only need one size,&quot; I said boldly. They were a bit shocked and confused. And then I showed them this.&lt;/p&gt;
&lt;p&gt;Here are two &lt;code&gt;Button&lt;/code&gt;s:&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-8&quot;&amp;gt;
&amp;lt;OffsetWrap&amp;gt;
&amp;lt;div class=&quot;flex flex-col gap-4&quot;&amp;gt;
&amp;lt;Button onClick={() =&amp;gt; {}}&amp;gt;Click me&amp;lt;/Button&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  &amp;lt;div class=&quot;flex flex-row&quot;&amp;gt;
    &amp;lt;Button onClick={() =&amp;gt; {}}&amp;gt;Click me&amp;lt;/Button&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;/OffsetWrap&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;Stylistically, there is nothing different about them. I didn&apos;t change their markup at all or give them different classes. All I did was change what Flex context each &lt;code&gt;Button&lt;/code&gt; is in.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;Stack&amp;gt;
  &amp;lt;Button onPress={() =&amp;gt; {}}&amp;gt;Click me&amp;lt;/Button&amp;gt;

  &amp;lt;Row&amp;gt;
    &amp;lt;Button onPress={() =&amp;gt; {}}&amp;gt;Click me&amp;lt;/Button&amp;gt;
  &amp;lt;/Row&amp;gt;
&amp;lt;/Stack&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A &lt;code&gt;Stack&lt;/code&gt; is a Flex &lt;code&gt;column&lt;/code&gt; context, a &lt;code&gt;Row&lt;/code&gt; a Flex &lt;code&gt;row&lt;/code&gt; context. The default &lt;code&gt;align-items&lt;/code&gt; in a Flex context is &lt;code&gt;stretch&lt;/code&gt;. This means children of a Flex &lt;code&gt;column&lt;/code&gt; parent behave similar to &lt;code&gt;block&lt;/code&gt; level elements. They fill the full width of their parent.&lt;/p&gt;
&lt;p&gt;On the other hand, children of a Flex &lt;code&gt;row&lt;/code&gt; parent behave like &lt;code&gt;inline&lt;/code&gt; or &lt;code&gt;inline-block&lt;/code&gt; elements. They shrink to the size of their minimum content width.&lt;/p&gt;
&lt;p&gt;The designers were a bit stunned that they could have both buttons &lt;em&gt;just by changing the context they were rendered in&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;But this was a challenge for devs. They were slow to understand that the way to have an &lt;code&gt;inline-block&lt;/code&gt;-like button was to wrap it in a &lt;code&gt;Row&lt;/code&gt;. Even &lt;em&gt;after&lt;/em&gt; I did multiple demos and wrote examples in our documentation. It never became intuitive for them.&lt;/p&gt;
&lt;p&gt;I&apos;d have people ask me, &quot;What if I want multiple buttons of the same width next to each other?&quot;&lt;/p&gt;
&lt;p&gt;Easy. More composition:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;Row&amp;gt;
  &amp;lt;Row.Item grow={1} shrink={1}&amp;gt;
    &amp;lt;Button onPress={() =&amp;gt; {}}&amp;gt;Click me&amp;lt;/Button&amp;gt;
  &amp;lt;/Row.Item&amp;gt;

  &amp;lt;Row.Item grow={1} shrink={1}&amp;gt;
    &amp;lt;Button onPress={() =&amp;gt; {}}&amp;gt;Click me&amp;lt;/Button&amp;gt;
  &amp;lt;/Row.Item&amp;gt;

  &amp;lt;Row.Item grow={1} shrink={1}&amp;gt;
    &amp;lt;Button onPress={() =&amp;gt; {}}&amp;gt;Click me&amp;lt;/Button&amp;gt;
  &amp;lt;/Row.Item&amp;gt;
&amp;lt;/Row&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-8&quot;&amp;gt;
&amp;lt;OffsetWrap&amp;gt;
&amp;lt;div class=&quot;flex flex-row gap-4&quot;&amp;gt;
&amp;lt;div class=&quot;flex shrink grow flex-col&quot;&amp;gt;
&amp;lt;Button&amp;gt;Click me&amp;lt;/Button&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;div class=&quot;flex shrink grow flex-col&quot;&amp;gt;
&amp;lt;Button&amp;gt;Click me&amp;lt;/Button&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;div class=&quot;flex shrink grow flex-col&quot;&amp;gt;
&amp;lt;Button&amp;gt;Click me&amp;lt;/Button&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;Every Flex container came with an &lt;code&gt;.Item&lt;/code&gt; compound component that we could use to apply values like &lt;code&gt;grow&lt;/code&gt;, &lt;code&gt;shrink&lt;/code&gt;, &lt;code&gt;basis&lt;/code&gt;, or &lt;code&gt;alignSelf&lt;/code&gt; to. It enabled us to compose any arrangement we needed.&lt;/p&gt;
&lt;p&gt;Taking it a step further, I could wrap the &lt;code&gt;children&lt;/code&gt; of a Flex container under the hood with &lt;code&gt;Flex.Item&lt;/code&gt;s and give them a nice API like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;Row childrenGrow={1} childrenShrink={1}&amp;gt;
  &amp;lt;Button onPress={() =&amp;gt; {}}&amp;gt;Click me&amp;lt;/Button&amp;gt;
  &amp;lt;Button onPress={() =&amp;gt; {}}&amp;gt;Click me&amp;lt;/Button&amp;gt;
  &amp;lt;Button onPress={() =&amp;gt; {}}&amp;gt;Click me&amp;lt;/Button&amp;gt;
&amp;lt;/Row&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This manner of composing things applied to other ways of styling and manipulating elements, too. For example, &lt;code&gt;box-shadow&lt;/code&gt;s in React Native are a giant pain in the ass, so I made a &lt;code&gt;Shadow&lt;/code&gt; component that you just wrapped other components in that did all the iOS and Android magic under the hood.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;Shadow&amp;gt;
  &amp;lt;Card&amp;gt;{/* other stuff */}&amp;lt;/Card&amp;gt;
&amp;lt;/Shadow&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The whole system depended on this ability to compose components together to achieve what we desired. It really was a solid system and something I was proud of.&lt;/p&gt;
&lt;h3&gt;So what was the problem?&lt;/h3&gt;
&lt;p&gt;The main problem was there are &lt;a href=&quot;/two-types-of-composition&quot;&gt;two types of composition&lt;/a&gt;, and most people are ok at object composition, and aren&apos;t very good at functional composition.&lt;/p&gt;
&lt;p&gt;The struggles with this kind of composition made me realize something: &lt;strong&gt;many devs don&apos;t write styles from a deep, rooted place of knowledge and know exactly what they need to write to make it do what they want; they write code by throwing stuff at the wall until it sticks.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I promise you, that&apos;s not an insult. I was the one who failed. Not the other devs.&lt;/p&gt;
&lt;p&gt;Even though writing &lt;code&gt;styled-components&lt;/code&gt; with bespoke CSS over and over was really slow and led to literally thousands of unnecessary lines of styling, it had one major benefit: &lt;strong&gt;people could easily try stuff&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Yes, they wrote a lot of redundant styles. Yes, there were tons of poor choices made. But they could kinda make it work. The user wouldn&apos;t really know it was a pile of hot, unmaintainable garbage under the hood, and it would be someone else&apos;s mess to deal with later.&lt;/p&gt;
&lt;p&gt;The problem with the Chakra UI-like system was there were almost no escape hatches in the entire system. You either had to really understand how to compose your way to a solution, or you were stuck. There wasn&apos;t enough surface area for anyone to throw something at the wall. &lt;strong&gt;That was entirely on purpose. It solved our original problems, but it meant many devs struggled to adapt&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;What I would do differently&lt;/h3&gt;
&lt;p&gt;After a while, I came to recognize the struggle devs were having. No amount of training or documentation seemed to be helping either. Some of them just weren&apos;t getting it and didn&apos;t really care to try and learn the system anyways. I felt like I had failed them. &amp;lt;Marker content=&quot;Even if, realistically, I hadn&apos;t&quot; /&amp;gt;&lt;/p&gt;
&lt;p&gt;I spent a lot of time thinking about the new problem I had created, and I eventually realized what I would do differently. If I could go back and do it again, I would have built the design system around &lt;code&gt;Tailwind&lt;/code&gt;/&lt;code&gt;NativeWind&lt;/code&gt; instead.&lt;/p&gt;
&lt;p&gt;My main reasoning goes like this: Fewer devs struggle to compose objects or tokens than they do functions. I would be giving up some of the restrictiveness that ensured rightness we had with the Chakra UI-style design system, but I&apos;d make it far simpler for devs to try things out. To throw things at the wall again. Our codebase would receive more sub-optimally written features, but at least they would have features.&lt;/p&gt;
&lt;p&gt;I think this path would have been an easier leap from the bespoke CSS of &lt;code&gt;styled-components&lt;/code&gt; to composing &lt;code&gt;Tailwind&lt;/code&gt; classes.&lt;/p&gt;
&lt;p&gt;Now, there are challenges with this approach, too. In the last couple of months, I have built another cross platform design system (and their apps) for a client that&apos;s following this approach. &lt;code&gt;Nativewind&lt;/code&gt; is imperfect, &amp;lt;Marker content=&quot;And at the time we started, we had to use the unofficially released v4 which is not something I would generally recommend or do.&quot; /&amp;gt; and we&apos;ve had to build a lot of components from scratch with the approach, but overall, the other devs are at least able to try things and move forward.&lt;/p&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;Some people will always struggle with using functional composition to build what they need to build. They need more escape hatches. Making the right tradeoff regarding how restrictive the system was may have made it easier to adopt for many devs. Going forward, I&apos;ll consider this more deeply in my decisions.&lt;/p&gt;
</content:encoded><category>React</category><category>Design Systems</category><category>CSS</category><category>Tailwind</category></item><item><title>Prefer Noun-Adjective Naming</title><link>https://kyleshevlin.com/prefer-noun-adjective-naming/</link><guid isPermaLink="true">https://kyleshevlin.com/prefer-noun-adjective-naming/</guid><description>English grammar puts the adjective before the noun, but when it comes to file or function naming, I think you should do the opposite.</description><pubDate>Sat, 18 May 2024 23:21:57 GMT</pubDate><content:encoded>&lt;p&gt;This one will be super short.&lt;/p&gt;
&lt;p&gt;In English grammar, the adjective comes before the noun. The green house. The large dog. The old man. Etc, etc.&lt;/p&gt;
&lt;p&gt;Because of this, we tend to also name our functions, components, objects, etc, the same way. &lt;code&gt;PrimaryButton&lt;/code&gt;, &lt;code&gt;DefaultHeader&lt;/code&gt;, &lt;code&gt;StandardLayout&lt;/code&gt;, etc.&lt;/p&gt;
&lt;p&gt;I prefer to use noun-adjective naming for one simple reason: alphabetical order.&lt;/p&gt;
&lt;p&gt;Let&apos;s say I&apos;m creating several components related to the same noun. I&apos;ve been working on a streaming app for a client recently, so I&apos;ll use a &lt;code&gt;Stream&lt;/code&gt; as my noun. A &lt;code&gt;Stream&lt;/code&gt; can be in three states: &lt;code&gt;created&lt;/code&gt;, &lt;code&gt;ended&lt;/code&gt;, or &lt;code&gt;live&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If I follow English grammar and make components for each state, I end up with &lt;code&gt;CreatedStream&lt;/code&gt;, &lt;code&gt;EndedStream&lt;/code&gt;, and &lt;code&gt;LiveStream&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now, imagine that these are right next to all your other components in the same directory. They could be separated by dozens of components inbetween &lt;code&gt;C&lt;/code&gt; and &lt;code&gt;E&lt;/code&gt;, or &lt;code&gt;E&lt;/code&gt; and &lt;code&gt;L&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;- CreatedStream.tsx
- CurrentUser.tsx
- EndedStream.tsx
- FullScreen.tsx
- GoLiveButton.tsx
- LiveStream.tsx
// etc...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Also, try searching for them. What if you forget that it&apos;s &lt;code&gt;Ended&lt;/code&gt; and not &lt;code&gt;Completed&lt;/code&gt; for that stage. You have to get the right adjective to get your search on the right path. &amp;lt;Marker content=&quot;Fuzzy search will probably work for you, but it&apos;s still easier to search starting with the noun.&quot; /&amp;gt;&lt;/p&gt;
&lt;p&gt;But if you flip them and go noun-adjective, &lt;code&gt;StreamCreated&lt;/code&gt;, &lt;code&gt;StreamEnded&lt;/code&gt;, and &lt;code&gt;StreamLive&lt;/code&gt;, all your components are right next to each other in your directory.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;- ButtonGoLive.tsx
- ScreenFull.tsx
- StreamCreated.tsx
- StreamEnded.tsx
- StreamLive.tsx
- UserCurrent.tsx
// etc...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In addition, it&apos;s much easier to search this way. Just type the noun &lt;code&gt;Stream&lt;/code&gt; and choose which one you need.&lt;/p&gt;
&lt;p&gt;It&apos;s a small change, but I think it makes for far better organization in your codebase. Try it, see if you like it, too.&lt;/p&gt;
</content:encoded><category>React</category><category>JavaScript</category><category>TypeScript</category><category>Prefer</category></item><item><title>Prefer Multiple Compositions</title><link>https://kyleshevlin.com/prefer-multiple-compositions/</link><guid isPermaLink="true">https://kyleshevlin.com/prefer-multiple-compositions/</guid><description>The flexibility of JavaScript and React means there are lots of ways to achieve the same result. Let&apos;s consider why we might choose one way over another when it comes to React. Specifically, when to choose a more verbose solution with composition over the DRYest code possible.</description><pubDate>Fri, 17 May 2024 21:12:18 GMT</pubDate><content:encoded>&lt;p&gt;Consider the following &lt;em&gt;absurdly&lt;/em&gt; simple example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function VideoControls() {
  const { isPlaying, play, pause } = useVideoControls()

  return (
    &amp;lt;Button onPress={isPlaying ? pause : play}&amp;gt;
      &amp;lt;Icon name={isPlaying ? &apos;pause&apos; : &apos;play&apos;} /&amp;gt;
      &amp;lt;Button.Text&amp;gt;{isPlaying ? &apos;Pause&apos; : &apos;Play&apos;}&amp;lt;/Button.Text&amp;gt;
    &amp;lt;/Button&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We have ourselves a &lt;code&gt;Button&lt;/code&gt; that presumably controls the state of a video. It&apos;s not that complicated and probably very similar to many components you&apos;ve seen over time.&lt;/p&gt;
&lt;p&gt;This is a valid way to write &lt;em&gt;this&lt;/em&gt; component. With something this simple, there&apos;s not a lot of concern regarding the implementation.&lt;/p&gt;
&lt;p&gt;That said, if we think about the pattern more broadly, that is the pattern of &lt;em&gt;handling all conditions in a single composition&lt;/em&gt;, I think we can start to see some weaknesses in writing code this way.&lt;/p&gt;
&lt;p&gt;The thing that makes me question whether we should use the single composition pattern here is that we have three conditionally rendered pieces that all are based on the same value. In my experience, when many decisions hinge on a single value, &lt;strong&gt;it&apos;s better to prefer multiple compositions, even when it&apos;s more verbose, than to do so much conditional handling inline&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;If we prefer composition, our &lt;code&gt;VideoControls&lt;/code&gt; will look like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function VideoControls() {
  const { isPlaying, play, pause } = useVideoControls()

  if (isPlaying) {
    return (
      &amp;lt;Button onPress={pause}&amp;gt;
        &amp;lt;Icon name=&quot;pause&quot; /&amp;gt;
        &amp;lt;Button.Text&amp;gt;Pause&amp;lt;/Button.Text&amp;gt;
      &amp;lt;/Button&amp;gt;
    )
  }

  return (
    &amp;lt;Button onPress={play}&amp;gt;
      &amp;lt;Icon name=&quot;play&quot; /&amp;gt;
      &amp;lt;Button.Text&amp;gt;Play&amp;lt;/Button.Text&amp;gt;
    &amp;lt;/Button&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can even take it a step further easily:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function VideoControls() {
  const { isPlaying } = useVideoControls()

  return isPlaying ? &amp;lt;PauseButton /&amp;gt; : &amp;lt;PlayButton /&amp;gt;
}

function PauseButton() {
  const { pause } = useVideoControls()

  return (
    &amp;lt;Button onPress={pause}&amp;gt;
      &amp;lt;Icon name=&quot;pause&quot; /&amp;gt;
      &amp;lt;Button.Text&amp;gt;Pause&amp;lt;/Button.Text&amp;gt;
    &amp;lt;/Button&amp;gt;
  )
}

function PlayButton() {
  const { play } = useVideoControls()

  return (
    &amp;lt;Button onPress={play}&amp;gt;
      &amp;lt;Icon name=&quot;play&quot; /&amp;gt;
      &amp;lt;Button.Text&amp;gt;Play&amp;lt;/Button.Text&amp;gt;
    &amp;lt;/Button&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, in an example like this, you might argue that this looks worse. &quot;I don&apos;t like early returns!&quot;, &quot;I don&apos;t like small components!&quot; I can hear some people say.&lt;/p&gt;
&lt;p&gt;Yes, the example of a single &lt;code&gt;Button&lt;/code&gt; might be a bit too rudimentary for us to be overly concerned with how we write it, but it exemplifies common choices we make in far more complicated components.&lt;/p&gt;
&lt;p&gt;Because JavaScript and React are so flexible, we can tend not to give much thought to how we organize our code for maintainability. We see a problem &lt;em&gt;there&lt;/em&gt;, we put an inline fix &lt;em&gt;there&lt;/em&gt;. Job done.&lt;/p&gt;
&lt;p&gt;But as the product gets more complicated, we can start to lose velocity when there are lots of &quot;little conditionals&quot; littered about. It&apos;s less obvious which branch of logic you are in. Are these conditionals related? Are they not? Often, we need to read almost every line of code to figure it out.&lt;/p&gt;
&lt;p&gt;But if we prefer multiple compositions like we did in the second and third example, notice what we accomplished. We went from three conditionals to just a single one. I would argue that the code is much simpler and we have made it a lot harder to introduce bugs. How easy would it be to reverse a ternary accidentally?&lt;/p&gt;
&lt;p&gt;If you&apos;re not already convinced that composition leads to better components, let&apos;s consider some more examples.&lt;/p&gt;
&lt;p&gt;What if we&apos;re fetching data on the client? Sure, there might be parts of the UI that need to be there regardless of the state of the data fetching, but often times we could write entirely separate compositions that map nicely to each state we could be in.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function DataView() {
  const { data, error, isLoading } = useGetMyData()

  if (isLoading) {
    return &amp;lt;LoadingComposition /&amp;gt;
  }

  if (error) {
    return &amp;lt;ErrorComposition error={error} /&amp;gt;
  }

  if (isEmpty(data)) {
    return &amp;lt;EmptyComposition /&amp;gt;
  }

  return &amp;lt;SuccessComposition data={data} /&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preferring composition also works nicely with objects that share a &lt;a href=&quot;https://www.typescriptlang.org/docs/handbook/unions-and-intersections.html#discriminating-unions&quot;&gt;discriminated union&lt;/a&gt;. I&apos;m working on a streaming app for a client at the moment. The &lt;code&gt;Stream&lt;/code&gt; can be in several &lt;code&gt;phase&lt;/code&gt;s: &lt;code&gt;&apos;created&apos; | &apos;live&apos; | &apos;ended&apos;&lt;/code&gt;. The screens for these different &lt;code&gt;phase&lt;/code&gt;s can be quite different. The following is an extremely pared down version of some of the different UI rendered per &lt;code&gt;phase&lt;/code&gt;. I could write some code like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function StreamDisplay({ stream }: { stream: Stream }) {
  const { phase } = stream

  let additionalClasses = &apos;&apos;

  if (phase === &apos;ended&apos;) {
    additionalClasses = &apos;justify-center items-center&apos;
  }

  if (phase === &apos;created&apos;) {
    additionalClasses = &apos;justify-end&apos;
  }

  return (
    &amp;lt;View className={`relative flex flex-1 flex-col ${additionalClasses}`}&amp;gt;
      {phase === &apos;live&apos; &amp;amp;&amp;amp; (
        &amp;lt;View className=&quot;absolute right-4 top-4&quot;&amp;gt;
          &amp;lt;VideoControls /&amp;gt;
        &amp;lt;/View&amp;gt;
      )}

      {phase === &apos;ended&apos; &amp;amp;&amp;amp; &amp;lt;Text&amp;gt;Stream has ended.&amp;lt;/Text&amp;gt;}

      {phase === &apos;created&apos; &amp;amp;&amp;amp; &amp;lt;GoLiveButton /&amp;gt;}
    &amp;lt;/View&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I hope you agree with me, that this is all over the place. We&apos;re changing Flex properties based on &lt;code&gt;phase&lt;/code&gt;, we&apos;re conditionally rendering buttons and text and all sorts of other stuff. It&apos;s accurate, but I think it&apos;s way more convoluted than necessary. We don&apos;t need to write our components &lt;em&gt;this&lt;/em&gt; DRY. I&apos;d much rather repeat myself a bit, and make it much easier to read, maintain and update. Like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function StreamDisplay({ stream }: { stream: Stream }) {
  const { phase } = stream

  if (phase === &apos;created&apos;) {
    return (
      &amp;lt;View className=&quot;flex flex-1 flex-col justify-end&quot;&amp;gt;
        &amp;lt;GoLiveButton /&amp;gt;
      &amp;lt;/View&amp;gt;
    )
  }

  if (phase === &apos;ended&apos;) {
    return (
      &amp;lt;View className=&quot;flex flex-1 flex-col items-center justify-center&quot;&amp;gt;
        &amp;lt;Text&amp;gt;Stream has ended.&amp;lt;/Text&amp;gt;
      &amp;lt;/View&amp;gt;
    )
  }

  if (phase === &apos;live&apos;) {
    return (
      &amp;lt;View className=&quot;relative flex-1&quot;&amp;gt;
        &amp;lt;View className=&quot;absolute right-4 top-4&quot;&amp;gt;
          &amp;lt;VideoControls /&amp;gt;
        &amp;lt;/View&amp;gt;
      &amp;lt;/View&amp;gt;
    )
  }

  return null
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And if I&apos;m being honest, I probably actually write it like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function StreamDisplay({ stream }: { stream: Stream }) {
  switch (stream.phase) {
    case &apos;created&apos;:
      return &amp;lt;StreamCreated stream={stream} /&amp;gt;

    case &apos;ended&apos;:
      return &amp;lt;StreamEnded stream={stream} /&amp;gt;

    case &apos;live&apos;:
      return &amp;lt;StreamLive stream={stream} /&amp;gt;

    default:
      return null
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;My point is simple. Even if we have to write a few more wrapping elements, by favoring composition, we make the code &lt;strong&gt;wildly&lt;/strong&gt; more understandable and maintainable. You spend absolutely &lt;em&gt;no&lt;/em&gt; time trying to figure out if you&apos;re in the correct component or not.&lt;/p&gt;
&lt;p&gt;If our &lt;code&gt;Stream&lt;/code&gt; ever gets another phase, we just make another composition. If the &lt;code&gt;live&lt;/code&gt; phase needs an update, we don&apos;t need to hunt through &lt;code&gt;StreamDisplay&lt;/code&gt; and make sure we don&apos;t break anything for the &lt;code&gt;created&lt;/code&gt; and &lt;code&gt;ended&lt;/code&gt; phases. We can go straight to &lt;code&gt;StreamLive&lt;/code&gt; and add it.&lt;/p&gt;
&lt;p&gt;I hope this post elucidates some of the challenges you might have felt but not verbalized in working with lots of little conditionals in your code. Preferring multiple compositions can make your work a lot more understandable and maintainable, and now you know how to do it.&lt;/p&gt;
&lt;p&gt;There are several related posts below that I think you&apos;ll enjoy, check them out if you have time.&lt;/p&gt;
</content:encoded><category>React</category><category>JavaScript</category><category>TypeScript</category><category>Refactoring</category><category>Prefer</category></item><item><title>&lt;code&gt;align-items: center&lt;/code&gt; vs. &lt;code&gt;text-align: center&lt;/code&gt;</title><link>https://kyleshevlin.com/align-items-center-vs-text-align-center/</link><guid isPermaLink="true">https://kyleshevlin.com/align-items-center-vs-text-align-center/</guid><description>Learn when to use align-items: center or text-align: center in Flex columns.</description><pubDate>Sat, 04 May 2024 16:39:19 GMT</pubDate><content:encoded>&lt;p&gt;For going on three years now, I&apos;ve been working daily in an environment where all the code that I write has to support both React and React Native. People unfamiliar with what it takes to support both platforms might not realize a few restrictions you must deal with. One of them is this: Flexbox is your &lt;em&gt;only&lt;/em&gt; layout option.&lt;/p&gt;
&lt;p&gt;That&apos;s right. No tables. No grids. No &lt;em&gt;anything&lt;/em&gt; else. Flexbox is all you got.&lt;/p&gt;
&lt;p&gt;Because of this, there&apos;s a common mistake I&apos;ve seen developers make over and over I want to demonstrate and fix.&lt;/p&gt;
&lt;p&gt;In React Native, every element at a fundamental level is a &lt;code&gt;View&lt;/code&gt; or a &lt;code&gt;Text&lt;/code&gt;. Thus, when creating components that work across platforms, we have to use these &lt;code&gt;View&lt;/code&gt; and &lt;code&gt;Text&lt;/code&gt; components on web, too. Generally, this is accomplished through a library like &lt;a href=&quot;https://necolas.github.io/react-native-web/&quot;&gt;react-native-web&lt;/a&gt;, which renders the correct underlying component depending on the platform.&lt;/p&gt;
&lt;p&gt;It&apos;s important to know that there is one key difference between a &lt;code&gt;View&lt;/code&gt; and a &lt;code&gt;div&lt;/code&gt;: a &lt;code&gt;View&lt;/code&gt; is &lt;em&gt;not&lt;/em&gt; a &lt;code&gt;block&lt;/code&gt; level element.&lt;code&gt;View&lt;/code&gt; is a &lt;code&gt;flex&lt;/code&gt; container with &lt;code&gt;flex-direction&lt;/code&gt; set to &lt;code&gt;column&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;With that in mind, now I&apos;m going to show you two very similar examples, and I want you to spot the difference.&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-8 flex flex-col gap-4 md:flex-row&quot;&amp;gt;
&amp;lt;div class=&quot;flex grow flex-col items-center rounded-xl border-2 p-4&quot;&amp;gt;
&amp;lt;span class=&quot;font-sans&quot;&amp;gt;Lorem ipsum&amp;lt;/span&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;div class=&quot;flex grow flex-col rounded-xl border-2 p-4&quot;&amp;gt;
&amp;lt;span class=&quot;text-center font-sans&quot;&amp;gt;Lorem ipsum&amp;lt;/span&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;Did you spot it? What about now?&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-8 flex flex-col gap-4 md:flex-row&quot;&amp;gt;
&amp;lt;div class=&quot;flex grow flex-col items-center rounded-xl border-2 p-4&quot;&amp;gt;
&amp;lt;span class=&quot;font-sans&quot;&amp;gt;
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam
fermentum, arcu id faucibus accumsan, turpis ex interdum est, eget
tristique odio odio eget nibh.
&amp;lt;/span&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;div class=&quot;flex grow flex-col rounded-xl border-2 p-4&quot;&amp;gt;
&amp;lt;span class=&quot;text-center font-sans&quot;&amp;gt;
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam
fermentum, arcu id faucibus accumsan, turpis ex interdum est, eget
tristique odio odio eget nibh.
&amp;lt;/span&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;You see the difference? Both examples are Flex columns. The first example has set &lt;code&gt;align-items&lt;/code&gt; to &lt;code&gt;center&lt;/code&gt;, while the second example has kept the default &lt;code&gt;align-items&lt;/code&gt; of &lt;code&gt;stretch&lt;/code&gt;, but used &lt;code&gt;text-align: center&lt;/code&gt; on the text instead. This is a small detail that&apos;s easy to overlook, but can have you scratching your head later trying to get things to align the way you&apos;d like.&lt;/p&gt;
&lt;p&gt;When the text is short, it can seem like which CSS you use doesn&apos;t matter, but if we were to add a background to the text in our first two examples, we&apos;d notice the difference right away.&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-8 flex flex-col gap-4 md:flex-row&quot;&amp;gt;
&amp;lt;div class=&quot;flex grow flex-col items-center rounded-xl border-2 p-4&quot;&amp;gt;
&amp;lt;span class=&quot;bg-pink-500 font-sans text-white&quot;&amp;gt;Lorem ipsum&amp;lt;/span&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;div class=&quot;flex grow flex-col rounded-xl border-2 p-4&quot;&amp;gt;
&amp;lt;span class=&quot;bg-pink-500 text-center font-sans text-white&quot;&amp;gt;
Lorem ipsum
&amp;lt;/span&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;When we change &lt;code&gt;align-items&lt;/code&gt; to &lt;code&gt;center&lt;/code&gt;, we shrink all the children to their minimum content width. For text that is shorter than the width of its container, it will appear the same as &lt;code&gt;text-align: center&lt;/code&gt;, but will behave differently once our text starts to wrap.&lt;/p&gt;
&lt;p&gt;My main reason for pointing this out is that I so often see unnecessary compensations on the &lt;code&gt;children&lt;/code&gt; of a Flex container. Yes, sometimes it might be easier to set a particular &lt;code&gt;align-items&lt;/code&gt; on the parent, and then use &lt;code&gt;align-self&lt;/code&gt; on a child to make an adjustment. That&apos;s why the CSS property exists, but often these compensations are unnecessary entirely.&lt;/p&gt;
&lt;p&gt;For example, if we use &lt;code&gt;align-items: center&lt;/code&gt; instead of setting the &lt;code&gt;text-align&lt;/code&gt; on the title, and we later have an element that we need to take up the full width, we might compensate by setting it&apos;s &lt;code&gt;width&lt;/code&gt; to &lt;code&gt;100%&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-8 flex flex-col items-center gap-4 rounded-xl border-2 p-4&quot;&amp;gt;
&amp;lt;div class=&quot;bg-pink-500 font-sans text-white&quot;&amp;gt;This is an example title&amp;lt;/div&amp;gt;
&amp;lt;div class=&quot;w-full bg-pink-500 font-sans text-white&quot;&amp;gt;
This is an example paragraph with the width set to 100%.
&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;We could avoid that simply by setting &lt;code&gt;text-align: center&lt;/code&gt; on the title instead.&lt;/p&gt;
&lt;p&gt;If you peek under the hood at the Tailwind for that example, you&apos;ll see we&apos;ve added two classes when one would have done the job. Do this enough times across an app, and the number of unnecessary styles can really grow.&lt;/p&gt;
&lt;p&gt;This is a simple thing to get confused about and only notice later when you&apos;re making a lot of compensations on the children to get things aligned correctly. Hopefully by seeing this simple example, the gears will start turning and you&apos;ll spot when you might need to use one or the other, or even sometimes both.&lt;/p&gt;
</content:encoded><category>React</category><category>CSS</category><category>Tailwind</category></item><item><title>Creating a React Native &amp;ldquo;Curved Bottom Bar&amp;rdquo; with Handwritten SVG</title><link>https://kyleshevlin.com/react-native-curved-bottom-bar-with-handwritten-svg/</link><guid isPermaLink="true">https://kyleshevlin.com/react-native-curved-bottom-bar-with-handwritten-svg/</guid><description>I recently made a &quot;curved bottom bar&quot; in React Native for a client. Instead of using a library, let&amp;apos;s build it from scratch with some handwritten SVG. It&amp;apos;s no where near as intimidating as it sounds.</description><pubDate>Sat, 20 Apr 2024 15:45:12 GMT</pubDate><content:encoded>&lt;p&gt;import { CURVED_TAB_BAR_D, Shape } from &apos;./_components.tsx&apos;&lt;/p&gt;
&lt;p&gt;I&apos;m building my first full React Native app right now for a client and ran into a challenging problem right away. There&apos;s a trend in native apps for the bottom tab bar to have a cutout for a larger circular action button right in the middle. I&apos;ve seen it called the &quot;curved bottom bar&quot; in my research. To make it clear what I&apos;m talking about, let me share the first example I found on my phone, which was from Venmo:&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-8 flex flex-col items-center&quot;&amp;gt;
&amp;lt;div class=&quot;max-w-[420px]&quot;&amp;gt;
&amp;lt;Image
alt=&quot;The Venmo bottom bar with the curved cutout for a giant blue button with the Venmo V in it.&quot;
src=&quot;/images/venmo_example.jpg&quot;
/&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;Notice that you can see the text of an item beneath and through the cutout. That&apos;s a key feature of this design. In researching how to accomplish this, I found several libraries, but none of them were ready to work with the routing we&apos;re using in the applications. I was going to have to do it from scratch.&lt;/p&gt;
&lt;p&gt;What I found was most people accomplished this using SVG, which is ironic given that React Native doesn&apos;t natively support SVG. What I found &lt;em&gt;interesting&lt;/em&gt; about how they were accomplishing it was their use of &lt;a href=&quot;https://github.com/d3/d3-shape&quot;&gt;d3&apos;s &lt;code&gt;d3-shape&lt;/code&gt; package&lt;/a&gt; instead of writing the SVG by hand, which is remarkably easy to do. Let me prove it to you.&lt;/p&gt;
&lt;p&gt;Through the course of this post, we&apos;re going to build this:&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-8 flex justify-center text-accent&quot;&amp;gt;
&amp;lt;Shape /&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;We&apos;ll do it step by step, so you can follow along.&lt;/p&gt;
&lt;p&gt;Writing SVG by hand is a lot simpler than you might suspect. It reminds me of learning regular expressions. It looks really intimidating, but once you learn a few things, it becomes far less scary. We can combine some basic SVG skills with &lt;a href=&quot;/parametric-design&quot;&gt;&quot;parametric design&quot; principles&lt;/a&gt; to create a custom shape that will be &lt;em&gt;perfect&lt;/em&gt; thanks to math.&lt;/p&gt;
&lt;p&gt;Everything I&apos;ve ever learned about writing SVG by hand comes from this: &lt;a href=&quot;https://svgpocketguide.com/&quot;&gt;The SVG Pocket Guide&lt;/a&gt;. It&apos;s a wonderful resource and I go back to it time and time again. I encourage you bookmark it, as I&apos;m sure you&apos;ll do the same.&lt;/p&gt;
&lt;h3&gt;Drawing the shape&lt;/h3&gt;
&lt;p&gt;We&apos;re going to draw this shape using a &lt;code&gt;path&lt;/code&gt; element. Drawing a path is a lot like giving instructions to a someone with a pencil. Start here, go there. Move to here, draw a line to there. Close the loop. You just have to learn how to read the way we give the &lt;code&gt;path&lt;/code&gt; those instructions.&lt;/p&gt;
&lt;p&gt;We&apos;re going to partner this with parametric design by using variables. These variables will describe certain values we want in our &lt;code&gt;path&lt;/code&gt;. That way, if we want to tweak something, we just tweak a variable and our &lt;code&gt;path&lt;/code&gt; updates.&lt;/p&gt;
&lt;p&gt;We&apos;re going to build a basic rectangle first as the foundation of our shape. We&apos;re going to start in the bottom-left corner of the rectangle and work our way around the shape clockwise. Let&apos;s see the code, and then I&apos;ll break it down.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const WIDTH = 320
const HEIGHT = 48

/**
 * Line by line explanation
 * - Start in the bottom-left
 * - Draw a line to top-left
 * - Draw a line to top-right
 * - Draw a line to bottom-right
 * - Close the path
 */
const d = `
M0,${HEIGHT}
L0,0
L${WIDTH},0
L${WIDTH},${HEIGHT}
Z
`

function Shape() {
  return (
    &amp;lt;svg width={WIDTH} height={HEIGHT}&amp;gt;
      &amp;lt;path d={d} /&amp;gt;
    &amp;lt;/svg&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We&apos;ve stored some values for the width and height of our shape and we can change those to suit our needs. Next, we&apos;ve created a &lt;code&gt;d&lt;/code&gt; variable, which is the value we hand to our &lt;code&gt;path&lt;/code&gt; element. Let&apos;s break down this string further.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;M&lt;/code&gt; stands for &lt;code&gt;moveTo&lt;/code&gt;. We&apos;re giving our &lt;code&gt;path&lt;/code&gt; the instruction of moving to the bottom-left of our shape. Coordinates work as if &lt;code&gt;0,0&lt;/code&gt; is the top-left of our space, moving positively to the right and down. This makes &lt;code&gt;${WIDTH},${HEIGHT}&lt;/code&gt; the bottom-right of our shape. If you&apos;re wondering why we started in the bottom-left, those reasons will reveal themselves soon.&lt;/p&gt;
&lt;p&gt;So we&apos;ve moved to the point of &lt;code&gt;0,${HEIGHT}&lt;/code&gt;. Next, &lt;code&gt;L&lt;/code&gt; stands for &lt;code&gt;line&lt;/code&gt;. More specifically, draw a line from our current point to the next point. So when we say &lt;code&gt;L0,0&lt;/code&gt;, we&apos;re drawing a line from the bottom-left to the top-left of our shape.&lt;/p&gt;
&lt;p&gt;From there, we make two more lines to the top-right and bottom-right of our shape. However, we don&apos;t draw a third line back to the place we started. Instead, we use the &lt;code&gt;Z&lt;/code&gt; command. This tells the path to &quot;close&quot;, which returns to where we started. Thus, we get this shape:&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-8 flex justify-center text-accent&quot;&amp;gt;
&amp;lt;Shape d=&quot;M0,48 L0,0 L320,0 L320,48 Z&quot; /&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;Next, let&apos;s add the rounded top corners. That update looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const WIDTH = 320
const HEIGHT = 48
const CORNER_RADIUS = 12

/**
 * Line by line explanation
 * - Start in the bottom-left
 * - Draw a line towards the top-left to the start of our corner radius,
 *    use the top-left as the curve control point,
 *    and curve to the other end of our corner radius
 * - Draw a line towards the top-right to the start of our corner radius,
 *    use the top-right as the curve control point,
 *    and curve to the other end of our corner radius
 * - Draw a line to bottom-right
 * - Close the path
 */
const d = `
M0,${HEIGHT}
L0,${CORNER_RADIUS} Q0,0 ${CORNER_RADIUS},0
L${WIDTH - CORNER_RADIUS},0 Q${WIDTH},0 ${WIDTH},${CORNER_RADIUS}
L${WIDTH},${HEIGHT}
Z
`

function Shape() {
  return (
    &amp;lt;svg width={WIDTH} height={HEIGHT}&amp;gt;
      &amp;lt;path d={d} /&amp;gt;
    &amp;lt;/svg&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We added a variable and a few instructions! Let&apos;s break them down.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;CORNER_RADIUS&lt;/code&gt; describes how far we want to start the curve from the corners. We can add or subtract that value from other values to properly place the start and end points of our curves, and the &lt;code&gt;Q&lt;/code&gt; command is how we make those curves.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Q&lt;/code&gt; stands for &quot;quadratic bézier curve&quot; and it takes two coordinates for its command: the control point and the end point. Think of it this way, a segment of path is drawn from the start point to the end point. Then, the control point is moved to change how the line curves between the start point and end point.&lt;/p&gt;
&lt;p&gt;So when we see:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;L0,${CORNER_RADIUS} Q0,0 ${CORNER_RADIUS},0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We&apos;re telling the path to draw a line to &lt;code&gt;0,12&lt;/code&gt;, use &lt;code&gt;0,0&lt;/code&gt; as the control point, and curve to &lt;code&gt;12,0&lt;/code&gt;. If we change the value of &lt;code&gt;CORNER_RADIUS&lt;/code&gt;, then it would change which points it uses.&lt;/p&gt;
&lt;p&gt;When we render our new shape, we get:&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-8 flex justify-center text-accent&quot;&amp;gt;
&amp;lt;Shape d=&quot;M0,48 L0,12 Q0,0 12,0 L308,0 Q320,0 320,12 L320,48 Z&quot; /&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;Next, let&apos;s work on the cutout semi-circle in the middle. We can use math to get this centered and curved correctly. We&apos;ll be adding quite a few variables, so don&apos;t get overwhelmed. They&apos;ll make sense soon enough.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const WIDTH = 320
const HEIGHT = 48
const CORNER_RADIUS = 12
const CUTOUT_RADIUS = 30
const CUTOUT_LEFT_X = WIDTH / 2 - CUTOUT_RADIUS
const CUTOUT_RIGHT_X = WIDTH / 2 + CUTOUT_RADIUS

/**
 * Line by line explanation
 * - Start in the bottom-left
 * - Draw a line towards the top-left to the start of our corner radius,
 *    use the top-left as the curve control point,
 *    and curve to the other end of our corner radius
 * - Draw a line to the left edge of our cutout
 * - Draw an elliptical arc with an equal x and y radius to create a circle,
 *     have 0 rotation on the x-axis,
 *     use the smaller arc (we could use either as they are equal),
 *     sweep the arc in a counter-clockwise direction,
 *     complete the arc on the right cutout point
 * - Draw a line towards the top-right to the start of our corner radius,
 *    use the top-right as the curve control point,
 *    and curve to the other end of our corner radius
 * - Draw a line to bottom-right
 * - Close the path
 */
const d = `
M0,${HEIGHT}
L0,${CORNER_RADIUS} Q0,0 ${CORNER_RADIUS},0
L${CUTOUT_LEFT_X},0
A${CUTOUT_RADIUS},${CUTOUT_RADIUS} 0 0 0 ${CUTOUT_RIGHT_X},0
L${WIDTH - CORNER_RADIUS},0 Q${WIDTH},0 ${WIDTH},${CORNER_RADIUS}
L${WIDTH},${HEIGHT}
Z
`

function Shape() {
  return (
    &amp;lt;svg width={WIDTH} height={HEIGHT}&amp;gt;
      &amp;lt;path d={d} /&amp;gt;
    &amp;lt;/svg&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We start by defining a &lt;code&gt;CUTOUT_RADIUS&lt;/code&gt;, we can increase or decrease this value to make the cutout larger or smaller. Next, we derive a few useful values, namely the &lt;code&gt;x&lt;/code&gt; position for the left and right side of the cutout. Then we draw an &quot;arc&quot;.&lt;/p&gt;
&lt;p&gt;That&apos;s what the &lt;code&gt;A&lt;/code&gt; is for, an &quot;elliptical arc&quot;. This command takes a lot of values, but because we&apos;re making a semi-circle, we&apos;re able to simplify a few of them. The first value is the &lt;code&gt;x-radius&lt;/code&gt; and &lt;code&gt;y-radius&lt;/code&gt; of our ellipse. One way to think of a circle is as an ellipse whose focii are both in the center, meaning both radii are equal. That&apos;s what &lt;code&gt;A${CUTOUT_RADIUS},${CUTOUT_RADIUS}&lt;/code&gt; represents.&lt;/p&gt;
&lt;p&gt;The next value determines the rotation of the shape on the &lt;code&gt;x&lt;/code&gt; axis. Since there is no rotation, the value is &lt;code&gt;0&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Next, we have the &quot;large-arc-flag&quot;, essentially a boolean to determine if we want the larger or shorter of the two arcs produced by an ellipse. In our case they are equal, so we could use either &lt;code&gt;1&lt;/code&gt; or &lt;code&gt;0&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The next value is the &quot;sweep-flag&quot;, meaning should we draw our arc in a clockwise (&lt;code&gt;1&lt;/code&gt;) or counter-clockwise (&lt;code&gt;0&lt;/code&gt;) direction. Since we&apos;re going from the &lt;code&gt;CUTOUT_LEFT_X&lt;/code&gt; down and to the right, we use &lt;code&gt;0&lt;/code&gt; for our value.&lt;/p&gt;
&lt;p&gt;Lastly, we identify the point the arc should complete at, &lt;code&gt;${CUTOUT_RIGHT_X},0&lt;/code&gt; and we&apos;ve completed our arc. It looks like this:&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-8 flex justify-center text-accent&quot;&amp;gt;
&amp;lt;Shape d=&quot;M0,48 L0,12 Q0,0 12,0 L130,0 A30,30 0 0 0 190,0 L308,0 Q320,0 320,12 L320,48 Z&quot; /&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;From here, all we need to do is absolutely position this in the correct spot in our UI and build our buttons and tabs on top of it. If we need to make tweaks later, all we need to do is update some of the variables.&lt;/p&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;We don&apos;t always need a library to draw SVG in an understandable way. It just takes a little bit of effort to understand the available commands.&lt;/p&gt;
&lt;p&gt;Using variables to control aspects of our SVG allow us to tweak and modify our shape in a way that we know will always work. We could even hook these values into inputs and sliders to adjust them as we see fit.&lt;/p&gt;
&lt;p&gt;I hope you feel less intimidated about SVG now that you&apos;ve seen how to draw some of it by hand and inspired to try and use this technique in some of your own work.&lt;/p&gt;
</content:encoded><category>React</category><category>React Native</category><category>SVG</category><category>JavaScript</category></item><item><title>Tailwind &amp;ldquo;Minimum Full Height&amp;rdquo; Layout</title><link>https://kyleshevlin.com/tailwind-minimum-full-height-layout/</link><guid isPermaLink="true">https://kyleshevlin.com/tailwind-minimum-full-height-layout/</guid><description>I&amp;apos;ve been using Tailwind CSS on a lot of projects lately. Almost all my layouts for these projects are some version of the &quot;minimum full height&quot; layout, and I wanted to quickly show you how I do that with Tailwind.</description><pubDate>Sat, 30 Mar 2024 18:23:51 GMT</pubDate><content:encoded>&lt;p&gt;import { Example } from &apos;./_components.tsx&apos;&lt;/p&gt;
&lt;p&gt;I&apos;ve been using &lt;a href=&quot;https://tailwindcss.com/&quot;&gt;Tailwind CSS&lt;/a&gt; on a lot of projects lately. Almost all my layouts for these projects are some version of the &quot;minimum full height&quot; layout, and I wanted to quickly show you how I do that with Tailwind.&lt;/p&gt;
&lt;p&gt;The keys are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;html&lt;/code&gt; must be &lt;code&gt;height: 100%&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;body&lt;/code&gt; must be &lt;code&gt;min-height: 100%&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;body&lt;/code&gt; must be a Flex column container&lt;/li&gt;
&lt;li&gt;&lt;code&gt;main&lt;/code&gt; (or whatever element you choose) is &lt;code&gt;flex-grow: 1&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here are the important pieces of the markup you&apos;re looking for:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;html class=&quot;h-full&quot;&amp;gt;
  &amp;lt;body class=&quot;flex min-h-full flex-col&quot;&amp;gt;
    &amp;lt;header&amp;gt;&amp;lt;/header&amp;gt;
    &amp;lt;main class=&quot;grow&quot;&amp;gt;&amp;lt;/main&amp;gt;
    &amp;lt;footer&amp;gt;&amp;lt;/footer&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Percentage based heights only work if their parent element is a fixed height. In this case, since the topmost parent is set to the full height of the browser window, we can then also use a percentage based height on its direct child, the &lt;code&gt;body&lt;/code&gt; element.&lt;/p&gt;
&lt;p&gt;Because we want our &lt;code&gt;body&lt;/code&gt; element to be able to extend &lt;em&gt;beyond&lt;/em&gt; the full height of the browser when it has that much content, we only use &lt;code&gt;min-h-full&lt;/code&gt; on it.&lt;/p&gt;
&lt;p&gt;Next, by setting &lt;code&gt;body&lt;/code&gt; as a Flex column layout, we can use the &lt;code&gt;flex-grow&lt;/code&gt; property on one of its children to tell the layout engine, &quot;expand this element to any remaining available space&quot;. In this case, that&apos;s the &lt;code&gt;main&lt;/code&gt; element.&lt;/p&gt;
&lt;p&gt;Thus, with this markup, our &lt;code&gt;header&lt;/code&gt; and &lt;code&gt;footer&lt;/code&gt; will take up the amount of space they require, and the &lt;code&gt;main&lt;/code&gt; element will take up the rest to the full height of the browser if there is too little content to fill the space, and beyond if there is more than enough content.&lt;/p&gt;
&lt;p&gt;Here&apos;s a small example: &amp;lt;Marker content=&quot;A fixed height is used on the outermost &amp;lt;code&amp;gt;div&amp;lt;/code&amp;gt; to make it seem like a browser window. A &amp;lt;code&amp;gt;gap&amp;lt;/code&amp;gt; is used on the &amp;lt;code&amp;gt;div&amp;lt;/code&amp;gt; representing the &amp;lt;code&amp;gt;body&amp;lt;/code&amp;gt; element just for visibility.&quot; /&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-8&quot;&amp;gt;
&amp;lt;Example client:load /&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;And that&apos;s it. From there I encourage you to figure out the &lt;a href=&quot;https://en.wikipedia.org/wiki/Holy_grail_(web_design)&quot;&gt;&quot;holy grail&quot; layout&lt;/a&gt; to further develop your skills and understanding.&lt;/p&gt;
&lt;h3&gt;Update - 2024-04-03&lt;/h3&gt;
&lt;p&gt;Multiple people on Twitter pointed out that it might be better to use &lt;code&gt;h-dvh&lt;/code&gt; instead of &lt;code&gt;h-full&lt;/code&gt; on the &lt;code&gt;html&lt;/code&gt; element, and they&apos;re correct. In some cases, most likely ones involving mobile browsers, it might be better to use &lt;code&gt;h-dvh&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For those unfamiliar like I was, &lt;code&gt;dvh&lt;/code&gt; stands for &quot;dynamic viewport height&quot;. I found &lt;a href=&quot;https://dev.to/frehner/css-vh-dvh-lvh-svh-and-vw-units-27k4&quot;&gt;this solid dev.to article breaking down the various units&lt;/a&gt;, so I don&apos;t have to.&lt;/p&gt;
&lt;p&gt;On mobile screens, &lt;code&gt;h-dvh&lt;/code&gt; will track the full height and adjust if any other UI obstructs the viewport, such as the native navigation and such. So anything pinned to the bottom like our &lt;code&gt;footer&lt;/code&gt; is, will track along with the viewport resizing as those bits of UI change.&lt;/p&gt;
&lt;p&gt;So give &lt;code&gt;h-dvh&lt;/code&gt; a try if you find &lt;code&gt;h-full&lt;/code&gt; doesn&apos;t do the trick.&lt;/p&gt;
</content:encoded><category>Tailwind</category><category>CSS</category></item><item><title>Make Checkpoint</title><link>https://kyleshevlin.com/make-checkpoint/</link><guid isPermaLink="true">https://kyleshevlin.com/make-checkpoint/</guid><description>Learn how to create a simple Makefile to quickly create a &quot;checkpoint&quot; in your Git history when you are rapidly prototyping.</description><pubDate>Fri, 29 Mar 2024 16:01:20 GMT</pubDate><content:encoded>&lt;p&gt;When I&apos;m working on production code, I tend to be really good about making atomic commits in &lt;code&gt;git&lt;/code&gt;. I&apos;m a big fan of using patch commits, &lt;code&gt;git commit -p&lt;/code&gt;, to be really precise about what I am adding in that commit.&lt;/p&gt;
&lt;p&gt;But when I&apos;m prototyping or working on a new side project, &lt;strong&gt;throw that all out the window&lt;/strong&gt;!&lt;/p&gt;
&lt;p&gt;I&apos;m really bad about it on a side project. I can&apos;t tell you how many times I&apos;ve written entire projects without making a single commit. It&apos;s truly laughable. I have to do better, and luckily, it&apos;s easy to do so.&lt;/p&gt;
&lt;p&gt;I originally learned this tip from &lt;a href=&quot;https://twitter.com/aweary&quot;&gt;Brandon Dail on Twitter&lt;/a&gt;. The tip is to use a &lt;code&gt;Makefile&lt;/code&gt; to create a script that generates a &quot;checkpoint&quot;, a &lt;code&gt;git commit&lt;/code&gt; with a timestamp.&lt;/p&gt;
&lt;p&gt;We&apos;ll add a new file to our project named &lt;code&gt;Makefile&lt;/code&gt;, and then add the following to it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;checkpoint:
	@git add -A
	@git commit -m &quot;checkpoint at $$(date &apos;+%Y-%m-%dT%H:%M:%S%z&apos;)&quot;
	@git push
	@echo Checkpoint created and pushed to remote
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, in the terminal, I can run the command &lt;code&gt;make checkpoint&lt;/code&gt; &amp;lt;Marker content=&quot;If you know you will never add another script, you can remove the name &amp;lt;code&amp;gt;checkpoint:&amp;lt;/code&amp;gt; from the &amp;lt;code&amp;gt;Makefile&amp;lt;/code&amp;gt; and then simplify the command to &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; in the terminal. It will treat the instructions as the default command and run them.&quot; /&amp;gt; and it does the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Stages all the files to be committed&lt;/li&gt;
&lt;li&gt;Commits them with a message of &quot;checkpoint at &amp;lt;timestamp&amp;gt;&quot;&lt;/li&gt;
&lt;li&gt;Pushes the branch&lt;/li&gt;
&lt;li&gt;Logs out that the work is done&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It&apos;s that simple.&lt;/p&gt;
&lt;p&gt;Now when I&apos;m jamming on a new idea, I don&apos;t have to worry about my poor committing habits, I can just make checkpoints, which is way better than nothing.&lt;/p&gt;
&lt;p&gt;So if you&apos;re like me and really lazy about &lt;code&gt;git&lt;/code&gt; while hacking on something, consider adding this to your next project. Might help you out a little bit.&lt;/p&gt;
</content:encoded><category>Productivity</category><category>Prototyping</category><category>Scripts</category></item><item><title>Agathist VSCode Themes</title><link>https://kyleshevlin.com/agathist-vscode-themes/</link><guid isPermaLink="true">https://kyleshevlin.com/agathist-vscode-themes/</guid><description>I created a VSCode theme inspired by Agathist&apos;s brand colors and released it as a VSCode Extension.</description><pubDate>Sat, 16 Mar 2024 16:55:07 GMT</pubDate><content:encoded>&lt;p&gt;import Image from &apos;../../../components/Image.astro&apos;&lt;/p&gt;
&lt;p&gt;About a week ago I started messing around with creating a &lt;a href=&quot;https://code.visualstudio.com/&quot;&gt;VSCode&lt;/a&gt; theme inspired by &lt;a href=&quot;https://agath.ist&quot;&gt;Agathist&lt;/a&gt;&apos;s brand colors using using &lt;a href=&quot;https://themer.dev&quot;&gt;themer.dev&lt;/a&gt;. I kept tweaking and tweaking until I had something that, as the kids say, kind of slaps.&lt;/p&gt;
&lt;p&gt;Because I genuinely enjoyed how the theme was working for me, I thought it would be a neat idea to turn it into a VSCode extension and use it to get the word out about Agathist.&lt;/p&gt;
&lt;p&gt;&quot;Agathist Themes&quot; is available for VSCode today. You can find it by searching for &quot;Agathist Themes&quot; either in the Extensions tab or the &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=agathist.agathist-vscode-themes&quot;&gt;VSCode Marketplace&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Currently, only &quot;Agathist Dark&quot; is available, but I have plans to make other themes soon, starting with a light theme.&lt;/p&gt;
&lt;p&gt;&amp;lt;Image
alt=&quot;A Counter component written in TypeScript with the Agathist Dark theme&quot;
caption=&quot;A Counter component written in TypeScript with the Agathist Dark theme&quot;
src=&quot;/images/agathist-vscode-themes/tsx-example.jpg&quot;
/&amp;gt;&lt;/p&gt;
&lt;h3&gt;I love it! 😍 What can I do with my feelings?&lt;/h3&gt;
&lt;p&gt;You can give it a review and a bunch of stars on the VSCode Marketplace. Or you can give the &lt;a href=&quot;https://github.com/agathist/vscode-themes&quot;&gt;Github repo&lt;/a&gt; a star. You can also tell other people about the theme, or send me a kind word on social media.&lt;/p&gt;
&lt;h3&gt;I hate &amp;lt;bothersome thing&amp;gt;! 😤 What can I do with my feelings?&lt;/h3&gt;
&lt;p&gt;Themes will continue to get tweaks and updates as issues naturally arise, but you&apos;re also welcome to submit an official issue to the repo, which can be found at &lt;a href=&quot;https://github.com/agathist/vscode-themes&quot;&gt;https://github.com/agathist/vscode-themes&lt;/a&gt;. I&apos;d love it if you shared an image and all the data I need to reproduce the issues when you do.&lt;/p&gt;
&lt;h3&gt;What&apos;s next?&lt;/h3&gt;
&lt;p&gt;As mentioned before, a light theme will be whipped up eventually. I like using light themes when I&apos;m coding outside in the sun and the good weather is coming quickly.&lt;/p&gt;
</content:encoded><category>VSCode</category></item><item><title>Two Types of Composition</title><link>https://kyleshevlin.com/two-types-of-composition/</link><guid isPermaLink="true">https://kyleshevlin.com/two-types-of-composition/</guid><description>Not only is &quot;composition&quot; a confusing word, but there is more than one way to do it. Let&amp;apos;s break those ways down into two types and learn about &quot;nesting composition&quot; versus &quot;merging composition&quot;.</description><pubDate>Tue, 12 Mar 2024 15:23:44 GMT</pubDate><content:encoded>&lt;p&gt;import { Button } from &apos;../../../components/Button.tsx&apos;
import Hr from &apos;../../../components/Hr.astro&apos;
import ClassClash from &apos;./_ClassClash.astro&apos;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Author&apos;s note&lt;/strong&gt;: I am writing this post so that I can reference it in the near future (famous last words, I know). If it seems odd and from out of nowhere, it&apos;s because it lives in a greater context in my head. One that I haven&apos;t put into words writing yet. Thank you for your patience in advance.&lt;/p&gt;
&lt;p&gt;-Kyle&lt;/p&gt;
&lt;p&gt;&amp;lt;Hr /&amp;gt;&lt;/p&gt;
&lt;p&gt;I&apos;ve been thinking about composition for a long time. I use the word a lot, but I&apos;m often met with confused faces when I do. I could be wrong, but I feel like &quot;composition&quot; in programming is one of those words that many people sort of understand but would really struggle to clearly define. That&apos;s ok. I&apos;m not calling anyone out.&lt;/p&gt;
&lt;p&gt;You hear over and over, &quot;Prefer composition over inheritance!&quot;, but no one really breaks down &lt;em&gt;what&lt;/em&gt; composition is. &lt;strong&gt;Let&apos;s fix that&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;First, &quot;composition&quot; is the act of combining and recombining existing &quot;elements&quot; &amp;lt;Marker content={&lt;code&gt;&quot;Elements&quot; here is used in the abstract, not in the sense of HTML elements.&lt;/code&gt;} /&amp;gt; to create new ones. It&apos;s like combining atoms to make molecules, except without needing a laboratory or a chemistry degree.&lt;/p&gt;
&lt;p&gt;Second, in my opinion, there are two different &quot;types&quot; of composition: function composition and object composition, but I think it might be more useful to think of these as &lt;strong&gt;nesting composition&lt;/strong&gt; and &lt;strong&gt;merging composition&lt;/strong&gt;. I think learning to recognize these two types of composition is beneficial.&lt;/p&gt;
&lt;h3&gt;Function (nesting) composition&lt;/h3&gt;
&lt;p&gt;I&apos;ve written about &lt;a href=&quot;/just-enough-fp-composition&quot;&gt;function composition&lt;/a&gt; before, so I won&apos;t go into great detail. Suffice it to say, this is when we nest functions together, such that the result from one becomes the input to another. We make new functions by combining and recombining other functions in different orders to achieve new results. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const repeat = str =&amp;gt; str + &apos; &apos; + str
const exclaim = str =&amp;gt; str + &apos;!&apos;
const shout = str =&amp;gt; str.toUpperCase()

const result = shout(repeat(exclaim(&apos;composition over inheritance&apos;)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However, if we use our imaginations a bit, we can see that this very same thing happens in other contexts that we would not normally think of as functions. Such as with CSS and HTML.&lt;/p&gt;
&lt;p&gt;For the last few years, I&apos;ve worked on applications where the only layout mechanism available was Flexbox. &amp;lt;Marker content=&quot;Yup. This is what you have to do to make components that work on web and React Native since RN only supports Flexbox.&quot; /&amp;gt; Therefore, I had to use nesting compositions to create various layouts I wanted to achieve.&lt;/p&gt;
&lt;p&gt;For example, if I have a Flexbox column, all of it&apos;s child elements are set to &lt;code&gt;align-items: stretch&lt;/code&gt; by default. The &lt;code&gt;stretch&lt;/code&gt; value means that each child is stretched on the cross-axis, and thus takes up the full width of the parent container.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;div class=&quot;flex flex-col gap-4&quot;&amp;gt;
  &amp;lt;p class=&quot;border&quot;&amp;gt;
    Here is a paragraph with a border to show that it stretches the full width.
  &amp;lt;/p&amp;gt;
  &amp;lt;p class=&quot;border&quot;&amp;gt;
    Notice that the button below stretches the full width of the parent
    container as well.
  &amp;lt;/p&amp;gt;
  &amp;lt;button&amp;gt;Click me&amp;lt;/button&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;div class=&quot;bg-gray-100 p-4 font-sans dark:bg-gray-800&quot;&amp;gt;
&amp;lt;div class=&quot;flex flex-col gap-4&quot;&amp;gt;
&amp;lt;div class=&quot;border border-gray-500&quot;&amp;gt;
Here is a paragraph with a border to show that it stretches the full
width.
&amp;lt;/div&amp;gt;
&amp;lt;div class=&quot;border border-gray-500&quot;&amp;gt;
Notice that the button below stretches the full width of the parent
container as well.
&amp;lt;/div&amp;gt;
&amp;lt;Button&amp;gt;Click me&amp;lt;/Button&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;But let&apos;s say I want the &lt;code&gt;button&lt;/code&gt; only to take up the space of its text (and &lt;em&gt;only&lt;/em&gt; the button should do this, the paragraph should remain the same), as if it was &lt;code&gt;display: inline-block&lt;/code&gt;?&lt;/p&gt;
&lt;p&gt;Rather than try and add &lt;em&gt;ad hoc&lt;/em&gt; CSS to this particular button (the go-to move for so many developers in my experience), or modifying the parent in some way, what if we just alter the composition?&lt;/p&gt;
&lt;p&gt;Let&apos;s wrap our button in a flex row container instead:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;div class=&quot;flex flex-col gap-4&quot;&amp;gt;
  &amp;lt;p class=&quot;border&quot;&amp;gt;
    Here is a paragraph with a border to show that it stretches the full width.
  &amp;lt;/p&amp;gt;
  &amp;lt;p class=&quot;border&quot;&amp;gt;
    Notice that the button below now only takes up the space of its minimum
    content width.
  &amp;lt;/p&amp;gt;
  &amp;lt;div class=&quot;flex&quot;&amp;gt;
    &amp;lt;button&amp;gt;Click me&amp;lt;/button&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;div class=&quot;bg-gray-100 p-4 font-sans dark:bg-gray-800&quot;&amp;gt;
&amp;lt;div class=&quot;flex flex-col gap-4&quot;&amp;gt;
&amp;lt;div class=&quot;border border-gray-500&quot;&amp;gt;
Here is a paragraph with a border to show that it stretches the full
width.
&amp;lt;/div&amp;gt;
&amp;lt;div class=&quot;border border-gray-500&quot;&amp;gt;
Notice that the button below now only takes up the space of its minimum
content width.
&amp;lt;/div&amp;gt;
&amp;lt;div class=&quot;flex&quot;&amp;gt;
&amp;lt;Button&amp;gt;Click me&amp;lt;/Button&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;Through nested composition, we&apos;ve changed the appearance of our UI. In this case, a flex row container shrinks its children to their minimum content width &lt;em&gt;by default&lt;/em&gt;, and thus we achieve the button look we&apos;re going for.&lt;/p&gt;
&lt;p&gt;Our HTML elements (with the proper CSS) behave sort of like functions in that they take their children as inputs and modify their output. If we were working within a system like React, where components &lt;em&gt;are&lt;/em&gt; functions, we really would be doing function composition:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function MyComponent({ children }) {
  return (
    &amp;lt;Stack gap={4}&amp;gt;
      &amp;lt;Text&amp;gt;{children}&amp;lt;/Text&amp;gt;
      &amp;lt;Row&amp;gt;
        &amp;lt;Button&amp;gt;Click me&amp;lt;/Button&amp;gt;
      &amp;lt;/Row&amp;gt;
    &amp;lt;/Stack&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Object (merging) composition&lt;/h3&gt;
&lt;p&gt;Objects can be merged together to form new objects, primarily with the &lt;code&gt;...&lt;/code&gt; &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax&quot;&gt;spread operator&lt;/a&gt;. Some common places this technique is used are extending configuration objects, or updating state objects.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import baseConfig from &apos;something&apos;

export const myConfig = {
  ...baseConfig,
  someProperty: {
    foo: &apos;bar&apos;,
  },
}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;function reducer(state, action) {
  switch (action.type) {
    case &apos;TOGGLE_OPEN&apos;: {
      return {
        ...state,
        isOpen: !state.isOpen,
      }
    }

    default:
      return state
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Object composition differs from function composition in a couple ways:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;For the most part, the objects are merged at a single level. Yes, we can merge at a deeper level in the object, but it has no impact on any of the higher levels of the object.&lt;/li&gt;
&lt;li&gt;Merging is a destructive act. When one object is merged into another, any key in the second object that matches a key in the first object replaces the first property&apos;s value with the second object&apos;s value.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Another way that you may have used this form of composition is with style objects:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const primaryButtonStyles = {
  backgroundColor: &apos;blue&apos;,
  color: &apos;white&apos;,
  padding: &apos;1em&apos;,
}

const dangerButtonStyles = {
  ...primaryButtonStyles,
  backgroundColor: &apos;red&apos;,
}

console.log(dangerButtonStyles)
// { backgroundColor: &apos;red&apos;, color: &apos;white&apos;, padding: &apos;1em&apos;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Taking this a step further, we might be able to think of CSS class composition as object (merging) composition. Consider these classes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.primary {
  background-color:;
}

.danger {
  background-color: red;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If we were to (accidentally) apply both of these styles to an element, the order of our classes would have an impact on the element&apos;s appearance, but maybe not in the way you expect.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;div class=&quot;primary danger&quot;&amp;gt;I will be red&amp;lt;/div&amp;gt;
&amp;lt;div class=&quot;danger primary&quot;&amp;gt;I will also be red, lol&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;ClassClash /&amp;gt;&lt;/p&gt;
&lt;p&gt;This occurs because of &lt;em&gt;where&lt;/em&gt; our object composition is &lt;em&gt;really&lt;/em&gt; occurring. Because our &lt;code&gt;.danger&lt;/code&gt; class comes after our &lt;code&gt;.primary&lt;/code&gt; class in our stylesheet, the latter class&apos; values replace the values of the former class when there are matching keys.&lt;/p&gt;
&lt;p&gt;We always have to be aware of how merging composition may have unintended consequences!&lt;/p&gt;
&lt;h3&gt;Why does any of this matter?&lt;/h3&gt;
&lt;p&gt;The main reason I find this important has to do with how easy it is for someone to understand one form of composition versus the other.&lt;/p&gt;
&lt;p&gt;I have found that people find object/merging composition far easier to understand, even though it often has more pitfalls. It often provides developers with more &quot;escape hatches&quot; and ways to &quot;throw stuff at the wall until it sticks&quot;. In other words, there&apos;s often more than one way to achieve the desired result, at the tradeoff of potentially making a destructive mess in the process.&lt;/p&gt;
&lt;p&gt;On the other hand, function/nesting composition is often superior in terms of strictness of inputs and outputs, but is more difficult for developers to intuit. There&apos;s less room for trying things to see if it works by design.&lt;/p&gt;
&lt;p&gt;Be honest with yourself. How well do you know CSS? Do you know precisely what you&apos;re doing, or do you need to be able to throw stuff at the wall? There&apos;s no shame in the answer, I promised, but you might be able to guess what my future post will be about based on how you respond.&lt;/p&gt;
&lt;p&gt;Consider our simple example above with the &lt;code&gt;Button&lt;/code&gt;. It&apos;s so much easier for devs to throw more classes at the CSS, or use the &lt;code&gt;style&lt;/code&gt; prop, rather than recognize, &quot;If I wrap this &lt;code&gt;Button&lt;/code&gt; in a &lt;code&gt;Row&lt;/code&gt;, it will achieve the result I&apos;m looking for!&quot; I know devs can get there. I&apos;ve trained them to do it and seen it happen, but it&apos;s not intuitive for many of them.&lt;/p&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;You might not find it useful to think of composition in these two ways, but I do, and I hope it helps you in some small way.&lt;/p&gt;
&lt;p&gt;Here&apos;s a quick break down of what I&apos;ve discussed:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Composition is combining existing elements to create new ones&lt;/li&gt;
&lt;li&gt;Nesting composition uses wrapping elements to modify functionality
&lt;ul&gt;
&lt;li&gt;Parents change the functionality of child elements&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Merging composition smashes elements together destructively to achieve new ones
&lt;ul&gt;
&lt;li&gt;The order of the smashing is important&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><category>JavaScript</category><category>TypeScript</category><category>Software Engineering</category></item><item><title>Agathist Q&amp;A</title><link>https://kyleshevlin.com/agathist-q-and-a/</link><guid isPermaLink="true">https://kyleshevlin.com/agathist-q-and-a/</guid><description>Agathist is my new software development firm. Learn about it in this self-directed question and answer post.</description><pubDate>Tue, 05 Mar 2024 16:35:56 GMT</pubDate><content:encoded>&lt;p&gt;You might have noticed a few new &quot;ads&quot; around here recently for something called Agathist. Let me tell you what that&apos;s all about in a (hopefully) fun self-directed Q&amp;amp;A.&lt;/p&gt;
&lt;h3&gt;What is Agathist?&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://agath.ist&quot;&gt;Agathist&lt;/a&gt; is the software development firm I started this year. I want to take my talents and use them more broadly, working with multiple clients on a variety of projects, to build good software with good people.&lt;/p&gt;
&lt;h3&gt;Why the name Agathist?&lt;/h3&gt;
&lt;p&gt;The word &quot;agathist&quot; is derived from the Greek word &lt;em&gt;agathos&lt;/em&gt;, which means &quot;the good&quot;. Therefore, an agathist is one who believes in goodness, but unlike an optimist who tries to see the upside of bad situations, an agathist acknowledges reality and does the work to make it better.&lt;/p&gt;
&lt;h3&gt;When did you come up with the idea to start Agathist?&lt;/h3&gt;
&lt;p&gt;I first conceived of Agathist in 2017. I bought the domain &lt;a href=&quot;https://agath.ist&quot;&gt;agath.ist&lt;/a&gt; because I thought the name was perfect for a company. It rolls off the tongue. It doesn&apos;t hurt that the top level domain for Istanbul is &lt;code&gt;.ist&lt;/code&gt;. That was the icing on the cake.&lt;/p&gt;
&lt;p&gt;I even made a placeholder page for it back then, as if I was starting an agency. Up to that point in my career, I had &lt;em&gt;only&lt;/em&gt; worked at agencies, so it was what I knew. But I never did anything with the site other than renew the domain each year.&lt;/p&gt;
&lt;p&gt;I didn&apos;t start seriously considering starting a software development firm as a career option until last fall. In November, I had a revelation regarding work and realized that it was extremely unlikely for me to find a Goldilocks job where I could thrive, working with my neurodivergence and not against it. The only way I could do that would be to take a chance on myself and start my own company.&lt;/p&gt;
&lt;p&gt;Perhaps someday I will write about all the things I realized about being neurodivergent in the workplace, but for now I&apos;ll make it very simple. When I consider all of my possible employment options going forward, working for myself and building a team of my own is the only one that gives me the opportunity to be happy.&lt;/p&gt;
&lt;h3&gt;What are your goals for Agathist?&lt;/h3&gt;
&lt;p&gt;It&apos;s impossible to know all the goals I &lt;em&gt;should&lt;/em&gt; have right now, but here are a few: &amp;lt;Marker content=&quot;I hope it will be fun to revisit these someday.&quot; /&amp;gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Land our first client&lt;/li&gt;
&lt;li&gt;Stay afloat for the year&lt;/li&gt;
&lt;li&gt;Succeed enough to hire our first employee&lt;/li&gt;
&lt;li&gt;Grow enough to have a small team&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I also want to mention, while not strictly a goal, one of the reasons I want to start Agathist is to be in a position to help my friends out. With all the layoffs, there&apos;s a lot of talent in our industry just going to waste right now. There&apos;s no shortage of projects that need to be done. I think there&apos;s an opportunity to find those projects and put together a team to do them.&lt;/p&gt;
&lt;p&gt;Basically, if you&apos;ve trusted me all these years for my writing and what I share around the Internet, I want you to trust me to take on a project that&apos;s important to you, to be able to use my network to gather up some talented folks and knock it out of the park.&lt;/p&gt;
&lt;h3&gt;What do you hope to get out of Agathist?&lt;/h3&gt;
&lt;p&gt;A living that doesn&apos;t kill me.&lt;/p&gt;
&lt;p&gt;That might sound hyperbolic, but it&apos;s so difficult to work under the power structures of companies when you&apos;re neurodivergent. The masking, the lack of autonomy, and the workplace politics are all extra challenges wasting useful energy. &amp;lt;Marker content=&quot;Yes, these things can be difficult for anyone, but they are especially challenging for neurodivergent people.&quot; /&amp;gt; There&apos;s a reason why people with neurodivergence experience far higher rates of burnout.&lt;/p&gt;
&lt;p&gt;By taking ownership, I can at least flip some of those structures in my favor and put more of my energy where I want it to go. While it might not be the most financially sensible move, &amp;lt;Marker content=&quot;It might be a great move, too. Time will tell.&quot; /&amp;gt; it does give me the best opportunity to create structures that work for me rather than against me.&lt;/p&gt;
&lt;p&gt;I also hope to get back to learning and growing. My last job was a poor fit in this regard. It was a quagmire. I spent all of my energy pouring into others, trying to build up their skills so we could move forward. No one was pouring into me and there were no opportunities for growth. I became stuck as well. Starting Agathist is part of my journey to getting out of that muck.&lt;/p&gt;
&lt;p&gt;For right now, I&apos;m specifically excited to ramp up on some of the new trends in web development, like React Server Components. I&apos;m also excited about the opportunity to spend more time doing fullstack work for clients, becoming more skilled with Postgres, SQL and other backend skills.&lt;/p&gt;
&lt;p&gt;In addition, I suspect that as Agathist grows, my role within it will change, too. I will have opportunities to learn and grow more into the leader I want to be. I can&apos;t say it enough, I&apos;m excited about the future.&lt;/p&gt;
&lt;h3&gt;What kind of projects are you looking for?&lt;/h3&gt;
&lt;p&gt;I&apos;m open to a lot of ideas! My career has allowed me to work on so many different things, such that I genuinely believe I could help out on any web (or React Native) project in so many ways. Here are a few ways I&apos;m focusing on right now:&lt;/p&gt;
&lt;h4&gt;&lt;strong&gt;Fullstack applications&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;I&apos;d love to land some bigger applications with some bigger companies. &amp;lt;Marker content=&quot;Who wouldn&apos;t, right?!&quot; /&amp;gt; Projects with some real meat to them. I actually love working on product in the early stages, where there&apos;s lots of work to get done and you can really just put your head down and go. Let us take your idea and build version 1.0. Get you rolling.&lt;/p&gt;
&lt;h4&gt;&lt;strong&gt;Codebase improvement&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;I&apos;m thinking of this as &quot;Refactor as a Service&quot;. Every place I&apos;ve ever worked has needed lots of love. I&apos;m skilled at revitalizing legacy code and making it pleasurable to work in. I&apos;d be happy to bring that to a project.&lt;/p&gt;
&lt;p&gt;In addition, I&apos;ve been approached a couple times now to do &quot;Revamp as a Service&quot;, too. If you have an older website that just needs to be ported to something more modern, let us do that. We can set you up on a modern stack you&apos;re happy with, with a better developer experience, and get you back on the happy path.&lt;/p&gt;
&lt;h4&gt;&lt;strong&gt;Design systems&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;I&apos;ve spent the last 10 years working in React and the last 2 years building a design system that supports both React and React Native. In other words, I know a thing or two about building really great component systems.&lt;/p&gt;
&lt;p&gt;If you&apos;re team has been looking to build one of these but doesn&apos;t know how, or just needs help getting started, I&apos;d love to help.&lt;/p&gt;
&lt;h3&gt;Is anyone else on the team with you?&lt;/h3&gt;
&lt;p&gt;Yes! Right now one of my best friends is working with me. &amp;lt;Marker content=&quot;I am so excited!&quot; /&amp;gt; This way we&apos;ll have enough hands and minds to take on some bigger projects. I&apos;ll add subcontractors as necessary this year and hopefully be in a position to hire some as full-time employees when the time comes.&lt;/p&gt;
&lt;h3&gt;What are Agathist&apos;s rates?&lt;/h3&gt;
&lt;p&gt;Good question! The truth is you can&apos;t have one rate for all clients. You need to optimize your rate for value. Bigger companies, bigger projects that bring in bigger revenues, they&apos;re worth more value to the client, and thus the rate should be higher to match that value.&lt;/p&gt;
&lt;p&gt;That said, I&apos;m a very transparent person, &amp;lt;Marker content=&quot;A trait that is &amp;lt;em&amp;gt;also&amp;lt;/em&amp;gt; related to my neurodivergence. Yay, oversharing!&quot; /&amp;gt; I&apos;m starting my bids at $125/hour and shooting for no more than 40 hours per week &lt;em&gt;split&lt;/em&gt; between my colleague and me. I want to keep our workload very reasonable and give myself ample time to pursue new clients and grow the business. I can&apos;t do that if I&apos;m full-time coding.&lt;/p&gt;
&lt;p&gt;I suspect our rates will go up a bit as we obtain clients, so if you&apos;re reading this in the future, don&apos;t be surprised if they&apos;re higher. Please keep in mind, rates aren&apos;t only for making money, they are a tool for managing workload and that&apos;s really important to me.&lt;/p&gt;
&lt;p&gt;Lastly, I have no interest in gouging people. I&apos;m not really wired to treat money as king. I&apos;m wired to do things well and to do things right. I want to take on projects that interest me (and my team) &lt;em&gt;and&lt;/em&gt; make business sense for both the client and us. That won&apos;t always mean going with the company that can pay the most!&lt;/p&gt;
&lt;h3&gt;How can I get in touch with Agathist about a project?&lt;/h3&gt;
&lt;p&gt;I&apos;m not shy, I&apos;ll talk to you about it however you want!&lt;/p&gt;
&lt;p&gt;That said, you can fill out the form on &lt;a href=&quot;https://agath.ist/contact&quot;&gt;the contact page&lt;/a&gt;. That&apos;s probably the best way to do it!&lt;/p&gt;
&lt;p&gt;If forms aren&apos;t your style, you can also send me an email at &lt;a href=&quot;mailto:kyle@agath.ist&quot;&gt;kyle@agath.ist&lt;/a&gt;. I&apos;d be happy to discuss it there.&lt;/p&gt;
&lt;p&gt;Lastly, if you&apos;re really adventurous, you can click the Agathist ads you see around here, too. That will lead you in the right direction.&lt;/p&gt;
&lt;h3&gt;How can I help Agathist be successful?&lt;/h3&gt;
&lt;p&gt;I think the simplest thing you can do is think of us when an opportunity presents itself. You meet someone looking for a team to help them with a project? Let them know about Agathist.&lt;/p&gt;
&lt;p&gt;Have a project at work you really want to see happen but don&apos;t have the headcount for? Consider Agathist.&lt;/p&gt;
&lt;p&gt;Our main hurdle right now is landing those first clients. Once the ball is rolling, we&apos;ll have new, exciting challenges to deal with.&lt;/p&gt;
&lt;p&gt;Other ways you can help us out include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sharing this post&lt;/li&gt;
&lt;li&gt;Sharing the &lt;a href=&quot;https://agath.ist&quot;&gt;Agathist website&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Writing a testimonial if we&apos;ve worked together&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are probably even more ways I&apos;m not thinking of right now. Be creative!&lt;/p&gt;
&lt;h3&gt;How are you going to conclude this Q&amp;amp;A?&lt;/h3&gt;
&lt;p&gt;By saying thank you. Thank you to the people who believe that I can do this. Thank you to the mentors helping me learn some lessons the easy way, rather than the hard way. And thank you to the network of wonderful people I have that makes this a possibility. I appreciate each and every one of you.&lt;/p&gt;
</content:encoded><category>Career</category></item><item><title>No Outer &lt;code&gt;margin&lt;/code&gt;</title><link>https://kyleshevlin.com/no-outer-margin/</link><guid isPermaLink="true">https://kyleshevlin.com/no-outer-margin/</guid><description>It is an anti-pattern to add margin to the outermost element of a component. It breaks encapsulation and makes components difficult to reuse. Let&apos;s learn what to do instead.</description><pubDate>Mon, 26 Feb 2024 16:13:32 GMT</pubDate><content:encoded>&lt;p&gt;Building reusable components can be challenging to do well, and there are some anti-patterns that are easy to fall into that can make it even more difficult.&lt;/p&gt;
&lt;p&gt;One of the most common antipatterns I see is having &lt;code&gt;margin&lt;/code&gt; (and in some cases &lt;code&gt;padding&lt;/code&gt;) on the outermost element of a component. This is an easy mistake to make, but luckily, it&apos;s easily avoided once we know what we&apos;re looking for.&lt;/p&gt;
&lt;h3&gt;What are &quot;outer&quot; &lt;code&gt;margin&lt;/code&gt;s and &lt;code&gt;padding&lt;/code&gt;s?&lt;/h3&gt;
&lt;p&gt;I define &quot;outer&quot; here as &lt;code&gt;margin&lt;/code&gt;s that extend beyond the &lt;code&gt;border-box&lt;/code&gt; of the UI. Generally speaking, this would be applying &lt;code&gt;margin&lt;/code&gt; to the outermost element of a component.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Card({ children }) {
  return (
    // WARNING: Don&apos;t do this! It is an outer `margin`!
    &amp;lt;div style={{ marginBottom: &apos;1rem&apos; }}&amp;gt;{children}&amp;lt;/div&amp;gt;
  )
}

function EmployeeCard({ name, occupation }) {
  return (
    &amp;lt;Card&amp;gt;
      {/**
       * This is fine! We can use internal margins for layout,
       * but there are better ways we&apos;ll learn later!
       */}
      &amp;lt;div style={{ marginBottom: &apos;1rem&apos; }}&amp;gt;{name}&amp;lt;/div&amp;gt;
      &amp;lt;div&amp;gt;{occupation}&amp;lt;/div&amp;gt;
    &amp;lt;/Card&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In addition to &lt;strong&gt;never&lt;/strong&gt; using outer &lt;code&gt;margin&lt;/code&gt;, we should &lt;strong&gt;never&lt;/strong&gt; use &lt;code&gt;padding&lt;/code&gt; for the same purpose. The outermost element of a component should not have &lt;code&gt;padding&lt;/code&gt; &lt;strong&gt;unless&lt;/strong&gt; that element has a &lt;code&gt;border&lt;/code&gt; or a &lt;code&gt;background-color&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Card({ children }) {
  return (
    // WARNING! Don&apos;t do this! It is an outer `padding`!
    // Without a border or background color, it has
    // the same appearance/effect as a `margin`
    &amp;lt;div style={{ paddingBottom: &apos;1rem&apos; }}&amp;gt;{children}&amp;lt;/div&amp;gt;
  )
}

function BorderCard({ children }) {
  return (
    &amp;lt;div
      style={{
        border: &apos;1px solid tomato&apos;,
        backgroundColor: &apos;gray&apos;,
        // This padding is ok because we have styles that extend to the
        // border-box of our component, thus defining a boundary for
        // this UI!
        padding: &apos;1rem&apos;,
      }}
    &amp;gt;
      {children}
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;What&apos;s the big deal? Why is this a problem/anti-pattern?&lt;/h3&gt;
&lt;p&gt;The problem with outer &lt;code&gt;margin&lt;/code&gt;s and &lt;code&gt;padding&lt;/code&gt;s like the examples above is that it breaks encapsulation. I&apos;ve written about &lt;a href=&quot;/encapsulation&quot;&gt;encapsulation&lt;/a&gt; before, but never in terms of UI. Essentially, styles like these have an impact on the other components around it. Components with outer &lt;code&gt;margin&lt;/code&gt;s get their elbows out, &lt;a href=&quot;https://en.wikipedia.org/wiki/NBA_Jam&quot;&gt;NBA Jam style&lt;/a&gt;, knocking around adjacent components.&lt;/p&gt;
&lt;p&gt;The impact of these styles often lead to what I call &quot;compensations&quot;, essentially workarounds to &lt;em&gt;undo&lt;/em&gt; what we&apos;ve already done. We&apos;ll see some examples of this soon.&lt;/p&gt;
&lt;p&gt;Not only do outer &lt;code&gt;margin&lt;/code&gt;s require compensations, they give the underlying component too many responsibilities. External spacing should &lt;strong&gt;never&lt;/strong&gt; be the responsibility of a component. Components should only ever be concerned with internal spacing.&lt;/p&gt;
&lt;h3&gt;An abstract example&lt;/h3&gt;
&lt;p&gt;Let&apos;s say I have a reusable component called &lt;code&gt;Item&lt;/code&gt; that looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Item() {
  return &amp;lt;div className=&quot;rounded bg-accent p-8&quot; /&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-4&quot;&amp;gt;
&amp;lt;div class=&quot;rounded bg-accent p-8&quot; /&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;Imagine &lt;code&gt;Item&lt;/code&gt; is any reusable UI. Perhaps it&apos;s an &lt;code&gt;InfoCard&lt;/code&gt; or a &lt;code&gt;ListRow&lt;/code&gt; in a list. It doesn&apos;t really matter &lt;em&gt;what&lt;/em&gt; the specifics of &lt;code&gt;Item&lt;/code&gt; are, we only need to know that it&apos;s a &lt;em&gt;single unit&lt;/em&gt; of UI for our purposes.&lt;/p&gt;
&lt;p&gt;Let&apos;s say I have many &lt;code&gt;Item&lt;/code&gt;s next to each other. Let&apos;s give them different background colors so it&apos;s clear which one is which:&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-4&quot;&amp;gt;
&amp;lt;div class=&quot;rounded bg-accent p-8&quot; /&amp;gt;
&amp;lt;div class=&quot;rounded bg-pink-500 p-8&quot; /&amp;gt;
&amp;lt;div class=&quot;rounded bg-orange-400 p-8&quot; /&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;Now that I have many &lt;code&gt;Item&lt;/code&gt;s, it&apos;s necessary to space them away from each other. It might be very tempting to add a &lt;code&gt;margin-bottom&lt;/code&gt; to each one, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Item() {
  // Notice the `mb-4` class
  return &amp;lt;div className=&quot;mb-4 rounded bg-accent p-8&quot; /&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-4&quot;&amp;gt;
&amp;lt;div class=&quot;mb-4 rounded bg-accent p-8&quot; /&amp;gt;
&amp;lt;div class=&quot;mb-4 rounded bg-pink-500 p-8&quot; /&amp;gt;
&amp;lt;div class=&quot;mb-4 rounded bg-orange-400 p-8&quot; /&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;That &lt;em&gt;looks&lt;/em&gt; fine, but we need to look at it with more scrutiny. What if we add a &lt;code&gt;border&lt;/code&gt; around the wrapping element? What are we going to see?&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-4 rounded border-4 border-lime-400&quot;&amp;gt;
&amp;lt;div class=&quot;mb-4 rounded bg-accent p-8&quot; /&amp;gt;
&amp;lt;div class=&quot;mb-4 rounded bg-pink-500 p-8&quot; /&amp;gt;
&amp;lt;div class=&quot;mb-4 rounded bg-orange-400 p-8&quot; /&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;Oof! We have an extra margin at the bottom.&lt;/p&gt;
&lt;p&gt;It&apos;s at this point less experienced devs start making all sorts of &quot;compensations&quot; to handle this situation. If it&apos;s a dynamically rendered list of &lt;code&gt;Item&lt;/code&gt;s, we might be tempted to use an &lt;code&gt;index&lt;/code&gt; in our loop and somehow remove the &lt;code&gt;margin-bottom&lt;/code&gt; on the last one. &amp;lt;Marker content=&quot;Or even apply a wrapping element with a negative &amp;lt;code&amp;gt;margin&amp;lt;/code&amp;gt;. Gross.&quot; /&amp;gt; We might even go so far as to add the dreaded &lt;code&gt;marginBottom={false}&lt;/code&gt; prop, a bad case of &lt;a href=&quot;/quit-your-yapping&quot;&gt;Yet Another Prop syndrome&lt;/a&gt; if I&apos;ve ever seen one. &amp;lt;Marker content=&quot;Seriously, these kinds of props make me want to 🤮&quot; /&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Don&apos;t do this. You&apos;ll make me cry.
function Item({ marginBottom = true }) {
  const mb = marginBottom ? &apos;mb-4&apos; : &apos;&apos;
  return &amp;lt;div className={`rounded bg-accent p-8 ${mb}`} /&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But what about other scenarios? What are you going to do if you have to put your &lt;code&gt;Item&lt;/code&gt;s into a &lt;code&gt;Row&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-4 flex rounded border-4 border-lime-400&quot;&amp;gt;
&amp;lt;div class=&quot;mb-4 rounded bg-accent p-8&quot; /&amp;gt;
&amp;lt;div class=&quot;mb-4 rounded bg-pink-500 p-8&quot; /&amp;gt;
&amp;lt;div class=&quot;mb-4 rounded bg-orange-400 p-8&quot; /&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;Or a &lt;code&gt;Grid&lt;/code&gt;?&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-4 grid grid-cols-2 grid-rows-2 rounded border-4 border-lime-400&quot;&amp;gt;
&amp;lt;div class=&quot;mb-4 rounded bg-accent p-8&quot; /&amp;gt;
&amp;lt;div class=&quot;mb-4 rounded bg-pink-500 p-8&quot; /&amp;gt;
&amp;lt;div class=&quot;mb-4 rounded bg-orange-400 p-8&quot; /&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;Are you going to make boolean props for all the margins? I sure hope
not!&lt;/p&gt;
&lt;h3&gt;A concrete example&lt;/h3&gt;
&lt;p&gt;One of the most common ways I see this is with headings. Let&apos;s say I have a component for &lt;code&gt;H2&lt;/code&gt;s in my codebase:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function H2({ children }) {
  return &amp;lt;h2 className=&quot;mb-4 text-xl font-bold&quot;&amp;gt;{children}&amp;lt;/h2&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That looks like this:&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-4 bg-gray-100 px-4 py-2 dark:bg-gray-800&quot;&amp;gt;
&amp;lt;h2 className=&quot;mb-4 text-xl font-bold&quot;&amp;gt;
Using the &amp;lt;code&amp;gt;h2&amp;lt;/code&amp;gt;. Notice the space below.
&amp;lt;/h2&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;This might seem like a good idea. Headings tend to be found in large blocks of text and doesn&apos;t the user agent stylesheet give &lt;code&gt;h1&lt;/code&gt; through &lt;code&gt;h6&lt;/code&gt; a &lt;code&gt;margin-bottom&lt;/code&gt; by default anyways?&lt;/p&gt;
&lt;p&gt;Sure, but the web isn&apos;t simply long-form text anymore. It&apos;s componentized and we need to be able to use our elements in more scenarios than just long-form text.&lt;/p&gt;
&lt;p&gt;What if we want to add additional data around it? Perhaps we need to put a subtitle right below it, or a date, or timestamp?&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-4 bg-gray-100 px-4 py-2 dark:bg-gray-800&quot;&amp;gt;
&amp;lt;h2 className=&quot;mb-4 text-xl font-bold&quot;&amp;gt;
Using the &amp;lt;code&amp;gt;h2&amp;lt;/code&amp;gt;
&amp;lt;/h2&amp;gt;
&amp;lt;div class=&quot;font-sans text-lg&quot;&amp;gt;Uh oh. I&apos;m spaced really far away!&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;Now you&apos;re back-pedaling to either undo the &lt;code&gt;mb-4&lt;/code&gt; class or compensate for it some other way. Better to leave it off entirely and do the proper solution, which we&apos;ll discuss next.&lt;/p&gt;
&lt;h3&gt;The solution&lt;/h3&gt;
&lt;p&gt;The solution to this problem is simple, use parent elements or components for layout and spacing.&lt;/p&gt;
&lt;p&gt;As I said before, it is never the responsibility of a component to manage its external spacing, only its internal spacing. We can always use a parent element or component to manage the layout of adjacent components.&lt;/p&gt;
&lt;p&gt;Regardless of what layout solution you use, whether it&apos;s with components with something like &lt;a href=&quot;https://chakra-ui.com/&quot;&gt;Chakra UI&lt;/a&gt; or classes like &lt;a href=&quot;https://tailwindcss.com&quot;&gt;Tailwind&lt;/a&gt;, I find the best solutions heavily use Flex or Grid containers with &lt;code&gt;gap&lt;/code&gt; to apply spacing. Let&apos;s do that here with our &lt;code&gt;Item&lt;/code&gt;s:&lt;/p&gt;
&lt;p&gt;After removing the &lt;code&gt;mb-4&lt;/code&gt; class from our &lt;code&gt;Item&lt;/code&gt;, we can now wrap our items in another element to do the spacing. For example, our &lt;code&gt;Stack&lt;/code&gt; looks like this:&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-4 flex flex-col gap-4 rounded border-4 border-lime-400&quot;&amp;gt;
&amp;lt;div class=&quot;rounded bg-accent p-8&quot; /&amp;gt;
&amp;lt;div class=&quot;rounded bg-pink-500 p-8&quot; /&amp;gt;
&amp;lt;div class=&quot;rounded bg-orange-400 p-8&quot; /&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;Our &lt;code&gt;Row&lt;/code&gt; looks like this:&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-4 flex gap-4 rounded border-4 border-lime-400&quot;&amp;gt;
&amp;lt;div class=&quot;rounded bg-accent p-8&quot; /&amp;gt;
&amp;lt;div class=&quot;rounded bg-pink-500 p-8&quot; /&amp;gt;
&amp;lt;div class=&quot;rounded bg-orange-400 p-8&quot; /&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;And our &lt;code&gt;Grid&lt;/code&gt; looks like this:&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-4 grid grid-cols-2 grid-rows-2 gap-4 rounded border-4 border-lime-400&quot;&amp;gt;
&amp;lt;div class=&quot;rounded bg-accent p-8&quot; /&amp;gt;
&amp;lt;div class=&quot;rounded bg-pink-500 p-8&quot; /&amp;gt;
&amp;lt;div class=&quot;rounded bg-orange-400 p-8&quot; /&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;No matter where we need to put our &lt;code&gt;Item&lt;/code&gt;, we know we can control how it&apos;s laid out in our UI. We&apos;ve fixed its encapsulation problem and made it more reusable.&lt;/p&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;No &lt;code&gt;margin&lt;/code&gt; on the outermost element&lt;/li&gt;
&lt;li&gt;No &lt;code&gt;padding&lt;/code&gt; on the outermost element &lt;strong&gt;unless&lt;/strong&gt; it has a &lt;code&gt;border&lt;/code&gt; or &lt;code&gt;background-color&lt;/code&gt; to visually define the &lt;code&gt;border-box&lt;/code&gt; boundary of the UI&lt;/li&gt;
&lt;li&gt;Use parent elements or components to do layout instead&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Other articles&lt;/h3&gt;
&lt;p&gt;You can&apos;t write an article about this topic without giving credit and reference to Max Stoiber&apos;s &lt;a href=&quot;https://mxstbr.com/thoughts/margin/&quot;&gt;&quot;Margin considered harmful&quot;&lt;/a&gt;. Give it a read.&lt;/p&gt;
</content:encoded><category>React</category><category>CSS</category><category>Reusability</category><category>Anti-patterns</category></item><item><title>Type &lt;code&gt;TODO&lt;/code&gt;</title><link>https://kyleshevlin.com/type-todo/</link><guid isPermaLink="true">https://kyleshevlin.com/type-todo/</guid><description>In TypeScript, sometimes &lt;code&gt;any&lt;/code&gt; is our best option, but we can go a step further and give ourselves a little more signal than that.</description><pubDate>Tue, 23 Jan 2024 03:47:59 GMT</pubDate><content:encoded>&lt;p&gt;import SocialPost from &apos;../../../components/SocialPost.astro&apos;&lt;/p&gt;
&lt;p&gt;With tongue firmly in cheek, I tweeted the following:&lt;/p&gt;
&lt;p&gt;&amp;lt;SocialPost
authorName=&quot;Kyle Shevlin&quot;
authorHandle=&quot;@kyleshevl.in&quot;
authorProfile=&quot;https://bsky.app/profile/kyleshevl.in&quot;
avatarUrl=&quot;/images/kyle-headshot.jpg&quot;
content=&quot;Perhaps my favorite TypeScript tip&quot;
date=&quot;2024-01-22&quot;
postImageUrl=&quot;/images/type-todo-any.png&quot;
postImageAlt=&quot;type TODO = any&quot;
/&amp;gt;&lt;/p&gt;
&lt;p&gt;The response the post received was a lot larger than I was expecting, so I thought I&apos;d take a moment to explain why this is both a tip and a joke at the same time.&lt;/p&gt;
&lt;h3&gt;Tip: Sometimes &lt;code&gt;any&lt;/code&gt; is ok&lt;/h3&gt;
&lt;p&gt;If you&apos;ve written TypeScript for long enough, then I am willing to bet &lt;code&gt;any&lt;/code&gt; has come to your rescue a time or two.&lt;/p&gt;
&lt;p&gt;Any app of reasonable complexity, especially a codebase that has some age, perhaps still has some JavaScript, will likely have nasty parts that are difficult to type correctly.&lt;/p&gt;
&lt;p&gt;Add to this any time pressure or consideration between value created versus the time it&apos;s taking to do so, and you&apos;ll find yourself in a situation where it is just not worth it to solve that hairy type problem right now. That&apos;s where the &lt;code&gt;TODO&lt;/code&gt; type comes in handy.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type TODO = any
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The scenario that prompted me to write the tweet was converting a JavaScript file to TypeScript. I had a value I couldn&apos;t get the types right for in the first few minutes. It was a file that was already JavaScript, and thus inherently not type-safe, and it was a file that hadn&apos;t been modified in years. Given these factors, using an &lt;code&gt;any&lt;/code&gt; was appropriate. Making it a &lt;code&gt;TODO&lt;/code&gt; provides some signal that perhaps a time may come where it can be updated and improved.&lt;/p&gt;
&lt;p&gt;Don&apos;t forget, you don&apos;t have to name it &lt;code&gt;TODO&lt;/code&gt; either. You can name it something more specific. Perhaps you prefix a typename with &lt;code&gt;UNSAFE_&lt;/code&gt; or something similar to signal that you&apos;ve opted out of type safety.&lt;/p&gt;
&lt;h3&gt;Joke: You shouldn&apos;t use &lt;code&gt;TODO&lt;/code&gt; excessively&lt;/h3&gt;
&lt;p&gt;While there are appropriate times to use the &lt;code&gt;TODO&lt;/code&gt; type, it definitely should not be abused. If many parts, or particularly important parts, are littered with &lt;code&gt;TODO&lt;/code&gt; or &lt;code&gt;any&lt;/code&gt; types, then you may want to consider if it&apos;s possible to devote more time to getting the types correct.&lt;/p&gt;
&lt;p&gt;We want to use &lt;code&gt;any&lt;/code&gt; or &lt;code&gt;TODO&lt;/code&gt; purposefully, as the very rare escape hatch and a signal that the following code is unsafe. Don&apos;t just use them to hide something under the proverbial rug, use them to make it clear that something requires further attention when possible.&lt;/p&gt;
&lt;h3&gt;Bonus tip&lt;/h3&gt;
&lt;p&gt;I use a VSCode extension, &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=wayou.vscode-todo-highlight&quot;&gt;TODO Highlight&lt;/a&gt;, that highlights keywords in your editor. With a few tweaks to the settings, the extension will highlight &lt;em&gt;every use of &lt;code&gt;TODO&lt;/code&gt; in your app&lt;/em&gt;. That way, you never visually miss where you have them.&lt;/p&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;Recognize &lt;code&gt;any&lt;/code&gt; or &lt;code&gt;TODO&lt;/code&gt; can be useful in a pinch, especially when considering the time/value tradeoff. Do treat them like a real &lt;code&gt;TODO&lt;/code&gt; and try and fix them when you have time. Use either type sparingly.&lt;/p&gt;
&lt;p&gt;Lastly, keep improving your TypeScript skills and you&apos;ll find you reach for these types less often.&lt;/p&gt;
</content:encoded><category>TypeScript</category></item><item><title>Wrangling Tuple Types</title><link>https://kyleshevlin.com/wrangling-tuple-types/</link><guid isPermaLink="true">https://kyleshevlin.com/wrangling-tuple-types/</guid><description>TypeScript doesn&apos;t know whether you&apos;re returning an array or a tuple from a function, so let&apos;s learn a couple ways we can fix that problem.</description><pubDate>Sun, 21 Jan 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This is going to be a short and simple TypeScript tip for you about &lt;a href=&quot;/what-is-a-tuple&quot;&gt;tuples&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;At the time of this writing, JavaScript and TypeScript do not officially have a tuple type. &lt;a href=&quot;https://github.com/tc39/proposal-record-tuple&quot;&gt;That TC39 proposal is still in the works&lt;/a&gt;. The best you can do is a fixed-length array.&lt;/p&gt;
&lt;p&gt;So let&apos;s say we have a function that returns a tuple, like a custom hook:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function useBool(initialValue = false) {
  const [state, setState] = React.useState(initialValue)

  const handlers = React.useMemo(
    () =&amp;gt; ({
      on: () =&amp;gt; setState(true),
      off: () =&amp;gt; setState(false),
      toggle: () =&amp;gt; setState(s =&amp;gt; !s),
      reset: () =&amp;gt; setState(initialValue),
    }),
    [initialValue],
  )

  return [state, handlers]
}

const result = useBool()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Returning a tuple is a nice API because it allows the consumer of the &lt;code&gt;result&lt;/code&gt; to &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment&quot;&gt;array destructure&lt;/a&gt; the values into custom names whenever it&apos;s used. It&apos;s a bit nicer doing:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const [isOpen, setIsOpen] = useBool()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Than it is to do the object equivalent:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const { state: isOpen, handlers: setIsOpen } = useBool()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That said, what do you think the return type is for our &lt;code&gt;useBool&lt;/code&gt; function? The answer might surprise you. &lt;code&gt;result&lt;/code&gt;&apos;s type is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const result: (
  | boolean
  | {
      on: () =&amp;gt; void
      off: () =&amp;gt; void
      toggle: () =&amp;gt; void
      reset: () =&amp;gt; void
    }
)[]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The return type is a non-fixed-length heterogenous array of the union of &lt;code&gt;boolean&lt;/code&gt; and the shape of our &lt;code&gt;handlers&lt;/code&gt; object. Basically, &lt;strong&gt;TypeScript doesn&apos;t know the &lt;em&gt;index&lt;/em&gt; of our values in the array&lt;/strong&gt;. We will run into a lot of annoying type issues if we try and use this in a component.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Secret({ message }: { message: string }) {
  const [isOpen, setIsOpen] = useBool()

  return (
    &amp;lt;div&amp;gt;
      {/**
       * TS will error here, saying you can&apos;t call
       * a method on a boolean
       */}
      &amp;lt;button type=&quot;button&quot; onClick={setIsOpen.toggle}&amp;gt;
        {/**
         * TS won&apos;t yell at you because anything can be truthy
         * or falsy, but it won&apos;t know that `isOpen` is strictly
         * a boolean
         */}
        {isOpen ? &apos;Hide&apos; : &apos;Reveal&apos;}
      &amp;lt;/button&amp;gt;

      {isOpen &amp;amp;&amp;amp; &amp;lt;div&amp;gt;{message}&amp;lt;/div&amp;gt;}
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The first error that pops out is &lt;code&gt;setIsOpen.toggle&lt;/code&gt; might not be a function because it might be a &lt;code&gt;boolean&lt;/code&gt;. If you continue to examine &lt;code&gt;isOpen&lt;/code&gt; closer, you&apos;ll also find it&apos;s not typed as a &lt;code&gt;boolean&lt;/code&gt;, but rather as the union. You can take a look for yourself in &lt;a href=&quot;https://www.typescriptlang.org/play?#code/JYWwDg9gTgLgBAJQKYEMDG8BmUIjgcilQ3wChTMBXAOw2AmrkoGckAhCCAGwAphrgMYCi4A1EZSRwAvHEwjWASjgBvUnDhoGzeAG0dKGEgA0cVjADKMQ0gC6MxMRgA6Fkis2+AoSPFdJiuQaWtQ6cAAWKNQAJlxIUMwOyOgubgCySCAQPDzK0gB8cDxqGhoMAFxFeYXmHkY8MFABxuqlEJiYlbkyNUiW1vXyXEotpXAwEADmk3Fd1WZ9dUg8iQVwAITMiqOlROZzPQv9nvyCwmISSIEaAL7bcLqnPhf+doGtRDCUUIz6AyYRKKxeLMWykG7kEJhPaULjwWRuDjcXLkCg0OgMOAWJBoT7FOAgJDMZgoSZSG6VFQEokksmVHRQfiTOB3VStKF6YDMADyYCQ1FM5gAkjy+dR7AjWEjeO8NJ9voweK0NAAeaLAABu+WVpRVACNKDAJowYABPPnSABEBqNDEtcAYAGEuMA0ABraQqYWi-nOCbTOI3bVjMYqLm8-lwAD8BAAEsBokh8HBKvhkBrUFx8BCQ3AVQB6G3G7U6jRhn2MABklbz6q1KkJxNJSBuBbr+Rzuvz7dagRuQA&quot;&gt;this TypeScript Playground&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You and I know that &lt;code&gt;useBool&lt;/code&gt; returns a tuple, how do we convince TypeScript of that fact?&lt;/p&gt;
&lt;h3&gt;The way I used to do it&lt;/h3&gt;
&lt;p&gt;I advise others to avoid defining function return types whenever possible to allow TypeScript inference to do its thing. There&apos;s really no need to be overly prescriptive. Type the inputs, let TS handle the outputs.&lt;/p&gt;
&lt;p&gt;Except in the case of tuples.&lt;/p&gt;
&lt;p&gt;As we&apos;ve seen, TypeScript thinks the return type is an array and this is understandable because we don&apos;t have &lt;em&gt;real&lt;/em&gt; tuples. So taking our &lt;code&gt;useBool&lt;/code&gt; function, we could add a return type to it.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function useBool(initialValue = false): [
  boolean,
  {
    on: () =&amp;gt; void
    off: () =&amp;gt; void
    toggle: () =&amp;gt; void
    reset: () =&amp;gt; void
  },
] {
  const [state, setState] = React.useState(initialValue)

  const handlers = React.useMemo(
    () =&amp;gt; ({
      on: () =&amp;gt; setState(true),
      off: () =&amp;gt; setState(false),
      toggle: () =&amp;gt; setState(s =&amp;gt; !s),
      reset: () =&amp;gt; setState(initialValue),
    }),
    [initialValue],
  )

  return [state, handlers]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, TypeScript knows that we intend to return a fixed length array and forces us to conform to it. The type checker correctly types &lt;code&gt;state&lt;/code&gt; and &lt;code&gt;handlers&lt;/code&gt; throughout our code.&lt;/p&gt;
&lt;p&gt;But our solution is a bit verbose and brittle. If we ever make a change to our hook&apos;s API, we&apos;ll have to manually update the types. Is there a more elegant way? Yes.&lt;/p&gt;
&lt;h3&gt;Why didn&apos;t I think of this sooner?&lt;/h3&gt;
&lt;p&gt;A simpler answer to our problem is to add &lt;code&gt;as const&lt;/code&gt; after our returned tuple, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function useBool(initialValue = false) {
  const [state, setState] = React.useState(initialValue)

  const handlers = React.useMemo(
    () =&amp;gt; ({
      on: () =&amp;gt; setState(true),
      off: () =&amp;gt; setState(false),
      toggle: () =&amp;gt; setState(s =&amp;gt; !s),
      reset: () =&amp;gt; setState(initialValue),
    }),
    [initialValue],
  )

  return [state, handlers] as const
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This tells TypeScript that the return value of &lt;code&gt;useBool&lt;/code&gt; is a &lt;code&gt;readonly&lt;/code&gt; array. It will never be modified. Because it&apos;s &lt;code&gt;readonly&lt;/code&gt;, TypeScript correctly types &lt;code&gt;state&lt;/code&gt; and &lt;code&gt;handlers&lt;/code&gt; anywhere they are used.&lt;/p&gt;
&lt;p&gt;It&apos;s a dead simple change, and only recently did it occur to me to do it this way. I should have been doing it this way for years. But hopefully I saved you a little trouble learning it the hard way.&lt;/p&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;Unless you tell TypeScript otherwise, it will assume that you&apos;re returning an array, not a tuple, from a function. You can either explicitly define a return type, or use &lt;code&gt;as const&lt;/code&gt; on the return value to inform TypeScript of the correct types.&lt;/p&gt;
</content:encoded><category>React</category><category>TypeScript</category></item><item><title>UI Composition</title><link>https://kyleshevlin.com/ui-composition/</link><guid isPermaLink="true">https://kyleshevlin.com/ui-composition/</guid><description>Often we run into tricky UI situations as a result of overloading an element with styling responsibilities. We can solve this problem by separating the responsibilities and re-composing the individual components.</description><pubDate>Tue, 03 Oct 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import { Card } from &apos;./_components&apos;&lt;/p&gt;
&lt;p&gt;I frequently come across components with either egregious conditionals, bizarre CSS, or both, to solve problems that can be easily solved with composition. It just takes some practice to recognize what responsibilities a particular part of a component should have, and how to properly separate and apply those responsibilities. Let&apos;s make an example.&lt;/p&gt;
&lt;p&gt;Let&apos;s say you have a &lt;code&gt;Card&lt;/code&gt; component. A &lt;code&gt;Card&lt;/code&gt; should have a border and the content inside should be padded from this border. Let&apos;s also give it a &lt;code&gt;box-shadow&lt;/code&gt; for some fun. It&apos;ll look like this:&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-8&quot;&amp;gt;
&amp;lt;div class=&quot;flex justify-center&quot;&amp;gt;
&amp;lt;Card&amp;gt;
&amp;lt;div class=&quot;flex flex-col gap-4&quot;&amp;gt;
&amp;lt;h3 class=&quot;font-sans text-xl&quot;&amp;gt;This is a Card&amp;lt;/h3&amp;gt;
&amp;lt;p&amp;gt;This is the Card&apos;s content. Notice it is padded from the border.&amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/Card&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;Cool, looks great! But soon you learn that the design team wants to be able to have &quot;sections&quot; in the &lt;code&gt;Card&lt;/code&gt;, divided by what is essentially an &lt;code&gt;hr&lt;/code&gt; tag. What happens if we do that without making any changes?&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-8&quot;&amp;gt;
&amp;lt;div class=&quot;flex justify-center&quot;&amp;gt;
&amp;lt;Card&amp;gt;
&amp;lt;div class=&quot;flex flex-col gap-4&quot;&amp;gt;
&amp;lt;h3 class=&quot;font-sans text-xl&quot;&amp;gt;This is Section 1&amp;lt;/h3&amp;gt;
&amp;lt;p&amp;gt;This is the content of Section 1. Isn&apos;t it great?!&amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;hr class=&quot;h-[2px] bg-gray-300&quot; /&amp;gt;
&amp;lt;div&amp;gt;
&amp;lt;h3 class=&quot;font-sans text-xl&quot;&amp;gt;This is Section 2&amp;lt;/h3&amp;gt;
&amp;lt;p class=&quot;mt-4&quot;&amp;gt;
This is the content of Section 2. Isn&apos;t it &amp;lt;em&amp;gt;also&amp;lt;/em&amp;gt; great?!
&amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/Card&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;That&apos;s probably not what we want. We want the divider to be able to go the full width of the card, and we want each section to be padded the same. We could try and do some hacky CSS. If I were working in a codebase with this component, I would not be shocked to see something like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.card hr {
  /* This matches the vertical padding of the wrap */
  margin-top: 1rem;
  margin-bottom: 1rem;
  /* negative margin moves the `hr` to the left side of the box */
  margin-left: -1rem;
  /* 2rem accounts for left and right padding */
  width: calc(100% + 2rem);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This might work, but it&apos;s not the most robust solution we can come up with. Rather than write some hacky CSS, we need to take a step back in order to make forward progress again. Composition is going to help us do that.&lt;/p&gt;
&lt;p&gt;You see, it might not be obvious, but &lt;code&gt;Card&lt;/code&gt; has &lt;strong&gt;too many responsibilities&lt;/strong&gt;. Just like classes, objects and functions can do too much, so can elements with their styling.&lt;/p&gt;
&lt;p&gt;When we look closely, we can see &lt;code&gt;Card&lt;/code&gt; is doing two separate jobs. First, it&apos;s wrapping all of the children in a border and box shadow. Second, it&apos;s applying a padding between that wrapping border and the children. In order to solve our problem, we need to separate these responsibilities into multiple components.&lt;/p&gt;
&lt;p&gt;Let&apos;s break &lt;code&gt;Card&lt;/code&gt; into a compound component, with &lt;code&gt;Wrap&lt;/code&gt;, &lt;code&gt;Section&lt;/code&gt;, and &lt;code&gt;Divider&lt;/code&gt; components.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Card.Wrap = function Wrap({ children }) {
  return (
    &amp;lt;div className=&quot;rounded border-2 border-gray-300 shadow-[8px_8px] shadow-accent&quot;&amp;gt;
      {children}
    &amp;lt;/div&amp;gt;
  )
}

Card.Section = function Section({ children }) {
  return &amp;lt;div class=&quot;p-4&quot;&amp;gt;{children}&amp;lt;/div&amp;gt;
}

Card.Divider = function Divider() {
  return &amp;lt;hr class=&quot;border-t-2 border-t-gray-300&quot; /&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we can compose our pieces together correctly.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;Card.Wrap&amp;gt;
  &amp;lt;Card.Section&amp;gt;
    &amp;lt;Stack gap={1}&amp;gt;
      &amp;lt;h3&amp;gt;This is Section 1&amp;lt;/h3&amp;gt;
      &amp;lt;p&amp;gt;This is the content for Section 1&amp;lt;/p&amp;gt;
    &amp;lt;/Stack&amp;gt;
  &amp;lt;/Card.Section&amp;gt;

  &amp;lt;Card.Divider /&amp;gt;

  &amp;lt;Card.Section&amp;gt;
    &amp;lt;p&amp;gt;
      This is an entirely different section. Notice the padding works correctly!
    &amp;lt;/p&amp;gt;
  &amp;lt;/Card.Section&amp;gt;
&amp;lt;/Card.Wrap&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-8&quot;&amp;gt;
&amp;lt;div class=&quot;flex justify-center&quot;&amp;gt;
&amp;lt;Card.Wrap&amp;gt;
&amp;lt;Card.Section&amp;gt;
&amp;lt;div class=&quot;flex flex-col gap-4&quot;&amp;gt;
&amp;lt;h3 class=&quot;font-sans text-xl&quot;&amp;gt;This is Section 1&amp;lt;/h3&amp;gt;
&amp;lt;p&amp;gt;This is the content for Section 1&amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/Card.Section&amp;gt;
&amp;lt;Card.Divider /&amp;gt;
&amp;lt;Card.Section&amp;gt;
&amp;lt;p&amp;gt;
This is an entirely different section. Notice the padding and divider
work correctly!
&amp;lt;/p&amp;gt;
&amp;lt;/Card.Section&amp;gt;
&amp;lt;/Card.Wrap&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;This right here, the act of recognizing &lt;code&gt;Card&lt;/code&gt; was overloaded with responsibilities and breaking them apart, is the work of building component-based design systems. This is how we make these components robust and flexible.&lt;/p&gt;
&lt;p&gt;We can take two steps to make this a bit better. Let&apos;s make the original &lt;code&gt;Card&lt;/code&gt; component a sane default composition of the compound components:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Card({ children }) {
  return (
    &amp;lt;Card.Wrap&amp;gt;
      &amp;lt;Card.Section&amp;gt;{children}&amp;lt;/Card.Section&amp;gt;
    &amp;lt;/Card.Wrap&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This way, when someone needs the simplest &lt;code&gt;Card&lt;/code&gt;, they can just use it.&lt;/p&gt;
&lt;p&gt;The second way we can improve this is to make it an error to use &lt;code&gt;Card.Section&lt;/code&gt; or &lt;code&gt;Card.Divider&lt;/code&gt; outside of &lt;code&gt;Card.Wrap&lt;/code&gt; using a Context.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Setting the default to false will let us trigger our Error if necessary
const CardContext = React.useContext(false)

const useCardContext = () =&amp;gt; {
  const context = React.useContext(CardContext)

  // We&apos;ll set context to true in our Provider, which will avoid this condition
  // We don&apos;t even need to return anything from this hook because we&apos;re not
  // using the context value anyways.
  if (!context) {
    throw new Error(
      &apos;You may only use Card compound components inside of a `Card.Wrap` component&apos;,
    )
  }
}

Card.Wrap = function Wrap({ children }) {
  return (
    // By setting the value to true, we enable our
    // compound components to work safely
    &amp;lt;CardContext.Provider value={true}&amp;gt;
      &amp;lt;div
        style={{
          border: &apos;2px solid var(--colors-offsetMore)&apos;,
          borderRadius: 4,
          boxShadow: &apos;8px 8px var(--colors-accent)&apos;,
        }}
      &amp;gt;
        {children}
      &amp;lt;/div&amp;gt;
    &amp;lt;/CardContext.Provider&amp;gt;
  )
}

Card.Section = function Section({ children }) {
  useCardContext()

  return &amp;lt;div style={{ padding: &apos;1rem&apos; }}&amp;gt;{children}&amp;lt;/div&amp;gt;
}

Card.Divider = function Divider() {
  useCardContext()

  return &amp;lt;hr /&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can take this a step even further and prevent nesting &lt;code&gt;Section&lt;/code&gt;s or passing a &lt;code&gt;Divider&lt;/code&gt; into a &lt;code&gt;Section&lt;/code&gt;, by adding another layer of our context provider in there.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Card.Section = function Section({ children }) {
  useCardContext()

  return (
    &amp;lt;CardContext.Provider value={false}&amp;gt;
      &amp;lt;div style={{ padding: &apos;1rem&apos; }}&amp;gt;{children}&amp;lt;/div&amp;gt;
    &amp;lt;/CardContext.Provider&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I hope your imagination helps you see that this problem affects more than our simple &lt;code&gt;Card&lt;/code&gt; component; that there are other offenses of having too many styling responsibilities. One of the most common ones is &lt;a href=&quot;https://mxstbr.com/thoughts/margin/&quot;&gt;exporting margins&lt;/a&gt;, but I&apos;ll save writing about that for another day.&lt;/p&gt;
&lt;p&gt;When you&apos;re struggling to get some UI to work the way you want, try to take a step back to make a step forward. Examine if some part of your component is overloaded, and if separating those responsibilities might not solve the problem.&lt;/p&gt;
</content:encoded><category>React</category></item><item><title>Typescript Prevents Bad Things... and Good Things</title><link>https://kyleshevlin.com/typescript-prevents-bad-things-and-good-things/</link><guid isPermaLink="true">https://kyleshevlin.com/typescript-prevents-bad-things-and-good-things/</guid><description>TypeScript is great at preventing bad things from happening, but it can prevent us from having some good things, too. When writing the types for functionality is onerously more difficult than writing the functionality itself, we might miss out on the good things that could have been.</description><pubDate>Fri, 08 Sep 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import { RandomNumber } from &apos;./_components&apos;&lt;/p&gt;
&lt;p&gt;A few days ago, TypeScript was the main topic of discussion on tech Twitter. &amp;lt;Marker content=&quot;I will never call it that other name.&quot; /&amp;gt; The reasons why aren&apos;t worth giving any more time or energy. But I do wish to discuss some thoughts &lt;em&gt;I&lt;/em&gt; have regarding working with TypeScript.&lt;/p&gt;
&lt;p&gt;Let me state up front, my experience with TypeScript has been largely a net positive. But being a net positive is not the same thing as being &lt;em&gt;entirely&lt;/em&gt; positive. I have had negative experiences with TypeScript and I have some criticisms I will address in this post.&lt;/p&gt;
&lt;h3&gt;TL;DR;&lt;/h3&gt;
&lt;p&gt;TypeScript prevents many bad things: bugs, errors, bad assumptions and more. The type system can give you a lot of confidence in your programs. This is overwhelmingly positive.&lt;/p&gt;
&lt;p&gt;I also think TypeScript prevents good things, too. It is often far easier to express &lt;em&gt;functionality&lt;/em&gt; than it is to express the &lt;em&gt;types&lt;/em&gt; required for that functionality. This can stifle creativity and innovation. It&apos;s very easy to build something undeniably useful in the realm of JavaScript, that turns out to be extremely difficult to express type-wise in TypeScript.&lt;/p&gt;
&lt;p&gt;I think it&apos;s ok to admit this. I posit it is more difficult to learn the type system deeply and intuitively than the rest of programming language. Thus, most of us working in TypeScript who are not experts in the type system are making a tradeoff where we limit our programmatic expressiveness for the sake of type safety. I think it&apos;s ok to have nostalgia for how easy it was to express ourselves when it was just JavaScript.&lt;/p&gt;
&lt;h3&gt;In plain terms&lt;/h3&gt;
&lt;p&gt;I feel very confident in my JavaScript abilities. In my ability to &lt;em&gt;express&lt;/em&gt; the functionality I desire with the language. Because TypeScript is a superset of JavaScript, I maintain this ability to express the functionality I desire.&lt;/p&gt;
&lt;p&gt;That said, my ability to express the type correctness of my functionality is far more limited. I don&apos;t think I&apos;m alone in this limitation. In fact, it makes me wonder if it&apos;s a limitation of the type system itself! I say &quot;wonder&quot; purposefully. Someone far better at using the type system could likely prove me wrong.&lt;/p&gt;
&lt;p&gt;In fact, I would love it if they would. Guide me, teach me to be better, because I think it is far harder to gain fluency in TypeScript&apos;s type system than it is to write programs. It&apos;s esoteric, algebraic, &amp;lt;Marker content={&lt;code&gt;I am pretty darn good at math, as I&apos;ll describe soon, so please don&apos;t come at me with &quot;Get gud!&quot;&lt;/code&gt;} /&amp;gt; and there are far fewer resources on deciphering and unlocking its nuances than there are of the rest of the language.&lt;/p&gt;
&lt;p&gt;I think because because of this gap between the ease of expressing the functionality and the difficulty of expressing the type correctness for that functionality, we often have to forego otherwise &quot;good things&quot; because we cannot guarantee thorough type safety in order to so. On occasion, we get &lt;em&gt;worse&lt;/em&gt; APIs because they are easier to express type-wise, even when doing so hampers and limits functionality and expressiveness.&lt;/p&gt;
&lt;p&gt;Shortly, I will demonstrate this challenge with a bit of code I wrote for fun, that in a world of just JavaScript, it would be fine to use. But despite my best efforts--asking a TS expert on Twitter, consulting Chat-GPT for hours, reading docs, and even trying to decipher the types in another library--I have been unsuccessful in getting the types right and have to abandon this &quot;good thing&quot;. Without the type safety, it&apos;s not usable by others in the community.&lt;/p&gt;
&lt;h3&gt;My background with types&lt;/h3&gt;
&lt;p&gt;I do not have an extensive background with typed programming languages. My experience is primarily with forms of typed JavaScript. Starting in 2019, I spent just over 2 years working with &lt;a href=&quot;https://flow.org/&quot;&gt;Flow&lt;/a&gt;. &amp;lt;Marker content=&quot;I still prefer Flow&apos;s error messages if I&apos;m being honest.&quot; /&amp;gt; I have essentially written TypeScript every day since that time.&lt;/p&gt;
&lt;p&gt;I have dabbled in some strongly typed languages, with ReasonML and ReScript being the ones I have used most seriously. I have finished a few small projects with these languages and have also contributed to an open source project that used these languages.&lt;/p&gt;
&lt;p&gt;I am by no means an expert in types or TypeScript, but I&apos;m not uncomfortable with them either.&lt;/p&gt;
&lt;p&gt;In university, I double majored in Philosophy and Mathematics. These areas of study are useful for understanding a type system. Just look at some of my blog posts. I enjoy a little &lt;a href=&quot;/set-theory&quot;&gt;set theory&lt;/a&gt; and &lt;a href=&quot;/symbolic-logic&quot;&gt;symbolic logic&lt;/a&gt; here and there.&lt;/p&gt;
&lt;p&gt;What I am trying to say is I believe I am capable of learning a type system well. I have the tools and skills. But I will admit up front, there are parts of TypeScript for which I have struggled to develop any intuition, which we will discuss in more detail later.&lt;/p&gt;
&lt;h3&gt;That time I couldn&apos;t use state machines at work because they weren&apos;t type safe yet&lt;/h3&gt;
&lt;p&gt;I couldn&apos;t find a better place to add this anecdote, but I need to share it with this post because it&apos;s a &quot;good thing&quot; that was prevented by the lack of complete type safety.&lt;/p&gt;
&lt;p&gt;I tried to introduce state machines to a work place to manage a very complicated bit of UI. Most people saw the value of the state machine for this particular situation and appreciated the run time guarantee of never getting into impossible states.&lt;/p&gt;
&lt;p&gt;The problem was I couldn&apos;t get the correct types for the state of the machine. It was a combo of Flow and the existing types for the library. It just couldn&apos;t be done.&lt;/p&gt;
&lt;p&gt;I was &lt;em&gt;required&lt;/em&gt; by a staff engineer to abandon the use of state machines and told if I wanted that kind of run-time safety, I would have to also make it compile-time safe, aka type safe. I ended up writing a reducer that acted like a state machine. There are some posts about it around here. It was ~3x the code to express the same functionality. But hey, types!&lt;/p&gt;
&lt;h3&gt;A recent struggle as an example&lt;/h3&gt;
&lt;p&gt;I really enjoy learning about how things work on a fundamental level. I also enjoy solving puzzles. &amp;lt;Marker content=&quot;Probably why I enjoy Advent of Code as much as I do.&quot; /&amp;gt; In order to experience these two joys at once, I will occasionally attempt to rebuild a small library (or a stripped down version of one) from scratch, so I can both test myself and see what I learn in the process.&lt;/p&gt;
&lt;p&gt;Recently, I decided to try and write a small pattern matching library, similar to &lt;a href=&quot;https://github.com/gvergnaud/ts-pattern&quot;&gt;ts-pattern&lt;/a&gt;. I enjoy &lt;a href=&quot;/pattern-matching&quot;&gt;pattern matching&lt;/a&gt;, but it&apos;s not built into JavaScript, so if we want to experience the expressiveness of using it, we have to implement it ourselves.&lt;/p&gt;
&lt;p&gt;Here&apos;s what I wanted to accomplish with my lib:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Our function must receive an input that can be matched against an arbitrary number of cases&lt;/li&gt;
&lt;li&gt;It would be nice if those cases could be values or a predicate function that received the input&lt;/li&gt;
&lt;li&gt;It must be able to return a default value&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I wrote my first pass in plain JavaScript in ~5 minutes. It looked something like this: &amp;lt;Marker content=&quot;It should go without saying, the following code could be written as a class or use the &amp;lt;code&amp;gt;this&amp;lt;/code&amp;gt; keyword. I don&apos;t want to hear it. I &amp;lt;em&amp;gt;know&amp;lt;/em&amp;gt; how to do that. I just &amp;lt;em&amp;gt;happen&amp;lt;/em&amp;gt; to enjoy writing functions and closures instead. If I do see you complain about it on Twitter, I&apos;ll know you never read these footnotes when you really should.&quot; /&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/**
 * Because ts-pattern uses match/with, I wanted to do something
 * slightly different. I decided to use Ruby&apos;s case/when, but since
 * &quot;case&quot; is already a keyword in JavaScript, I&apos;m spelling it &quot;kase&quot;
 */
function kase(input) {
  // Over time, I&apos;ve developed a fondness for writing simple closures
  // and so a closure is how we manage the state of our pattern matcher
  let isMatched = false
  let result = undefined

  // I also prefer to avoid using `this` if I can
  // We can do this easily by instantiating the object
  // and referring to it
  const api = {}

  // Our primary way of testing patterns against the input
  // If we get a match, the result is set to the return of the callback
  function when(pattern, callback) {
    if (isMatched) return api

    // This allows us to pass values or a predicate function
    const predicate =
      typeof pattern === &apos;function&apos;
        ? () =&amp;gt; pattern(input)
        : () =&amp;gt; pattern === input

    if (predicate()) {
      isMatched = true
      result = callback(input)
    }

    return api
  }

  // Default case handling
  function otherwise(callback) {
    if (isMatched) return result

    return callback(input)
  }

  // If no default case is provided, we need a way to get the result
  function end() {
    return result
  }

  api.when = when
  api.otherwise = otherwise
  api.end = end

  return api
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This simple function works great. We can use it like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const result = kase(Math.round(Math.random() * 100))
  .when(
    x =&amp;gt; x &amp;lt;= 33,
    () =&amp;gt; &apos;Low&apos;,
  )
  .when(
    x =&amp;gt; x &amp;lt;= 67,
    () =&amp;gt; &apos;Mid&apos;,
  )
  .when(69, () =&amp;gt; &apos;Nice!&apos;)
  .otherwise(() =&amp;gt; &apos;High&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And check it out in action: &amp;lt;Marker content={&lt;code&gt;Sorry if it takes you forever to get a &quot;Nice!&quot; response.&lt;/code&gt;} /&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;RandomNumber client:load /&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;p&gt;Now, let the trouble begin.&lt;/p&gt;
&lt;p&gt;We&apos;re going to try and add types to this. Here&apos;s what we need to accomplish (and I have thus far been unable):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;kase&lt;/code&gt; needs to be typed such that it returns an object with &lt;code&gt;when&lt;/code&gt;, &lt;code&gt;otherwise&lt;/code&gt;, and &lt;code&gt;end&lt;/code&gt; typed correctly&lt;/li&gt;
&lt;li&gt;The functions passed to &lt;code&gt;when&lt;/code&gt; and &lt;code&gt;otherwise&lt;/code&gt; need to infer the correct type of the &lt;code&gt;input&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;result&lt;/code&gt; needs to be a union of the types returned by the &lt;code&gt;callback&lt;/code&gt;s provided to &lt;code&gt;when&lt;/code&gt;s and &lt;code&gt;otherwise&lt;/code&gt; and returned from &lt;code&gt;otherwise&lt;/code&gt; and &lt;code&gt;end&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you want to follow along and try to work it out on your own, you can use this &lt;a href=&quot;https://www.typescriptlang.org/play?#code/PQKhCgAIUghBTAxgQwK4Gd6QC7oLQAOy228ATgHaQbzqQC2xiAFsAO4CW2zANJAJKQ2yCqQAmOAPaQx09JPrxuHCgHMoMdABsOq5ti0BPGRwBmp8vFEA6ATKQcx8Cdmk1IAJVQAjQwHI6FEx2Zis+b1RsSHQVRHgNSAAiIPhEyA46ZC0yeGQxY2RIAGt4QzZJMgkVSAApZAA3ZABlRDIOAmw+fj96aIJ4LR01dKjEouRMRI1gcFNUCkRsDkkqccwAChUCSIBKSABvKEhgYEgAeXryHA5FLr9L+0utSX6JQtMVsQpaOg+yITaS2GMXoBC0WEQz3QqBy6COJ0gIgk8kRkEhkmhOXSdGYkjYQiwjAoyFUWG4WHQ2GIWEkpkgkhhkCIJHIVEY2BY5CO4KiGQAskxQhIALyQUxZTDcpSQWGoLRRUXzJymFTOcDw06CCXSAg5Cz-VyI+qSRzUGLDAAGynQFvSdMEKAoGsgAHUISIZNJrZBcjEjJBfOkKJSREtiCpVDhQvTvAArJDYZ1ImXwfVtYaGrhHRArSmIggcSCi-YAX3VkGOpzOjN1N2QZGMwmMtJwtCBkeZpEomVUyBUefJQe2iYrCP4dLYWFJUUK7JYfEHsvl2Oi0sNi6UMKoLcHKEG3mQiCKRzmCyWKyEoQo607rL4e60B6Pe0OFYrZkgm3QAo5Qr2OWwLd8w4cs3wRAAVZgMkRQY8ToDApCZCY6EaLRUFoel-kKXVnA4FBSDFeZFmWJ03zRXMohwsQ8OpIsjjI7BDH6Ftb0oIthVFPxT2IlY-HosjIAAfk-PZhQAPiQllKE2Chhx2fiyIALhEosJNYqgONFLZIlA986RvHJqPw+B1h2F8FOxH9ORFHAyHQiylwVNEskfQ8ihkuT+LLfiAKA5ACyObzR1OAARVM0GXFJIGYJEhnUCtuPPbdyTITgNgfJ8inMsiPy-Ky-xTQC2Mc3TCqAjK3I83ZAtAsc6QoaRlQiqIoug3VJHqRxnD4SdIG+ZxUSbRDpyjLASoSoikp9CgxFMg4fM3YraDlEdICC4DrDYK8i0vKwjn8jhrEkFK0qwUVjtCVKMniCsDusKwbIe0DfLYg7wBLIA&quot;&gt;TypeScript Playground&lt;/a&gt; to interact with the code and try and fix the type errors.&lt;/p&gt;
&lt;p&gt;The very first error we see is:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Parameter &apos;input&apos; implicitly has an &apos;any&apos; type&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;We can knock this one out easily. We don&apos;t want to specify a type of &lt;code&gt;input&lt;/code&gt;, we simply want whatever the user passes in to be the type throughout the function. This is exactly what a generic is for, so let&apos;s add one:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function kase&amp;lt;Input&amp;gt;(input: Input) {
  // ... the rest
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That was easy. The next error we have is:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Variable &apos;result&apos; implicitly has type &apos;any&apos; in some locations where its type cannot be determined.&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;We get this error because we set &lt;code&gt;result&lt;/code&gt; as the return of our &lt;code&gt;callback&lt;/code&gt;s but we don&apos;t know that type yet. Let&apos;s add an &lt;code&gt;unknown&lt;/code&gt; and come back to it. There are other errors we can solve before that one:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let result: unknown = undefined
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, the next error we have is:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Parameter &apos;pattern&apos; implicitly has an &apos;any&apos; type.&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;So let&apos;s give it a type. A &lt;code&gt;pattern&lt;/code&gt; is either an &lt;code&gt;unknown&lt;/code&gt; value &amp;lt;Marker content=&quot;We will revisit this later, too.&quot; /&amp;gt; or it&apos;s a function that receives the &lt;code&gt;input&lt;/code&gt; and returns a &lt;code&gt;boolean&lt;/code&gt;. That looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function when(pattern: ((input: Input) =&amp;gt; boolean) | unknown, callback) {
  //...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Our next two errors are actually of the same variety:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Parameter &apos;callback&apos; implicitly has an &apos;any&apos; type.&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Let&apos;s make ourselves a little helper type to handle this.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type Callback&amp;lt;Input&amp;gt; = (input: Input) =&amp;gt; unknown

function kase&amp;lt;Input&amp;gt;(input: Input) {
  // ...
  function when(
    pattern: ((input: Input) =&amp;gt; boolean) | unknown,
    callback: Callback&amp;lt;Input&amp;gt;,
  ) {
    // ...
  }

  function otherwise(callback: Callback&amp;lt;Input&amp;gt;) {
    //...
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So far, this has been pretty easy. Our remaining errors are all related. I&apos;ll combine them into one: &lt;code&gt;Properties &apos;when&apos;, &apos;otherwise&apos; and &apos;end&apos; do not exist on type &apos;{}&apos;&lt;/code&gt;. We instantiated &lt;code&gt;api&lt;/code&gt; as an empty object and thus, TypeScript doesn&apos;t know what properties should eventually exist on &lt;code&gt;api&lt;/code&gt;. We need to either change our code or cast the type of &lt;code&gt;api&lt;/code&gt;. Let&apos;s try casting it. I&apos;m going to create another helper type to do so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// ...
type API&amp;lt;Input&amp;gt; = {
  when: (
    pattern: ((input: Input) =&amp;gt; boolean) | unknown,
    callback: Callback&amp;lt;Input&amp;gt;,
  ) =&amp;gt; API&amp;lt;Input&amp;gt;

  otherwise: (callback: Callback&amp;lt;Input&amp;gt;) =&amp;gt; unknown

  end: () =&amp;gt; unknown
}

function kase&amp;lt;Input&amp;gt;(input: Input) {
  // ...
  const api = {} as API&amp;lt;Input&amp;gt;
  //...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Great! Now all our errors are gone. Or are they?&lt;/p&gt;
&lt;p&gt;While we have no errors in our function, we don&apos;t have type safety. We actually have to try and call this function and see what happens. So let&apos;s use it below where we define it, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const result = kase(Math.random())
  .when(
    x =&amp;gt; x &amp;lt; 0.33,
    () =&amp;gt; &apos;low&apos;,
  )
  .when(
    x =&amp;gt; x &amp;lt; 0.67,
    () =&amp;gt; &apos;mid&apos;,
  )
  .otherwise(() =&amp;gt; &apos;high&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What do you know? We have errors. &lt;code&gt;Parameter &apos;x&apos; implicitly has an &apos;any&apos; type.&lt;/code&gt; Why is this the case? We indicated that &lt;code&gt;pattern&lt;/code&gt; should return the type of the &lt;code&gt;input&lt;/code&gt;, so TypeScript should already know the type of &lt;code&gt;x&lt;/code&gt;. What gives?&lt;/p&gt;
&lt;p&gt;Well, it turns out there are two problems with our types so far.&lt;/p&gt;
&lt;p&gt;First, if we examine the resulting type of &lt;code&gt;when&lt;/code&gt;, it turns out &lt;code&gt;pattern&lt;/code&gt; is actually &lt;code&gt;unknown&lt;/code&gt;. Our union isn&apos;t working the way we expected.&lt;/p&gt;
&lt;p&gt;Second, when we check if &lt;code&gt;pattern&lt;/code&gt; is a function, it doesn&apos;t narrow it to our predicate type, it narrows it only to &lt;code&gt;Function&lt;/code&gt;. There is no way for TypeScript to determine that when &lt;code&gt;pattern&lt;/code&gt; is a function, it&apos;s specifically our predicate function, at this moment. To fix this, takes a bit of work.&lt;/p&gt;
&lt;p&gt;We&apos;re going to make a few more helper types, &lt;em&gt;change&lt;/em&gt; one of our original type decisions, and use a &lt;a href=&quot;https://www.typescriptlang.org/docs/handbook/advanced-types.html#using-type-predicates&quot;&gt;type predicate function&lt;/a&gt; for our pattern predicate function. So much predication! Here we go:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// ...
type Predicate&amp;lt;Input&amp;gt; = (input: Input) =&amp;gt; boolean

// Here we make an &quot;API&quot; change, instead of `unknown`
// we narrow it to only types that match the Input generic
type Pattern&amp;lt;Input&amp;gt; = Predicate&amp;lt;Input&amp;gt; | Input

type API&amp;lt;Input&amp;gt; = {
  when: (pattern: Pattern&amp;lt;Input&amp;gt;, callback: Callback&amp;lt;Input&amp;gt;) =&amp;gt; API&amp;lt;Input&amp;gt;
  // ...
}

// This is a type predicate, a function that returns a boolean
// where we indicate to TypeScript the type `pattern` is
// when this function returns true
function isPredicate&amp;lt;Input&amp;gt;(
  pattern: Pattern&amp;lt;Input&amp;gt;,
): pattern is Predicate&amp;lt;Input&amp;gt; {
  return typeof pattern === &apos;function&apos;
}

function kase&amp;lt;Input&amp;gt;(input: Input) {
  //...
  function when(pattern: Pattern&amp;lt;Input&amp;gt;, callback: Callback&amp;lt;Input&amp;gt;) {
    //...
    const predicate = isPredicate&amp;lt;Input&amp;gt;(pattern)
      ? () =&amp;gt; pattern(input)
      : () =&amp;gt; pattern === input
    // ...
  }
  //...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Awesome! There are no errors. If you&apos;re following along, your playground &lt;a href=&quot;https://www.typescriptlang.org/play?#code/C4TwDgpgBAwghgGwQIzgYwNYB4CSA7MAV2AD4oBeKACgEsDiAuKfI4ASgrMLwzwHsA7ngDcAKFGhIUAAoAnCABMaaOMAi56pCtTqsmLYh3JlkfPgghw84ydGmq1svBtZlKcxctXqDWgD7Mmjbg0ACC0jguxG5QAN6iUFACABYQeExUYA4QTkz2wI7OviQANFAqSKiYTPCV6NjFRmThkcUJUHzAqbICNADOEBkVKPU1iCOYUaRNUNy8gtaJaQoZM3P8QmIAvuIAZtxowDR8eFD9HkoqalMkmdm5MvdFmiRsTFkFOaf9MvKX3jc4u15MBCE4oLY+LsoB9ChRyJQAOT7PCHY54RGiHaiAD0ACo8Qk8VAAEIQFSEAYQvoAWlhX1mAz6UAAtqo0Mkcb0umUcEkrGoFBC+FAFCK+nwWRAunQAOZEqB9BA0WXJYAIECimi7XY5NLAAB0zFF5JoCkUwsZ0AASoRkCBEcyVAMuak8GVkMRFXQ0BAFQAiZ0Qf1nZmIeRwBSauBQDAQEACPiyIV0KAAKTgADc4ABlNCyGhgYC8xEsxWQJBys7AKD+jBwAb+ok40QotEnWMNnwvWiafSaDjxRI4nFQADymZyEJoUpLk5Nk4QfEgQpjuxOCjwED6zPXsiSBaOeFl3pZYAs5SXfTB2-aI6gViFEofl741-koagyUESWgbLwcCytAXTQH0wDeB00J8GCMJPKy7LdO0Fg1v0ACyCEWpQuyIAMSHSlA8jXggwBMOsCzaNw5q7HQijiMOo58jhIpgPIur7sAIpZnwZqMlWAAGMp9HxZzQnyKiLFA94AOrQOJooioJUCWH0NAalA9pnHgYECjQqhViBHTIAAVuSwB3qOj4ERAbEFselo0GZiRoCcYEPmANDaLEWwPsyLQ3HRkmjmOMEsTOcCyJqAhwJqUIQtuR4nvSThhrKcB0K5Bm6MQ5nMNCAjQEBNYxmywAcmUBmEYQxGfgMNYcRCqRWaC4KxQZwxVBg7RtkcHYpGkdyfA8+SFDcZTtaMsDjB1NyDu0iTajofToaVqQKBwIJgqccDuQF9FQAAKskPzjIIzKUpaWQ7lA2YIIQ24dPuMYsZ4VzQN16JzeULk1s9-xqNo5x-F41zFANhRsJ9iSJAA-NQMxJXgvasBDUOo1AqycLBg2nAilBZWZn0LZkQOvVQbCzWjobLRymEQrId2Q1ZRE1pQ42YEjhifdiqMbeC200O03OBVAAAi1lwFVNZBl+j7KseXUHD1pydN0vQDFQbMYGMdSTI0QKo0TaEYWtTWbUzku7ab4Kaxz7CCwF944NC-AmthkvlF2n4sXwmZmooZT5VAW4WjGUWavVhUNdAlXEQrqJK0peAKGT+tQ7zpwx45UBC-zBp9TjSRuu0ucqzkavQJQpc9P0fqJLnyzaMsAXp25AvYs5Wk1pn2j1ury3JAasiPpKZMo1AedulQn0AB6Y7PWBQAADAaADMK8lJ9KfGFAiJLgImKJGPE-9TPc9QAvy8AGwAOwb6jW9kKWZoH1AR9V+XVAPzvR2qoibBAA&quot;&gt;should look like this&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;But!!! Do we have full type safety? No, we don&apos;t. Hover over the type of &lt;code&gt;result&lt;/code&gt;. It&apos;s still &lt;code&gt;unknown&lt;/code&gt;, which makes sense, we said we&apos;d come back to that later, and now &lt;em&gt;is&lt;/em&gt; later.&lt;/p&gt;
&lt;h4&gt;A brief aside&lt;/h4&gt;
&lt;p&gt;Getting to this point, where we have everything typed correctly except for &lt;code&gt;result&lt;/code&gt;, didn&apos;t take me long, but it took me a lot longer than writing the functionality. The first few steps were pretty easy, maybe taking 20 minutes or so. But once I got to the point where &lt;code&gt;pattern&lt;/code&gt; wasn&apos;t typed correctly, where &lt;code&gt;x&lt;/code&gt; was implicitly &lt;code&gt;any&lt;/code&gt;, I started to lose time quickly.&lt;/p&gt;
&lt;p&gt;I explained it to you simply here, but that&apos;s only because I tried and failed a few ways before figuring it all out. I went down the road of &lt;a href=&quot;https://www.typescriptlang.org/docs/handbook/2/functions.html#function-overloads&quot;&gt;function overloads&lt;/a&gt;, casting, all sorts of other attempts. I tried rewriting it as a &lt;code&gt;class&lt;/code&gt; to see if it was easier to type. I tried a lot of things until I got to this point. Probably took anywhere from 1-4 hours. Not really sure because it&apos;s mixed in with other experiments and attempts.&lt;/p&gt;
&lt;p&gt;But that&apos;s exactly what I&apos;m getting at. Functionality was exponentially easier to express than the type correctness of that functionality. ~5 minutes compared to hours.&lt;/p&gt;
&lt;p&gt;The next step we&apos;re about to do, at the moment I write this, I &lt;em&gt;still&lt;/em&gt; haven&apos;t solved. I have probably put 8-12 hours into this. I&apos;ve tried rewriting the entire API to make it better, but I haven&apos;t cracked it yet. &lt;em&gt;This&lt;/em&gt; is where productivity is lost. It&apos;s at this point where if this wasn&apos;t solely for my own edification, I&apos;d just go back to a &lt;code&gt;switch (true)&lt;/code&gt; pattern and move on. It&apos;s not worth me making this helpful function anymore.&lt;/p&gt;
&lt;h3&gt;Damn it!!!&lt;/h3&gt;
&lt;p&gt;So... I stepped away after writing that previous paragraph. It was entirely true at that point in time. But after I ate some lunch and did some chores, I came back and gave it one more try (probably about my 10th try) and wouldn&apos;t you know, &lt;strong&gt;I finally got it&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;I still stand by what I&apos;ve posited so far in this post. Getting the types correct can be onerous and burdensome. It certainly has been for me in this specific example, and situations like this very one have happened to me dozens of times before. TS can stand for TimeSuck sometimes. &amp;lt;Marker content=&quot;I call dibs if no one has ever said that before.&quot; /&amp;gt;&lt;/p&gt;
&lt;p&gt;That said, let&apos;s get this nut cracked. Let&apos;s figure out how to get &lt;code&gt;result&lt;/code&gt; typed correctly.&lt;/p&gt;
&lt;p&gt;To figure this out, let&apos;s consider what &lt;code&gt;result&lt;/code&gt; should be. It begins as &lt;code&gt;undefined&lt;/code&gt;, and then it should be the return type of any &lt;code&gt;callback&lt;/code&gt; passed to &lt;code&gt;when&lt;/code&gt; or &lt;code&gt;otherwise&lt;/code&gt;. So if all those &lt;code&gt;callback&lt;/code&gt;s return &lt;code&gt;string&lt;/code&gt;, I would expect &lt;code&gt;result&lt;/code&gt; to be the type &lt;code&gt;string | undefined&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;So far, we have the return of a &lt;code&gt;Callback&lt;/code&gt; as &lt;code&gt;unknown&lt;/code&gt;. It&apos;s true that we don&apos;t know what that value is, but we can pass a second generic to &lt;code&gt;Callback&lt;/code&gt; to at least give it a name, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type Callback&amp;lt;Input, Return&amp;gt; = (input: Input) =&amp;gt; Return
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This should break a &lt;em&gt;lot&lt;/em&gt; of things. Everywhere we&apos;ve used &lt;code&gt;Callback&lt;/code&gt; now expects a second type passed to it. So how do we do this?&lt;/p&gt;
&lt;p&gt;Let&apos;s start by adding a &lt;code&gt;Return&lt;/code&gt; generic to &lt;code&gt;when&lt;/code&gt; and &lt;code&gt;otherwise&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type API&amp;lt;Input&amp;gt; = {
  when: &amp;lt;Return&amp;gt;(
    pattern: Pattern&amp;lt;Input&amp;gt;,
    callback: Callback&amp;lt;Input, Return&amp;gt;,
  ) =&amp;gt; API&amp;lt;Input&amp;gt;

  otherwise: &amp;lt;Return&amp;gt;(callback: Callback&amp;lt;Input, Return&amp;gt;) =&amp;gt; unknown
  //...
}

function kase&amp;lt;Input&amp;gt;(input: Input) {
  //...
  function when&amp;lt;Return&amp;gt;(
    pattern: Pattern&amp;lt;Input&amp;gt;,
    callback: Callback&amp;lt;Input, Return&amp;gt;,
  ) {
    //...
  }

  function otherwise&amp;lt;Return&amp;gt;(callback: Callback&amp;lt;Input, Return&amp;gt;) {
    //...
  }
  //...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ok, but &lt;code&gt;result&lt;/code&gt; is still &lt;code&gt;unknown&lt;/code&gt;. Why? Because the return types for &lt;code&gt;when&lt;/code&gt;, &lt;code&gt;otherwise&lt;/code&gt; and &lt;code&gt;end&lt;/code&gt; don&apos;t track the &lt;code&gt;result&lt;/code&gt;. How can we do this? We need to change those &lt;code&gt;unknown&lt;/code&gt;s into a &lt;code&gt;Result&lt;/code&gt; somehow.&lt;/p&gt;
&lt;p&gt;I&apos;m not going to lie, this next part is not very intuitive, especially if you don&apos;t have any functional programming experience.&lt;/p&gt;
&lt;p&gt;Right now, our &lt;code&gt;api&lt;/code&gt; mutates and returns the &lt;code&gt;result&lt;/code&gt; because it&apos;s held in a closure. In JavaScript, this is fine and used to be a far more common pattern than it is now. But what if instead of mutating &lt;code&gt;result&lt;/code&gt;, we make our &lt;code&gt;api&lt;/code&gt; stateless, and return a new &lt;code&gt;api&lt;/code&gt; with the correct state baked in instead? What if we make our &lt;code&gt;api&lt;/code&gt; immutable? Then we&apos;d be able to identify what type of &lt;code&gt;Result&lt;/code&gt; we have when we return the new &lt;code&gt;api&lt;/code&gt;. How do we do this?&lt;/p&gt;
&lt;p&gt;First, we&apos;re going to start with a &quot;factory function&quot;. We&apos;re going to take &lt;em&gt;everything&lt;/em&gt; inside of &lt;code&gt;kase&lt;/code&gt; and move it inside a &lt;code&gt;kaseFactory&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function kase&amp;lt;Input&amp;gt;(input: Input) {
  return kaseFactory&amp;lt;Input&amp;gt;(input)
}

function kaseFactory&amp;lt;Input&amp;gt;(input: Input) {
  // literally everything we had to this point
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, we&apos;re going to make our factory stateless. Instead of holding &lt;code&gt;isMatched&lt;/code&gt; and &lt;code&gt;result&lt;/code&gt; in closure, we&apos;re going to pass them in as arguments to the factory. The &quot;state&quot; of the &lt;code&gt;api&lt;/code&gt; is static, and to change the state, we&apos;ll just return a new &lt;code&gt;api&lt;/code&gt; with the next state. Thus, our initial state has &lt;code&gt;isMatched&lt;/code&gt; set to &lt;code&gt;false&lt;/code&gt; and &lt;code&gt;result&lt;/code&gt; set to &lt;code&gt;undefined&lt;/code&gt;, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function kase&amp;lt;Input&amp;gt;(input: Input) {
  return kaseFactory&amp;lt;Input, undefined&amp;gt;(input, false, undefined)
}

function kaseFactory&amp;lt;Input, Result&amp;gt;(
  input: Input,
  isMatched: boolean,
  result: Result,
) {
  // And we delete the following commented out lines
  // let isMatched = false
  // let result: unknown = undefined.
  // The rest is the same
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice two things: First, that we added a &lt;code&gt;Result&lt;/code&gt; generic to &lt;code&gt;kaseFactory&lt;/code&gt; and pass in &lt;code&gt;undefined&lt;/code&gt; as our initial type when we call it in &lt;code&gt;kase&lt;/code&gt;. Second, that we&apos;re currently in a broken state. We need to fix a few things, but I wanted to explain what we&apos;re about to do first.&lt;/p&gt;
&lt;p&gt;Up til now, when we got a match, that is when &lt;code&gt;predicate()&lt;/code&gt; returned &lt;code&gt;true&lt;/code&gt;, we mutated the &lt;code&gt;isMatched&lt;/code&gt; and &lt;code&gt;result&lt;/code&gt; values. This mutation prevented us from being able to type &lt;code&gt;result&lt;/code&gt; properly.&lt;/p&gt;
&lt;p&gt;Going forward, when we have a match, we&apos;re going to create and return a new &lt;code&gt;api&lt;/code&gt; by calling &lt;code&gt;kaseFactory&lt;/code&gt; with new arguments. We&apos;ll pass in the same &lt;code&gt;input&lt;/code&gt;, &lt;code&gt;true&lt;/code&gt; for the &lt;code&gt;isMatched&lt;/code&gt; parameter, and then the result of calling the &lt;code&gt;callback&lt;/code&gt;. We&apos;ll also be able to pass the &lt;code&gt;Input&lt;/code&gt; generic along, as well as the &lt;code&gt;typeof result&lt;/code&gt; from the callback, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function when&amp;lt;Return&amp;gt;(
  pattern: Pattern&amp;lt;Input&amp;gt;,
  callback: Callback&amp;lt;Input, Return&amp;gt;,
) {
  if (isMatched) return api

  const predicate = isPredicate&amp;lt;Input&amp;gt;(pattern)
    ? () =&amp;gt; pattern(input)
    : () =&amp;gt; pattern === input

  if (predicate()) {
    // Here&apos;s the change
    const result = callback(input)

    return kaseFactory&amp;lt;Input, typeof result&amp;gt;(input, true, result)
  }

  return api
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we&apos;re returning a whole new &lt;code&gt;api&lt;/code&gt; with the correct types baked in! This means we now know the type of &lt;code&gt;Result&lt;/code&gt; no matter where we are in the chain.&lt;/p&gt;
&lt;p&gt;We&apos;re almost finished. We just need to add a &lt;code&gt;Result&lt;/code&gt; generic to our &lt;code&gt;API&lt;/code&gt; type so that we correctly describe the return types of our methods.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type API&amp;lt;Input, Result&amp;gt; = {
  when: &amp;lt;Return&amp;gt;(
    pattern: Pattern&amp;lt;Input&amp;gt;,
    callback: Callback&amp;lt;Input, Return&amp;gt;,
    // Notice the union passed in the `Result` generic slot
  ) =&amp;gt; API&amp;lt;Input, Result | Return&amp;gt;

  // Same union is now returned here as well
  otherwise: &amp;lt;Return&amp;gt;(callback: Callback&amp;lt;Input, Return&amp;gt;) =&amp;gt; Result | Return

  // End is guaranteed to be the `Result`
  end: () =&amp;gt; Result
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now... now, we&apos;ve truly done it. Our &lt;code&gt;result&lt;/code&gt; will be typed correctly when we use &lt;code&gt;kase()&lt;/code&gt;. If you&apos;ve been following along, this is what your code should look like at this time:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type Callback&amp;lt;Input, Return&amp;gt; = (input: Input) =&amp;gt; Return

type Predicate&amp;lt;Input&amp;gt; = (input: Input) =&amp;gt; boolean

type Pattern&amp;lt;Input&amp;gt; = Predicate&amp;lt;Input&amp;gt; | Input

type API&amp;lt;Input, Result&amp;gt; = {
  when: &amp;lt;Return&amp;gt;(
    pattern: Pattern&amp;lt;Input&amp;gt;,
    callback: Callback&amp;lt;Input, Return&amp;gt;,
  ) =&amp;gt; API&amp;lt;Input, Result | Return&amp;gt;

  otherwise: &amp;lt;Return&amp;gt;(callback: Callback&amp;lt;Input, Return&amp;gt;) =&amp;gt; Result | Return

  end: () =&amp;gt; Result
}

function isPredicate&amp;lt;Input&amp;gt;(
  pattern: Pattern&amp;lt;Input&amp;gt;,
): pattern is Predicate&amp;lt;Input&amp;gt; {
  return typeof pattern === &apos;function&apos;
}

function kase&amp;lt;Input&amp;gt;(input: Input) {
  return kaseFactory&amp;lt;Input, undefined&amp;gt;(input, false, undefined)
}

function kaseFactory&amp;lt;Input, Result&amp;gt;(
  input: Input,
  isMatched: boolean,
  result: Result,
) {
  const api = {} as API&amp;lt;Input, Result&amp;gt;

  function when&amp;lt;Return&amp;gt;(
    pattern: Pattern&amp;lt;Input&amp;gt;,
    callback: Callback&amp;lt;Input, Return&amp;gt;,
  ) {
    if (isMatched) return api

    const predicate = isPredicate&amp;lt;Input&amp;gt;(pattern)
      ? () =&amp;gt; pattern(input)
      : () =&amp;gt; pattern === input

    if (predicate()) {
      const result = callback(input)

      return kaseFactory&amp;lt;Input, typeof result&amp;gt;(input, true, result)
    }

    return api
  }

  function otherwise&amp;lt;Return&amp;gt;(callback: Callback&amp;lt;Input, Return&amp;gt;) {
    if (isMatched) return result

    return callback(input)
  }

  function end() {
    return result
  }

  api.when = when
  api.otherwise = otherwise
  api.end = end

  return api
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Let&apos;s take a moment&lt;/h3&gt;
&lt;p&gt;Can we just take a moment to appreciate just how challenging this was?&lt;/p&gt;
&lt;p&gt;It required wiring three different generics through our types, which frankly, I could have made a &lt;em&gt;whole&lt;/em&gt; lot harder to read. &amp;lt;Marker content=&quot;Like so many types I read that only use &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;U&amp;lt;/code&amp;gt;, etc.&quot; /&amp;gt;&lt;/p&gt;
&lt;p&gt;It required a type predicate in order to properly narrow our &lt;code&gt;pattern&lt;/code&gt;. Admittedly, a type predicate is not difficult to use, but does require knowing about this uncommon feature.&lt;/p&gt;
&lt;p&gt;Finally, it required &lt;strong&gt;adding an entire layer of indirection&lt;/strong&gt; in order to be able to type our end &lt;code&gt;result&lt;/code&gt; correctly! How many people are going to think about adding &quot;yet another function&quot; to solve this problem? &amp;lt;Marker content={&lt;code&gt;I&apos;m not going to lie, I frequently say, &quot;You can solve any problem with enough wrapping functions.&quot; I&apos;ve also been known to say the CSS equivalent, &quot;You can solve any layout problem with enough wrapping &amp;lt;code&amp;gt;div&amp;lt;/code&amp;gt;s.&quot;&lt;/code&gt;} /&amp;gt; Maybe a bunch of you, but I&apos;d bet just as many give up entirely. I almost did. &amp;lt;Marker content=&quot;And there ain&apos;t no shame in it!&quot; /&amp;gt;&lt;/p&gt;
&lt;h3&gt;Wrap up&lt;/h3&gt;
&lt;p&gt;Programming &lt;em&gt;is&lt;/em&gt; communication. The inherent difficulty of all communication, programming, linguistic, or otherwise, is that we can only communicate what we are capable of expressing. &amp;lt;Marker content=&quot;There&apos;s also the whole issue of the receiver of the communication, but I&apos;m going to ignore that at the moment.&quot; /&amp;gt;&lt;/p&gt;
&lt;p&gt;When it comes to programming in TypeScript, at least for me, the effort to express functionality and the effort to express the types for that functionality can be &lt;em&gt;wildly&lt;/em&gt; different. This example I shared took ~5 minutes to write the functionality and &lt;em&gt;several days and attempts&lt;/em&gt; for me to get the types right. That&apos;s... not awesome.&lt;/p&gt;
&lt;p&gt;I hope it&apos;s clear, I&apos;m &lt;em&gt;not&lt;/em&gt; arguing we should stop using TypeScript. But I am arguing that we should be mature enough to acknowledge how challenging it can be to write type safe code sometimes. That sometimes we give up having some &quot;good things&quot; for the sake of avoiding many &quot;bad things&quot;.&lt;/p&gt;
&lt;p&gt;Also, we should probably just add pattern matching on types like OCaml to TypeScript already. &amp;lt;Marker content=&quot;🙃&quot; /&amp;gt;&lt;/p&gt;
</content:encoded><category>React</category><category>JavaScript</category><category>TypeScript</category></item><item><title>Quit Your YAP-ing</title><link>https://kyleshevlin.com/quit-your-yapping/</link><guid isPermaLink="true">https://kyleshevlin.com/quit-your-yapping/</guid><description>Learn when adding yet another prop to a React component becomes a problem and how to fix it with composition.</description><pubDate>Mon, 14 Aug 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import { Button } from &apos;../../../components/Button&apos;
import { Card1, Card2, CardWithChildren, CardWithSlotsExample } from &apos;./_Cards&apos;&lt;/p&gt;
&lt;p&gt;A couple years back, I came up with what I hope is a clever name to a common problem I see in React components, but I never took the time to write about it. I call it YAP (Yet Another Prop) Syndrome, and once you recognize it, you&apos;ll see it every where.&lt;/p&gt;
&lt;p&gt;YAP occurs when we add props to a component that would be better handled by composition. Simple definition, but I&apos;ll be the first to admit that it&apos;s challenging to develop the intuition to recognize this, but I&apos;ll do my best to give you a few examples.&lt;/p&gt;
&lt;p&gt;Most components require &lt;em&gt;some&lt;/em&gt; props in order to work, this is simply how functions work. Most accept inputs to be used in the output. YAP occurs when we add &lt;em&gt;excessive&lt;/em&gt; props that could be handled better by making a new composition. This is often the result of requirements changing as time goes by without giving alternative solutions much thought.&lt;/p&gt;
&lt;p&gt;Let&apos;s consider a simple &lt;code&gt;Card&lt;/code&gt; component with a button in the &lt;code&gt;Card&lt;/code&gt;&apos;s footer.&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-8 flex justify-center&quot;&amp;gt;
&amp;lt;Card1 client:load /&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;Now, it&apos;s completely possible that the first time you&apos;re given this design, you bake the &lt;code&gt;button&lt;/code&gt; in because there&apos;s only going to be one. A simplistic approach might look like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type CardProps = {
  action?: {
    onClick: () =&amp;gt; void
    text: string
  }
  body?: string
  title?: string
}

/**
 * All the code samples in this post are rudimentary and omit styles. I trust
 * you can figure out what markup you would need to get the result you want.
 */
function Card({ action, body, title }: CardProps) {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;div&amp;gt;
        {title &amp;amp;&amp;amp; &amp;lt;h4&amp;gt;{title}&amp;lt;/h4&amp;gt;}
        {body &amp;amp;&amp;amp; &amp;lt;div&amp;gt;{body}&amp;lt;/div&amp;gt;}
      &amp;lt;/div&amp;gt;

      {action &amp;amp;&amp;amp; (
        &amp;lt;div&amp;gt;
          &amp;lt;button onClick={action.onClick} type=&quot;button&quot;&amp;gt;
            {action.text}
          &amp;lt;/button&amp;gt;
        &amp;lt;/div&amp;gt;
      )}
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is probably fine.&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-8 flex justify-center&quot;&amp;gt;
&amp;lt;Gif
alt=&quot;Cartoon dog sits at a table sipping coffee while the entire room is on fire and filling with smoke, calmly saying, &apos;This is fine.&apos;&quot;
gifSrc=&quot;/images/this-is-fine-fire.gif&quot;
staticSrc=&quot;/images/this-is-fine-fire.jpg&quot;
/&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;That is until a few months go by, and someone decides that maybe a card can have two buttons, a left and a right one. Something like this:&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-8 flex justify-center&quot;&amp;gt;
&amp;lt;Card2 /&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;Now, a really bad approach would be &lt;code&gt;left&lt;/code&gt; and &lt;code&gt;right&lt;/code&gt; props, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type Action = {
  onClick: () =&amp;gt; void
  text: string
}

/**
 * Bonus tip: I prefer to write keys with adjectives
 * in noun-adjective order. That way, all the like keys
 * are grouped together when I sort them alphabetically
 */
type CardProps = {
  actionLeft?: Action
  actionRight?: Action
  body?: string
  title?: string
}

function Card({ actionLeft, actionRight, body, title }: CardProps) {
  const hasAction = actionLeft || actionRight

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;div&amp;gt;
        {title &amp;amp;&amp;amp; &amp;lt;h4&amp;gt;{title}&amp;lt;/h4&amp;gt;}
        {body &amp;amp;&amp;amp; &amp;lt;div&amp;gt;{body}&amp;lt;/div&amp;gt;}
      &amp;lt;/div&amp;gt;

      {hasAction &amp;amp;&amp;amp; (
        &amp;lt;div style={{ display: &apos;flex&apos;, gap: &apos;1rem&apos; }}&amp;gt;
          {actionLeft &amp;amp;&amp;amp; &amp;lt;CardAction action={actionLeft} /&amp;gt;}
          {actionRight &amp;amp;&amp;amp; &amp;lt;CardAction action={actionRight} /&amp;gt;}
        &amp;lt;/div&amp;gt;
      )}
    &amp;lt;/div&amp;gt;
  )
}

function CardAction({ action }: { action: Action }) {
  return (
    &amp;lt;button
      onClick={action.onClick}
      type=&quot;button&quot;
      style={{
        flex: &apos;1 1 auto&apos;,
      }}
    &amp;gt;
      {action.text}
    &amp;lt;/button&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&quot;But Kyle, why is this bad? It works, doesn&apos;t it?&quot;&lt;/p&gt;
&lt;p&gt;Sort of. It sort of works.&lt;/p&gt;
&lt;p&gt;You see, we&apos;ve started YAP-ing. We&apos;re adding &quot;yet another prop&quot; to adjust our component, but once we start down this path, there&apos;s no good way to stop going further.&lt;/p&gt;
&lt;p&gt;Which prop should we map a single action to? &lt;code&gt;actionLeft&lt;/code&gt;? &lt;code&gt;actionRight&lt;/code&gt;? I don&apos;t know, and neither will the other people using &lt;code&gt;Card&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;What happens if the designer requests a third button? Do we add an &lt;code&gt;actionMiddle&lt;/code&gt; prop? What happens if the user provides &lt;code&gt;actionMiddle&lt;/code&gt; and &lt;code&gt;actionRight&lt;/code&gt; but no &lt;code&gt;actionLeft&lt;/code&gt;? Does &lt;code&gt;actionMiddle&lt;/code&gt; &lt;em&gt;become&lt;/em&gt; an &lt;code&gt;actionLeft&lt;/code&gt;, or should there be an empty space to the left?&lt;/p&gt;
&lt;p&gt;What happens if they ask for only a single button, but it should only span half the width of the &lt;code&gt;Card&lt;/code&gt;&apos;s footer? Which prop is that now? If we have three different action slots, how do we do &lt;em&gt;half&lt;/em&gt; of the width of the card?&lt;/p&gt;
&lt;p&gt;As I&apos;ve already said, the better solution is composition. Give the consumer (the one using the component in their code) the ability to create &lt;em&gt;any&lt;/em&gt; composition they need. 1 button, 2 buttons, 3 buttons, no buttons. It doesn&apos;t matter.&lt;/p&gt;
&lt;p&gt;We can take a few approaches to this. Let&apos;s explore them.&lt;/p&gt;
&lt;h3&gt;Using &lt;code&gt;children&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;First, we could use &lt;code&gt;children&lt;/code&gt; and let the consumer make whatever they need there.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Card({ body, children, title }) {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;div&amp;gt;
        {title &amp;amp;&amp;amp; &amp;lt;h4&amp;gt;{title}&amp;lt;/h4&amp;gt;}
        {body &amp;amp;&amp;amp; &amp;lt;div&amp;gt;{body}&amp;lt;/div&amp;gt;}
      &amp;lt;/div&amp;gt;

      {children &amp;amp;&amp;amp; &amp;lt;div&amp;gt;{children}&amp;lt;/div&amp;gt;}
    &amp;lt;/div&amp;gt;
  )
}

function ExampleWithChildren() {
  return (
    &amp;lt;Card body=&quot;Here is an example body text.&quot; title=&quot;Example Title&quot;&amp;gt;
      &amp;lt;Flex justify=&quot;space-between&quot;&amp;gt;
        &amp;lt;button onClick={() =&amp;gt; {}} type=&quot;button&quot;&amp;gt;
          Click me
        &amp;lt;/button&amp;gt;

        &amp;lt;button onClick={() =&amp;gt; {}} type=&quot;button&quot;&amp;gt;
          Click me, too
        &amp;lt;/button&amp;gt;
      &amp;lt;/Flex&amp;gt;
    &amp;lt;/Card&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-8 flex justify-center&quot;&amp;gt;
&amp;lt;CardWithChildren
client:load
body=&quot;Here is an example body text.&quot;
title=&quot;Example Title&quot;&lt;/p&gt;
&lt;blockquote&gt;&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;div style={{ minWidth: &apos;30ch&apos; }}&amp;gt;
  &amp;lt;div class=&quot;flex justify-between&quot;&amp;gt;
    &amp;lt;Button onClick={() =&amp;gt; {}}&amp;gt;Click Me&amp;lt;/Button&amp;gt;
    &amp;lt;Button onClick={() =&amp;gt; {}}&amp;gt;Click Me, too&amp;lt;/Button&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;/CardWithChildren&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;This approach works well. We&apos;re able to control the layout of the buttons however we would like. We can layout any number of buttons or no buttons at all. We can even add other elements we might need: text, images, etc.&lt;/p&gt;
&lt;p&gt;The downside of this approach is &lt;code&gt;children&lt;/code&gt; feels a touch odd when there are other elements rendered from props. It&apos;s unclear where this will render without looking at the implementation of the component. We can maybe make this a little bit clearer with &quot;slots&quot;.&lt;/p&gt;
&lt;h3&gt;Using slots&lt;/h3&gt;
&lt;p&gt;Slots is not a common term in React, but they&apos;ve been there since the beginning. You&apos;ll more commonly hear the word &quot;slots&quot; in regards to other frameworks such as Vue and Astro, but in React, it&apos;s simply a prop that accepts a JSX element and renders it in a location in the component.&lt;/p&gt;
&lt;p&gt;Let&apos;s say we&apos;re asked to make it possible for &lt;code&gt;Card&lt;/code&gt; to have some content above and below the main body of content. We can&apos;t use &lt;code&gt;children&lt;/code&gt; without giving the consumer a way of rendering the body. We could do this with compound components, but let&apos;s focus on a different approach. We&apos;re going to name two props: &lt;code&gt;header&lt;/code&gt; and &lt;code&gt;footer&lt;/code&gt;, and if the consumer passes in something to that prop, it&apos;ll get rendered in the appropriate slot. Like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Card({ body, footer, header, title }) {
  return (
    &amp;lt;div&amp;gt;
      {header &amp;amp;&amp;amp; &amp;lt;div&amp;gt;{header}&amp;lt;/div&amp;gt;}

      &amp;lt;div&amp;gt;
        {title &amp;amp;&amp;amp; &amp;lt;h4&amp;gt;{title}&amp;lt;/h4&amp;gt;}
        {body &amp;amp;&amp;amp; &amp;lt;div&amp;gt;{body}&amp;lt;/div&amp;gt;}
      &amp;lt;/div&amp;gt;

      {footer &amp;amp;&amp;amp; &amp;lt;div&amp;gt;{footer}&amp;lt;/div&amp;gt;}
    &amp;lt;/div&amp;gt;
  )
}

function ExampleWithSlots() {
  const header = &amp;lt;Flex justify=&quot;center&quot;&amp;gt;EXAMPLE&amp;lt;/Flex&amp;gt;

  const footer = (
    &amp;lt;Flex justify=&quot;space-between&quot;&amp;gt;
      &amp;lt;button onClick={() =&amp;gt; {}} type=&quot;button&quot;&amp;gt;
        Click me
      &amp;lt;/button&amp;gt;

      &amp;lt;button onClick={() =&amp;gt; {}} type=&quot;button&quot;&amp;gt;
        Click me, too
      &amp;lt;/button&amp;gt;
    &amp;lt;/Flex&amp;gt;
  )

  return (
    &amp;lt;Card
      body=&quot;Here is an example body text.&quot;
      header={header}
      footer={footer}
      title=&quot;Example Title&quot;
    /&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-8 flex justify-center&quot;&amp;gt;
&amp;lt;CardWithSlotsExample client:load /&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;It&apos;s tempting to handle conditional React code with yet another prop, but it&apos;s often a bad solution and makes our code more complex than necessary. Make sure you&apos;re not adding excessive props in a situation that could be better handled with composition.&lt;/p&gt;
&lt;p&gt;If you determine composition is a better answer, you have several options at your disposal. You might even be able to combine &lt;a href=&quot;/compound-components&quot;&gt;compound components&lt;/a&gt; and composition to help you quit your YAP-ing.&lt;/p&gt;
&lt;p&gt;Good luck and let me know if you need any help with this.&lt;/p&gt;
</content:encoded><category>React</category></item><item><title>Compound Components</title><link>https://kyleshevlin.com/compound-components/</link><guid isPermaLink="true">https://kyleshevlin.com/compound-components/</guid><description>Ever been given a requirement to keep all the existing functionality of a component working, but allow for arbitrarily different layouts? Here&apos;s how to handle that.</description><pubDate>Sat, 27 May 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import { Custom1 } from &apos;./_Custom1&apos;
import { Custom2 } from &apos;./_Custom2&apos;
import { Custom3 } from &apos;./_Custom3&apos;
import { Tabs } from &apos;./_Tabs&apos;
import { ITEMS } from &apos;./_shared&apos;&lt;/p&gt;
&lt;p&gt;Compound components are nothing new in React, but it&apos;s an advanced pattern that not everyone takes the time to learn. I want to break down how I build compound components, and make it easy for you to do the same.&lt;/p&gt;
&lt;p&gt;For a working example, we&apos;re going to build a &lt;code&gt;Tabs&lt;/code&gt; component.&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-8&quot;&amp;gt;
&amp;lt;Tabs client:only=&quot;react&quot; items={ITEMS} /&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;The code for that might look something like this: &amp;lt;Marker content=&quot;Styling details omitted.&quot; /&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Tabs({ items = [] }) {
  const [selectedValue, setSelectedValue] = React.useState(items.at(0)?.value)

  // There are plenty of better ways to do this
  // I&apos;m keeping it simple for the example
  const [selectedItem] = items.filter(item =&amp;gt; item.value === selectedValue)

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;div&amp;gt;
        {items.map(item =&amp;gt; (
          &amp;lt;button
            key={item.value}
            onClick={() =&amp;gt; {
              setSelectedValue(item.value)
            }}
          &amp;gt;
            {item.value}
          &amp;lt;/button&amp;gt;
        ))}
      &amp;lt;/div&amp;gt;

      {selectedItem &amp;amp;&amp;amp; &amp;lt;div&amp;gt;{selectedItem.content}&amp;lt;/div&amp;gt;}
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, to transform this into a compound component, we&apos;re going to start by creating a &lt;code&gt;TabsContext&lt;/code&gt;, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const TabsContext = React.createContext()

const useTabsContext = () =&amp;gt; React.useContext(TabsContext)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Our &lt;code&gt;useTabsContext&lt;/code&gt; hook will only make sense if we add a &lt;code&gt;TabsContext.Provider&lt;/code&gt; somewhere. For compound components, I like to create a &lt;code&gt;Root&lt;/code&gt; component that renders this &lt;code&gt;Provider&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Tabs.Root = function TabsRoot({ children }) {
  return (
    &amp;lt;TabsContext.Provider value={undefined}&amp;gt;{children}&amp;lt;/TabsContext.Provider&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The job of the &lt;code&gt;Root&lt;/code&gt; component is to receive all of the props that &lt;code&gt;Tabs&lt;/code&gt; would accept and utilize the context&apos;s &lt;code&gt;value&lt;/code&gt; to distribute them to the compound components we will create. For now, we&apos;re passing &lt;code&gt;undefined&lt;/code&gt; because we haven&apos;t determined all that we need to store in the context just yet.&lt;/p&gt;
&lt;p&gt;I would also like to point out that we attach &lt;code&gt;Root&lt;/code&gt; as a property of the &lt;code&gt;Tabs&lt;/code&gt; component. I do this primarily as a convenience. We could export a &lt;code&gt;TabsRoot&lt;/code&gt; component, but I find it easier to import the main component, and then use the properties (the other sub-components) to create whatever composition I need.&lt;/p&gt;
&lt;p&gt;We can add our &lt;code&gt;Tabs.Root&lt;/code&gt; component to what will be our default &lt;code&gt;Tabs&lt;/code&gt; composition without disrupting any functionality, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;return (
  &amp;lt;Tabs.Root&amp;gt;
    &amp;lt;div&amp;gt;
      &amp;lt;div&amp;gt;
        {items.map(item =&amp;gt; (
          &amp;lt;button
            key={item.value}
            onClick={() =&amp;gt; {
              setSelectedValue(item.value)
            }}
          &amp;gt;
            {item.value}
          &amp;lt;/button&amp;gt;
        ))}
      &amp;lt;/div&amp;gt;

      {selectedItem &amp;amp;&amp;amp; &amp;lt;div&amp;gt;{selectedItem.content}&amp;lt;/div&amp;gt;}
    &amp;lt;/div&amp;gt;
  &amp;lt;/Tabs.Root&amp;gt;
)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now that we have our &lt;code&gt;Tabs.Root&lt;/code&gt; in place and can make use of the &lt;code&gt;TabsContext&lt;/code&gt;, what state do we need to manage with the it?&lt;/p&gt;
&lt;p&gt;We need to be able to get the &lt;code&gt;selectedValue&lt;/code&gt; and set it from anywhere within &lt;code&gt;Tabs.Root&lt;/code&gt; using the &lt;code&gt;useTabsContext&lt;/code&gt; hook. Let&apos;s start by duplicating the state in &lt;code&gt;Tabs.Root&lt;/code&gt; to pass to the &lt;code&gt;Provider&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Notice we&apos;ve added an `initialValue` prop
Tabs.Root = function TabsRoot({ children, initialValue }) {
  const [selectedValue, setSelectedValue] = React.useState(initialValue)

  return (
    &amp;lt;TabsContext.Provider value={{ selectedValue, setSelectedValue }}&amp;gt;
      {children}
    &amp;lt;/TabsContext.Provider&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And then in &lt;code&gt;Tabs&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// we&apos;ll need an initialValue, we can default it to the first item if it exists
const initialValue = items[0]?.value

return (
  &amp;lt;Tabs.Root initialValue={initialValue}&amp;gt;
    &amp;lt;div&amp;gt;{/* the rest... */}&amp;lt;/div&amp;gt;
  &amp;lt;/Tabs.Root&amp;gt;
)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, we&apos;re at a place where we can start to migrate some of the sub-components of &lt;code&gt;Tabs&lt;/code&gt; into compound components. Let&apos;s start with the &lt;code&gt;Tabs.Trigger&lt;/code&gt;, the button we use to select a tab:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Tabs.Trigger = function TabsTrigger({ children, value }) {
  const { setSelectedValue } = useTabsContext()

  return &amp;lt;button onClick={() =&amp;gt; setSelectedValue(value)}&amp;gt;{children}&amp;lt;/button&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice we pass a &lt;code&gt;value&lt;/code&gt; to the &lt;code&gt;Tabs.Trigger&lt;/code&gt;. This is what we use to update the &lt;code&gt;selectedValue&lt;/code&gt; state in our Context. Clicking the &lt;code&gt;Tabs.Trigger&lt;/code&gt; updates the state of the &lt;code&gt;TabsContext&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;We can do something similar with the &lt;code&gt;Tabs.Content&lt;/code&gt; component:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Tabs.Content = function TabsContent({ children, value }) {
  const { selectedValue } = useTabsContext()

  if (value !== selectedValue) return null

  return &amp;lt;div&amp;gt;{children}&amp;lt;/div&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice with &lt;code&gt;Tabs.Content&lt;/code&gt; that we control whether it renders or not thru the context. This is fundamentally different than before where we essentially filtered our list of &lt;code&gt;items&lt;/code&gt;. Now, we will map over all the &lt;code&gt;items&lt;/code&gt; and let &lt;code&gt;Tabs.Content&lt;/code&gt; determine whether it should return some UI or &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;With our sub-components built, we can update &lt;code&gt;Tabs&lt;/code&gt; to use them. Pay attention to how we have to map over &lt;code&gt;items&lt;/code&gt; twice, once for the &lt;code&gt;Trigger&lt;/code&gt; components and another time for the &lt;code&gt;Content&lt;/code&gt; components.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Tabs({ items = [] }) {
  const initialValue = items[0]?.value

  return (
    &amp;lt;Tabs.Root initialValue={initialValue}&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;div&amp;gt;
          {items.map(({ value }) =&amp;gt; (
            &amp;lt;Tabs.Trigger key={value} value={value}&amp;gt;
              {value}
            &amp;lt;/Tabs.Trigger&amp;gt;
          ))}
        &amp;lt;/div&amp;gt;

        {items.map(({ content, value }) =&amp;gt; (
          &amp;lt;Tabs.Content key={value} value={value}&amp;gt;
            {content}
          &amp;lt;/Tabs.Content&amp;gt;
        ))}
      &amp;lt;/div&amp;gt;
    &amp;lt;/Tabs.Root&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, we did all that work and component hasn&apos;t changed. Still looks and works great. But don&apos;t be fooled. Just because the functionality hasn&apos;t changed at all, doesn&apos;t mean making it slightly more complicated wasn&apos;t worth it. What we&apos;ve actually done is separate the functionality of the &lt;code&gt;Tabs&lt;/code&gt; from whatever user interface we decide to create with it. We can move the &lt;code&gt;Trigger&lt;/code&gt;s anywhere we want in relation to the &lt;code&gt;Content&lt;/code&gt; and as long as we pass in the correct &lt;code&gt;value&lt;/code&gt;, it will continue to work flawlessly.&lt;/p&gt;
&lt;p&gt;For example, perhaps the &lt;code&gt;Tab.Trigger&lt;/code&gt;s should go on the bottom:&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-8&quot;&amp;gt;
&amp;lt;Custom1 client:only=&quot;react&quot; /&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function TabsBottom({ items = [] }) {
  return (
    &amp;lt;Tabs.Root initialValue={items[0]?.value}&amp;gt;
      &amp;lt;div&amp;gt;
        {items.map(({ content, value }) =&amp;gt; (
          &amp;lt;Tabs.Content key={value} value={value}&amp;gt;
            {content}
          &amp;lt;/Tabs.Content&amp;gt;
        ))}
      &amp;lt;/div&amp;gt;

      &amp;lt;Flex&amp;gt;
        {items.map(({ value }) =&amp;gt; (
          &amp;lt;Tabs.Trigger key={value} value={value}&amp;gt;
            {value}
          &amp;lt;/Tabs.Trigger&amp;gt;
        ))}
      &amp;lt;/Flex&amp;gt;
    &amp;lt;/Tabs.Root&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or perhaps on the side:&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-8&quot;&amp;gt;
&amp;lt;Custom2 client:only=&quot;react&quot; /&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function TabsSide({ items = [] }) {
  return (
    &amp;lt;Tabs.Root initialValue={items[0]?.value}&amp;gt;
      &amp;lt;Flex&amp;gt;
        &amp;lt;Flex direction=&quot;column&quot;&amp;gt;
          {items.map(({ value }) =&amp;gt; (
            &amp;lt;Tabs.Trigger key={value} value={value}&amp;gt;
              {value}
            &amp;lt;/Tabs.Trigger&amp;gt;
          ))}
        &amp;lt;/Flex&amp;gt;

        &amp;lt;FlexItem grow={1}&amp;gt;
          {items.map(({ content, value }) =&amp;gt; (
            &amp;lt;Tabs.Content key={value} value={value}&amp;gt;
              {content}
            &amp;lt;/Tabs.Content&amp;gt;
          ))}
        &amp;lt;/FlexItem&amp;gt;
      &amp;lt;/Flex&amp;gt;
    &amp;lt;/Tabs.Root&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or perhaps we should have &lt;strong&gt;all&lt;/strong&gt; the &lt;code&gt;Tab.Trigger&lt;/code&gt;s you can think of:&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-8&quot;&amp;gt;
&amp;lt;Custom3 client:only=&quot;react&quot; /&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;Now, we&apos;re able to create any composition for &lt;code&gt;Tabs&lt;/code&gt; that we might need, while still having a great default composition for normal usage. Need icons in the &lt;code&gt;Trigger&lt;/code&gt;s? No problem. Need different colors for each &lt;code&gt;Content&lt;/code&gt;? No problem. There is almost no limit to what you can do with this pattern.&lt;/p&gt;
&lt;p&gt;Hope this helps you understand compound components a little better, and that you gain some benefit from adopting it in your projects. Let me know if it does!&lt;/p&gt;
</content:encoded><category>React</category></item><item><title>Context, Composition, and Flexibility</title><link>https://kyleshevlin.com/context-composition-and-flexibility/</link><guid isPermaLink="true">https://kyleshevlin.com/context-composition-and-flexibility/</guid><description>Using React Context and component composition, we can achieve both flexibility and different functionality</description><pubDate>Tue, 02 May 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import { Example1, Example2, Example3 } from &apos;./_Examples&apos;&lt;/p&gt;
&lt;p&gt;Recently, I had the following situation at work. It has been adapted to be &lt;strong&gt;less&lt;/strong&gt; professional and &lt;strong&gt;more&lt;/strong&gt; humorous:&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;Designer&lt;/strong&gt;: Hey, you know our &lt;code&gt;Input&lt;/code&gt; component?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Me&lt;/strong&gt;: Yeah, this one?&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-8&quot;&amp;gt;
&amp;lt;Example1 client:only=&quot;react&quot; /&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Designer&lt;/strong&gt;: Yeah, that&apos;s the one! Look, I want you to make it so that when the &lt;code&gt;Input&lt;/code&gt; is optional, it shows a little bit of helper text to the right of label that says &lt;code&gt;&quot;(optional)&quot;&lt;/code&gt;. Like this:&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-8&quot;&amp;gt;
&amp;lt;Example2 client:only=&quot;react&quot; /&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Me&lt;/strong&gt;: Oh, you wouldn&apos;t prefer to show an asterisk when it&apos;s &lt;em&gt;required&lt;/em&gt; like almost every other website in existence? Like this:&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-8&quot;&amp;gt;
&amp;lt;Example3 client:only=&quot;react&quot; /&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Designer&lt;/strong&gt;: Well, most of our &lt;code&gt;Input&lt;/code&gt;s should be required so we felt that this would be less noisy. Don&apos;t want to see &lt;code&gt;*&lt;/code&gt;s everywhere.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Me&lt;/strong&gt;: But every &lt;code&gt;Input&lt;/code&gt; in all our apps, and all the web actually, is optional &lt;strong&gt;by default&lt;/strong&gt;. You have to set the &lt;code&gt;required&lt;/code&gt; attribute explicitly. Meaning the more likely scenario is seeing &lt;code&gt;&quot;(optional)&quot;&lt;/code&gt; everywhere.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Designer&lt;/strong&gt;: Yeah... I don&apos;t care. Just do it.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Now, if you&apos;ve done software engineering for any significant amount of time, you&apos;ve probably run into a scenario just like this one. It sucks to be told to do something that you know isn&apos;t the right solution.&lt;/p&gt;
&lt;p&gt;That said, in this particular scenario, there&apos;s a pretty easy way for both of us to win and I&apos;m hoping it will give you some more strategies when you&apos;re in a similar situation again in the future. Let me show you how.&lt;/p&gt;
&lt;h3&gt;First instincts vs. second thoughts&lt;/h3&gt;
&lt;p&gt;Given the nature of the change, it would be really tempting to solve it as simply as possible, perhaps like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Input({ id, label, required = false }) {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;label htmlFor={id}&amp;gt;
        {label}
        {!required &amp;amp;&amp;amp; &apos; (optional)&apos;}
      &amp;lt;/label&amp;gt;
      &amp;lt;input id={id} required={required} /&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This definitely solves the problem, but we know that this isn&apos;t a great solution. It&apos;s likely to get push back from other teams who want something they&apos;re more accustomed to, like an &lt;code&gt;*&lt;/code&gt; on required fields.&lt;/p&gt;
&lt;p&gt;We might be tempted to change it so that &lt;code&gt;Input&lt;/code&gt; receives a &lt;code&gt;variant&lt;/code&gt; that determines how to handle this, perhaps like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Input({ id, label, required = false, variant = &apos;showOptionals&apos; }) {
  const getHelperText = () =&amp;gt; {
    if (variant === &apos;showOptionals&apos; &amp;amp;&amp;amp; !required) return &apos; (optional)&apos;
    if (variant === &apos;showRequireds&apos; &amp;amp;&amp;amp; required) return &apos;*&apos;

    return null
  }

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;label htmlFor={id}&amp;gt;
        {label}
        {getHelperText()}
      &amp;lt;/label&amp;gt;
      &amp;lt;input id={id} required={required} /&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, if a team wants to show a more traditional &lt;code&gt;*&lt;/code&gt; on their required inputs, they can add the &lt;code&gt;variant=&quot;showRequired&quot;&lt;/code&gt; prop. &lt;strong&gt;However&lt;/strong&gt;, this would mean needing to add that to &lt;em&gt;every single &lt;code&gt;Input&lt;/code&gt; that needs that treatment&lt;/em&gt;. That&apos;s laborious, exhausting and tedious.&lt;/p&gt;
&lt;p&gt;What if there was a way to apply a &lt;code&gt;variant&lt;/code&gt; to every input, but only have to write it once?&lt;/p&gt;
&lt;h3&gt;Context and composition to the rescue&lt;/h3&gt;
&lt;p&gt;Let&apos;s create an &lt;code&gt;InputStyleContext&lt;/code&gt; that will pass the &lt;code&gt;variant&lt;/code&gt; to all consumers automatically.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const InputStyleContext = React.createContext()

function InputStyleProvider({ children, variant = &apos;none&apos; }) {
  return (
    &amp;lt;InputStyleContext.Provider value={variant}&amp;gt;
      {children}
    &amp;lt;/InputStyleContext.Provider&amp;gt;
  )
}

const useInputStyleContext = () =&amp;gt; React.useContext(InputStyleContext)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now that we have that, let&apos;s use the custom hook we made to get the &lt;code&gt;variant&lt;/code&gt; off of context, rather than passed in as a prop to &lt;code&gt;Input&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Input({ id, label, required = false }) {
  const variant = useInputStyleContext()

  const getHelperText = () =&amp;gt; {
    if (variant === &apos;showOptionals&apos; &amp;amp;&amp;amp; !required) return &apos; (optional)&apos;
    if (variant === &apos;showRequireds&apos; &amp;amp;&amp;amp; required) return &apos;*&apos;

    return null
  }

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;label htmlFor={id}&amp;gt;
        {label}
        {getHelperText()}
      &amp;lt;/label&amp;gt;
      &amp;lt;input id={id} required={required} /&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we have the option to change the appearance of our &lt;code&gt;Input&lt;/code&gt;s with a single wrapping component. You want the &lt;code&gt;&quot;(optional)&quot;&lt;/code&gt; text, do this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;InputStyleProvider variant=&quot;showOptionals&quot;&amp;gt;
  &amp;lt;Input id=&quot;name&quot; label=&quot;Name&quot; /&amp;gt;
&amp;lt;/InputStyleProvider&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or if you want to show &lt;code&gt;*&lt;/code&gt; on required fields, change the &lt;code&gt;variant&lt;/code&gt; to &lt;code&gt;showRequireds&lt;/code&gt;. It&apos;s that simple.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;InputStyleProvider variant=&quot;showRequireds&quot;&amp;gt;
  &amp;lt;Input id=&quot;name&quot; label=&quot;Name&quot; required /&amp;gt;
&amp;lt;/InputStyleProvider&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we have a solution that has satiated our designer, but gives us some flexibility still. I think that&apos;s a win-win.&lt;/p&gt;
&lt;p&gt;Try to remember that context and composition might be a good solution for your problem, too.&lt;/p&gt;
&lt;h3&gt;And for the record...&lt;/h3&gt;
&lt;p&gt;The very first form I worked on after this change was, in fact, 5 &lt;code&gt;Input&lt;/code&gt;s, all optional, all with the &lt;code&gt;&quot;(optional)&quot;&lt;/code&gt; text next to them. So much for being less noisy! Oh well.&lt;/p&gt;
</content:encoded><category>React</category></item><item><title>Algorithms: Insertion Sort</title><link>https://kyleshevlin.com/algorithms-insertion-sort/</link><guid isPermaLink="true">https://kyleshevlin.com/algorithms-insertion-sort/</guid><description>Learn the insertion sort algorithm in JavaScript and why it is slightly better than bubble sort</description><pubDate>Sun, 22 Jan 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import { InsertionSortVisual } from &apos;./_InsertionSortVisual&apos;&lt;/p&gt;
&lt;p&gt;Let me start this post with a question. Is an array of a single item a sorted array?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Not a trick question&lt;/strong&gt;! It is, and we use this fact with insertion sort.&lt;/p&gt;
&lt;p&gt;In the previous post on &lt;a href=&quot;/algorithms-bubble-sort&quot;&gt;bubble sort&lt;/a&gt;, our algorithm spent a lot of time comparing items that were already sorted, especially near the end of the sort. That&apos;s really inefficient. How might we be able to avoid making these unnecessary comparisons?&lt;/p&gt;
&lt;p&gt;If we were able to track an array that we &lt;em&gt;knew&lt;/em&gt; to be sorted, we could stop looping past this array and instead &lt;em&gt;insert&lt;/em&gt; items, one by one, into their correct position. Doing so, would save us a few unnecessary comparisons.&lt;/p&gt;
&lt;p&gt;To accomplish this, we treat the first item in the array as a sorted list of a single item. Then, we compare the rest of the items to the items in this sorted list. When we find a spot for our item, we insert it into the sorted portion. By the time we finish looping through each item, our list will be sorted. No need for a final loop to verify nothing changed.&lt;/p&gt;
&lt;h3&gt;The details&lt;/h3&gt;
&lt;p&gt;The insertion sort algorithm goes like this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Treat the first item as a sorted&lt;/li&gt;
&lt;li&gt;Thus, starting from the 2nd item in the array, loop through each item&lt;/li&gt;
&lt;li&gt;For each item:
&lt;ul&gt;
&lt;li&gt;Loop through the sorted portion of our array&lt;/li&gt;
&lt;li&gt;Compare each item in the sorted portion to the item in the outer loop&lt;/li&gt;
&lt;li&gt;If the outer item is less than the inner item
&lt;ul&gt;
&lt;li&gt;Remove the outer item from its current position&lt;/li&gt;
&lt;li&gt;Splice it into the inner position&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;function insertionSort(items) {
  let i
  let j

  /**
   * Loop from the start of the unsorted portion of our array
   * aka the second item
   */
  for (i = 1; i &amp;lt; items.length; i++) {
    /**
     * Loop thru the sorted portion of our array
     * aka from the first item to our outer item
     */
    for (j = 0; j &amp;lt; i; j++) {
      /**
       * Compare the item at `i` with `j`
       */
      if (items[i] &amp;lt; items[j]) {
        /**
         * We can remove the item at `i` out and destructure it
         */
        const [item] = items.splice(i, 1)

        /**
         * And splice the item back in at `j`
         */
        items.splice(j, 0, item)
      }
    }
  }

  return items
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can see it in action here:&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-8&quot;&amp;gt;
&amp;lt;InsertionSortVisual client:load /&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;Take notice that while we still do a lot of comparisons, we do quite a bit fewer than we did with bubble sort. In running the component above a few times in testing, I noticed it was about 1/2 as many as the bubble sort on average. That&apos;s a pretty good improvement. But we can still do better, and we&apos;ll learn how soon.&lt;/p&gt;
&lt;h3&gt;For egghead subscribers&lt;/h3&gt;
&lt;p&gt;If you enjoy learning from video content and have an egghead account, you can watch this lesson in the embed below or at &lt;a href=&quot;https://egghead.io/lessons/javascript-sort-an-array-with-a-nested-for-loop-using-insertion-sort-in-javascript&quot;&gt;https://egghead.io/lessons/javascript-sort-an-array-with-a-nested-for-loop-using-insertion-sort-in-javascript&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-8&quot;&amp;gt;
&amp;lt;EggheadEmbed
src=&quot;https://egghead.io/lessons/javascript-sort-an-array-with-a-nested-for-loop-using-insertion-sort-in-javascript/embed&quot;
title=&quot;Insertion Sort&quot;
/&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
</content:encoded><category>Data Structures and Algorithms</category></item><item><title>Algorithms: Bubble Sort</title><link>https://kyleshevlin.com/algorithms-bubble-sort/</link><guid isPermaLink="true">https://kyleshevlin.com/algorithms-bubble-sort/</guid><description>Learn the bubble sort algorithm in JavaScript, and why it is such a bad way to sort items</description><pubDate>Wed, 18 Jan 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import { BubbleSortVisual } from &apos;./_BubbleSortVisual&apos;&lt;/p&gt;
&lt;h3&gt;Preface&lt;/h3&gt;
&lt;p&gt;I&apos;ve had the itch recently to write articles for all the algorithms and data structures I covered in my original &lt;a href=&quot;https://egghead.io/courses/data-structures-and-algorithms-in-javascript&quot;&gt;Data Structures &amp;amp; Algorithms course&lt;/a&gt; and maybe a few others. &amp;lt;Marker content=&quot;Who knows? Maybe start working on another course.&quot; /&amp;gt; There&apos;s just something that tickles the pleasure centers of my brain to learn a new algorithm or review an old one. They might not always be useful in a practical sense, &amp;lt;Marker content=&quot;You will literally never use bubble sort at work, except as a joke.&quot; /&amp;gt; but I think practicing data structures &amp;amp; algorithms can help your brain improve its abilities to model problems well, and well-modeled problems are easier to solve.&lt;/p&gt;
&lt;p&gt;I also wanted to play around with visualizing the algorithms with some React components, so double the fun for me, and hopefully for you, too.&lt;/p&gt;
&lt;h3&gt;A few words on algorithms, in general&lt;/h3&gt;
&lt;p&gt;Algorithms get an undeservedly bad rap these days because the word has been appropriated to describe the manipulations of social media companies to show us more ads. Let&apos;s not allow that negative connotation to stop us from learning them.&lt;/p&gt;
&lt;p&gt;An algorithm is simply a set of instructions to perform a task, to get a desired outcome. A recipe is an algorithm. How you tie your shoes is an algorithm. The way you brush your teeth, an algorithm. Algorithms are everywhere and unavoidable.&lt;/p&gt;
&lt;p&gt;When we examine algorithms and enjoy the intricacies that make one slightly better than another, they might teach us a thing or two. Perhaps about the world around us, perhaps about ourselves.&lt;/p&gt;
&lt;p&gt;So don&apos;t let &quot;algorithm&quot; be a scary word for you just because of the media or the fact that it ends in a strange combination of consonants. Embrace them.&lt;/p&gt;
&lt;h3&gt;The bubble sort algorithm&lt;/h3&gt;
&lt;p&gt;We&apos;re going to start by learning the &quot;bubble sort&quot; algorithm. Its typically the first sorting algorithm people learn because it&apos;s a naive approach that&apos;s remarkably similar to how one might &lt;em&gt;actually&lt;/em&gt; sort a collection of items in real life. The algorithm, goes like this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Given a list of items, begin looping through the them one at a time&lt;/li&gt;
&lt;li&gt;For each item, compare it to the next item in the array
&lt;ul&gt;
&lt;li&gt;If they are out of order, swap them in place and track that a swap occurred&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;When the loop is complete:
&lt;ul&gt;
&lt;li&gt;If any swaps occurred, repeat the previous steps&lt;/li&gt;
&lt;li&gt;else, the array is sorted&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Simple, right? But simple, can be &lt;em&gt;extremely&lt;/em&gt; inefficient! The bubble sort algorithm has a Big O of &lt;code&gt;O(n^2)&lt;/code&gt;, otherwise known as &lt;a href=&quot;https://en.wikipedia.org/wiki/Time_complexity&quot;&gt;quadratic time&lt;/a&gt;. It&apos;s not the absolute worst score you can get for an algorithm, but it&apos;s pretty darn bad!&lt;/p&gt;
&lt;p&gt;For those unfamiliar with Big O notation, let me break it down for this particular case quickly. &amp;lt;Marker content=&quot;I know better than to promise a separate blog post on a topic, but this is by no means an exhaustive explanation of Big O.&quot; /&amp;gt; Big O is how computer scientists describe the &lt;strong&gt;worst case performance&lt;/strong&gt; of an algorithm. In the case of bubble sort, &lt;code&gt;n&lt;/code&gt; represents the number of items we are sorting. Our algorithm requires that we loop through every item in the list. If we only had to do that, our Big O would be &lt;code&gt;O(n)&lt;/code&gt;, indicating that as &lt;code&gt;n&lt;/code&gt; increases, the time it takes to sort them grows at the same rate.&lt;/p&gt;
&lt;p&gt;However, in bubble sort, inside of our first loop we have an inner loop that compares each item with &lt;em&gt;every other item&lt;/em&gt;. This results in doing &lt;code&gt;n * n&lt;/code&gt; operations, or &lt;code&gt;n^2&lt;/code&gt;. Think about this for a moment. This means that as &lt;code&gt;n&lt;/code&gt; increases, the time to sort them &lt;em&gt;quadratically&lt;/em&gt; increases. For example, if we have to sort 5x more items than a previous &lt;code&gt;n&lt;/code&gt;, it will perform 25x worse!&lt;/p&gt;
&lt;h3&gt;Coding it up&lt;/h3&gt;
&lt;p&gt;Let&apos;s write the code for this algorithm piece by piece. Now, it might seem odd, but I think it might be a bit easier to write if consider what we would have to do if we were given a &lt;strong&gt;perfectly sorted list&lt;/strong&gt;. How would we know that the list is sorted?&lt;/p&gt;
&lt;p&gt;In the case of bubble sort, we know a list is sorted when a loop through its items is completed without swapping any of them. Thus, even for a perfectly sorted array, we still have to make &lt;em&gt;at least&lt;/em&gt; one loop all the items. If we have to do something at least once, but conditionally after that first loop, does that conjure up a particularly rare looping mechanism for you?&lt;/p&gt;
&lt;p&gt;I hope you came up with the &lt;code&gt;do..while&lt;/code&gt; loop.&lt;/p&gt;
&lt;p&gt;So &lt;em&gt;rarely&lt;/em&gt; do we get to use this looping mechanism but it&apos;s quite useful for the right situation. We want to &lt;code&gt;do&lt;/code&gt; at least one loop through the array, and continue looping through it &lt;code&gt;while&lt;/code&gt; there were swaps in the previous loop. Let&apos;s write that code.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function bubbleSort(items) {
  let swapped = false

  do {
    // Gotta reset `swapped` with every outer loop
    swapped = false

    // TODO: Our inner loop will go here
  } while (swapped)

  return items
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, let&apos;s add our inner loop. We need to take each &lt;code&gt;item&lt;/code&gt; and check if it should swap with the &lt;code&gt;nextItem&lt;/code&gt;. We&apos;ll need the &lt;code&gt;index&lt;/code&gt; of our item to get the next item and to do swaps, and I like to do that with a combo of &lt;code&gt;for..of&lt;/code&gt; and &lt;code&gt;Array.prototype.entries()&lt;/code&gt;, like so: &amp;lt;Marker content=&quot;For this algorithm, because there is no need to &amp;lt;code&amp;gt;break&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;continue&amp;lt;/code&amp;gt;, you could also use &amp;lt;code&amp;gt;Array.prototype.forEach&amp;lt;/code&amp;gt; with a callback that made use of both the &amp;lt;code&amp;gt;item&amp;lt;/code&amp;gt; and the &amp;lt;code&amp;gt;index&amp;lt;/code&amp;gt; instead.&quot; /&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function bubbleSort(items) {
  let swapped = false

  do {
    swapped = false

    for (const [idx, item] of items.entries()) {
      const nextItem = items[idx + 1]

      if (item &amp;gt; nextItem) {
        items[idx] = nextItem
        items[idx + 1] = item
        swapped = true
      }
    }
  } while (swapped)

  return items
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can see how the algorithm works with a visual. This visual sorts 50 lines from shortest to tallest. It has two additional features not found in the code block above: it highlights the &lt;code&gt;item&lt;/code&gt; currently being sorted, and it tracks the number of comparisons made by the algorithm. You can run the visual several times to see how close it gets to that &lt;code&gt;n^2&lt;/code&gt; performance number. &amp;lt;Marker content=&quot;If you have the time. Each run will take a little over a minute because this algorithm is so inefficient.&quot; /&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-8&quot;&amp;gt;
&amp;lt;BubbleSortVisual client:load /&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;You can see that sorting items with bubble sort is agonizingly slow. We will discuss much faster and more efficient sorting algorithms, but it&apos;s useful to learn bubble sort all the same. Knowing poor performing algorithms can help us identify inefficient ones in our programs and guide us towards better solutions.&lt;/p&gt;
&lt;h3&gt;For egghead subscribers&lt;/h3&gt;
&lt;p&gt;If you enjoy learning from video content and have an egghead account, you can watch this lesson in the embed below or at &lt;a href=&quot;https://egghead.io/lessons/javascript-sort-an-array-with-a-javascript-do-while-loop-using-bubble-sort&quot;&gt;https://egghead.io/lessons/javascript-sort-an-array-with-a-javascript-do-while-loop-using-bubble-sort&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-8&quot;&amp;gt;
&amp;lt;EggheadEmbed
src=&quot;https://egghead.io/lessons/javascript-sort-an-array-with-a-javascript-do-while-loop-using-bubble-sort/embed&quot;
title=&quot;Bubble Sort&quot;
/&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
</content:encoded><category>Data Structures and Algorithms</category></item><item><title>JSX was a Mistake</title><link>https://kyleshevlin.com/jsx-was-a-mistake/</link><guid isPermaLink="true">https://kyleshevlin.com/jsx-was-a-mistake/</guid><description>JSX makes writing UIs feel really familiar for frontend devs, but it can obfuscate a key detail of which we should remain aware.</description><pubDate>Mon, 07 Nov 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import { Box, ChildrenExample, NoChildrenExample } from &apos;./_Examples&apos;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;It wasn&apos;t&lt;/strong&gt;. I just wanted your attention. Thanks.&lt;/p&gt;
&lt;p&gt;And now while I have it, I do want to discuss a bit of common confusion caused by JSX.&lt;/p&gt;
&lt;p&gt;One of the most common misunderstandings I run into with people regarding React is this: If a component has a state change and rerenders, it &lt;em&gt;does not&lt;/em&gt; cause &lt;code&gt;children&lt;/code&gt; to rerender. I think this is very obvious when we &lt;em&gt;remove&lt;/em&gt; JSX, and use &lt;code&gt;React.createElement&lt;/code&gt; instead. Let&apos;s have a look.&lt;/p&gt;
&lt;p&gt;Here we have one of my favorite components to demonstrate rerenders, a &lt;code&gt;Box&lt;/code&gt; that changes background color whenever it&apos;s rendered. This &lt;code&gt;Box&lt;/code&gt; allows us to pass &lt;code&gt;children&lt;/code&gt; through it. Thus, we&apos;ll make an &lt;code&gt;Example&lt;/code&gt; where we force an update, which will cause &lt;code&gt;Box&lt;/code&gt; to rerender.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { useForceUpdate } from &apos;./hooks&apos;
import { randomRGB } from &apos;./utils&apos;

function Box({ children }) {
  return (
    &amp;lt;div style={{ backgroundColor: randomRGB(), padding: &apos;1rem&apos; }}&amp;gt;
      {children}
    &amp;lt;/div&amp;gt;
  )
}

function Example() {
  const forceUpdate = useForceUpdate()

  return (
    &amp;lt;Box&amp;gt;
      &amp;lt;button type=&quot;button&quot; onClick={forceUpdate}&amp;gt;
        Update
      &amp;lt;/button&amp;gt;
    &amp;lt;/Box&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;div className=&quot;my-8&quot;&amp;gt;
&amp;lt;OffsetWrap&amp;gt;
&amp;lt;NoChildrenExample client:load /&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;As you can see, clicking &quot;Update&quot; causes the &lt;code&gt;Box&lt;/code&gt; to change colors. &amp;lt;Marker content=&quot;If you are visually impaired, I added a &amp;lt;code&amp;gt;data-background-color&amp;lt;/code&amp;gt; attribute to the &amp;lt;code&amp;gt;div&amp;lt;/code&amp;gt; that changes with it. I wasn&apos;t sure what else I could do, so I hope that helps. Please let me know if there&apos;s more I can do and I&apos;ll make an update.&quot; /&amp;gt; This is because &lt;code&gt;Box&lt;/code&gt; is a &lt;em&gt;function&lt;/em&gt; that gets called when &lt;code&gt;Example&lt;/code&gt; is called. This is obvious when instead of JSX, we use &lt;code&gt;React.createElement&lt;/code&gt; instead.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Box({ children }) {
  return React.createElement(&apos;div&apos;, {
    style: { backgroundColor: randomRGB(), padding: &apos;1rem&apos; },
    children,
  })
}

function Example() {
  const forceUpdate = useForceUpdate()

  return React.createElement(
    Box,
    null,
    React.createElement(&apos;button&apos;, { type: &apos;button&apos;, onClick: forceUpdate }),
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice that this time, we replaced &lt;code&gt;&amp;lt;div /&amp;gt;&lt;/code&gt; with &lt;code&gt;React.createElement(&apos;div&apos;)&lt;/code&gt;. Then when we needed to render the &lt;code&gt;Box&lt;/code&gt; in &lt;code&gt;Example&lt;/code&gt;, we pass it to another call of &lt;code&gt;React.createElement&lt;/code&gt;. Thus, each time &lt;code&gt;Example&lt;/code&gt; rerenders, we call a function to render a &lt;code&gt;Box&lt;/code&gt; and a function to render a &lt;code&gt;button&lt;/code&gt;. Makes it pretty clear where functions are getting called.&lt;/p&gt;
&lt;h3&gt;How does this relate to &lt;code&gt;children&lt;/code&gt;?&lt;/h3&gt;
&lt;p&gt;Well, simply put, &lt;code&gt;children&lt;/code&gt; is typically not a function call, it&apos;s just a value. &amp;lt;Marker content={&lt;code&gt;Yes, you can pass a function as &amp;lt;code&amp;gt;children&amp;lt;/code&amp;gt; like the &quot;render prop&quot; pattern and that would be treated differently&lt;/code&gt;} /&amp;gt;&lt;/p&gt;
&lt;p&gt;What if I add a &quot;slot&quot; for &lt;code&gt;children&lt;/code&gt; in our &lt;code&gt;Example&lt;/code&gt; component like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Example({ children }) {
  const forceUpdate = useForceUpdate()

  return React.createElement(
    Box,
    null,
    // createElement&apos;s third parameter is a rest parameter,
    // so we can add more items by adding more arguments
    React.createElement(&apos;button&apos;, { type: &apos;button&apos;, onClick: forceUpdate }),
    // here&apos;s the slot, it&apos;ll come after our button
    children,
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, what happens if we pass &lt;code&gt;Box&lt;/code&gt; as &lt;code&gt;children&lt;/code&gt; of our &lt;code&gt;Example&lt;/code&gt;?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;Example&amp;gt;
  &amp;lt;Box&amp;gt;I am a child&amp;lt;/Box&amp;gt;
&amp;lt;Example&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;div className=&quot;my-8&quot;&amp;gt;
&amp;lt;OffsetWrap&amp;gt;
&amp;lt;ChildrenExample client:load&amp;gt;
&amp;lt;Box client:load&amp;gt;I am a child&amp;lt;/Box&amp;gt;
&amp;lt;/ChildrenExample&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;Notice that our child &lt;code&gt;Box&lt;/code&gt; doesn&apos;t rerender, while the parent &lt;code&gt;Box&lt;/code&gt; still does. It remains the same background color it was when it initially rendered, because it&apos;s not getting called again when &lt;code&gt;Example&lt;/code&gt; rerenders.&lt;/p&gt;
&lt;p&gt;Heck, let&apos;s have some fun and put &lt;code&gt;Example&lt;/code&gt; into &lt;code&gt;Example&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&amp;lt;div className=&quot;my-8&quot;&amp;gt;
&amp;lt;OffsetWrap&amp;gt;
&amp;lt;ChildrenExample client:load&amp;gt;
&amp;lt;NoChildrenExample client:load /&amp;gt;
&amp;lt;/ChildrenExample&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;Kind of fun, isn&apos;t it?&lt;/p&gt;
&lt;h3&gt;When does this matter?&lt;/h3&gt;
&lt;p&gt;In most cases, I wouldn&apos;t fret about rerendering a &lt;code&gt;Box&lt;/code&gt; or whatever component you might be working with, but it&apos;s just good knowledge to have. You&apos;ll be better off having this concept etched into your brain than not.&lt;/p&gt;
&lt;p&gt;The place I&apos;m most concerned about getting this right is the use of Context Providers. I wrote a very similar blog post &lt;a href=&quot;/careful-with-context-composition&quot;&gt;all about that&lt;/a&gt;. Check it out if you&apos;re interested.&lt;/p&gt;
&lt;p&gt;In general, if you have a component with frequent state changes and it uses &lt;code&gt;children&lt;/code&gt;, consider letting as much of the inner contents be composed via &lt;code&gt;children&lt;/code&gt; as possible to avoid unnecessary rendering.&lt;/p&gt;
&lt;p&gt;You never know, you might just find your component is now a bit more reusable, too.&lt;/p&gt;
</content:encoded><category>React</category></item><item><title>Capture Phase Event Handling in React</title><link>https://kyleshevlin.com/capture-phase-event-handling-in-react/</link><guid isPermaLink="true">https://kyleshevlin.com/capture-phase-event-handling-in-react/</guid><description>Did you know you can declaratively handle events in the capture phase in React? I sure didn&apos;t until recently. Let&apos;s learn how.</description><pubDate>Sat, 18 Jun 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import Breakfast from &apos;./_Breakfast&apos;
import EventButton from &apos;./_EventButton&apos;&lt;/p&gt;
&lt;p&gt;So... as of the time I&apos;m writing this, I&apos;ve used React for 7 years and &lt;strong&gt;today&lt;/strong&gt; (February 22, 2022) I learned something completely unbeknownst to me. &amp;lt;Marker content=&quot;Yes, it took me 4 months to get back to this and write the last few paragraphs, lol.&quot; /&amp;gt; &lt;strong&gt;You can append&lt;/strong&gt; &lt;code&gt;Capture&lt;/code&gt; &lt;strong&gt;to an event name to have it handled in the &quot;capture&quot; phase of event delegation, instead of the &quot;bubbling&quot; phase&lt;/strong&gt;. Who knew?! It&apos;s &lt;a href=&quot;https://reactjs.org/docs/events.html#supported-events&quot;&gt;right here in the docs&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So what is this and why is it useful? Let&apos;s explore.&lt;/p&gt;
&lt;h3&gt;What is event capturing and bubbling?&lt;/h3&gt;
&lt;p&gt;In short, because there are a million other articles on the topic, event capturing and bubbling describe how events traverse the DOM. Look at the following markup:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    Event capturing and bubbling
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;div&amp;gt;
      &amp;lt;button&amp;gt;Click me&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When you click the &lt;code&gt;button&lt;/code&gt;, the &quot;capture&quot; phase begins. It starts at the top of the DOM, and traverses down the tree through each element. When it reaches the target, the &lt;code&gt;button&lt;/code&gt;, it begins the &quot;bubbling&quot; phase and traverses back up to the top of the DOM tree. We can imagine that loop like this:&lt;/p&gt;
&lt;p&gt;&amp;lt;TableSimple
headings={[&apos;Element&apos;, &apos;Event&apos;, &apos;Phase&apos;]}
items={[
[&apos;&amp;lt;code&amp;gt;html&amp;lt;/code&amp;gt;&apos;, &apos;&amp;lt;code&amp;gt;click&amp;lt;/code&amp;gt;&apos;, &apos;capture&apos;],
[&apos;&amp;lt;code&amp;gt;body&amp;lt;/code&amp;gt;&apos;, &apos;&amp;lt;code&amp;gt;click&amp;lt;/code&amp;gt;&apos;, &apos;capture&apos;],
[&apos;&amp;lt;code&amp;gt;div&amp;lt;/code&amp;gt;&apos;, &apos;&amp;lt;code&amp;gt;click&amp;lt;/code&amp;gt;&apos;, &apos;capture&apos;],
[&apos;&amp;lt;code&amp;gt;button&amp;lt;/code&amp;gt;&apos;, &apos;&amp;lt;code&amp;gt;click&amp;lt;/code&amp;gt;&apos;, &apos;capture&apos;],
[&apos;&amp;lt;code&amp;gt;button&amp;lt;/code&amp;gt;&apos;, &apos;&amp;lt;code&amp;gt;click&amp;lt;/code&amp;gt;&apos;, &apos;bubble&apos;],
[&apos;&amp;lt;code&amp;gt;div&amp;lt;/code&amp;gt;&apos;, &apos;&amp;lt;code&amp;gt;click&amp;lt;/code&amp;gt;&apos;, &apos;bubble&apos;],
[&apos;&amp;lt;code&amp;gt;body&amp;lt;/code&amp;gt;&apos;, &apos;&amp;lt;code&amp;gt;click&amp;lt;/code&amp;gt;&apos;, &apos;bubble&apos;],
[&apos;&amp;lt;code&amp;gt;html&amp;lt;/code&amp;gt;&apos;, &apos;&amp;lt;code&amp;gt;click&amp;lt;/code&amp;gt;&apos;, &apos;bubble&apos;],
]}
/&amp;gt;&lt;/p&gt;
&lt;p&gt;We can see this by writing just a few lines of code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Wildcard selector
const allElements = document.querySelectorAll(&apos;*&apos;)

function logNodeName() {
  // I know, I hate using `this` too
  console.log(this.nodeName)
}

for (const el of allElements) {
  // This one will be used in the capture phase
  el.addEventListener(&apos;click&apos;, logNodeName, true)
  // This one will be used in the bubbling phase
  el.addEventListener(&apos;click&apos;, logNodeName)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now I&apos;ve attached the &lt;code&gt;logNodeName&lt;/code&gt; function as a &lt;code&gt;click&lt;/code&gt; event handler to &lt;em&gt;every&lt;/em&gt; element on the &lt;code&gt;document&lt;/code&gt;. That means, clicking anywhere, should log out &lt;em&gt;all&lt;/em&gt; the elements touched in the &quot;bubbling&quot; phase. &lt;strong&gt;Note&lt;/strong&gt;: this does not remove any listeners, so it&apos;s possible to have memory leaks if you add or remove elements from the page between clicks. Try it out here:&lt;/p&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;EventButton client:load /&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;p&gt;You can see that it starts at the &lt;code&gt;html&lt;/code&gt; element and works its way down to the button and then works its way back up. Honestly, because I used the wildcard selector, &lt;code&gt;*&lt;/code&gt;, you can click &lt;em&gt;anywhere&lt;/em&gt; and see the output. Have fun.&lt;/p&gt;
&lt;h3&gt;Using the capture phase with React events&lt;/h3&gt;
&lt;p&gt;In most cases, React abstracts the process of attaching event handlers to elements. Rather than getting the element and writing &lt;code&gt;addEventListener&lt;/code&gt; and &lt;code&gt;removeEventListener&lt;/code&gt;, we use the associated element attribute for the given event we want to respond to, such as &lt;code&gt;onClick&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const button = document.getElementById(&apos;#btn&apos;)
button.addEventListener(&apos;click&apos;, () =&amp;gt; { console.log(&apos;clicked&apos;) })

// Vs.
&amp;lt;button onClick={() =&amp;gt; { console.log(&apos;clicked&apos;) }}&amp;gt;Click me&amp;lt;/button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;addEventListener&lt;/code&gt; and &lt;code&gt;removeEventListener&lt;/code&gt; receive an optional third argument of the type &lt;code&gt;boolean | Options&lt;/code&gt;. I will ignore the &lt;code&gt;Options&lt;/code&gt; object as you can &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener&quot;&gt;look that up here&lt;/a&gt; and instead focus on the &lt;code&gt;boolean&lt;/code&gt; that represents the &lt;code&gt;useCapture&lt;/code&gt; value.&lt;/p&gt;
&lt;p&gt;By passing &lt;code&gt;true&lt;/code&gt; into this third argument, we indicate that this event handler should be used in the capture phase. But, if we&apos;re using React&apos;s abstractions, we have no place to pass in a &lt;code&gt;useCapture&lt;/code&gt; argument. Do we?&lt;/p&gt;
&lt;p&gt;&lt;em&gt;We do.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;This is where appending &lt;code&gt;Capture&lt;/code&gt; to the event handler name comes in. If we want a click handler to be used in the capture phase, rather than the bubbling phase, we use &lt;code&gt;onClickCapture&lt;/code&gt; instead. Let&apos;s make an example.&lt;/p&gt;
&lt;p&gt;Let&apos;s say we have a group of buttons and every button should use the exact same event handler. Rather than attach the same handler to each button, we can attach it to the parent element in the capture phase. I&apos;m eating breakfast as I write this, so let&apos;s imagine a rudimentary menu for selecting a breakfast item.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const ITEMS = [&apos;Eggs&apos;, &apos;Bacon&apos;, &apos;Pancakes&apos;, &apos;Toast&apos;]

function Breakfast() {
  const [selected, setSelected] = React.useState(null)

  const selectItem = e =&amp;gt; {
    setSelected(e.target.value)
  }

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;div&amp;gt;Selected: {String(selected)}&amp;lt;/div&amp;gt;
      &amp;lt;div onClickCapture={selectItem}&amp;gt;
        {ITEMS.map(item =&amp;gt; (
          &amp;lt;button key={item} value={item}&amp;gt;
            {item}
          &amp;lt;/button&amp;gt;
        ))}
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;See it in action here:&lt;/p&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;Breakfast client:load /&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;p&gt;Now, before you judge the example too harshly for being rudimentary, let me be abundantly clear: &lt;strong&gt;This isn&apos;t the only way, or even the &lt;em&gt;recommended&lt;/em&gt; way, to accomplish this. It&apos;s just to teach the concept.&lt;/strong&gt; That said, I think it&apos;s kind of neat that we can do this &lt;em&gt;without&lt;/em&gt; &lt;code&gt;onClick&lt;/code&gt; handlers on each button.&lt;/p&gt;
&lt;h3&gt;Additional thoughts&lt;/h3&gt;
&lt;p&gt;This technique is a bit of a throwback. Back to a time where maybe you were using &lt;code&gt;&amp;lt;input type=&quot;button&quot;&amp;gt;&lt;/code&gt; or inlining an &lt;code&gt;onclick&lt;/code&gt; attribute on a parent. It&apos;s unlikely in React and other modern frontend frameworks that you&apos;ll ever have to use &lt;code&gt;*Capture&lt;/code&gt; events.&lt;/p&gt;
&lt;p&gt;However, that doesn&apos;t mean it&apos;s not worth throwing this into your repertoire! You never know when you might run into a situation where &lt;em&gt;this&lt;/em&gt; little tid bit is the simplest and most elegant way to solve the problem.&lt;/p&gt;
</content:encoded><category>React</category></item><item><title>Why Use &lt;code&gt;useReducer&lt;/code&gt;?</title><link>https://kyleshevlin.com/why-use-use-reducer/</link><guid isPermaLink="true">https://kyleshevlin.com/why-use-use-reducer/</guid><description>Do you know why you might use `useReducer` instead of `useState`? There are a few key questions you can ask yourself to make that decision.</description><pubDate>Mon, 06 Jun 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import SocialPost from &apos;../../../components/SocialPost.astro&apos;
import JumpingBall from &apos;./_JumpingBall&apos;
import ReducerJumpingBall from &apos;./_ReducerJumpingBall&apos;&lt;/p&gt;
&lt;p&gt;A while back now, my buddy &lt;a href=&quot;https://bsky.app/profile/mhartington.io&quot;&gt;Mike Hartington&lt;/a&gt;
asked this:&lt;/p&gt;
&lt;p&gt;&amp;lt;SocialPost
authorName=&quot;Mike Hartington&quot;
authorHandle=&quot;@mhartington.io&quot;
authorProfile=&quot;https://bsky.app/profile/mhartington.io&quot;
avatarUrl=&quot;https://cdn.bsky.app/img/avatar/plain/did:plc:7kwylbxx56yro6aqz3oh5d2s/bafkreih5czye4acyme3j5ckt4bmwkypwqyqcq4mgecjq55g2lavdy573n4@jpeg&quot;
date=&quot;2022-02-12&quot;
content={`Random question for my react friends...&lt;/p&gt;
&lt;p&gt;Is useReducer something folks use/like?`}
/&amp;gt;&lt;/p&gt;
&lt;p&gt;I gave a brief answer in the replies, but thought I&apos;d write a bit more about it here. If you&apos;ve come across my blog before, much of what I&apos;m going to write in this post will relate to other posts of mine, such as &lt;a href=&quot;/use-encapsulation&quot;&gt;&lt;code&gt;useEncapsulation&lt;/code&gt;&lt;/a&gt; and &lt;a href=&quot;/enumerate-dont-booleanate&quot;&gt;Enumerate, Don&apos;t Booleanate&lt;/a&gt; and more. There&apos;s a lot of overlap, so please check them out if you haven&apos;t. Forgive me if this all sounds familiar.&lt;/p&gt;
&lt;h3&gt;Two state primitives&lt;/h3&gt;
&lt;p&gt;React provides two state primitives, &lt;code&gt;useState&lt;/code&gt; and &lt;code&gt;useReducer&lt;/code&gt; for managing state for a component or custom hook. &lt;code&gt;useState&lt;/code&gt; is a hook that gives us a straightforward &lt;code&gt;[read, write]&lt;/code&gt; tuple. Like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const [count, setCount] = React.useState(0)

console.log(count) // &quot;read&quot; the value
setCount(count + 1) // &quot;write&quot; the next value
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The other primitive, &lt;code&gt;useReducer&lt;/code&gt; is a bit more complex. It gives us a &lt;code&gt;[read, emitEvent]&lt;/code&gt; tuple. Like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const reducer = (state, event) =&amp;gt; {
  switch (event) {
    case &apos;INCREMENT&apos;:
      return state + 1
    default:
      return state
  }
}

const [count, emitEvent] = React.useReducer(reducer, 0)

console.log(count) // &quot;read&quot; the value
emitEvent(&apos;INCREMENT&apos;) // emit the event
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, more often you&apos;ll see &lt;code&gt;emitEvent&lt;/code&gt; and &lt;code&gt;event&lt;/code&gt; named &lt;code&gt;dispatch&lt;/code&gt; and &lt;code&gt;action&lt;/code&gt; respectively. I, too, often do this. However, I wanted to make it clear that what we&apos;re doing when we use &lt;code&gt;useReducer&lt;/code&gt; is emitting and responding to events.&lt;/p&gt;
&lt;h3&gt;Choosing one over the other&lt;/h3&gt;
&lt;p&gt;In general, I treat &lt;code&gt;useState&lt;/code&gt; as the default tool for the state management job. In many situations, I have a single state to manage and writing a few &lt;a href=&quot;/prefer-declarative-state-updaters&quot;&gt;declarative state updaters&lt;/a&gt; for that state does the trick. That said, there are certain conditions that make &lt;code&gt;useReducer&lt;/code&gt; a better choice. Here are the things I consider when making the choice:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Does the next state frequently depend upon the current state?&lt;/li&gt;
&lt;li&gt;Is there more than one state to manage?&lt;/li&gt;
&lt;li&gt;More importantly, &lt;em&gt;are there situations where we change multiple states as a result of the same event&lt;/em&gt;?&lt;/li&gt;
&lt;li&gt;Are there times where the same user event is handled differently depending on the current state?&lt;/li&gt;
&lt;li&gt;Far less common, is there a use case where a consumer of the component may need to hook into and respond to events, aka the state reducer pattern?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you answered &quot;Yes&quot; to any of these questions, then you might have a good use case for using &lt;code&gt;useReducer&lt;/code&gt;. Let&apos;s work through an example to learn more.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Our example&lt;/h3&gt;
&lt;p&gt;Here I have a little jumping ball. Go ahead. Make it jump by clicking the button labeled &quot;Jump&quot;.&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-8&quot;&amp;gt;
&amp;lt;JumpingBall client:load /&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;Every time we click the button, the ball jumps. If we click it while the ball is already in the &quot;air&quot;, it has no effect on the ball, which continues to fall due to &quot;gravity&quot;. Try it. Click it as many times as you can while it&apos;s in the &quot;air&quot;.&lt;/p&gt;
&lt;p&gt;Nothing, right?&lt;/p&gt;
&lt;p&gt;Let&apos;s focus in on some key parts of the code that represent what happens when we click the &quot;Jump&quot; button&quot;. First, we need to establish some states. We&apos;re going to use a combination of &lt;code&gt;useState&lt;/code&gt; and &lt;code&gt;useRef&lt;/code&gt;. We&apos;re going to use &lt;code&gt;useState&lt;/code&gt; for states that we want the component to rerender when it changes, and refs for states that don&apos;t need to cause a rerender. I explain this more in depth in &lt;a href=&quot;/comparing-use-ref-and-use-state&quot;&gt;Comparing &lt;code&gt;useRef&lt;/code&gt; and &lt;code&gt;useState&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function JumpingBall() {
  // Y-position of the ball
  const [position, setPosition] = React.useState(0)
  // The amount of change the ball is experiencing for a given `tick`
  const delta = React.useRef(0)
  // The state of the ball, either &apos;idle&apos; or &apos;jumping&apos;
  const ballState = React.useRef(&apos;idle&apos;)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, we&apos;re going to implement a &lt;code&gt;tick&lt;/code&gt; function, which will attempt to update the ball&apos;s &lt;code&gt;position&lt;/code&gt; with every &quot;frame&quot; of our component. This is a rudimentary example of a game loop, if you&apos;re familiar with video game development.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const tick = React.useCallback(() =&amp;gt; {
  // If the ball is &apos;idle&apos;, then there is nothing to update
  if (ballState.current === &apos;idle&apos;) return

  // Otherwise, set the next position based on the current position
  setPosition(currentPosition =&amp;gt; {
    // Every tick subtracts a constant of GRAVITY from the delta change
    delta.current -= GRAVITY
    // The nextPosition is the current position + this change. Rounding is just
    // for making the ground check easier.
    const nextPosition = Math.floor(currentPosition + delta.current)

    // If the ball is on the ground (or below it), set the ball on the ground
    // and update its state
    if (nextPosition &amp;lt;= 0) {
      delta.current = 0
      ballState.current = &apos;idle&apos;
      return 0
    }

    // Otherwise, return the calculated next position
    return nextPosition
  })
}, [])
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, we need to handle our &quot;Jump&quot; button&apos;s click event.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const handleClick = React.useCallback(() =&amp;gt; {
  // This is why clicking multiple times does nothing, if its &apos;jumping&apos;
  // do nothing
  if (ballState.current === &apos;jumping&apos;) return

  // Otherwise, add the force of the jump to the delta
  delta.current += JUMP_IMPULSE
  // and change the ball state
  ballState.current = &apos;jumping&apos;
}, [])
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Lastly, we need to set up an effect to run our loop at ~60fps.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;React.useEffect(() =&amp;gt; {
  // Call `tick` roughly 60 times a second
  const id = setInterval(tick, 1000 / 60)

  // Clean it up if `tick` changes or we unmount the component
  return () =&amp;gt; clearInterval(id)
}, [tick])
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here is the component in its entirety now:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function JumpingBall() {
  const [position, setPosition] = React.useState(0)
  const delta = React.useRef(0)
  const ballState = React.useRef(&apos;idle&apos;)

  const tick = React.useCallback(() =&amp;gt; {
    if (ballState.current === &apos;idle&apos;) return

    setPosition(currentPosition =&amp;gt; {
      delta.current -= GRAVITY
      const nextPosition = Math.floor(currentPosition + delta.current)

      if (nextPosition &amp;lt;= 0) {
        delta.current = 0
        ballState.current = &apos;idle&apos;
        return 0
      }

      return nextPosition
    })
  }, [])

  const handleClick = React.useCallback(() =&amp;gt; {
    if (ballState.current === &apos;jumping&apos;) return

    delta.current += JUMP_IMPULSE
    ballState.current = &apos;jumping&apos;
  }, [])

  React.useEffect(() =&amp;gt; {
    const id = setInterval(tick, 1000 / 60)

    return () =&amp;gt; clearInterval(id)
  }, [tick])

  // ... and our UI is returned down here
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Sub-optimal elements of our code&lt;/h3&gt;
&lt;p&gt;Looking at this code, I see a few things that I think are sub-optimal, but very common in codebases, that we can improve.&lt;/p&gt;
&lt;p&gt;The primary issue I see is that we have code that manages the state in two different places, inside of &lt;code&gt;tick&lt;/code&gt; and &lt;code&gt;handleClick&lt;/code&gt;. In order to understand this code, we&apos;d have to read through both of these functions and understand how they relate to one another. Most worrisome to me is having state modifying functionality directly in the event handler. As silly as it sounds, I&apos;d prefer to see it separated into a state updater function called inside the event handler. Like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const tryJump = () =&amp;gt; {
  if (ballState.current === &apos;jumping&apos;) return

  delta.current += JUMP_IMPULSE
  ballState.current = &apos;jumping&apos;
}

const handleClick = () =&amp;gt; {
  tryJump()
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That way if anything else needs to be called with the event handler, such as logging, we don&apos;t need to make any changes to the state updating code as well.&lt;/p&gt;
&lt;p&gt;If we look deeper and consider the questions I prompted before, we recognize that we answer in the affirmative for several of them. Our state updates depend on the current state and we&apos;re updating multiple states at the same time. Let&apos;s refactor our code with a &lt;code&gt;useReducer&lt;/code&gt; pattern instead.&lt;/p&gt;
&lt;h3&gt;The refactor&lt;/h3&gt;
&lt;p&gt;First, let&apos;s gather our states into an &lt;code&gt;initialState&lt;/code&gt; object.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const initialState = {
  ballState: &apos;idle&apos;
  delta: 0,
  position: 0,
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, let&apos;s write our &lt;code&gt;reducer&lt;/code&gt;. I&apos;ll start with it essentially empty, and add our events one by one:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const reducer = (state, event) =&amp;gt; {
  switch (event) {
    default:
      return state
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&apos;s add the &lt;code&gt;CLICK&lt;/code&gt; event:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const reducer = (state, event) =&amp;gt; {
  switch (event) {
    case &apos;CLICK&apos;: {
      if (state.ballState === &apos;jumping&apos;) return state

      return {
        ...state,
        ballState: &apos;jumping&apos;
        delta: state.delta + JUMP_IMPULSE,
      }
    }

    default:
      return state;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now let&apos;s add our &lt;code&gt;TICK&lt;/code&gt; event:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const reducer = (state, event) =&amp;gt; {
  switch (event) {
    case &apos;CLICK&apos;: {
      if (state.ballState === &apos;jumping&apos;) return state

      return {
        ...state,
        ballState: &apos;jumping&apos;
        delta: state.delta + JUMP_IMPULSE,
      }
    }

    case &apos;TICK&apos;: {
      if (state.ballState === &apos;idle&apos;) return state

      const nextDelta = state.delta - GRAVITY
      const nextPosition = state.position + nextDelta

      if (nextPosition &amp;lt;= 0) {
        return initialState
      }

      return {
        ballState: &apos;jumping&apos;
        delta: nextDelta,
        position: nextPosition
      }
    }

    default:
      return state;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, let&apos;s use them in our component.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function JumpingBall() {
  const [state, dispatch] = React.useReducer(reducer, initialState)

  const tick = React.useCallback(() =&amp;gt; {
    dispatch(&apos;TICK&apos;)
  }, [])

  const handleClick = React.useCallback(() =&amp;gt; {
    dispatch(&apos;CLICK&apos;)
  }, [])

  React.useEffect(() =&amp;gt; {
    const id = setInterval(tick, 1000 / 60)

    return () =&amp;gt; clearInterval(id)
  }, [tick])
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice how much &lt;em&gt;simpler&lt;/em&gt; our event handlers are. Heck, we even discovered we had an event that probably wasn&apos;t obvious to us before, &lt;code&gt;TICK&lt;/code&gt;. Additionally, there&apos;s no logic in multiple functions we have to wrangle. It&apos;s all encapsulated within the &lt;code&gt;reducer&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Adding a &quot;double jump&quot; to our ball&lt;/h3&gt;
&lt;p&gt;A popular video game mechanic is to enable a &quot;double jump&quot;, that is, a second upward impulse while the player is jumping. For our case, we want the user to be able to click &quot;Jump&quot; a second time, while the ball is in the &quot;air&quot; and have it jump again. But &lt;em&gt;only&lt;/em&gt; one additional time.&lt;/p&gt;
&lt;p&gt;If we were still using &lt;code&gt;useState&lt;/code&gt;, we&apos;d have to find a way to add this logic inside of the event handler. You can maybe see where this is going. We&apos;d have to add another state to track, and an additional conditional inside of &lt;code&gt;handleClick&lt;/code&gt;. It wouldn&apos;t be a very organized way to add functionality.&lt;/p&gt;
&lt;p&gt;By using &lt;code&gt;useReducer&lt;/code&gt;, literally &lt;em&gt;nothing&lt;/em&gt; changes about &lt;code&gt;JumpingBall&lt;/code&gt;. The event handlers still dispatch the same events. The only thing that changes is our &lt;code&gt;reducer&lt;/code&gt;, so let&apos;s update it to handle a double jump.&lt;/p&gt;
&lt;p&gt;We&apos;re going to start by adding another state to track, &lt;code&gt;jumpsRemaining&lt;/code&gt;. This way it will be trivial to add a &quot;triple jump&quot; or more if we ever want to in the future. &amp;lt;Marker content=&quot;Can you tell I used to be a Hunter main in Destiny?&quot; /&amp;gt; Like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const initialState = {
  ballState: &apos;idle&apos;,
  delta: 0,
  jumpsRemaining: 2,
  position: 0,
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, we&apos;ll add a check for &lt;code&gt;jumpsRemaining&lt;/code&gt; to our &lt;code&gt;CLICK&lt;/code&gt; event:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const reducer = (state, event) =&amp;gt; {
  switch (event) {
    case &apos;CLICK&apos;: {
      if (state.jumpsRemaining === 0) {
        return state
      }

      return {
        ...state,
        ballState: &apos;jumping&apos;,
        delta: state.delta + JUMP_IMPULSE,
        jumpsRemaining: state.jumpsRemaining - 1,
      }
    }

    // ...
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Lastly, we need to update our &lt;code&gt;TICK&lt;/code&gt; event to update &lt;code&gt;jumpsRemaining&lt;/code&gt; when we hit the &quot;ground&quot;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Not a mistake, purposely empty
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Wait&lt;/strong&gt;! There&apos;s nothing to update. It&apos;s already handled by setting &lt;code&gt;state&lt;/code&gt; to &lt;code&gt;initialState&lt;/code&gt; when the ball hits the ground. Yet another benefit of using a reducer is that occasionally we can update multiple states in one fell swoop by resetting it to &lt;code&gt;initialState&lt;/code&gt; (or some other permutation of the state object).&lt;/p&gt;
&lt;p&gt;Now let&apos;s see how our ball &lt;em&gt;double&lt;/em&gt; jumps!&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-8&quot;&amp;gt;
&amp;lt;ReducerJumpingBall client:load /&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;If you time it right, you can send the ball flying off the canvas. Pretty cool how easy that change was to make.&lt;/p&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;useReducer&lt;/code&gt; may seem like overkill, but is an absolutely great tool in the right situation. It can drastically reduce the complexity of our event handlers, while also organizing our state managing code into a single place. Hope this post helps you in choosing which state primitive to use in the future.&lt;/p&gt;
&lt;p&gt;As always, you can find the full code for the &lt;code&gt;JumpingBall&lt;/code&gt; (with both state management patterns) by viewing the source code on Github. Look for the &lt;code&gt;why-use-use-reducer&lt;/code&gt; directory under published posts.&lt;/p&gt;
</content:encoded><category>React</category></item><item><title>Patterns for Functions with Conditionals</title><link>https://kyleshevlin.com/patterns-for-functions-with-conditionals/</link><guid isPermaLink="true">https://kyleshevlin.com/patterns-for-functions-with-conditionals/</guid><description>Let&apos;s explore two common function patterns for managing the complexity of conditional code.</description><pubDate>Tue, 24 May 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Recently, a &lt;a href=&quot;https://twitter.com/joelnet/status/1523710667424894977?s=20&amp;amp;t=51CDtjmt9M6z7GwvJtXvzA&quot;&gt;tweet about wrapping &lt;code&gt;for&lt;/code&gt; loops into functions&lt;/a&gt; &amp;lt;Marker content=&quot;And my consequent reply to it.&quot; /&amp;gt; inspired me to write a (hopefully) brief blog post on two common function patterns I use to handle conditional logic. Knowing how to write each pattern and knowing when to one or the other will help you wrangle complexity in your programs.&lt;/p&gt;
&lt;p&gt;In the past, I&apos;ve written about &lt;a href=&quot;/managing-cyclomatic-complexity&quot;&gt;complexity&lt;/a&gt; and managing it, and one of the ways I believe we can do this effectively is through patterns. Now, I don&apos;t think these patterns are revolutionary. They&apos;ve been around for a ages and I&apos;m not trying to take credit for them. That said, no one taught me these patterns in clear and succinct terms when I was learning to program either. My hope is to do that for you.&lt;/p&gt;
&lt;h3&gt;The “Single Mutable &lt;code&gt;result&lt;/code&gt;” pattern&lt;/h3&gt;
&lt;p&gt;The first pattern we&apos;re going to cover I call the &quot;single mutable result&quot; pattern. This function establishes a &lt;code&gt;result&lt;/code&gt; variable, conditionally mutates it, and returns it. The skeleton of it looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function singleMutatedResult() {
  let result // = some default value

  if (condition1) {
    // result = some transformation or replacement
  }

  if (condition2) {
    // result = some other transformation or replacement
  }

  return result
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This pattern is most useful when writing algorithmic code with conditions that transform the result. I think of them as &lt;em&gt;additive&lt;/em&gt; requirements, as in, &quot;If this condition exists, we make this &lt;em&gt;additional&lt;/em&gt; change&quot;. An example of this might be a function that calculates the total cost of an online purchase, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function getTotalCost(price, quantity, tax, shipping) {
  let result = price * quantity

  if (tax) {
    result = result + result * tax
  }

  if (shipping) {
    result = result + shipping
  }

  return result
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice that as we read the code, each condition leads to a transformation of the code, but we maintain the same &lt;code&gt;result&lt;/code&gt; variable the whole time. At any place in the algorithm, we can log out &lt;code&gt;result&lt;/code&gt; and get an idea of what we need to change to achieve the result we&apos;re looking for.&lt;/p&gt;
&lt;h3&gt;The “Early Exit” pattern&lt;/h3&gt;
&lt;p&gt;This is essentially the opposite of the &quot;single mutable result&quot; pattern, but is very useful for code that has &quot;short circuits&quot;. The &quot;early exit&quot; pattern uses guard clauses in order to return as soon as possible from the function. Here is the skeleton of this pattern:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function earlyExit(...args) {
  if (condition1) return result1
  if (condition2) return result2

  // Do the work to calculate our final result and return it
  return result3
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &quot;early exit&quot; pattern is great for conditional code that may involve missing information or restricted access, situations where we can bail out of the function before doing other calculations. A practical example might be deriving a user&apos;s name from a user object.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function getUserName(user) {
  if (!user) return null
  if (user.nickname) return user.nickname

  const [firstName] = user.fullName.split(&apos; &apos;)

  return firstName
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this example, if the &lt;code&gt;user&lt;/code&gt; doesn&apos;t exist, we can &quot;short circuit&quot; the function and exit early with a &lt;code&gt;null&lt;/code&gt; value. The next condition we can use to exit early is if the &lt;code&gt;user.nickname&lt;/code&gt; is set. Otherwise, we do the work of deriving the &lt;code&gt;firstName&lt;/code&gt; from the user. The &quot;early exit&quot; pattern is great for code where we never want to do more work than absolutely necessary to get the desired result.&lt;/p&gt;
&lt;p&gt;I think there are some characteristics of this pattern that are worth taking notice of. First, the guard clauses tend to be so succinct that I like to write them on a single line. Second, I have learned that some people struggle with code with early returns. Some languages don&apos;t allow/recommend it, so be gentle with people who struggle with this pattern. Teach them the benefits of avoiding unnecessary calculations and they&apos;ll come around.&lt;/p&gt;
&lt;h3&gt;What If...&lt;/h3&gt;
&lt;p&gt;Now, I want to be clear, both examples could be written with the other pattern, but they&apos;d be awkward. I&apos;m going to write them out, just to demonstrate. Let&apos;s get our total cost again, but with the &quot;early exit&quot; pattern.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function getTotalCost(price, quantity, tax, shipping) {
  const initialCost = price * quantity

  if (!tax &amp;amp;&amp;amp; !shipping) return initialCost
  if (tax &amp;amp;&amp;amp; !shipping) return initialCost + initialCost * tax
  if (!tax &amp;amp;&amp;amp; shipping) return initialCost + shipping

  // Logically this is tax &amp;amp;&amp;amp; shipping
  return initialCost + initialCost * tax + shipping
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Using the &quot;early exit&quot; pattern with this code had us repeating ourselves &lt;em&gt;over and over&lt;/em&gt;. We even had to add another conditional since we couldn&apos;t just skip the algorithmic step if it didn&apos;t apply.&lt;/p&gt;
&lt;p&gt;Now, let&apos;s use &quot;single mutable result&quot; with our user&apos;s name.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function getUserName(user) {
  let result = null

  if (user) {
    result = user.fullName.split(&apos; &apos;)[0]
  }

  if (user?.nickname) {
    result = user.nickname
  }

  return result
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Using the &quot;single mutable result&quot; pattern to get our user&apos;s name results in some very awkward transformations. Assuming we have a &lt;code&gt;user&lt;/code&gt;, we &lt;em&gt;always&lt;/em&gt; have to calculate the &lt;code&gt;firstName&lt;/code&gt; even if ultimately we don&apos;t use it. Why? Because the &lt;code&gt;nickname&lt;/code&gt; supersedes the &lt;code&gt;firstName&lt;/code&gt; and thus must overwrite the &lt;code&gt;result&lt;/code&gt; value last. We also have to use the &quot;optional chaining&quot; operator, &lt;code&gt;?.&lt;/code&gt;, because we &lt;em&gt;still&lt;/em&gt; can&apos;t be sure if we even have a &lt;code&gt;user&lt;/code&gt; by the time we hit that condition. Lastly, it can be difficult to reason that between the setting of &lt;code&gt;result&lt;/code&gt; to &lt;code&gt;null&lt;/code&gt; and all those transformations that if &lt;code&gt;result&lt;/code&gt; is &lt;em&gt;still&lt;/em&gt; &lt;code&gt;null&lt;/code&gt;, it means we have no &lt;code&gt;user&lt;/code&gt;. It&apos;s much clearer in the &quot;early exit&quot; example.&lt;/p&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;Writing conditional code can be challenging. Using the right pattern for the right reasons can make that challenge a lot easier. Get comfortable writing code with both patterns and you&apos;ll see an improvement in the quality of your code.&lt;/p&gt;
&lt;p&gt;Remember, the &quot;single mutable result&quot; is great for algorithmic code with transformational requirements. &quot;If this condition is true, transform &lt;code&gt;result&lt;/code&gt; to this new value&quot;. The &quot;early exit&quot; pattern is great for code with short circuits. &quot;If this condition is true, bail out with this value&quot;.&lt;/p&gt;
&lt;p&gt;Both are useful, and both have their place.&lt;/p&gt;
</content:encoded><category>JavaScript</category><category>Software Engineering</category><category>Refactoring</category></item><item><title>Updating State with a Component</title><link>https://kyleshevlin.com/updating-state-with-a-component/</link><guid isPermaLink="true">https://kyleshevlin.com/updating-state-with-a-component/</guid><description>Have you ever wanted to create a component like `Head` from `next/head` or `Helmet` from `react-helmet` that would update some state by using the `children` of a component? It&apos;s simpler than you might think.</description><pubDate>Thu, 05 May 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import Example from &apos;./_Example.astro&apos;&lt;/p&gt;
&lt;p&gt;Have you ever wanted to create a component like &lt;code&gt;Head&lt;/code&gt; from &lt;code&gt;next/head&lt;/code&gt; or &lt;code&gt;Helmet&lt;/code&gt; from &lt;code&gt;react-helmet&lt;/code&gt; that would update some state by using the &lt;code&gt;children&lt;/code&gt; of a component? It&apos;s simpler than you might think.&lt;/p&gt;
&lt;p&gt;A while back, I was working with a design that had an &lt;code&gt;h1&lt;/code&gt; heading in the middle of the &lt;code&gt;header&lt;/code&gt;. Like this:&lt;/p&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;Example /&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;p&gt;It&apos;s a bit of an odd design, but it&apos;s what they wanted. The challenge of the design is that the heading element has to live within the &lt;code&gt;&amp;lt;header&amp;gt;&lt;/code&gt; of the app, but the component code we&apos;ll be writing is for the area labeled &lt;code&gt;Page Content&lt;/code&gt;. There&apos;s a literal border (pun intended) between the content we&apos;re creating and the place we need to update the heading.&lt;/p&gt;
&lt;p&gt;Now, one way to solve this is to use a &lt;code&gt;Header&lt;/code&gt; component with a prop for the heading, or potentially with &lt;code&gt;children&lt;/code&gt; so you could compose &lt;code&gt;Header&lt;/code&gt; with the correct page title. Perhaps like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Header({ children }) {
  return (
    &amp;lt;header
      style={{
        display: &apos;flex&apos;,
        justifyContent: &apos;space-between&apos;,
        // In order to center the heading regardless of other items in the
        // header, we&apos;ll need to absolutely position it
        position: &apos;relative&apos;,
      }}
    &amp;gt;
      &amp;lt;Logo /&amp;gt;
      &amp;lt;h1
        style={{
          position: &apos;absolute&apos;,
          left: &apos;50%&apos;,
          transform: &apos;translateX(-50%)&apos;,
        }}
      &amp;gt;
        {children}
      &amp;lt;/h1&amp;gt;
      &amp;lt;Nav /&amp;gt;
    &amp;lt;/header&amp;gt;
  )
}

// Then used like so:
function SomePage({ children }) {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;Header&amp;gt;This page&apos;s title&amp;lt;/Header&amp;gt;
      &amp;lt;main&amp;gt;{children}&amp;lt;/main&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The downside of this approach is that we would have to use &lt;code&gt;Header&lt;/code&gt; in &lt;em&gt;every single page in the application&lt;/em&gt;. That&apos;s not ideal. It would be preferable to have &lt;code&gt;Header&lt;/code&gt; in a layout component higher up in the component hierarchy, used only a few times. It would be pretty easy to forget some important piece of the app layout on a page this way.&lt;/p&gt;
&lt;p&gt;While this might be the most common approach to solving the problem, there are alternatives. The next approach to try would be to use React Context and a custom hook. I cover this in my article &lt;a href=&quot;/how-to-use-react-context-effectively&quot;&gt;How to Use React Context Effectively&lt;/a&gt;, so check it out when you have a chance.&lt;/p&gt;
&lt;p&gt;In this approach, we&apos;d setup a context and export a hook we can use to update that context. Let&apos;s do that briefly, since it will be useful for the next part of this post as well:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Create the context
const HeadingContext = React.createContext()

// Create our provider
function HeadingProvider({ children }) {
  const [heading, setHeading] = React.useState(&apos;&apos;)

  return (
    &amp;lt;HeadingContext.Provider value={{ heading, setHeading }}&amp;gt;
      {children}
    &amp;lt;/HeadingContext.Provider&amp;gt;
  )
}

// Custom hook for consuming the context
const useHeadingContext = () =&amp;gt; React.useContext(HeadingContext)

// Hook specifically for updating the heading
// Name provides a little more context where it gets used
const useUpdateHeading = value =&amp;gt; {
  const { setHeading } = useHeadingContext()
  setHeading(value)
}

// Now our header consumes the `heading` value (let&apos;s assume that
// the `HeadingProvider` is higher in the tree)
function Header() {
  const { heading } = useHeadingContext()

  return (
    &amp;lt;header&amp;gt;
      &amp;lt;Logo /&amp;gt;
      &amp;lt;h1&amp;gt;{heading}&amp;lt;/h1&amp;gt;
      &amp;lt;Nav /&amp;gt;
    &amp;lt;/header&amp;gt;
  )
}

// And then we would update that heading like so
function SomePage({ children }) {
  useUpdateHeading(&quot;This page&apos;s title&quot;)

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;main&amp;gt;{children}&amp;lt;/main&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is reasonable. I certainly wouldn&apos;t stop anyone from doing this approach, but it feels off to me personally. I experience a bit of a disconnect here. This hook feels like an unrelated function, used arbitrarily and doesn&apos;t connect to the rest of the code in the component in a cohesive way. Admittedly, how I instinctively respond to some code is not a strong argument for anything, so as I said before, I wouldn&apos;t stop my team from doing this approach, but is there an alternative?&lt;/p&gt;
&lt;p&gt;There is. We can use that same context and a component to create a composable state updater. All we need to do is make use of &lt;code&gt;children&lt;/code&gt;. Here&apos;s one way of doing that. &amp;lt;Marker content=&quot;There are quite a few ways you could manipulate &amp;lt;code&amp;gt;children&amp;lt;/code&amp;gt; to suit your needs.&quot; /&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const ACCEPTABLE_TYPES = [&apos;string&apos;, &apos;number&apos;]

function Heading({ children }) {
  const { setHeading } = useHeadingContext()

  React.useEffect(() =&amp;gt; {
    if (ACCEPTABLE_TYPES.includes(typeof children)) {
      setHeading(children)
    }
  }, [children, setHeading])

  return null
}

// Now we can use that component _anywhere_ to update the heading
function SomePage({ children }) {
  return (
    &amp;lt;main&amp;gt;
      &amp;lt;Heading&amp;gt;This page&apos;s title&amp;lt;/Heading&amp;gt;
      {children}
    &amp;lt;/main&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, we use a &lt;a href=&quot;/renderless-components&quot;&gt;renderless component&lt;/a&gt; and an effect to keep the page title synced up. We&apos;ve also created a component that conveys some semantics to someone reading the code. In the case of the design, &lt;code&gt;Heading&lt;/code&gt; &lt;em&gt;really is&lt;/em&gt; the heading for the page, it&apos;s just at a distance to us in the DOM. Using this semantic component let&apos;s our code feel cohesive without negatively impacting the actual layout of the app.&lt;/p&gt;
&lt;p&gt;You can experiment with other ways to utilize &lt;code&gt;children&lt;/code&gt; to achieve this effect. Just be sure to sanitize &lt;code&gt;children&lt;/code&gt; in some way. You may want to look into the &lt;code&gt;React.Children&lt;/code&gt; API if you do. Otherwise, enjoy adding this little trick to your coding repertoire.&lt;/p&gt;
</content:encoded><category>React</category><category>JavaScript</category></item><item><title>Conway&apos;s Game of Life</title><link>https://kyleshevlin.com/conways-game-of-life/</link><guid isPermaLink="true">https://kyleshevlin.com/conways-game-of-life/</guid><description>Learn how to build Conway&apos;s Game of Life with JavaScript, React and the simulation pattern.</description><pubDate>Thu, 03 Feb 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import GameOfLife from &apos;./_GameOfLife&apos;&lt;/p&gt;
&lt;p&gt;In a previous post, &lt;a href=&quot;/simulation-pattern&quot;&gt;The Simulation Pattern&lt;/a&gt;, I mentioned &lt;a href=&quot;https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life&quot;&gt;Conway&apos;s Game of Life&lt;/a&gt;. In this post, we&apos;re going to implement it using the simulation pattern.&lt;/p&gt;
&lt;p&gt;The Game of Life is about &lt;a href=&quot;https://en.wikipedia.org/wiki/Cellular_automaton&quot;&gt;cellular automata&lt;/a&gt;, that is, how do individuals governed by a set of rules interact in a system. In this case, the individuals are the cells that make up a 2-dimensional grid.&lt;/p&gt;
&lt;p&gt;The game is a simulation because it advances in discrete increments. During each &lt;code&gt;tick&lt;/code&gt;, our cells may or may not change their state. Let&apos;s go over those states and the rules that govern the cellular behavior.&lt;/p&gt;
&lt;p&gt;Each cell can be in one of two states: &lt;code&gt;alive&lt;/code&gt; or &lt;code&gt;dead&lt;/code&gt;. Cells die or reanimate based on a set of conditions. Those are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;An &lt;code&gt;alive&lt;/code&gt; cell with fewer than 2 neighbors dies&lt;/li&gt;
&lt;li&gt;An &lt;code&gt;alive&lt;/code&gt; cell with 2 or 3 neighbors lives&lt;/li&gt;
&lt;li&gt;An &lt;code&gt;alive&lt;/code&gt; cell with 4 or more neighbors dies&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;dead&lt;/code&gt; cell with exactly 3 neighbors reanimates&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Given those rules, we can start to write the code that meets that criteria. I&apos;m going to use JavaScript &amp;amp; React, but I encourage you to try and write this in all sorts of languages and frameworks. It can be a lot of fun to explore a familiar problem in different ways.&lt;/p&gt;
&lt;p&gt;Let&apos;s create the shell of our simulation&apos;s &lt;a href=&quot;/what-is-a-factory-function&quot;&gt;factory function&lt;/a&gt;. Our initial state will be a 2-dimensional array of 10 rows and 10 columns, and every value will be &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Creates a 10 x 10 2d array of falses
const initialState = Array(10)
  .fill()
  .map(() =&amp;gt; Array(10).fill(false))

function createGameOfLifeSim() {
  let state = initialState

  return {
    tick() {},
    getState() {
      return state
    },
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, we need to encode the Game of Life rule&apos;s inside our &lt;code&gt;tick&lt;/code&gt; method. Because we frequently need to get a cell&apos;s neighbors, let&apos;s write a function that manages that functionality. Since this function needs access to the current &lt;code&gt;state&lt;/code&gt;, we can write it in the closure of our factory function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function createGameOfLifeSim() {
  let state = initialState

  function getNumberOfNeighbors(rowIdx, colIdx) {
    const neighborIndices = [
      [rowIdx - 1, colIdx - 1],
      [rowIdx - 1, colIdx],
      [rowIdx - 1, colIdx + 1],
      [rowIdx, colIdx - 1],
      [rowIdx, colIdx + 1],
      [rowIdx + 1, colIdx - 1],
      [rowIdx + 1, colIdx],
      [rowIdx + 1, colIdx + 1],
    ]

    const neighbors = neighborIndices
      .map(([row, col]) =&amp;gt; state?.[row]?.[col])
      .filter(Boolean).length

    return neighbors.length
  }

  return {
    tick() {},
    getState() {
      return state
    },
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I think it&apos;s worth examining this function briefly. To start, we create an array of &lt;code&gt;neighborIndices&lt;/code&gt;. These are the row and column indexes we will use to retrieve the neighbor values from the &lt;code&gt;state&lt;/code&gt; grid.&lt;/p&gt;
&lt;p&gt;Next, we want to determine how many &lt;code&gt;neighbors&lt;/code&gt; have the value &lt;code&gt;true&lt;/code&gt;. To do this, we &lt;code&gt;map&lt;/code&gt; over the &lt;code&gt;neighborIndices&lt;/code&gt;. Cells that are on the edge of our grid will create &lt;code&gt;neighborIndices&lt;/code&gt; outside the bounds of our grid, and so we use &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining&quot;&gt;optional chaining&lt;/a&gt;, the &lt;code&gt;?.&lt;/code&gt; you see there, to avoid errors that come from trying to access non-existent values.&lt;/p&gt;
&lt;p&gt;After that, it&apos;s your basic &lt;code&gt;filter(Boolean)&lt;/code&gt;, making use of &lt;a href=&quot;/just-enough-fp-pointfree&quot;&gt;pointfree programming&lt;/a&gt;, to only get &lt;code&gt;true&lt;/code&gt;s and then the &lt;code&gt;length&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now that we can efficiently get the number of alive neighbors a cell has, we can write the conditional logic to determine the next state.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;return {
  tick() {
    const nextState = state.map((row, rowIdx) =&amp;gt; {
      return row.map((cell, colIdx) =&amp;gt; {
        const neighbors = getNumberOfNeighbors(rowIdx, colIdx)

        // A dead cell only reanimates with exactly 3 neighbors
        if (!cell) return neighbors === 3

        // An alive cell only stays alive with 2 or 3 neighbors
        switch (neighbors) {
          case 2:
          case 3:
            return true
          default:
            return false
        }
      })
    })

    state = nextState

    // Will allow us to chain .getState() after a call to .tick()
    return this
  },
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I&apos;ve divided the logic into two sections: a guard and early return when the cell is dead, and a small &lt;code&gt;switch&lt;/code&gt; when the cell is alive. I often prefer to use &lt;code&gt;switch&lt;/code&gt;es because they are similar to &lt;a href=&quot;/pattern-matching&quot;&gt;pattern matching&lt;/a&gt;, and in this case, the fallthrough works to our benefit.&lt;/p&gt;
&lt;p&gt;This is the crux of our simulation. The full code should look like this so far:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Creates a 10 x 10 2d array of falses
const initialState = Array(10)
  .fill()
  .map(() =&amp;gt; Array(10).fill(false))

function createGameOfLifeSim() {
  let state = initialState

  function getNumberOfNeighbors(rowIdx, colIdx) {
    const neighborIndices = [
      [rowIdx - 1, colIdx - 1],
      [rowIdx - 1, colIdx],
      [rowIdx - 1, colIdx + 1],
      [rowIdx, colIdx - 1],
      [rowIdx, colIdx + 1],
      [rowIdx + 1, colIdx - 1],
      [rowIdx + 1, colIdx],
      [rowIdx + 1, colIdx + 1],
    ]

    const neighbors = neighborIndices
      .map(([row, col]) =&amp;gt; state?.[row]?.[col])
      .filter(Boolean).length

    return neighbors.length
  }

  return {
    tick() {
      const nextState = state.map((row, rowIdx) =&amp;gt; {
        return row.map((cell, colIdx) =&amp;gt; {
          const neighbors = getNumberOfNeighbors(rowIdx, colIdx)

          // A dead cell only reanimates with exactly 3 neighbors
          if (!cell) return neighbors === 3

          // An alive cell only stays alive with 2 or 3 neighbors
          switch (neighbors) {
            case 2:
            case 3:
              return true
            default:
              return false
          }
        })
      })

      state = nextState

      return this
    },
    getState() {
      return state
    },
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I want to add two more methods that will be useful for us when we build our UI: a &lt;code&gt;randomize&lt;/code&gt; method and a &lt;code&gt;toggleCell&lt;/code&gt; method. First, &lt;code&gt;randomize&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const randomBool = () =&amp;gt; Boolean(Math.round(Math.random()))

//... inside our factory function
return {
  //... the return of our sim
  randomize() {
    state = state.map(row =&amp;gt; row.map(randomBool))
    return this
  },
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With &lt;code&gt;randomize&lt;/code&gt;, we generate a completely random grid of &lt;code&gt;true&lt;/code&gt;s and &lt;code&gt;false&lt;/code&gt;s. Next, let&apos;s write &lt;code&gt;toggleCell&lt;/code&gt;. This will allow a user to click on a cell and toggle its state.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;return {
  //... the return of our sim
  toggleCell(rowIdx, colIdx) {
    state[rowIdx][colIdx] = !state[rowIdx][colIdx]
    /**
     * Because React requires immutable changes to know that
     * state has updated, we&apos;re going to clone the current state
     * in order to create an immutable update
     *
     * It&apos;s a pain in the butt, but it&apos;s what we gotta do
     *
     * Alternatives would be creating/using a clone util or
     * a package like Immer
     */
    state = state.map(row =&amp;gt; row.map(x =&amp;gt; x))
    return this
  },
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now with those extra methods in place, we can build our UI. Because we&apos;ve built our sim as a plain object with state held in closure, we can use it with whatever framework (or lack thereof) that we want. We just have to adapt it to the framework. That said, adapting it can result in some strange patterns. We&apos;ll see that as we make this work with React.&lt;/p&gt;
&lt;p&gt;Let&apos;s start with our basic markup and build up the functionality of our UI. I&apos;m going to use inline styles for the sake of simplicity, but use whatever styling method you prefer:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function GameOfLife() {
  const grid = [] // just a placeholder, will eventually be stateful

  return (
    &amp;lt;div style={{ display: &apos;flex&apos;, justifyContent: &apos;center&apos; }}&amp;gt;
      {/* Our grid */}
      &amp;lt;div&amp;gt;
        {grid.map((row, rowIdx) =&amp;gt; {
          return (
            &amp;lt;div key={rowIdx} style={{ display: &apos;flex&apos; }}&amp;gt;
              {row.map((cell, colIdx) =&amp;gt; {
                return &amp;lt;button key={colIdx} onClick={() =&amp;gt; {}} type=&quot;button&quot; /&amp;gt;
              })}
            &amp;lt;/div&amp;gt;
          )
        })}
      &amp;lt;/div&amp;gt;
      {/* Our actions */}
      &amp;lt;div style={{ display: &apos;flex&apos;, justifyContent: &apos;space-between&apos; }}&amp;gt;
        &amp;lt;button onClick={() =&amp;gt; {}} type=&quot;button&quot;&amp;gt;
          Start
        &amp;lt;/button&amp;gt;
        &amp;lt;button onClick={() =&amp;gt; {}} type=&quot;button&quot;&amp;gt;
          Randomize
        &amp;lt;/button&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now that we have our basic UI, let&apos;s add our simulation to the component. We want to have a single simulation for the lifetime of our component. The simplest way to do this is with &lt;code&gt;useRef&lt;/code&gt;. However, as I&apos;ve written about before in &lt;a href=&quot;/comparing-use-ref-and-use-state&quot;&gt;Comparing &lt;code&gt;useRef&lt;/code&gt; and &lt;code&gt;useState&lt;/code&gt;&lt;/a&gt;, changes to a ref will not cause our component to update, so we&apos;ll need a &lt;code&gt;useState&lt;/code&gt; as well. Here&apos;s how we&apos;re going to make that happen:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function GameOfLife() {
  const simRef = React.useRef(createGameOfLifeSim())
  const [grid, setGrid] = React.useState(simRef.current.getState())

  //... the rest of the component
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, whenever we make an update to our sim, we&apos;ll have to use &lt;code&gt;setGrid&lt;/code&gt; on the new state to update our UI. Bit of a pain, but manageable.&lt;/p&gt;
&lt;p&gt;Let&apos;s build out some of the UI functionality next. The primary function we need to add next is the button that starts and stops our simulation. What good is the Game of Life if it never &lt;code&gt;tick&lt;/code&gt;s?&lt;/p&gt;
&lt;p&gt;To do this, we&apos;re going to use an effect that will call &lt;code&gt;tick&lt;/code&gt; on an interval while the game is &lt;code&gt;running&lt;/code&gt;, and stop when the game is &lt;code&gt;paused&lt;/code&gt;. We can set that up like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const INTERVAL = 150

function GameOfLife() {
  const simRef = React.useRef(createGameOfLifeSim())
  const [grid, setGrid] = React.useState(simRef.current.getState())
  const [gameState, setGameState] = React.useState(&apos;paused&apos;)

  React.useEffect(() =&amp;gt; {
    // If the game is paused, the effect should do nothing
    if (gameState === &apos;paused&apos;) return

    // Otherwise, setup the interval...
    const intervalId = setInterval(() =&amp;gt; {
      // Because refs and state setters are stable across renders,
      // none of these need to be included as dependencies of the effect
      setGrid(simRef.current.tick().getState())
    }, INTERVAL)

    // ...and clean it up
    return () =&amp;gt; {
      clearInterval(intervalId)
    }
  }, [gameState])

  // Our handling function for toggling the state of the game
  const handleGameStateToggle = React.useCallback(() =&amp;gt; {
    setGameState(s =&amp;gt; (s === &apos;paused&apos; ? &apos;running&apos; : &apos;paused&apos;))
  }, [])

  return (
    //... most of the UI
    &amp;lt;button onClick={handleGameStateToggle} type=&quot;button&quot;&amp;gt;
      {gameState === &apos;paused&apos; ? &apos;Start&apos; : &apos;Stop&apos;}
    &amp;lt;/button&amp;gt;
    //... the rest of the UI
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Our game is ready to run, but all the cells are dead so nothing will happen. Let&apos;s make use of our &lt;code&gt;randomize&lt;/code&gt; and &lt;code&gt;toggleCell&lt;/code&gt; methods from before so we can change the state of our cells.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function GameOfLife() {
  //...
  const handleRandomize = React.useCallback(() =&amp;gt; {
    setGrid(simRef.current.randomize().getState())
  }, [])

  // Pay attention here, we&apos;re going to use a higher order function so that
  // we can partially apply the rowIdx and colIdx values
  const handleToggleCell = React.useCallback(
    (rowIdx, colIdx) =&amp;gt; () =&amp;gt; {
      setGrid(simRef.current.toggleCell(rowIdx, colIdx).getState())
    },
    [],
  )

  return (
    &amp;lt;div&amp;gt;
      //...then in the cell button UI
      &amp;lt;button
        key={colIdx}
        onClick={handleToggleCell(rowIdx, colIdx)}
        type=&quot;button&quot;
      /&amp;gt;
      //...then in our actions UI
      &amp;lt;button onClick={handleRandomize} type=&quot;button&quot;&amp;gt;
        Randomize
      &amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we have &lt;em&gt;all&lt;/em&gt; the pieces for our Game of Life. Your component code should look something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const INTERVAL = 150

function GameOfLife() {
  const simRef = React.useRef(createGameOfLifeSim())
  const [grid, setGrid] = React.useState(simRef.current.getState())
  const [gameState, setGameState] = React.useState(&apos;paused&apos;)

  React.useEffect(() =&amp;gt; {
    if (gameState === &apos;paused&apos;) return

    const intervalId = setInterval(() =&amp;gt; {
      setGrid(simRef.current.tick().getState())
    }, INTERVAL)

    return () =&amp;gt; {
      clearInterval(intervalId)
    }
  }, [gameState])

  const handleGameStateToggle = React.useCallback(() =&amp;gt; {
    setGameState(s =&amp;gt; (s === &apos;paused&apos; ? &apos;running&apos; : &apos;paused&apos;))
  }, [])

  const handleRandomize = React.useCallback(() =&amp;gt; {
    setGrid(simRef.current.randomize().getState())
  }, [])

  const handleToggleCell = React.useCallback(
    (rowIdx, colIdx) =&amp;gt; () =&amp;gt; {
      setGrid(simRef.current.toggleCell(rowIdx, colIdx).getState())
    },
    [],
  )

  return (
    &amp;lt;div style={{ display: &apos;flex&apos;, justifyContent: &apos;center&apos; }}&amp;gt;
      &amp;lt;div&amp;gt;
        {grid.map((row, rowIdx) =&amp;gt; {
          return (
            &amp;lt;div key={rowIdx} style={{ display: &apos;flex&apos; }}&amp;gt;
              {row.map((cell, colIdx) =&amp;gt; {
                return (
                  &amp;lt;button
                    key={colIdx}
                    onClick={handleToggleCell(rowIdx, colIdx)}
                    type=&quot;button&quot;
                  /&amp;gt;
                )
              })}
            &amp;lt;/div&amp;gt;
          )
        })}
      &amp;lt;/div&amp;gt;
      &amp;lt;div style={{ display: &apos;flex&apos;, justifyContent: &apos;space-between&apos; }}&amp;gt;
        &amp;lt;button onClick={handleGameStateToggle} type=&quot;button&quot;&amp;gt;
          {gameState === &apos;paused&apos; ? &apos;Start&apos; : &apos;Stop&apos;}
        &amp;lt;/button&amp;gt;
        &amp;lt;button onClick={handleRandomize} type=&quot;button&quot;&amp;gt;
          Randomize
        &amp;lt;/button&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The only thing left for you to do is tweak some styles. Specifically, you should play around with the &lt;code&gt;button&lt;/code&gt;s for each cell. Style them based on their current state. Have fun with it and see what you come up with.&lt;/p&gt;
&lt;p&gt;Here&apos;s a version of our game right here. Click &lt;code&gt;randomize&lt;/code&gt; and get the simulation started:&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-8&quot;&amp;gt;
&amp;lt;GameOfLife client:load /&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;h3&gt;Recap&lt;/h3&gt;
&lt;p&gt;The Game of Life is an interesting exercise that can use the simulation pattern. It&apos;s a great starting point for learning cellular automata. Change the rules, build it in other languages and frameworks, explore to your heart&apos;s content.&lt;/p&gt;
</content:encoded><category>JavaScript</category><category>React</category></item><item><title>The Simulation Pattern</title><link>https://kyleshevlin.com/simulation-pattern/</link><guid isPermaLink="true">https://kyleshevlin.com/simulation-pattern/</guid><description>The &amp;ldquo;simulation pattern&amp;rdquo; is a useful tool for anyone&apos;s programming repertoire. Let&apos;s learn how to use it on almost any state problem that advances by discrete increments.</description><pubDate>Fri, 28 Jan 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;Disclaimer&lt;/strong&gt;: If this pattern has an established name, let me know. I&apos;ll update the article to reflect that.&lt;/p&gt;
&lt;p&gt;In December, &amp;lt;Marker content=&quot;And some of January...&quot; /&amp;gt; I participated in &lt;a href=&quot;https://adventofcode.com&quot;&gt;Advent of Code&lt;/a&gt;. It was &lt;em&gt;mostly&lt;/em&gt; fun, but I did have some &lt;em&gt;extremely&lt;/em&gt; difficult days. If you follow me on Twitter, you know of my travails with day 19. Oof.&lt;/p&gt;
&lt;p&gt;That said, there was a common pattern I used to solve several of the puzzles that I want to share with you. I call it the &lt;strong&gt;&quot;simulation pattern&quot;&lt;/strong&gt; and if I hadn&apos;t tried to learn the &lt;em&gt;tiniest&lt;/em&gt; amount of game dev a few years back, I may have never learned it. Thus, I want to pass it on to you in the hopes you find it useful.&lt;/p&gt;
&lt;h3&gt;What is a “simulation”?&lt;/h3&gt;
&lt;p&gt;A &quot;simulation&quot;, in my own words, is where we create some conditions and store some state, and then add a &lt;code&gt;tick&lt;/code&gt; method to advance that state to the next discrete increment. &lt;a href=&quot;https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life&quot;&gt;Conway&apos;s Game of Life&lt;/a&gt; is an excellent example of a simulation and I encourage you to take this pattern and try to build Conway&apos;s Game of Life with it when you&apos;re done reading this post.&lt;/p&gt;
&lt;h3&gt;The pieces of the pattern&lt;/h3&gt;
&lt;p&gt;In its most basic form, a simulation is a &lt;a href=&quot;/what-is-a-closure&quot;&gt;closure&lt;/a&gt; which exposes a &lt;code&gt;tick&lt;/code&gt; method to advance to the next state. Using a &lt;a href=&quot;/what-is-a-factory-function&quot;&gt;factory function&lt;/a&gt;, it looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function createSimulation(initialState) {
  let state = initialState

  return {
    tick() {
      // Add functionality to update state
    },
    getState() {
      return state
    },
  }
}

const sim = createSimulation()
sim.tick()
sim.getState()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We create a function that holds our &lt;code&gt;state&lt;/code&gt; in closure. We add functionality in our exposed &lt;code&gt;tick&lt;/code&gt; method to advance the state, and we create a way to access the current state with &lt;code&gt;getState&lt;/code&gt;. All simulations are some variation of this pattern.&lt;/p&gt;
&lt;p&gt;Let&apos;s create a simple example to demonstrate this. All of us have to deal with money in some capacity, so a loan payoff calculator can be a useful tool to have. We can create a simulation that takes in a &lt;code&gt;principal&lt;/code&gt;, an &lt;code&gt;interestRate&lt;/code&gt;, and expose a &lt;code&gt;tick&lt;/code&gt; method that receives a &lt;code&gt;payment&lt;/code&gt; to determine how many payments are necessary to pay off a loan.&lt;/p&gt;
&lt;p&gt;First, let&apos;s create our factory function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function createLoanPayoffSimulation(principal, interestRate) {
  let total = principal

  return {
    tick(payment) {
      const interest = total * interestRate

      if (payment &amp;lt;= interest) {
        throw new Error(&apos;Impossible to pay off loan. Increase payment amount.&apos;)
      }

      const diff = interest - payment
      total += diff

      return this
    },
    getTotal() {
      return total
    },
  }
}

// Dividing by 12 gives us a monthly interest rate
const sim = createLoanPayoffSimulation(10000, 0.05 / 12)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now that we have our simulation, we can create a function that uses a simulation to determine how many payments are needed to payoff the loan.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function getTotalPayments(payoffSimulation, payment) {
  let payments = 0
  let paid = false

  while (!paid) {
    payoffSimulation.tick(payment)
    payments++

    const total = payoffSimulation.getTotal()
    paid = total &amp;lt;= 0
  }

  return payments
}

console.log(getTotalPayments(sim, 500)) // 21
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can pass different simulations with different conditions into &lt;code&gt;getTotalPayments&lt;/code&gt; to solve other loan payoff scenarios.&lt;/p&gt;
&lt;p&gt;Now that you&apos;ve seen the basics, give it a try on some other problems. Or try it on an Advent of Code problem, &lt;a href=&quot;https://adventofcode.com/2021/day/5&quot;&gt;like this one&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Related&lt;/h3&gt;
&lt;p&gt;You can also use &lt;a href=&quot;/generator-functions&quot;&gt;generator functions&lt;/a&gt; to create a similar effect, just with &lt;code&gt;next&lt;/code&gt; as the method instead of &lt;code&gt;tick&lt;/code&gt;. The difference being that you &lt;code&gt;yield&lt;/code&gt; the next state with each run of the function. I make a loan payment calculator in that post as well, so you can hopefully compare the two.&lt;/p&gt;
</content:encoded><category>JavaScript</category><category>Computer Science</category></item><item><title>The Wrapped State Setter Pattern</title><link>https://kyleshevlin.com/wrapped-state-setter-pattern/</link><guid isPermaLink="true">https://kyleshevlin.com/wrapped-state-setter-pattern/</guid><description>Sometimes we want to add functionality that happens with every call of a state setter. Learn how to wrap that state setter to add it.</description><pubDate>Wed, 19 Jan 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Today, in the process of working on what might potentially become a course on React, I used a pattern that I&apos;ve found useful from time to time that I want to share with you.&lt;/p&gt;
&lt;p&gt;Have you ever wanted to have something happen &lt;em&gt;every&lt;/em&gt; time you use &lt;code&gt;setState&lt;/code&gt; in React? Perhaps you wanted a way to finagle the &lt;code&gt;nextState&lt;/code&gt; or wanted to run a side effect where you store the value in &lt;code&gt;localStorage&lt;/code&gt;. We can accomplish this and more with a &quot;wrapped state setter&quot; pattern.&lt;/p&gt;
&lt;p&gt;Since my example app for the potential course uses &lt;code&gt;localStorage&lt;/code&gt; in lieu of a database, I&apos;ll use that for my example code. That said, the pattern is the same regardless of what you use it for, so let&apos;s dive in.&lt;/p&gt;
&lt;p&gt;Let&apos;s say my app stores a collection of notes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function App() {
  const [notes, setNotes] = React.useState([])
  //...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, let&apos;s add some &lt;a href=&quot;/prefer-declarative-state-updaters&quot;&gt;declarative state updaters&lt;/a&gt; that will update our notes. Keep in mind, there are multiple ways to write these updaters. Don&apos;t get too focused on the implementation details, just recognize we&apos;ve written a few. Like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function App() {
  const [notes, setNotes] = React.useState([])

  const createNote = note =&amp;gt; {
    setNotes(currentNotes =&amp;gt; [...currentNotes, note])
  }

  const updateNote = update =&amp;gt; {
    setNotes(currentNotes =&amp;gt; {
      const index = currentNotes.findIndex(note =&amp;gt; note.id === update.id)

      if (index &amp;lt; 0) return currentNotes

      return [
        ...currentNotes.slice(0, index),
        { ...currentNotes[index], ...update },
        ...currentNotes.slice(index + 1),
      ]
    })
  }

  const deleteNote = id =&amp;gt; {
    setNotes(currentNotes =&amp;gt; {
      const index = currentNotes.findIndex(note =&amp;gt; note.id === id)

      if (index &amp;lt; 0) return currentNotes

      return [...currentNotes.slice(0, index), ...currentNotes.slice(index + 1)]
    })
  }

  //...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, let&apos;s say that we want to store these changes to &lt;code&gt;notes&lt;/code&gt; in &lt;code&gt;localStorage&lt;/code&gt; &lt;em&gt;every&lt;/em&gt; time we make an update. What is the simplest way to do this?&lt;/p&gt;
&lt;p&gt;If we look at all our declarative updaters, they all make a call to &lt;code&gt;setNotes&lt;/code&gt;. If we had a way to change &lt;code&gt;setNotes&lt;/code&gt;, we could make this happen. This is where the &quot;wrapped&quot; part of the title comes in.&lt;/p&gt;
&lt;p&gt;We&apos;re going to create a function that will call the current &lt;code&gt;setNotes&lt;/code&gt; and use it to provide ourselves with a seam in which to extend the current behavior. Let&apos;s wrap it up, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const wrappedSetNotes = React.useCallback(update =&amp;gt; {
  // Call the original state setter, use the function updater to get the current state
  setNotes(currentNotes =&amp;gt; {
    // Determine the nextState
    const nextState =
      typeof update === &apos;function&apos; ? update(currentNotes) : update

    // This is where we extend the functionality
    localStorage.setItem(YOUR_LOCAL_STORAGE_KEY, JSON.stringify(nextState))

    // We preserve the existing functionality
    return nextState
  })
}, [])
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And then every where we previously called &lt;code&gt;setNotes&lt;/code&gt;, we update to &lt;code&gt;wrappedSetNotes&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const createNote = note =&amp;gt; {
  wrappedSetNotes(currentNotes =&amp;gt; [...currentNotes, note])
}

const updateNote = update =&amp;gt; {
  wrappedSetNotes(currentNotes =&amp;gt; {
    const index = currentNotes.findIndex(note =&amp;gt; note.id === update.id)

    if (index &amp;lt; 0) return currentNotes

    return [
      ...currentNotes.slice(0, index),
      { ...currentNotes[index], ...update },
      ...currentNotes.slice(index + 1),
    ]
  })
}

const deleteNote = id =&amp;gt; {
  wrappedSetNotes(currentNotes =&amp;gt; {
    const index = currentNotes.findIndex(note =&amp;gt; note.id === id)

    if (index &amp;lt; 0) return currentNotes

    return [...currentNotes.slice(0, index), ...currentNotes.slice(index + 1)]
  })
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, any updates that we make to &lt;code&gt;notes&lt;/code&gt; will have the side effect of updating the value in &lt;code&gt;localStorage&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;There are other ways to use this pattern. If you&apos;ve ever heard of the &quot;state reducer pattern&quot;, that&apos;s an example of wrapping the state setter.&lt;/p&gt;
&lt;p&gt;This pattern also doesn&apos;t have to be &lt;em&gt;just&lt;/em&gt; for state setters. If ever you find yourself with a function that you want to add some functionality to, you might be able to simply wrap it in a function, and add your functionality in the function body. Try it out, see if it works.&lt;/p&gt;
</content:encoded><category>JavaScript</category><category>React</category></item><item><title>Parametric Design</title><link>https://kyleshevlin.com/parametric-design/</link><guid isPermaLink="true">https://kyleshevlin.com/parametric-design/</guid><description>Parametric design is the process of using adjustable parameters to modify and influence a design. Add it to your box of tools.</description><pubDate>Tue, 18 Jan 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import ColorPicker from &apos;./_ColorPicker&apos;
import ResizableBox from &apos;./_ResizableBox&apos;
import FullSpiro from &apos;./_Spirograph&apos;&lt;/p&gt;
&lt;p&gt;This will be short and to the point. Yesterday, I tweaked the button styles on my blog. At the time I&apos;m writing this, the buttons have multiple box shadows to create what I hope is an interesting effect. In the process of getting the shadows &quot;correct&quot;, I employed &quot;parametric design&quot;. I believe parametric design is a valuable concept for developers to know and apply, &amp;lt;Marker content=&quot;&amp;lt;em&amp;gt;Especially&amp;lt;/em&amp;gt; if you&apos;re like me and not a very gifted designer.&quot; /&amp;gt; and I want to make sure it&apos;s a part of your vocabulary.&lt;/p&gt;
&lt;p&gt;Parametric design is the process of using adjustable parameters to modify and influence a design. In other words, we turn the values and &lt;strong&gt;relationships between values&lt;/strong&gt; into functions. Then, we wire up inputs to pass new arguments to them to get immediate feedback on the outcome.&lt;/p&gt;
&lt;p&gt;It can be very simple, like choosing a color:&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;mb-8&quot;&amp;gt;
&amp;lt;ColorPicker client:load /&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;Or perhaps the width and height of an item:&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;mb-8&quot;&amp;gt;
&amp;lt;ResizableBox client:load /&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;To something more complex, like generative art:&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;mb-8&quot;&amp;gt;
&amp;lt;FullSpiro client:load /&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;Parametric design is the foundation of so many dev and design tools that it&apos;s incredibly likely you&apos;ve encountered it without even knowing it. Wiring up inputs to provide immediate feedback can be a very satisfying way to experiment and solve problems.&lt;/p&gt;
&lt;p&gt;It&apos;s also a wonderful tool for non-coders. Good inputs can be a way of empowering them to solve their own problems.&lt;/p&gt;
&lt;p&gt;Parametric design is fundamentally about exploring. Next time you&apos;re building something and you&apos;re not quite sure what it should be, consider wiring up some inputs and see what happens.&lt;/p&gt;
</content:encoded><category>JavaScript</category><category>React</category></item><item><title>The &amp;ldquo;Folded Code&amp;rdquo; Test</title><link>https://kyleshevlin.com/the-folded-code-test/</link><guid isPermaLink="true">https://kyleshevlin.com/the-folded-code-test/</guid><description>Many text editors allow you to fold, or collapse, blocks of code. I believe we can improve the design of our code by using this to our advantage.</description><pubDate>Mon, 03 Jan 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;One underrated feature of code editors is &quot;code folding&quot;, the ability to fold a block of code, like this:&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;mb-4&quot;&amp;gt;
&amp;lt;Gif
alt=&quot;Animation of VSCode collapsing blocks of code from multiple lines, into a single line&quot;
gifSrc=&quot;/images/folding-code.gif&quot;
staticSrc=&quot;/images/code-folded-static.jpg&quot;
/&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;I use this feature all the time, and recently, it dawned on me that folding your code might help you write better code.&lt;/p&gt;
&lt;h3&gt;Why I fold code&lt;/h3&gt;
&lt;p&gt;When I&apos;m reading code, especially large files, I can find it overwhelming to see lots of code. Even more so when I&apos;m unfamiliar with the code. It&apos;s a lot of visual noise and information to take in all at once. In order to reduce this overwhelming sensation, I &lt;em&gt;literally&lt;/em&gt; reduce how much code is visible.&lt;/p&gt;
&lt;p&gt;If you use &lt;a href=&quot;https://code.visualstudio.com/&quot;&gt;VSCode&lt;/a&gt;, you can collapse code blocks from the keyboard using &quot;chords&quot;. A &quot;chord&quot; is a command that requires multiple key combinations to perform. You can fold up to 9 levels of indentation by pressing &lt;code&gt;cmd + k&lt;/code&gt;, followed by &lt;code&gt;cmd + &amp;lt;number between 1-9&amp;gt;&lt;/code&gt;. &amp;lt;Marker content=&quot;I work on a Mac, please convert &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;ctrl&amp;lt;/code&amp;gt; if you are a Windows user.&quot; /&amp;gt; The number you press is the level depth of the collapse. You can un-collapse all levels by performing &lt;code&gt;cmd + k&lt;/code&gt;, then &lt;code&gt;cmd + 0&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Often, when I open up a large file, I&apos;ll start by hitting &lt;code&gt;cmd + k&lt;/code&gt;, then &lt;code&gt;cmd + 1&lt;/code&gt; or &lt;code&gt;cmd + 2&lt;/code&gt; to reduce how much code I can see. This allows me to view the file at a higher level. It&apos;s seeing the code &quot;forest&quot; and ignoring the details of the code &quot;trees&quot; for a moment.&lt;/p&gt;
&lt;p&gt;Looking at code from this vantage point, where much of the implementation details are hidden, begs us to ask a key question: &lt;strong&gt;does the code &lt;em&gt;still&lt;/em&gt; describe its purpose at this level?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I believe &amp;lt;Marker content=&quot;Yes, this is my &amp;lt;em&amp;gt;opinion&amp;lt;/em&amp;gt;&quot; /&amp;gt; code that is easy to read, understand, and maintain will also be easy to follow at each level you fold. When you fold it to a level where it&apos;s unclear what happens inside the block, you &lt;em&gt;may&lt;/em&gt; have an opportunity to refactor and improve the code.&lt;/p&gt;
&lt;p&gt;I can think of two strong examples where the &quot;folded code&quot; test can be seen in action. First, tests.&lt;/p&gt;
&lt;p&gt;Think about a block of tests, as we unfold it, we get a more detailed view of the forest. A completely folded test might only say:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;describe(&apos;Stack&apos;, () =&amp;gt; {})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We know that this tests something called &lt;code&gt;Stack&lt;/code&gt;, which gives us some indication of what we might expect. Unfolding a layer reveals more detail:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;describe(&apos;Stack&apos;, () =&amp;gt; {
  it(&apos;should make a new stack&apos;, () =&amp;gt; {})
  it(&apos;should add an item to the stack&apos;, () =&amp;gt; {})
  it(&apos;should pop off the top item from the stack&apos;, () =&amp;gt; {})
  it(&apos;should indicate when the stack is empty&apos;, () =&amp;gt; {})
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And if we go further, we&apos;d see the implementation details of those tests (I&apos;ll spare you that for now).&lt;/p&gt;
&lt;p&gt;On the flip side, the second example is the corollary to these tests, the &lt;code&gt;class&lt;/code&gt; that we&apos;re testing.&lt;/p&gt;
&lt;p&gt;Now, I often prefer &lt;a href=&quot;what-is-a-factory-function&quot;&gt;factory functions&lt;/a&gt; and think that you can see the same benefits of code folding when writing them, but I believe more people are familiar with classes. Perhaps not in JavaScript, but if you have a background in other languages.&lt;/p&gt;
&lt;p&gt;If we were to write a &lt;code&gt;Stack&lt;/code&gt; class, going layer by layer, you will see that each level of folding reveals more about it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class Stack {}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, we start to reveal the API of the &lt;code&gt;Stack&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class Stack {
  constructor() {}
  push(item) {}
  pop() {}
  isEmpty() {}
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At this level, we&apos;ve revealed what the public API of the class is. If this were a more complicated object, we&apos;d also have some idea of the &lt;code&gt;protected&lt;/code&gt; or &lt;code&gt;private&lt;/code&gt; API as well. At the next level, we can see some of the implementation details.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class Stack {
  constructor() {
    this.stack = []
  }
  push(item) {
    this.stack.push(item)
  }
  pop() {
    return this.stack.pop()
  }
  isEmpty() {
    return this.stack.length === 0
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, you&apos;ll have to use your imagination a bit to apply this principle/test &amp;lt;Marker content=&quot;Honestly, I don&apos;t know what it is. Just a thought that&apos;s been in my brain for a few months.&quot; /&amp;gt; to your work. The stuff you work on day to day is far more complex than I can fit in an example, but I hope you&apos;re getting the gist of what I&apos;m getting at. If you can improve how well your code reads at each level it&apos;s folded, you&apos;re probably writing code that you and your colleagues can update and maintain easily in the future.&lt;/p&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;Code folding is a way to reduce visual noise and get a higher level perspective on a module&apos;s functionality. Strive to make your code understandable even when it&apos;s folded through the use of good structure and descriptive variable and function names. Use this &quot;test&quot; as a way to gauge how well you&apos;re communicating the intention of your code to your colleagues and future self.&lt;/p&gt;
</content:encoded><category>JavaScript</category><category>Software Engineering</category></item><item><title>My Course Platform</title><link>https://kyleshevlin.com/my-course-platform/</link><guid isPermaLink="true">https://kyleshevlin.com/my-course-platform/</guid><description>I am about to launch a course platform of my own making at https://courses.kyleshevlin.com. It is not fancy. But it is my own.</description><pubDate>Mon, 29 Nov 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import SocialPost from &apos;../../../components/SocialPost.astro&apos;&lt;/p&gt;
&lt;p&gt;So I had a wild idea a &lt;em&gt;while&lt;/em&gt; back now:&lt;/p&gt;
&lt;p&gt;&amp;lt;SocialPost
authorName=&quot;Kyle Shevlin&quot;
authorHandle=&quot;@kyleshevl.in&quot;
authorProfile=&quot;https://bsky.app/profile/kyleshevl.in&quot;
avatarUrl=&quot;https://cdn.bsky.app/img/avatar/plain/did:plc:h4qem3f3cz6yvs3r3xvs634g/bafkreig7fzbknganveoij56depkm4dxax3yo2cudxf6mase23vccmqn5xa@jpeg&quot;
date=&quot;2021-06-14&quot;
content={`
I&apos;m starting a new project today. I&apos;m going to build a mini-course on Array.reduce()!&lt;/p&gt;
&lt;p&gt;I&apos;ve seen a lot of confusion about this method, and I&apos;d like to help people out.&lt;/p&gt;
&lt;p&gt;For added difficulty, I&apos;m going to try and get it done in just a week.
`}
/&amp;gt;&lt;/p&gt;
&lt;p&gt;You may have noticed that it&apos;s been a little more than a week since I wrote that tweet. 😅&lt;/p&gt;
&lt;p&gt;There were a number of reasons that happened, but the main culprits were my estimate was way off, &amp;lt;Marker content=&quot;Classic.&quot; /&amp;gt; and burnout &amp;amp; depression hit me pretty hard this summer and fall. &amp;lt;Marker content=&quot;Shit happens. No need to hide that. Don&apos;t let it stop you permanently. Get help if you need it.&quot; /&amp;gt;&lt;/p&gt;
&lt;p&gt;But we&apos;re here now! Despite the challenges, the first version is built and ready for the world. Is it the greatest course platform the world has seen? &lt;strong&gt;Absolutely not&lt;/strong&gt;. Could it use dozens of improvements? &lt;strong&gt;Hell yeah&lt;/strong&gt;. But it&apos;s here, and I am proud of that.&lt;/p&gt;
&lt;p&gt;For the rest of this post, I want to answer some common questions I imagine people will ask me about &lt;a href=&quot;https://courses.kyleshevlin.com&quot;&gt;courses.kyleshevlin.com&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Why did you build it?&lt;/h3&gt;
&lt;p&gt;The biggest reason is to have control over how the content is created and released. Working with other course platforms has been great and very worthwhile, but I have had my struggles with timing and format. There have been weeks where I worked 16+ hours a day to get the content ready in time. By building a platform of my own, I get to write courses exactly how I would like to and publish them when I want to, for better or for worse.&lt;/p&gt;
&lt;p&gt;I write my blog using &lt;a href=&quot;https://mdxjs.com&quot;&gt;MDX&lt;/a&gt; and will be writing all the lessons on my course platform with it, too. It makes it super easy for me to add code snippets as well as fun, little interactive React components right in the middle of my writing. It has become my favorite way to write long form content.&lt;/p&gt;
&lt;p&gt;Another reason is just to prove I can do it. I&apos;ve never really taken making serious money into my own hands. I don&apos;t expect this to make me rich by any means, but proving to myself that I&apos;m capable of creating value of my own accord means something to me. I&apos;m not highly motivated by business, by money, by growth, so attempting to do this is a big step out of my comfort zone. It&apos;s attempting to do something I don&apos;t find natural, but believe I am capable of doing and it will benefit my family&apos;s life.&lt;/p&gt;
&lt;h3&gt;How did you build it?&lt;/h3&gt;
&lt;p&gt;If you look into the tweet thread, I explain in some detail how I got started. I &lt;em&gt;literally&lt;/em&gt; copied the code of this blog into a new directory and started ripping out the bits I didn&apos;t need and building the bits I did need. I wanted my branding to be consistent from &lt;a href=&quot;/&quot;&gt;kyleshevlin.com&lt;/a&gt; and &lt;a href=&quot;https://courses.kyleshevlin.com&quot;&gt;courses.kyleshevlin.com&lt;/a&gt;. Eventually, I&apos;ll probably create a shared component library for the two apps.&lt;/p&gt;
&lt;p&gt;So, to be specific, it&apos;s built with Gatsby &amp;lt;Marker content=&quot;It&apos;s still on v2, ha. I have to find time to do the upgrade all the way to v4.&quot; /&amp;gt; Here are some of the other pieces of the tech stack:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://supabase.io&quot;&gt;Supabase&lt;/a&gt; for my database &amp;amp; auth&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://stripe.com&quot;&gt;Stripe&lt;/a&gt; for payments&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://netlify.com&quot;&gt;Netlify&lt;/a&gt; for deploys &amp;amp; serverless functions&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://emotion.sh/&quot;&gt;Emotion&lt;/a&gt; for my styling&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://mdxjs.com&quot;&gt;MDX&lt;/a&gt; for my authoring&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://vimeo.com&quot;&gt;Vimeo&lt;/a&gt; for my video hosting&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Some of this may change as time goes by, but for me, this was the simplest way I could get started, and I&apos;m a big fan of keeping things simple.&lt;/p&gt;
&lt;h3&gt;What courses are you offering?&lt;/h3&gt;
&lt;p&gt;Right now, only the course on &lt;a href=&quot;https://courses.kyleshevlin.com/courses/array-reduce&quot;&gt;Array.reduce()&lt;/a&gt; will be available. I have started planning some additional courses to make next. Please feel free to send me a tweet with course suggestions.&lt;/p&gt;
&lt;h3&gt;Are there any &quot;extras&quot; that come with the course?&lt;/h3&gt;
&lt;p&gt;Yes. When you purchase a course, you&apos;ll get an invite to my private Discord server so that you can ask me questions about the material and get help from other people learning the material.&lt;/p&gt;
&lt;h3&gt;Will your egghead courses be on your platform?&lt;/h3&gt;
&lt;p&gt;The short answer is no. They will remain on egghead for as long as they will have them there. If those topics find their way on to this platform, it will be done as a revamp of the material. New videos with new written content for each lesson as well.&lt;/p&gt;
&lt;h3&gt;What are your goals for the platform?&lt;/h3&gt;
&lt;p&gt;I&apos;ve never been a goal-oriented person. I think of myself more as a trajectory-oriented person. I try and get my life moving in the direction I want to head and see where it takes me.&lt;/p&gt;
&lt;p&gt;To that end, I don&apos;t have MRR or DAU goals. Instead, I would like to see the platform have satisfied students. I would like to derive enough income from the platform to pay off my student loans early. I do not anticipate making enough money from it to quit a day job, and I am more likely to view it as a supplemental business.&lt;/p&gt;
&lt;p&gt;My trajectory is aimed towards sustainability. Can I make it as simple as possible to make quality content doing a little bit at a time, rather than these all out sprints I&apos;ve done in the past.&lt;/p&gt;
&lt;h3&gt;What are your next steps for the platform?&lt;/h3&gt;
&lt;p&gt;There are two things remaining on my TODO list:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I may shoot a few more videos for the &lt;code&gt;Array.reduce()&lt;/code&gt; course for those lessons that currently don&apos;t have one&lt;/li&gt;
&lt;li&gt;Implement &quot;licenses&quot; so that a business can buy bulk access to a course&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After that, I have a few ideas for the next courses. My hope is to keep them very tight and small. Once I have a few products to put out there, I will work on allowing you to buy bundles of courses in some fashion.&lt;/p&gt;
&lt;h3&gt;What can I do to help?&lt;/h3&gt;
&lt;p&gt;Thanks for asking. The simplest answers are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Buy the course if it will help you&lt;/li&gt;
&lt;li&gt;Fill out the feedback at the end of the course when you finish it&lt;/li&gt;
&lt;li&gt;Share the course with people who could use it&lt;/li&gt;
&lt;li&gt;Cheer me on via Twitter&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Closing remarks&lt;/h3&gt;
&lt;p&gt;Thanks for taking the time to read this. I look forward to seeing you over on my course platform and seeing where this journey takes us.&lt;/p&gt;
</content:encoded><category>Career</category><category>Thoughts</category></item><item><title>How I Would Use a UI Library</title><link>https://kyleshevlin.com/how-I-would-use-a-ui-library/</link><guid isPermaLink="true">https://kyleshevlin.com/how-I-would-use-a-ui-library/</guid><description>UI Libraries are great for having a solid design system to build from. Here&apos;s a small architectural decision I would do to make them even nicer to work with.</description><pubDate>Sat, 06 Nov 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I&apos;ve recently been working on a project that uses &lt;a href=&quot;https://chakra-ui.com/&quot;&gt;Chakra UI&lt;/a&gt;. I&apos;ve enjoyed using it, for the most part. I&apos;ve had a few moments that made me go, &quot;Do I want to build my own UI library?&quot; and then immediately snuffed that thought out of existence. Ain&apos;t nobody got time for that.&lt;/p&gt;
&lt;p&gt;That said, working with Chakra has made me think of an architectural pattern I would be very tempted to employ if I was building the project&apos;s design system from the ground up and knew it was going to be a long-living project.&lt;/p&gt;
&lt;p&gt;I&apos;ll get right to the chase. Here&apos;s my idea: for every UI component you&apos;re using in the library, create a &lt;a href=&quot;/facade-pattern&quot;&gt;facade&lt;/a&gt; of your own and consume the facade throughout your app. &lt;strong&gt;Do not&lt;/strong&gt; consume the library directly in your features and other component compositions. If I implemented this, I would go so far as to create an ESLint rule that enforced this pattern.&lt;/p&gt;
&lt;p&gt;Before I explain all the reasons why, here&apos;s a simple facade example. You&apos;ll probably think I&apos;m nuts.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import React from &apos;react&apos;
import { Button as ChakraButton } from &apos;@chakra-ui/react&apos;

export default function Button(props) {
  return &amp;lt;ChakraButton {...props} /&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I can hear you saying, &quot;Ok, why in the hell would you recommend this, Kyle?&quot; The answer is simple. This creates a lot of flexibility and likely will save me future pain when requirements change at a very low cost now.&lt;/p&gt;
&lt;p&gt;&quot;YAGNI! YAGNI! &lt;strong&gt;Y&lt;/strong&gt;ou&apos;re &lt;strong&gt;N&lt;/strong&gt;ot &lt;strong&gt;G&lt;/strong&gt;onna &lt;strong&gt;N&lt;/strong&gt;eed &lt;strong&gt;I&lt;/strong&gt;t!&quot; I hear you scream. Maybe you&apos;re right. But I&apos;ve never worked in a project that lasted a decent amount of time without some upheaval to the UI components.&lt;/p&gt;
&lt;p&gt;Here is a short, non-exhaustive list of things you can do easily with this one layer of indirection:&lt;/p&gt;
&lt;h4&gt;Swap out the library&lt;/h4&gt;
&lt;p&gt;If you need/want to try a different component library, you can swap out the implementation under the hood without any change to consumers of your UI components (your other developers/teammates). You can make this change &lt;em&gt;component by component&lt;/em&gt;. You don&apos;t have to do a wholesale, sweeping change.&lt;/p&gt;
&lt;h4&gt;Add or Restrict &lt;code&gt;props&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;If you want to &lt;em&gt;add&lt;/em&gt; &lt;code&gt;props&lt;/code&gt; that aren&apos;t on the underlying component, you can do so and map them to some functionality. Or you can create useful aliases to props if they would benefit your team.&lt;/p&gt;
&lt;p&gt;Also, you can &lt;em&gt;restrict&lt;/em&gt; which &lt;code&gt;props&lt;/code&gt; can be used in the underlying UI library. Maybe there&apos;s some weird &lt;code&gt;prop&lt;/code&gt; you just really want to avoid using. All easily done with a layer of indirection.&lt;/p&gt;
&lt;h4&gt;Rename/Remap &lt;code&gt;props&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;If you ever need to rename/remap a &lt;code&gt;prop&lt;/code&gt; because of an update to the component library, you can do so without needing to change every instance of that component throughout your app. No codemods. Just one simple change.&lt;/p&gt;
&lt;h3&gt;How I would implement this&lt;/h3&gt;
&lt;p&gt;I would start by making two directories: &lt;code&gt;features&lt;/code&gt; and &lt;code&gt;ui&lt;/code&gt;. I may need to add this to my &lt;a href=&quot;/how-i-structure-my-react-projects&quot;&gt;React project structure post&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Then, every UI component in my app gets a facade in the &lt;code&gt;ui&lt;/code&gt; directory. No exceptions.&lt;/p&gt;
&lt;p&gt;Finally, I would implement an ESLint rule preventing the import of any third party UI library into the &lt;code&gt;features&lt;/code&gt; directory. Features can only import components from other &lt;code&gt;features&lt;/code&gt; or the &lt;code&gt;ui&lt;/code&gt; directory.&lt;/p&gt;
&lt;h3&gt;Downsides&lt;/h3&gt;
&lt;p&gt;I can think of one downside to this approach. &lt;strong&gt;Documentation&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Consuming the UI library directly in your app means you rely solely on the documentation of the UI library. If you use the facade pattern, you have to indicate to your consumers where to find the information they need. This means pointing to the documentation of the implementation details, or writing your own docs to cover them. If you end up adding or restricting props, you&apos;re going to need to document how the component is used anyways.&lt;/p&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;Give yourself some future flexibility by using a facade between the UI library you&apos;re using and your features. The extra work could save you a lot of pain down the line.&lt;/p&gt;
</content:encoded><category>React</category><category>JavaScript</category></item><item><title>What is a Factory Function?</title><link>https://kyleshevlin.com/what-is-a-factory-function/</link><guid isPermaLink="true">https://kyleshevlin.com/what-is-a-factory-function/</guid><description>Factory functions help us quickly create objects. They make use of closures to have private values and functions, all while avoiding the `this` keyword. Learn how to use them in this article.</description><pubDate>Fri, 05 Nov 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Building upon &lt;a href=&quot;/what-is-a-closure&quot;&gt;closures&lt;/a&gt;, I want to teach you about &quot;factory functions&quot;, too. Factory functions often use closures, so it makes sense to learn them together. So if you don&apos;t know what a closure is or need a refresher, I encourage you to read that blog post first.&lt;/p&gt;
&lt;p&gt;A &lt;strong&gt;factory function&lt;/strong&gt; is a function that returns a new object. &amp;lt;Marker content=&quot;On occasion, it may return some other data structure.&quot; /&amp;gt; The key feature of a factory is that its only job is to &lt;em&gt;pump out those items&lt;/em&gt;, just like an actual factory.&lt;/p&gt;
&lt;p&gt;The simplest factory function returns a static object of keys and values. Ever needed to turn a small list of values into an object? Take that &lt;a href=&quot;/what-is-a-tuple&quot;&gt;tuple&lt;/a&gt; and give it to a factory function, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const createPerson = (name, twitterHandle) =&amp;gt; ({
  name,
  twitterHandle: `@${twitterHandle}`,
})

const kyle = createPerson(&apos;Kyle&apos;, &apos;kyleshevlin&apos;)
console.log(kyle.twitterHandle) // &apos;@kyleshevlin&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That&apos;s not all that interesting, but it can be a useful way to generate objects. If you had a long list of person-related tuples like this, you could use &lt;code&gt;createPerson&lt;/code&gt; with &lt;code&gt;Array.map&lt;/code&gt; to turn them into props for a React component.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const people = [
  [&apos;Kyle&apos;, &apos;kyleshevlin&apos;],
  [&apos;Jane&apos;, &apos;janeDoe12345&apos;],
  [&apos;John&apos;, &apos;johnDoe67890&apos;],
]

function PeopleList() {
  return (
    &amp;lt;ul&amp;gt;
      {people.map(personTuple =&amp;gt; {
        const person = createPerson(...personTuple)

        return (
          &amp;lt;li key={person.name}&amp;gt;
            &amp;lt;Person {...person} /&amp;gt;
          &amp;lt;/li&amp;gt;
        )
      })}
    &amp;lt;/ul&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is a great use of a factory function, but let&apos;s move on to a more interesting use case.&lt;/p&gt;
&lt;h3&gt;Replacing Classes with Factories&lt;/h3&gt;
&lt;p&gt;The place I use factories most often is when I want to return an object with methods but use closures to create private methods and values. Even better, I &lt;em&gt;never&lt;/em&gt; have to even think about the &lt;code&gt;this&lt;/code&gt; keyword.&lt;/p&gt;
&lt;p&gt;When I created my &lt;a href=&quot;https://kyleshevl.in/dsa&quot;&gt;data structures and algorithms course on egghead&lt;/a&gt;, I used factory functions to create the data structures. Let&apos;s make a &lt;code&gt;createQueue&lt;/code&gt; factory to show you how this strategy works.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function createQueue() {
  // Create an array in closure. This is a private variable.
  const queue = []

  // This could have been a private method, if we didn&apos;t also want to expose it
  // Notice how simple this is to understand. No need for `this`
  const isEmpty = () =&amp;gt; queue.length === 0

  return {
    enqueue(x) {
      queue.push(x)
    },
    dequeue() {
      return queue.shift()
    },
    peek() {
      if (isEmpty()) return undefined
      return queue[queue.length - 1]
    },
    get length() {
      return queue.length
    },
    isEmpty,
  }
}

const queue1 = createQueue()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What&apos;s great about this pattern is that it&apos;s compatible in &lt;em&gt;every&lt;/em&gt; browser. Private fields and private methods for JavaScript classes are widely implemented, but not every where (and never will be).&lt;/p&gt;
&lt;p&gt;I recently used this pattern to upgrade my &lt;a href=&quot;https://github.com/kyleshevlin/shevyjs&quot;&gt;shevyjs&lt;/a&gt; package. I was able to have truly private values and functions that I couldn&apos;t have back when I originally wrote the code. I highly recommend taking a look at the source code to see a more complex factory function in action.&lt;/p&gt;
&lt;h3&gt;Composition with Factories&lt;/h3&gt;
&lt;p&gt;There are 100s of posts out there on the difficulty of building object hierarchies with inheritance. I kind of want to skip that part and jump right to composition. &amp;lt;Marker content=&quot;Maybe I&apos;ll find the energy to write that post or update this one in the future, but I just don&apos;t have it in me right now.&quot; /&amp;gt;&lt;/p&gt;
&lt;p&gt;Let&apos;s imagine we&apos;re building a game with animal characters. Animals are notoriously difficult to create inheritance hierarchies for because of their diversity and literal exceptionality.&lt;/p&gt;
&lt;p&gt;In my game, let&apos;s say I want to create &lt;code&gt;Hawk&lt;/code&gt;, &lt;code&gt;Penguin&lt;/code&gt; and &lt;code&gt;FlyingFish&lt;/code&gt; factories. How can I use composition to make this possible?&lt;/p&gt;
&lt;p&gt;There are some shared traits with these animals. &lt;code&gt;Hawk&lt;/code&gt;s and &lt;code&gt;Penguin&lt;/code&gt;s both have wings, but not &lt;code&gt;FlyingFish&lt;/code&gt;. &lt;code&gt;Penguin&lt;/code&gt;s and &lt;code&gt;FlyingFish&lt;/code&gt; both swim, but &lt;code&gt;Hawk&lt;/code&gt;s don&apos;t. While also &lt;code&gt;Hawk&lt;/code&gt;s and &lt;code&gt;FlyingFish&lt;/code&gt; fly, while &lt;code&gt;Penguin&lt;/code&gt;s don&apos;t, despite their wings.&lt;/p&gt;
&lt;p&gt;Simply put, inheritance can&apos;t help us here. Let&apos;s compose our factories:&lt;/p&gt;
&lt;p&gt;First, we can make factories that &lt;code&gt;createBird&lt;/code&gt;s and &lt;code&gt;createFish&lt;/code&gt;, they will create very small objects.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const createBird = () =&amp;gt; ({
  hasWings: true,
})

const createFish = () =&amp;gt; ({
  hasFins: true,
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are more properties we could add, but we should be careful with adding too many to the base object. Next, we can create factories for objects based on what they do. Focusing on what something does, versus what it &lt;em&gt;is&lt;/em&gt; is a great way to find these kinds of compositional pieces:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const createFlyer = () =&amp;gt; ({
  canFly: true,
  fly(vx, vy, vz) {
    // Do something with the velocities
  },
})

const createSwimmer = () =&amp;gt; ({
  canSwim: true,
  swim(vx, vy, vz) {
    // Do something with the velocities
  },
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now that we have those, we can create compositions to create our various animal factories easily:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const createHawk = () =&amp;gt; ({
  ...createBird(),
  ...createFlyer(),
})

const createPenguin = () =&amp;gt; ({
  ...createBird(),
  ...createSwimmer(),
})

const createFlyingFish = () =&amp;gt; ({
  ...createFish(),
  ...createFlyer(),
  ...createSwimmer(),
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Look how clean that is! Ahh, just fills my heart with joy. Imagine trying to do that with classes?&lt;/p&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;Factory functions are functions that return objects. We can use factory functions and closures to have private variables and private functions, only exposing what we want to our consumer through the object we return, all while avoiding the &lt;code&gt;this&lt;/code&gt; keyword. Factories make for easy composition of values and functionality. Use them when inheritance can&apos;t solve your problems.&lt;/p&gt;
</content:encoded><category>JavaScript</category><category>Computer Science</category></item><item><title>Careful with Context Composition</title><link>https://kyleshevlin.com/careful-with-context-composition/</link><guid isPermaLink="true">https://kyleshevlin.com/careful-with-context-composition/</guid><description>Be careful with how you compose your UI when using Context. You might be making a common mistake causing extra rerenders.</description><pubDate>Mon, 18 Oct 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import Example1 from &apos;./_Example1&apos;
import Example2 from &apos;./_Example2&apos;
import Example3 from &apos;./_Example3&apos;
import Counter from &apos;./_Counter&apos;&lt;/p&gt;
&lt;p&gt;Recently, I helped a small team fix a performance issue involving React Context. It was a fairly simple fix that I want to share with you. I&apos;m going to set up the problem, show you the small change we needed to make, and share a small library I made to help you out in the future.&lt;/p&gt;
&lt;h3&gt;The Problem - Poor composition&lt;/h3&gt;
&lt;p&gt;To understand this post, we need to establish a shared context (pun intended). We need to understand that whenever state changes in a React app, the component in which the change occurs &lt;em&gt;will be rerendered&lt;/em&gt;. That means rerendering all the components that are called in that component&apos;s function body. Let&apos;s make this clear with some examples. I&apos;m going to create a &lt;code&gt;Box&lt;/code&gt;. The background color for &lt;code&gt;Box&lt;/code&gt; will change every time it renders. We&apos;ll force it to rerender with a &lt;code&gt;forceUpdate&lt;/code&gt; function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { Button } from &apos;./Button&apos;
import Flex from &apos;./Flex&apos;
// A spacing helper function from my shevyjs library
// It&apos;s an alias of the `baseSpacing` method
// Spacer uses this under the hood
import { bs } from &apos;./shevy&apos;
// These can be found on my snippets page
import randomRGB from &apos;./snippets/randomRGB&apos;
import useForceUpdate from &apos;./snippets/useForceUpdate&apos;

function Box() {
  return (
    &amp;lt;div
      style={{
        backgroundColor: randomRGB(),
        height: bs(4),
      }}
    /&amp;gt;
  )
}

function App() {
  const forceUpdate = useForceUpdate()

  return (
    &amp;lt;Flex direction=&quot;column&quot; gap={1}&amp;gt;
      &amp;lt;Button onClick={forceUpdate}&amp;gt;Force Update&amp;lt;/Button&amp;gt;
      &amp;lt;Box /&amp;gt;
    &amp;lt;/Flex&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And we can see it here:&lt;/p&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;Example1 client:only=&quot;react&quot; /&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;p&gt;Perfect. The background color of &lt;code&gt;Box&lt;/code&gt; changes every time it&apos;s rendered and it rerenders due to a state change. Now, let&apos;s add React Context to the mix.&lt;/p&gt;
&lt;p&gt;Let&apos;s create a &lt;code&gt;Context&lt;/code&gt;, &lt;code&gt;Provider&lt;/code&gt;, and a custom hook for consuming that context. We&apos;re going to use &lt;code&gt;forceUpdate&lt;/code&gt; as the only &lt;code&gt;value&lt;/code&gt; passed to the &lt;code&gt;Provider&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import React from &apos;react&apos;

const MyContext = React.createContext()

function MyProvider({ children }) {
  const forceUpdate = useForceUpdate()

  return &amp;lt;MyContext.Provider value={forceUpdate}&amp;gt;{children}&amp;lt;/MyContext.Provider&amp;gt;
}

const useMyContext = () =&amp;gt; React.useContext(MyContext)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, I&apos;m going to &lt;strong&gt;purposely&lt;/strong&gt; make a bad choice, and add a &lt;code&gt;Box&lt;/code&gt; component to &lt;code&gt;MyProvider&lt;/code&gt;. Notice that &lt;code&gt;Box&lt;/code&gt; will now be in the same scope that the state change associated with &lt;code&gt;forceUpdate&lt;/code&gt; occurs (because &lt;code&gt;forceUpdate&lt;/code&gt; creates a state change inside the &lt;code&gt;useForceUpdate&lt;/code&gt; hook).&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function MyProvider({ children }) {
  const forceUpdate = useForceUpdate()

  return (
    &amp;lt;MyContext.Provider value={forceUpdate}&amp;gt;
      {children}
      &amp;lt;Box /&amp;gt;
    &amp;lt;/MyContext.Provider&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, let&apos;s change the &lt;code&gt;App&lt;/code&gt; a bit, using our new &lt;code&gt;Context&lt;/code&gt; and custom hook.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Trigger() {
  // Remember that the only value of our context is `forceUpdate`
  // but we purposely want to consume our context at the moment
  const forceUpdate = useMyContext()

  return &amp;lt;Button onClick={forceUpdate}&amp;gt;Force Update&amp;lt;/Button&amp;gt;
}

function App() {
  return (
    &amp;lt;MyProvider&amp;gt;
      &amp;lt;Trigger /&amp;gt;
    &amp;lt;/MyProvider&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, you will notice that the resulting UI is &lt;em&gt;exactly&lt;/em&gt; the same. We have a button on top of a box. &lt;strong&gt;Here&apos;s the thing to pay attention to&lt;/strong&gt;: Typically, only consumers of a context will be forced to rerender when the context &lt;code&gt;value&lt;/code&gt; updates, but because we made a bad decision and put our &lt;code&gt;Box&lt;/code&gt; in the same function that has a state change, it&apos;s going to rerender, too. Look at it:&lt;/p&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;Example2 client:only=&quot;react&quot; /&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;p&gt;If you&apos;re not paying attention, you may be confused why &lt;code&gt;Box&lt;/code&gt; is rerendering when it doesn&apos;t consume your context, but it all has to do with how we chose to make our composition. Let&apos;s fix it now.&lt;/p&gt;
&lt;h3&gt;The Solution - Only expose &lt;code&gt;children&lt;/code&gt; in a &lt;code&gt;Provider&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;The problem is we&apos;re rendering a component in the same scope as the state change of our context. If we move &lt;code&gt;Box&lt;/code&gt; from &lt;code&gt;MyProvider&lt;/code&gt; and into our &lt;code&gt;App&lt;/code&gt; instead, we&apos;ll have the same UI, but &lt;code&gt;Box&lt;/code&gt; won&apos;t rerender when we click the &lt;code&gt;Trigger&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// No more `Box` in this component
function MyProvider({ children }) {
  const forceUpdate = useForceUpdate()

  return &amp;lt;MyContext.Provider value={forceUpdate}&amp;gt;{children}&amp;lt;/MyContext.Provider&amp;gt;
}

function App() {
  return (
    &amp;lt;MyProvider&amp;gt;
      &amp;lt;Flex direction=&quot;column&quot; gap={1}&amp;gt;
        &amp;lt;Trigger /&amp;gt;
        &amp;lt;Box /&amp;gt;
      &amp;lt;/Flex&amp;gt;
    &amp;lt;/MyProvider&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And let&apos;s see it in action. Notice, &lt;code&gt;Box&lt;/code&gt; will not rerender. Click the &lt;code&gt;Trigger&lt;/code&gt; all you want, it will not change.&lt;/p&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;Example3 client:only=&quot;react&quot; /&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;p&gt;I assure you, a state change is still occurring, but because &lt;code&gt;Box&lt;/code&gt; is not rendered in the scope of the state change, but rather as one of the &lt;code&gt;children&lt;/code&gt; of &lt;code&gt;MyProvider&lt;/code&gt;, it won&apos;t rerender. Our UI is &lt;em&gt;exactly&lt;/em&gt; the same in all scenarios so far, but we can see how using the correct composition improves how our app functions.&lt;/p&gt;
&lt;h3&gt;A More Robust Solution: &lt;code&gt;react-generate-context&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;I&apos;m a believer that if you can put guide rails in place to keep people on a good path, you should use them. When I saw the mistake the team was making, I realized I could build a small package that puts these guide rails in place. Say hello to &lt;a href=&quot;https://github.com/kyleshevlin/react-generate-context&quot;&gt;&lt;code&gt;react-generate-context&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This library is a single function, &lt;code&gt;generateContext&lt;/code&gt;, that receives a custom hook to manage the &lt;code&gt;value&lt;/code&gt; for your &lt;code&gt;Context&lt;/code&gt; and returns to you the &lt;code&gt;Provider&lt;/code&gt; and custom hook for that context.&lt;/p&gt;
&lt;p&gt;The main feature? Because you don&apos;t have direct access to the &lt;code&gt;Provider&lt;/code&gt;, you can&apos;t put any other components inside of it.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import generateContext from &apos;react-generate-context&apos;

const [MyProvider, useMyContext] = generateContext(() =&amp;gt; {
  const forceUpdate = useForceUpdate()
  return forceUpdate
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice that the function we pass to &lt;code&gt;generateContext&lt;/code&gt; is itself a custom hook. We use it to establish the very same value we did before. We can consume &lt;code&gt;useMyContext&lt;/code&gt; in &lt;code&gt;Trigger&lt;/code&gt; just like before, too.&lt;/p&gt;
&lt;p&gt;To make a slightly better example, and the one you&apos;ll find if you visit the &lt;a href=&quot;https://github.com/kyleshevlin/react-generate-context&quot;&gt;Github page&lt;/a&gt; for it, let&apos;s make a &lt;code&gt;Counter&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const useCounterValue = ({ startingCount = 0 }) =&amp;gt; {
  const [state, setState] = React.useState(startingCount)
  const handlers = React.useMemo(
    () =&amp;gt; ({
      inc: () =&amp;gt; {
        setState(s =&amp;gt; s + 1)
      },
      dec: () =&amp;gt; {
        setState(s =&amp;gt; s - 1)
      },
    }),
    [],
  )

  return [state, handlers]
}

const [CounterProvider, useCounter] = generateContext(useCounterValue)

function Counter() {
  const [count, { inc, dec }] = useCounter()

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;div&amp;gt;{count}&amp;lt;/div&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;button onClick={inc}&amp;gt;+&amp;lt;/button&amp;gt;
        &amp;lt;button onClick={dec}&amp;gt;-&amp;lt;/button&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}

function App() {
  return (
    &amp;lt;CounterProvider startingCount={100}&amp;gt;
      &amp;lt;Counter /&amp;gt;
    &amp;lt;/CounterProvider&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And here it is in action:&lt;/p&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;Counter client:only=&quot;react&quot; /&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;p&gt;Using this package, it&apos;s impossible to screw up your &lt;code&gt;Provider&lt;/code&gt; in a way that creates unnecessary rerenders for components. That&apos;s a win in my book.&lt;/p&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;Resist any urge to put other components in the scope of your custom &lt;code&gt;Provider&lt;/code&gt; for a React Context. Doing so means rerendering those components whenever the state of the context changes. Instead, only expose &lt;code&gt;children&lt;/code&gt; from your custom &lt;code&gt;Provider&lt;/code&gt; and compose components under the &lt;code&gt;Provider&lt;/code&gt;. Using &lt;code&gt;react-generate-context&lt;/code&gt; removes some of this boilerplate for you.&lt;/p&gt;
</content:encoded><category>React</category></item><item><title>Comparing `useRef` and `useState`</title><link>https://kyleshevlin.com/comparing-use-ref-and-use-state/</link><guid isPermaLink="true">https://kyleshevlin.com/comparing-use-ref-and-use-state/</guid><description>People are often confused by `useRef`. Let&apos;s try and fix that confusion by comparing it with `useState`.</description><pubDate>Wed, 22 Sep 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import BackgroundCounter from &apos;./_BackgroundCounter&apos;
import HookCategories from &apos;./_HookCategories.astro&apos;
import RandomBox from &apos;./_RandomBox&apos;
import RefRandomBox from &apos;./_RefRandomBox&apos;&lt;/p&gt;
&lt;p&gt;When I discuss React with people, I often hear that others find &lt;code&gt;useRef&lt;/code&gt; to be confusing. People are uncertain about when and why they should use it. They often opt to use &lt;code&gt;useState&lt;/code&gt; instead when perhaps it&apos;s not the right choice. I think one way of gaining an understanding of &lt;code&gt;useRef&lt;/code&gt; is to compare it with &lt;code&gt;useState&lt;/code&gt;, so let&apos;s do that.&lt;/p&gt;
&lt;p&gt;Before we get into the specific differences, I want to share a realization I recently had. I realized that the standard React Hooks come in four categories:&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-8&quot;&amp;gt;
&amp;lt;HookCategories /&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;Notice that I put &lt;code&gt;useRef&lt;/code&gt; in &lt;em&gt;two&lt;/em&gt; categories. It doesn&apos;t fall neatly into one or the other. It holds a bit of state, whatever value is assigned to &lt;code&gt;ref.current&lt;/code&gt;, making it a &quot;State Manager&quot;. But it&apos;s also a &quot;Stabilizer&quot; because changing the value of &lt;code&gt;ref.current&lt;/code&gt; &lt;strong&gt;does not&lt;/strong&gt; cause a component to update.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;useState&lt;/code&gt;, on the other hand, is designed to update a component. &amp;lt;Marker content=&quot;That&apos;s kind of the whole point, ha.&quot; /&amp;gt; In fact, I like to help people understand &lt;code&gt;useState&lt;/code&gt; better by showing them how to make a &lt;code&gt;useForceUpdate&lt;/code&gt; hook with it.&lt;/p&gt;
&lt;p&gt;If you have written React for long enough, or have had the chance to work or search through some class component code, you may have used or come across an invocation of &lt;code&gt;this.forceUpdate()&lt;/code&gt;. React class components have a method, &lt;code&gt;forceUpdate&lt;/code&gt;, that you can use to imperatively force a component to rerender. It was an escape hatch of last resort. The move to React Hooks meant we lost this escape hatch, right?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Wrong&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;We can create that same imperative escape hatch function like so: &amp;lt;Marker content={&lt;code&gt;You can also find this code on my &amp;lt;a href=&quot;/snippets&quot;&amp;gt;Snippets&amp;lt;/a&amp;gt; under &amp;lt;a href=&quot;/snippets/use-force-update&quot;&amp;gt;useForceUpdate()&amp;lt;/a&amp;gt;.&lt;/code&gt;} /&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const useForceUpdate = () =&amp;gt; {
  const [, setState] = React.useState(true)
  const forceUpdate = React.useCallback(() =&amp;gt; {
    setState(x =&amp;gt; !x)
  }, [])

  return forceUpdate
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&apos;s break this code down. First, we only destructure the state setter from the &lt;code&gt;useState&lt;/code&gt; hook. &amp;lt;Marker content=&quot;With array destructuring, you can skip values at any index just be not declaring a variable name at that position.&quot; /&amp;gt; We don&apos;t actually &lt;em&gt;need&lt;/em&gt; the state, we just need it to change whenever we want to force an update. Next, we make a callback function, stabilize it with &lt;code&gt;useCallback&lt;/code&gt;, and use a &lt;a href=&quot;/prefer-function-updaters-in-state-setters&quot;&gt;function updater&lt;/a&gt; to flip the boolean back and forth. We then return our function from the hook. If we include this in a component, which we will see soon enough, we can force it to update. Let&apos;s put this into practice.&lt;/p&gt;
&lt;p&gt;As I&apos;ve demonstrated before in my post on &lt;a href=&quot;/using-react-memo-to-avoid-unnecessary-rerenders&quot;&gt;React.memo&lt;/a&gt;, one way to visually see that a component has updated is to give it a random background color with each render. Let&apos;s make a component that does just that. First, the &lt;code&gt;randomRGB&lt;/code&gt; function: &amp;lt;Marker content={&lt;code&gt;This, too, can be found on my &amp;lt;a href=&quot;/snippets&quot;&amp;gt;Snippets&amp;lt;/a&amp;gt; page under &amp;lt;a href=&quot;/snippets/random-rgb&quot;&amp;gt;randomRGB()&amp;lt;/a&amp;gt;&lt;/code&gt;} /&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const random255 = () =&amp;gt; Math.floor(Math.random() * 255)

const randomRGB = () =&amp;gt; {
  const r = random255()
  const g = random255()
  const b = random255()

  return `rgb(${r}, ${g}, ${b})`
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, we&apos;ll make a box with a &quot;Force Update&quot; button that uses &lt;code&gt;randomRGB&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Box() {
  const forceUpdate = useForceUpdate()

  return (
    &amp;lt;div style={{ backgroundColor: randomRGB(), padding: 10 }}&amp;gt;
      &amp;lt;button onClick={forceUpdate}&amp;gt;Force Update&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And let&apos;s see it in action.&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-8&quot;&amp;gt;
&amp;lt;RandomBox client:load /&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;Neat. Now, hopefully it&apos;s clear what causes a rerender with &lt;code&gt;useState&lt;/code&gt;. The question we must now ask ourselves is, &quot;How does this relate to &lt;code&gt;useRef&lt;/code&gt;?&quot;. Let&apos;s try to make a similar box, but use &lt;code&gt;useRef&lt;/code&gt; instead. We&apos;ll have to create our own state updater to do this since &lt;code&gt;useRef&lt;/code&gt; doesn&apos;t give us one.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function RefBox() {
  const ref = React.useRef(true)
  const flip = React.useCallback(() =&amp;gt; {
    ref.current = !ref.current
  }, [])

  return (
    &amp;lt;div style={{ backgroundColor: randomRGB(), padding: 10 }}&amp;gt;
      &amp;lt;button onClick={flip}&amp;gt;Try to update&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-8&quot;&amp;gt;
&amp;lt;RefRandomBox client:load /&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;I bet you just clicked that button repeatedly and wondered if it&apos;s actually doing anything. I assure you it is, check your console. I snuck a &lt;code&gt;console.log&lt;/code&gt; into &lt;code&gt;flip&lt;/code&gt; on you.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;useRef&lt;/code&gt; is a &lt;em&gt;mutable&lt;/em&gt; value store. In other words, we can imperatively update the &lt;code&gt;ref&lt;/code&gt; by assigning a new value to &lt;code&gt;ref.current&lt;/code&gt;. However, a component &lt;em&gt;does not&lt;/em&gt; update when &lt;code&gt;ref.current&lt;/code&gt; changes. Some other kind of state update needs to happen in order for the component to rerender.&lt;/p&gt;
&lt;p&gt;Let&apos;s make an example that combines these two features together. We&apos;ll make a box with a counter as a &lt;code&gt;ref&lt;/code&gt;. We&apos;ll update that counter in the background and see the current value of that &lt;code&gt;ref&lt;/code&gt; whenever we force the component to update.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function BackgroundCounter() {
  const counter = React.useRef(0)
  const forceUpdate = useForceUpdate()

  React.useEffect(() =&amp;gt; {
    const interval = setInterval(() =&amp;gt; {
      counter.current++
    }, 100)

    return () =&amp;gt; {
      clearInterval(interval)
    }
  }, [])

  const reset = () =&amp;gt; {
    counter.current = 0
    forceUpdate()
  }

  return (
    &amp;lt;div style={{ backgroundColor: randomRGB() }}&amp;gt;
      &amp;lt;div&amp;gt;{counter.current}&amp;lt;/div&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;button onClick={forceUpdate} type=&quot;button&quot;&amp;gt;
          Force Update
        &amp;lt;/button&amp;gt;
        &amp;lt;button onClick={reset} type=&quot;button&quot;&amp;gt;
          Reset
        &amp;lt;/button&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And let&apos;s see how that works.&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-8&quot;&amp;gt;
&amp;lt;BackgroundCounter client:load /&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;Notice that the value displayed only updates when we force it to. It&apos;s been changing in the background this entire time, and yet, because it was a &lt;code&gt;ref&lt;/code&gt;, the component never updates. It was probably a pretty big number the first time you updated it, too. It&apos;s been running since you started reading this article.&lt;/p&gt;
&lt;p&gt;So when might we practically want to use &lt;code&gt;useRef&lt;/code&gt;? Well, the answer is the combination of those facts, &quot;Whenever we need a value that will always be available, can be changed when necessary, without updating the component.&quot; I know that seems unhelpful, but let&apos;s make another example.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;useRef&lt;/code&gt; essentially allows us to create a value in closure for the lifetime of the component. If you need a refresher on &lt;a href=&quot;/what-is-a-closure&quot;&gt;closures, I got you&lt;/a&gt;. Have you ever had an effect that you wanted to ensure only ran once? &amp;lt;Marker content=&quot;Be careful here. This might only be the behavior you &amp;lt;em&amp;gt;think&amp;lt;/em&amp;gt; you want. This is the kind of thing where bugs quickly creep up.&quot; /&amp;gt; We can make a &lt;code&gt;useEffectOnlyOnce&lt;/code&gt; hook by using a &lt;code&gt;ref&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function useEffectOnlyOnce(effect, dependencies) {
  const hasRun = React.useRef(false)

  React.useEffect(() =&amp;gt; {
    if (hasRun.current) return

    hasRun.current = true
    effect()
  }, dependencies)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or what about an effect that can only run &lt;em&gt;after&lt;/em&gt; a component has initially mounted?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function useEffectAfterInitialMount(effect, dependencies) {
  const isMounted = React.useRef(false)

  React.useEffect(() =&amp;gt; {
    if (!isMounted.current) {
      isMounted.current = true
      return
    }

    effect()
  }, dependencies)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or, I don&apos;t know, what about an effect that only runs every &lt;code&gt;nth&lt;/code&gt; time because you just want to be silly?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function useEffectEveryNthTime(effect, dependencies, n) {
  const count = React.useRef(0)

  React.useEffect(() =&amp;gt; {
    count.current++

    if (count.current % n === 0) {
      effect()
    }
  }, dependencies)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The point is a &lt;code&gt;ref&lt;/code&gt; is very useful when you need to track a value for the lifetime of a component but don&apos;t need it&apos;s every change to update the UI. If you need that, you probably need to use a different state manager hook.&lt;/p&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;Changing &lt;code&gt;useState&lt;/code&gt;&apos;s value will always cause a rerender, even if that state isn&apos;t used anywhere in the component. Changing &lt;code&gt;useRef&lt;/code&gt;&apos;s value will never cause a rerender, even if you use that state somewhere in the component.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;useRef&lt;/code&gt; is useful for having a stable reference to a value throughout the lifetime of a component. It is a mutable value held in the closure of your component function and can be used by the functions created in the body of the component function.&lt;/p&gt;
</content:encoded><category>React</category><category>JavaScript</category></item><item><title>What is a Closure?</title><link>https://kyleshevlin.com/what-is-a-closure/</link><guid isPermaLink="true">https://kyleshevlin.com/what-is-a-closure/</guid><description>JavaScript closures are confusing for some, but they do not have to be. Learn what a closure is and why they are a powerful tool to have in your programming repertoire.</description><pubDate>Thu, 02 Sep 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In JavaScript, and some other languages, too, there is the concept of a &quot;closure&quot;. This concept can be confusing at first, but once understood, can become a useful tool in your repertoire. I want to help you discover how useful it can be.&lt;/p&gt;
&lt;p&gt;In short, a &quot;closure&quot; occurs when a bit of &quot;state&quot;, created inside of a function body, is exposed, with some indirection, to the outside world in the function&apos;s return. To make sense of this, let&apos;s break down a few things.&lt;/p&gt;
&lt;p&gt;This is a function.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function() {}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When I create values inside of this function, they are scoped to the body, the &lt;code&gt;{}&lt;/code&gt;, of the function. They cannot be accessed from outside of the function body.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function counter() {
  let count = 0
}

console.log(count) // Uncaught ReferenceError: count is not defined
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If I return the &lt;code&gt;count&lt;/code&gt;, the outside world can access the value, but it has no means of updating the value. Think of this as a bit of &quot;state&quot;, but one that cannot be updated.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function counter() {
  let count = 0
  return count
}

const count = counter()

console.log(count) // 0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If instead of returning the &lt;code&gt;count&lt;/code&gt;, I instead return an object that gives you access to reading the current &lt;code&gt;count&lt;/code&gt; and methods for updating &lt;code&gt;count&lt;/code&gt;, I will have exposed a bit of &quot;state&quot; that &lt;em&gt;can&lt;/em&gt; be updated.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function createCounter() {
  let count = 0

  return {
    /**
     * Read the current state
     */
    state: () =&amp;gt; count,
    /**
     * Increment the state by 1
     */
    increment: () =&amp;gt; {
      count++
    },
    /**
     * Decrement the state by 1
     */
    decrement: () =&amp;gt; {
      count--
    },
  }
}

const counter = createCounter()

console.log(counter.state()) // 0
counter.increment()
counter.increment()
counter.increment()
console.log(counter.state()) // 3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, I have a bit of state from our &lt;code&gt;createCounter&lt;/code&gt; function body that is held in the memory of my program so long as I still have access to the returned &lt;code&gt;counter&lt;/code&gt; object. &lt;em&gt;That&lt;/em&gt; is the &lt;strong&gt;closure&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;I can read that state, I can update that state, but not directly. I do it &lt;em&gt;indirectly&lt;/em&gt; through the API established by the returned object. &amp;lt;Marker content=&quot;The &amp;lt;code&amp;gt;createCounter&amp;lt;/code&amp;gt; function is actually a &amp;lt;strong&amp;gt;factory function&amp;lt;/strong&amp;gt;, which I hope to write about next.&quot; /&amp;gt; Can you start to see how useful this is?&lt;/p&gt;
&lt;p&gt;This method can be used to create persistent state for the life of our program, it can be used for &lt;a href=&quot;/just-enough-fp-partial-application&quot;&gt;partially applying values&lt;/a&gt; to &lt;a href=&quot;/just-enough-fp-currying&quot;&gt;curried functions&lt;/a&gt;, it can be used to create &lt;em&gt;truly&lt;/em&gt; private functions and values, something we don&apos;t yet have for &lt;code&gt;classes&lt;/code&gt; in JavaScript. The applications are numerous.&lt;/p&gt;
&lt;p&gt;I highly encourage you try making a few simple closures (if you haven&apos;t before), to get the hang of it. I think it can be a real eye opener, and you&apos;ll start to think of the returns of your functions as little APIs that your program interacts with.&lt;/p&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;A closure is created when state held inside of a function body is exposed to the world outside of that function through its return value. It remains accessible, albeit indirectly, so long as the returned value exists in the program.&lt;/p&gt;
</content:encoded><category>JavaScript</category><category>Computer Science</category></item><item><title>Prefer Function Updaters in State Setters</title><link>https://kyleshevlin.com/prefer-function-updaters-in-state-setters/</link><guid isPermaLink="true">https://kyleshevlin.com/prefer-function-updaters-in-state-setters/</guid><description>React state can be updated in two ways: replace the `currentState` with the `nextState`, or transform the `currentState` to the `nextState` with a function. Prefer the function.</description><pubDate>Mon, 30 Aug 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import ItemSelectorBad from &apos;./_ItemSelectorBad&apos;&lt;/p&gt;
&lt;p&gt;This one will be short and sweet. &amp;lt;Marker content=&quot;At least I thought so when I started writing this, and I have no intention of changing the sentence now&quot; /&amp;gt; You&apos;re using React. You have some state.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const [selectedItem, setSelectedItem] = React.useState(null)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You&apos;re already on board with the concepts in &lt;a href=&quot;/use-encapsulation&quot;&gt;useEncapsulation&lt;/a&gt; and &lt;a href=&quot;/prefer-declarative-state-updaters&quot;&gt;Prefer Declarative State Updaters&lt;/a&gt;, so you make a custom hook combining your state with the functions that will update that state.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function useItemSelection() {
  const [selectedItem, setSelectedItem] = React.useState(null)

  const handlers = React.useMemo(
    () =&amp;gt; ({
      selectItem: item =&amp;gt; {
        setSelectedItem(item)
      },
      unselectItem: () =&amp;gt; {
        setSelectedItem(null)
      },
    }),
    [],
  )

  return [selectedItem, handlers]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Fantastic. Your selection logic is encapsulated in a nice, little custom hook. Your boss and colleagues love you and your code. All is well in the world!&lt;/p&gt;
&lt;p&gt;Until...&lt;/p&gt;
&lt;p&gt;You get some new requirements.&lt;/p&gt;
&lt;p&gt;&quot;We would love it if clicking on the &lt;strong&gt;currently selected item&lt;/strong&gt; would &lt;strong&gt;unselect&lt;/strong&gt; the item, rather than do nothing. Can you do that?&quot;&lt;/p&gt;
&lt;p&gt;Of course we can! But the question is how shall we do it? There are at minimum, two ways. Let&apos;s do it the less-than-great way first.&lt;/p&gt;
&lt;p&gt;In order to &quot;unselect&quot; an item, we need to know that the item we&apos;re selecting is the same as current &lt;code&gt;selectedItem&lt;/code&gt;. We could use the &lt;code&gt;selectedItem&lt;/code&gt; that&apos;s in scope.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function useItemSelection() {
  const [selectedItem, setSelectedItem] = React.useState(null)

  const handlers = React.useMemo(
    () =&amp;gt; ({
      // ...same handlers as before

      smartSelectItem: item =&amp;gt; {
        // Here we use `selectedItem` from the parent scope
        // We&apos;re _also_ assuming the &quot;items&quot; have an `id`
        // We will fix that later
        if (item?.id === selectedItem?.id) {
          setSelectedItem(null)
          return
        }

        setSelectedItem(item)
      },
    }),
    // Now we had to add `selectedItem` as a dependency
    // All handlers will update _every_ time `selectedItem` updates
    [selectedItem],
  )

  return [selectedItem, handlers]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can pop this into a component and see that it works.&lt;/p&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;ItemSelectorBad client:load /&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;p&gt;Great, this works as expected. Why is it less-than-great?&lt;/p&gt;
&lt;p&gt;Because we&apos;re relying on a dependency we don&apos;t need to rely on, and in so doing, we&apos;re forcing our state updaters to change unnecessarily.&lt;/p&gt;
&lt;p&gt;If we use a &quot;function updater&quot; instead of relying on the &lt;code&gt;selectedItem&lt;/code&gt; in scope, we can avoid the &lt;code&gt;selectedItem&lt;/code&gt; dependency entirely.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const handlers = React.useMemo(() =&amp;gt; {
  // ...same handlers as before, except...
  smartSelectItem: item =&amp;gt; {
    setSelectedItem(currentItem =&amp;gt; {
      if (item?.id === currentItem?.id) return null
      return item
    })
  }
}, [])
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we no longer have a dependency because React is giving us all the information we need to determine the next state within the state setter itself. On top of that, we get a tidy little, almost &lt;a href=&quot;/pattern-matching&quot;&gt;pattern matching like&lt;/a&gt; function body. The fact that each branch of logic must return the &lt;code&gt;nextState&lt;/code&gt; helps us in other ways. I&apos;ve made the following bug a few times in my career: &amp;lt;Marker content=&quot;And lost a few hours here and there yelling at my computer about it. &amp;lt;span&amp;gt;😅&amp;lt;/span&amp;gt;&quot; /&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  smartSelectItem: item =&amp;gt; {
    if (item?.id === selectedItem?.id) {
      setSelectedItem(null)
    }

    setSelectedItem(item)
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;See my mistake?&lt;/p&gt;
&lt;p&gt;I forgot to &lt;code&gt;return&lt;/code&gt; in the guard statement. Classic.&lt;/p&gt;
&lt;h3&gt;Other Benefits&lt;/h3&gt;
&lt;p&gt;Hooks solved a lot of problems, but they didn&apos;t get rid of a few &quot;gotchas&quot;. In fact, &lt;code&gt;useState&lt;/code&gt; created an &lt;em&gt;extra&lt;/em&gt; gotcha you didn&apos;t have to deal with in class component days. Let&apos;s start there:&lt;/p&gt;
&lt;h4&gt;Object updates are not merged anymore&lt;/h4&gt;
&lt;p&gt;In the class component days, you could create a state like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this.state = {
  error: null,
  data: null,
  loading: false,
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And you could do updates like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this.setState({ loading: true })
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And your &lt;code&gt;state&lt;/code&gt; would be:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;console.log(this.state) // { error: null, data: null, loading: true }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But try this with a hook instead:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const [state, setState] = React.useState({
  error: null,
  data: null,
  loading: false,
})

setState({ loading: true })

console.log(state) // { loading: true }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;What?!&lt;/strong&gt; That&apos;s right, objects aren&apos;t merged. They are &lt;em&gt;replaced&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;I personally think this makes sense. By making the state setter more rudimentary, the API becomes straightforward. No longer do you need to know about the &quot;behavior&quot; of the state setter. It&apos;s less information you need to store in memory, and I&apos;m a big fan of that.&lt;/p&gt;
&lt;p&gt;You can get around this using function updaters:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const [state, setState] = React.useState({
  error: null,
  data: null,
  loading: false,
})

setState(currentState =&amp;gt; ({
  ...currentState,
  loading: true,
}))

console.log(state) // { error: null, data: null, loading true }
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Calling state setters more than once in a handler body&lt;/h4&gt;
&lt;p&gt;This &quot;gotcha&quot; has also been true since the class component days. If you call a state setter more than once in the same function body, there&apos;s a &lt;em&gt;really&lt;/em&gt; good chance that the update will not be what you expect when that function body completes.&lt;/p&gt;
&lt;p&gt;Here&apos;s an absurd example, with a &lt;code&gt;useTripleCounter&lt;/code&gt; hook:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function useTripleCount() {
  const [state, setState] = React.useState(0)

  const handlers = React.useMemo(
    () =&amp;gt; ({
      inc: () =&amp;gt; {
        setState(state + 1)
        setState(state + 1)
        setState(state + 1)
      },
      dec: () =&amp;gt; {
        setState(state - 1)
        setState(state - 1)
        setState(state - 1)
      },
    }),
    [state],
  )

  return [state, handlers]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If I use this in a component, what&apos;s going to happen? All three &lt;code&gt;setState&lt;/code&gt;s are going to be called, utilizing the same &lt;code&gt;state&lt;/code&gt; dependency and &lt;code&gt;state&lt;/code&gt; will only change by a value of &lt;code&gt;1&lt;/code&gt;. Not to mention, our &lt;code&gt;handlers&lt;/code&gt; update every single time &lt;code&gt;state&lt;/code&gt; updates, which may lead to more rerenders than necessary.&lt;/p&gt;
&lt;p&gt;But, if we swap those updates for function updaters:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const handlers = React.useMemo(
  () =&amp;gt; ({
    inc: () =&amp;gt; {
      // often I shorten `state` to just `s` when the update is this small
      setState(s =&amp;gt; s + 1)
      setState(s =&amp;gt; s + 1)
      setState(s =&amp;gt; s + 1)
    },
    dec: () =&amp;gt; {
      setState(s =&amp;gt; s - 1)
      setState(s =&amp;gt; s - 1)
      setState(s =&amp;gt; s - 1)
    },
  }),
  [],
)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What happens now? Now our updates are all applied. Our count increments and decrements by &lt;code&gt;3&lt;/code&gt;. I hope you can see how this might be useful in a &lt;em&gt;real&lt;/em&gt; situation. &amp;lt;Marker content=&quot;Though I might recommend you find a way to &amp;lt;em&amp;gt;not&amp;lt;/em&amp;gt; call a state setter multiple times in the same function body instead.&quot; /&amp;gt;&lt;/p&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;Using function updaters leads to fewer gotchas and requires fewer dependencies than simply replacing the current state. Consider using them more often to improve your stateful React components.&lt;/p&gt;
&lt;h3&gt;Bonus: Improving the &lt;code&gt;useItemSelection&lt;/code&gt; hook&lt;/h3&gt;
&lt;p&gt;I wanted to take a moment and make this hook a little better before finishing the post. This relates to my recent post on &lt;a href=&quot;dependency-injection-and-default-parameters&quot;&gt;dependency injection&lt;/a&gt; which you should read.&lt;/p&gt;
&lt;p&gt;Did you happen to notice &lt;em&gt;another&lt;/em&gt; dependency in the &lt;code&gt;useItemSelection&lt;/code&gt; hook? Here it is in full so you can look for it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function useItemSelection() {
  const [selectedItem, setSelectedItem] = React.useState(null)

  const handlers = React.useMemo(
    () =&amp;gt; ({
      selectItem: item =&amp;gt; {
        setSelectedItem(item)
      },
      unselectItem: () =&amp;gt; {
        setSelectedItem(null)
      },
      smartSelectItem: item =&amp;gt; {
        setSelectedItem(currentItem =&amp;gt; {
          if (item?.id === currentItem?.id) return null
          return item
        })
      },
    }),
    [],
  )

  return [selectedItem, handlers]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Hopefully you recognized that &lt;code&gt;smartSelectItem&lt;/code&gt; knows a &lt;em&gt;bit&lt;/em&gt; too much about the shape of the items being selected. What if these items are &lt;em&gt;not&lt;/em&gt; objects? What if they are but don&apos;t have &lt;code&gt;id&lt;/code&gt;s, but some other key?&lt;/p&gt;
&lt;p&gt;Let&apos;s use dependency injection and a default parameter to fix this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const tryId = x =&amp;gt; x?.id

function useItemSelection(getKey = tryId) {
  const [selectedItem, setSelectedItem] = React.useState(null)

  const handlers = React.useMemo(
    () =&amp;gt; ({
      selectItem: item =&amp;gt; {
        setSelectedItem(item)
      },
      unselectItem: () =&amp;gt; {
        setSelectedItem(null)
      },
      smartSelectItem: item =&amp;gt; {
        setSelectedItem(currentItem =&amp;gt; {
          if (getKey(item) === getKey(currentItem)) return null
          return item
        })
      },
    }),
    [getKey],
  )

  return [selectedItem, handlers]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now &lt;code&gt;useItemSelection&lt;/code&gt; is a bit more flexible. Perhaps you want to use &lt;code&gt;name&lt;/code&gt; as a key instead:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const [state, handlers] = useItemSelection(x =&amp;gt; x?.name)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;No longer does &lt;code&gt;useItemSelection&lt;/code&gt; force your data into a shape. You can easily conform &lt;code&gt;useItemSelection&lt;/code&gt; to your data.&lt;/p&gt;
</content:encoded><category>React</category><category>JavaScript</category><category>Prefer</category></item><item><title>Dependency Injection and Default Parameters</title><link>https://kyleshevlin.com/dependency-injection-and-default-parameters/</link><guid isPermaLink="true">https://kyleshevlin.com/dependency-injection-and-default-parameters/</guid><description>Learn how to increase the flexibility and testability of your programs by passing dependencies in as function arguments alongside default parameters.</description><pubDate>Thu, 19 Aug 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I&apos;ve been working on lessons for a new course recently, and one of the the lessons I created inspired me to share one of my favorite techniques for creating flexible functions: &lt;strong&gt;dependency injection and default parameters&lt;/strong&gt;. Let&apos;s dig in.&lt;/p&gt;
&lt;h3&gt;Dependency injection&lt;/h3&gt;
&lt;p&gt;Now, I don&apos;t have a computer science degree, so my understanding of what &quot;dependency injection&quot; is &lt;em&gt;might&lt;/em&gt; be a little different than yours, but allow me to explain how I understand it so we&apos;re on the same page for the rest of the blog post.&lt;/p&gt;
&lt;p&gt;Let&apos;s start by coming to agreement on what a &quot;dependency&quot; is. Let&apos;s say I have the following function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function formatString(str) {
  return capitalize(str)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is a simple, well named function. It &lt;em&gt;formats&lt;/em&gt; a string. But the part I want to focus on for a moment is the use of &lt;code&gt;capitalize&lt;/code&gt;. What is &lt;code&gt;capitalize&lt;/code&gt; in this situation?&lt;/p&gt;
&lt;p&gt;It is a dependency.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;formatString&lt;/code&gt; &lt;em&gt;depends&lt;/em&gt; on &lt;code&gt;capitalize&lt;/code&gt; (for now). If &lt;code&gt;capitalize&lt;/code&gt; isn&apos;t in scope for &lt;code&gt;formatString&lt;/code&gt;, the program falls apart and throws an error. In this way, &lt;em&gt;anything&lt;/em&gt; a &lt;code&gt;function&lt;/code&gt; &amp;lt;Marker content=&quot;Or class, which is more typically used when describing dependency injection.&quot; /&amp;gt; depends on is a dependency.&lt;/p&gt;
&lt;p&gt;This, of course, begs the next question: what does it mean to &quot;inject&quot; a dependency. Let&apos;s modify our &lt;code&gt;formatString&lt;/code&gt; function a little bit and find out.&lt;/p&gt;
&lt;p&gt;Instead of relying on &lt;code&gt;capitalize&lt;/code&gt; to be in the same scope, let&apos;s make it a parameter of the function and pass &lt;code&gt;capitalize&lt;/code&gt; in as an argument.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function formatString(str, formatter) {
  return formatter(str)
}

const capitalizedHello = formatString(&apos;hello&apos;, capitalize)
console.log(capitalizedHello) // &apos;Hello&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now the &lt;code&gt;formatter&lt;/code&gt; of our &lt;code&gt;formatString&lt;/code&gt; function is passed in as an argument. This allows us to pass in other &lt;code&gt;formatter&lt;/code&gt;s as well.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const scream = str =&amp;gt; [...str].map(x =&amp;gt; x.toUpperCase()).join(&apos;&apos;)
const snakeCase = str =&amp;gt; str.replace(/\s/g, &apos;_&apos;)

const str = &apos;hello world&apos;

formatString(str, scream) // HELLO WORLD
formatString(str, snakeCase) // hello_world
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But what happens if we &lt;em&gt;forget&lt;/em&gt; to pass in a &lt;code&gt;formatter&lt;/code&gt;?&lt;/p&gt;
&lt;p&gt;&lt;em&gt;*Cue the womp womp womp noises&lt;/em&gt; 🎺&lt;/p&gt;
&lt;p&gt;It falls apart, right? We can solve this with a default parameter.&lt;/p&gt;
&lt;h3&gt;Default parameters&lt;/h3&gt;
&lt;p&gt;JavaScript functions can be variadic, meaning they can be called with a variable number of arguments. When a function is called without an argument for a particular parameter, that parameter is assigned &lt;code&gt;undefined&lt;/code&gt;. However, if this is undesirable behavior, we can define defaults for these unassigned parameters using &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters&quot;&gt;default parameters&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In the case of our &lt;code&gt;formatString&lt;/code&gt; function, we can make use of the &lt;code&gt;identity&lt;/code&gt; function.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const identity = x =&amp;gt; x
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;identity&lt;/code&gt; function simply returns whatever is passed in. Give it a string. Get that string right back. It&apos;s perfect for a default parameter in our &lt;code&gt;formatString&lt;/code&gt; function. &amp;lt;Marker content=&quot;It turns out, the identity function is a useful default parameter in a lot of other functions, too&quot; /&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function formatString(str, formatter = identity) {
  return formatter(str)
}

formatString(&apos;hello world&apos;) // hello world
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, we don&apos;t need to provide a dependency if the default one suits our needs. Are you starting to see how this can bake flexibility into the programs you write?&lt;/p&gt;
&lt;h3&gt;Practical example&lt;/h3&gt;
&lt;p&gt;I&apos;m currently working on a course to help people understand &lt;code&gt;Array.reduce()&lt;/code&gt; better. It confuses a lot of people, and if you&apos;re one of them, know help is coming.&lt;/p&gt;
&lt;p&gt;In the course, we do a &lt;em&gt;lot&lt;/em&gt; of exercises using &lt;code&gt;reduce&lt;/code&gt; to build up our muscle memory. One of the more practical exercises is a &lt;code&gt;counts&lt;/code&gt; function. It receives an array, and counts the items in the array based on some criteria. The question is, how do we determine the criteria for counting the items?&lt;/p&gt;
&lt;p&gt;In the case of primitive values, such as &lt;code&gt;Number&lt;/code&gt;s, &lt;code&gt;String&lt;/code&gt;s and &lt;code&gt;Boolean&lt;/code&gt;s, the criteria is fairly simple: use the item itself. Let&apos;s start building this &lt;code&gt;counts&lt;/code&gt; function, but with a &lt;code&gt;for&lt;/code&gt; loop. Don&apos;t want to spoil all my course material:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function counts(items) {
  const result = {}

  for (const item of items) {
    if (result[item] === undefined) {
      result[item] = 0
    }

    result[item]++
  }

  return result
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now if we call &lt;code&gt;counts&lt;/code&gt; on some arrays with primitives, we&apos;d get results like these:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;counts([true, false, true, true, false, false, true])
// { true: 4, false: 3 }

counts([1, 2, 2, 3, 3, 3])
// { &apos;1&apos;: 1, &apos;2&apos;: 2, &apos;3&apos;: 3}

counts([&apos;apple&apos;, &apos;banana&apos;, &apos;apple&apos;, &apos;orange&apos;, &apos;orange&apos;, &apos;apple&apos;])
// { apple: 3, banana: 1, orange: 2}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That works great, but how do we handle situations where our items aren&apos;t primitives? Or situations where we might want to do something more complicated than use the &lt;code&gt;item&lt;/code&gt; itself as the key? &amp;lt;Marker content=&quot;Or handle &amp;lt;code&amp;gt;undefined&amp;lt;/code&amp;gt; as a value?&quot; /&amp;gt;&lt;/p&gt;
&lt;p&gt;You guessed it. Dependency injection and a default parameter.&lt;/p&gt;
&lt;p&gt;Let&apos;s add an argument to our &lt;code&gt;counts&lt;/code&gt; function, a &lt;code&gt;getKey&lt;/code&gt; callback function that will be passed the &lt;code&gt;item&lt;/code&gt; (and some other arguments). This function will determine the &lt;code&gt;key&lt;/code&gt; to be used in our &lt;code&gt;counts&lt;/code&gt; function for us.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function counts(items, getKey /* what should the default parameter be? */) {
  const result = {}

  // Notice the change we make with entries()
  for (const [index, item] of items.entries()) {
    // This is the same signature as the callback for .map or .filter
    const key = getKey(item, index, items)

    if (result[key] === undefined) {
      result[key] = 0
    }

    result[key]++
  }

  return result
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, if we have a more complicated array of items, or simply want to do something more complicated &lt;em&gt;with&lt;/em&gt; a primitive array of items, we can. Let&apos;s say I&apos;m counting inventory of some clothing. I want to be able to generate &lt;code&gt;counts&lt;/code&gt; based on the &lt;code&gt;color&lt;/code&gt; of the shirt and the &lt;code&gt;size&lt;/code&gt; of the shirt.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const shirts = [
  { color: &apos;red&apos;, size: &apos;M&apos; },
  { color: &apos;blue&apos;, size: &apos;M&apos; },
  { color: &apos;red&apos;, size: &apos;S&apos; },
  { color: &apos;red&apos;, size: &apos;L&apos; },
  { color: &apos;blue&apos;, size: &apos;S&apos; },
]

counts(shirts, item =&amp;gt; item.color)
// { red: 3, blue: 2 }

counts(shirts, item =&amp;gt; item.size)
// { L: 1, M: 2, S: 2 }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can even use it to do something like count how many even and odd numbers are in a list.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const nums = [1, 2, 3, 4, 5, 6, 7, 8, 9]

counts(nums, x =&amp;gt; (x % 2 ? &apos;odd&apos; : &apos;even&apos;))
// { odd: 5, even: 4 }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Injecting the &lt;code&gt;getKey&lt;/code&gt; dependency makes this function a lot more flexible. We just have one thing remaining. Did you figure out what the default &lt;code&gt;getKey&lt;/code&gt; function should be?&lt;/p&gt;
&lt;p&gt;That&apos;s right. It should be &lt;code&gt;identity&lt;/code&gt;. Our final &lt;code&gt;counts&lt;/code&gt; function looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function counts(items, getKey = identity) {
  const result = {}

  for (const [index, item] of items.entries()) {
    const key = getKey(item, index, items)

    if (result[key] === undefined) {
      result[key] = 0
    }

    result[key]++
  }

  return result
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;Functions can be made more flexible by passing in their dependencies rather than relying on them being available in their scope. We can set good defaults to handle most cases, and then override that parameter with argument of our own which injects the dependency. This pattern can be seen in something as small as the examples here, to much bigger systems.&lt;/p&gt;
&lt;h3&gt;Additional resources&lt;/h3&gt;
&lt;p&gt;One of the most fantastic talks I&apos;ve ever seen is &quot;Nothing is Something&quot; by &lt;a href=&quot;https://sandimetz.com/&quot;&gt;Sandi Metz&lt;/a&gt;. I have watched this talk half a dozen times in my life, it&apos;s that good. Even if you never write a line of Ruby, deep diving on her talks is well worth your time.&lt;/p&gt;
&lt;p&gt;This talk, &quot;Nothing is Something&quot;, really explores how dependency injection and object composition is the way to create truly flexible programs. I strongly encourage you to give it a watch:&lt;/p&gt;
&lt;p&gt;&amp;lt;div style={{ display: &apos;flex&apos;, justifyContent: &apos;center&apos; }}&amp;gt;
&amp;lt;iframe
width=&quot;560&quot;
height=&quot;315&quot;
src=&quot;https://www.youtube.com/embed/29MAL8pJImQ&quot;
title=&quot;YouTube video player&quot;
frameborder=&quot;0&quot;
allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&quot;
allowfullscreen
/&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
</content:encoded><category>JavaScript</category></item><item><title>Discriminated Unions and Destructuring in TypeScript</title><link>https://kyleshevlin.com/discriminated-unions-and-destructuring-in-typescript/</link><guid isPermaLink="true">https://kyleshevlin.com/discriminated-unions-and-destructuring-in-typescript/</guid><description>Discriminated unions in TypeScript can go awry when you use object or array destructuring. Learn why it happens and what you can do to fix the problem.</description><pubDate>Wed, 11 Aug 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I&apos;m writing this post because I&apos;ve forgotten the following material enough times to warrant leaving myself a permanent resource for future reference. I figure it will likely help out a few of you as well.&lt;/p&gt;
&lt;p&gt;I am a big fan of state machines, but often find myself unable to use them in the projects I work on. People are so hesitant to give them a try. I&apos;ll never understand it. Given this, I turn to the next best thing: enums.&lt;/p&gt;
&lt;p&gt;I like to enumerate the finite states my functions can return. If you&apos;re writing TypeScript, something I find myself doing more and more of these days, enumerated states often mean using &lt;a href=&quot;https://www.typescriptlang.org/docs/handbook/2/narrowing.html#discriminated-unions&quot;&gt;&quot;discriminated unions&quot;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A discriminated union is a type where a key or value can be used to determine the rest of the shape of that type. An example might be several types for objects that have a &lt;code&gt;kind&lt;/code&gt; key, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type GetPostsSuccess = {
  kind: &apos;success&apos;
  context: {
    data: { posts: [] }
  }
}

type GetPostsFailure = {
  kind: &apos;failure&apos;
  context: {
    error: { message: &apos;something went wrong&apos; }
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I can combine these with a union:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type GetPostResults = GetPostsSuccess | GetPostsFailure
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And now I can discriminate that union by the &lt;code&gt;kind&lt;/code&gt; key:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function getPosts(): GetPostResults {
  // Let&apos;s assume something happens and I get a result
}

function doSomethingWithPosts() {
  const result = getPosts()

  switch (result.kind) {
    case &apos;success&apos;:
      return result.context.data.posts

    case &apos;failure&apos;:
      return result.context.error.message
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I don&apos;t have to check if &lt;code&gt;result.context&lt;/code&gt; has &lt;code&gt;error&lt;/code&gt; or &lt;code&gt;data&lt;/code&gt; in either case because the TypeScript compiler &lt;em&gt;knows&lt;/em&gt; that if &lt;code&gt;result.kind&lt;/code&gt; is &lt;code&gt;&quot;success&quot;&lt;/code&gt;, then the rest of the object has &lt;code&gt;context.data.posts&lt;/code&gt;. This is a really nice feature, but it&apos;s easily broken with &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment&quot;&gt;destructuring&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changing that example only slightly, we break &lt;strong&gt;everything&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function getPosts(): GetPostResults {
  // Let&apos;s assume something happens and I get a result
}

function doSomethingWithPosts() {
  const { kind, context } = getPosts()

  switch (kind) {
    case &apos;success&apos;:
      return context.data.posts // Error

    case &apos;failure&apos;:
      return context.error.message // Error
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you try this in TypeScript, &lt;a href=&quot;https://www.typescriptlang.org/play?#code/C4TwDgpgBA4hwAUD2BnYKDKBXAxjiKKUAvFAN4CwAUFFANYCWAdgCYBcUA5CrvoZ9Vo4kTYBAAewDpRq0oLAIbAF0qGFToOAbQC6UAL6CD1Q1WqhIseMjQoAYgoYAbLACdopGbUasOnAGaOLu4CssKiElLkRrQQrq5IrqoAtgQoCgDmEH4oSKnAABbMGVAA7hCiZQlMGZzGsqam5uDQcIgaAEoEWE7oJFbttth4aVAAPgM26A7ObhDU1P5YTDjADCJQWYPoABQAlBxtU108vUReUAD0l1AAMvDcUAqEWKlQuflFNVAFCmCQTCIClYUAAkpt4E8oO5TsATAsqEsVmsNiwkBg8vAvhkAOoMQpTFD7aJhERocj0ZgsAA0UHCYkkBn6W0J+wRtBQpXxOAKUB2PhYexJcjpz2g3F4aU4bBicncwDcTDpIgZwAAdIplGr1LYrjcAKLxRLsuQ4MVcQKzEIy2Qi+WK5URSRquIJVxq1KETLQa5QQ1uoyNIA&quot;&gt;which you can do here&lt;/a&gt;, it will error. Twice, actually. It will tell you that &lt;code&gt;data&lt;/code&gt; doesn&apos;t exist on &lt;code&gt;context&lt;/code&gt; in the &lt;code&gt;&apos;success&apos;&lt;/code&gt; case and that &lt;code&gt;error&lt;/code&gt; doesn&apos;t exist in the &lt;code&gt;&apos;failure&apos;&lt;/code&gt; case. To which you will respond with, &quot;Sure the heck does!&quot;&lt;/p&gt;
&lt;p&gt;You, a mere mortal, can determine precisely what shape the type is, but alas, the TypeScript compiler can not.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In short, TypeScript loses the &quot;refinement&quot; of the discrimination when we use object or array destructuring. If you destructure an object or an array, TypeScript is unable to remember the shape of the whole based on a part. If we destructure &lt;code&gt;kind&lt;/code&gt;, it completely forgets what &lt;code&gt;context&lt;/code&gt; &lt;em&gt;specifically&lt;/em&gt; is, and instead types it as a union of what it could be:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type context =
  | {
      data: { posts: [] }
    }
  | {
      error: { message: &apos;something went wrong&apos; }
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It&apos;s created a union that&apos;s no longer discriminated and you&apos;re stuck having to check what keys or what objects again. Not ideal.&lt;/p&gt;
&lt;p&gt;I&apos;ll give you another example using an array as a &lt;a href=&quot;https://kyleshevlin.com/what-is-a-tuple&quot;&gt;tuple&lt;/a&gt;. This is a replication of the very problem I was working on today when I ran into this.&lt;/p&gt;
&lt;p&gt;I was trying to set up some state to follow the progress of calling an API. This is a very common pattern in web apps that benefits a lot from using enumerated states. Here are the types I created:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;enum States {
  IDLE = &apos;IDLE&apos;,
  LOADING = &apos;LOADING&apos;,
  SUCCESS = &apos;SUCCESS&apos;,
  FAILURE = &apos;FAILURE&apos;,
}

type Post = {
  title: string
  body: string
}

type Data = { posts: Array&amp;lt;Post&amp;gt; }

type Results =
  | [States.IDLE, undefined]
  | [States.LOADING, undefined]
  | [States.SUCCESS, Data]
  | [States.FAILURE, Error]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Examining &lt;code&gt;Results&lt;/code&gt;, we can see a discriminated union based on the &lt;code&gt;States&lt;/code&gt; enum. Let&apos;s create a custom hook that will use these types and fetch our posts:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function useGetPosts(): Results {
  const [result, setResult] = useState&amp;lt;Results&amp;gt;([States.IDLE, undefined])

  useEffect(() =&amp;gt; {
    setResult([States.LOADING, undefined])

    fetch(&apos;/api/posts&apos;)
      .then(res =&amp;gt; res.json())
      .then(data =&amp;gt; {
        setResult([States.SUCCESS, data])
      })
      .catch(error =&amp;gt; {
        setResult([States.FAILURE, error])
      })
  }, [])

  return result
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Going through the code, our typechecker is satisfied. Our &lt;code&gt;Results&lt;/code&gt; tuple is always one of our four possible results. Let&apos;s make use of this in a component.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Posts() {
  const result = useGetPosts()
  const [state, context] = result

  switch (state) {
    case States.IDLE:
      return &amp;lt;div&amp;gt;idle&amp;lt;/div&amp;gt;

    case States.LOADING:
      return &amp;lt;div&amp;gt;loading...&amp;lt;/div&amp;gt;

    case States.SUCCESS: {
      return (
        &amp;lt;div&amp;gt;
          {context.posts.map(post =&amp;gt; (
            &amp;lt;div key={post.title}&amp;gt;
              {post.title} {post.body}
            &amp;lt;/div&amp;gt;
          ))}
        &amp;lt;/div&amp;gt;
      )
    }

    case States.FAILURE: {
      return &amp;lt;div&amp;gt;{context.message}&amp;lt;/div&amp;gt;
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What do you think happens in this case? &lt;strong&gt;We lose our refinement!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;We&apos;ve done a perfectly natural thing in modern JavaScript. We&apos;ve returned a small array from our custom hook with our &lt;code&gt;state&lt;/code&gt; and some relevant &lt;code&gt;context&lt;/code&gt;, and then we destructured that &lt;code&gt;state&lt;/code&gt; and that &lt;code&gt;context&lt;/code&gt; where we make use of that hook so that our code is really easy to read for humans. &lt;em&gt;But it&apos;s not easy for the compiler&lt;/em&gt;. &amp;lt;Marker content=&quot;Compiler schmiler! This really grinds my gears.&quot; /&amp;gt;&lt;/p&gt;
&lt;p&gt;Instead, we need to make adjustments to keep our refinement.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Posts() {
  const result = useGetPosts()

  switch (result[0] /* state */) {
    case States.IDLE:
      return &amp;lt;div&amp;gt;idle&amp;lt;/div&amp;gt;

    case States.LOADING:
      return &amp;lt;div&amp;gt;loading...&amp;lt;/div&amp;gt;

    case States.SUCCESS: {
      // We can destructure here because our `context` is refined to the
      // correct shape by the switch statement. We can also skip
      // destructuring `state` and rename `context` to `data` in one step
      const [, data] = result

      return (
        &amp;lt;div&amp;gt;
          {data.posts.map(post =&amp;gt; (
            &amp;lt;div key={post.title}&amp;gt;
              {post.title} {post.body}
            &amp;lt;/div&amp;gt;
          ))}
        &amp;lt;/div&amp;gt;
      )
    }

    case States.FAILURE: {
      const [, error] = result
      return &amp;lt;div&amp;gt;{error.message}&amp;lt;/div&amp;gt;
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This produces no TypeScript errors. I find the code to be &lt;em&gt;ok&lt;/em&gt;. I could live with this, but it does not bring me joy.&lt;/p&gt;
&lt;p&gt;In this particular situation, it might be best to stick with an object instead of a tuple. Then at least you could have &lt;code&gt;result.state&lt;/code&gt; and &lt;code&gt;result.context&lt;/code&gt;. You would lose the convenience of renaming the values to be contextually appropriate though, eg &lt;code&gt;data&lt;/code&gt; in &lt;code&gt;SUCCESS&lt;/code&gt; and &lt;code&gt;error&lt;/code&gt; in &lt;code&gt;FAILURE&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Hopefully this has helped you understand discriminated unions a bit better and prevents you from getting stuck on these destructuring gotchas in the future. At the very least, I hope writing this helps &lt;em&gt;me&lt;/em&gt; with those things in the future, too.&lt;/p&gt;
</content:encoded><category>React</category><category>JavaScript</category><category>TypeScript</category></item><item><title>Prefer Declarative State Updaters</title><link>https://kyleshevlin.com/prefer-declarative-state-updaters/</link><guid isPermaLink="true">https://kyleshevlin.com/prefer-declarative-state-updaters/</guid><description>Learn how declarative state updaters improve the quality of your component&apos;s code.</description><pubDate>Sat, 07 Aug 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Since the advent of React hooks, I have seen a pattern emerge that I think is &lt;em&gt;less than ideal&lt;/em&gt;. I&apos;ve started calling it the &quot;naked state setter&quot; pattern.&lt;/p&gt;
&lt;p&gt;Before I explain it, I want to be clear: it&apos;s not an anti-pattern. You&apos;re not in any danger if you use it, but I don&apos;t think it&apos;s the &lt;em&gt;best&lt;/em&gt; pattern. I also think the growing use of types, eg. TypeScript or Flow, has obscured this less-then-ideal pattern, so recognizing it can be even trickier.&lt;/p&gt;
&lt;p&gt;Let me break down what I&apos;m seeing with some code. I&apos;m going to use a rudimentary example, so I&apos;m going to ask you to use some imagination throughout this post. Let&apos;s build a simple counter: &amp;lt;Marker content=&quot;Big surprise, right?&quot; /&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Counter() {
  const [count, setCount] = React.useState(0)
  return &amp;lt;div&amp;gt;{count}&amp;lt;/div&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Before you get distracted wondering why I have state when I have nothing changing the state, I want to point out what the &quot;naked state setter&quot; &lt;em&gt;is&lt;/em&gt;. It&apos;s the &lt;code&gt;setCount&lt;/code&gt; in this example. It&apos;s bare. It&apos;s &lt;strong&gt;naked&lt;/strong&gt;. It&apos;s not wrapped in anything. Get it?&lt;/p&gt;
&lt;p&gt;Let&apos;s finish our component (for now).&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { Button } from &apos;./components/Button&apos;

function Counter() {
  const [count, setCount] = React.useState(0)

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;div&amp;gt;{count}&amp;lt;/div&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;Button
          onClick={() =&amp;gt; {
            setCount(s =&amp;gt; s + 1)
          }}
        &amp;gt;
          +
        &amp;lt;/Button&amp;gt;
        &amp;lt;Button
          onClick={() =&amp;gt; {
            setCount(s =&amp;gt; s - 1)
          }}
        &amp;gt;
          -
        &amp;lt;/Button&amp;gt;
        &amp;lt;Button
          onClick={() =&amp;gt; {
            setCount(0)
          }}
        &amp;gt;
          reset
        &amp;lt;/Button&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We&apos;ve written all of our state updater functions inline. This isn&apos;t that uncommon, and honestly, there are many situations where this is fine. But just because it&apos;s fine, doesn&apos;t mean it can&apos;t be better.&lt;/p&gt;
&lt;p&gt;So what is the problem with these state updater functions?&lt;/p&gt;
&lt;p&gt;They don&apos;t tell you what they do! You have to read the body of the function to get that information. They barely wrap our naked state setter in anything. Just a pair of &lt;code&gt;{}&lt;/code&gt;. It&apos;s like wrapping our callback function in a toga. We are &lt;em&gt;very&lt;/em&gt; close to the bare skin.&lt;/p&gt;
&lt;p&gt;What if, instead, we made declarative state updater functions?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { Button } from &apos;./components/Button&apos;

function Counter() {
  const [count, setCount] = React.useState(0)

  const incrementCount = React.useCallback(() =&amp;gt; {
    setCount(s =&amp;gt; s + 1)
  }, [])

  const decrementCount = React.useCallback(() =&amp;gt; {
    setCount(s =&amp;gt; s - 1)
  }, [])

  const resetCount = React.useCallback(() =&amp;gt; {
    setCount(0)
  }, [])

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;div&amp;gt;{count}&amp;lt;/div&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;Button onClick={incrementCount}&amp;gt;+&amp;lt;/Button&amp;gt;
        &amp;lt;Button onClick={decrementCount}&amp;gt;-&amp;lt;/Button&amp;gt;
        &amp;lt;Button onClick={resetCount}&amp;gt;reset&amp;lt;/Button&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, we have three declarative state updaters. They describe what they do. They&apos;re wrapped in more than just &lt;code&gt;{}&lt;/code&gt;. They have a &lt;strong&gt;name&lt;/strong&gt;. As I&apos;m reading the UI, it&apos;s very clear what action will be taken for each &lt;code&gt;onClick&lt;/code&gt; event.&lt;/p&gt;
&lt;p&gt;&quot;But why does this matter, Kyle? It&apos;s all in the same component. It&apos;s simple. I can understand it!&quot;&lt;/p&gt;
&lt;p&gt;Ok. I hear you. You&apos;re right that in this contrived example, it&apos;s understandable. But what about when we have to pass those state updaters down to some children components?&lt;/p&gt;
&lt;p&gt;Let&apos;s say this component looked like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import CounterActions from &apos;./CounterActions&apos;

function Counter() {
  const [count, setCount] = React.useState(0)

  // What props should CounterActions get?
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;div&amp;gt;{count}&amp;lt;/div&amp;gt;
      &amp;lt;CounterActions /&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this case, I&apos;ve got another component that renders the actions of the &lt;code&gt;Counter&lt;/code&gt;. &lt;code&gt;CounterActions&lt;/code&gt; has the UI responsible for updating the state in &lt;code&gt;Counter&lt;/code&gt;. In order to do that, we have a few choices in what we pass to &lt;code&gt;CounterActions&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Naively, we could just give it &lt;code&gt;setCount&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;CounterActions setCount={setCount} /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This works, right? I can write all those updaters in the &lt;code&gt;CounterActions&lt;/code&gt; component. But what if I don&apos;t control &lt;code&gt;CounterActions&lt;/code&gt;? Maybe I&apos;m giving them a little too much leeway by giving them the naked state setter. What if &lt;code&gt;CounterActions&lt;/code&gt; arbitrarily decides to increment and decrement by values other than &lt;code&gt;1&lt;/code&gt;? What if I&apos;m giving them a little too much control? Nothing stops someone from writing &lt;code&gt;CounterActions&lt;/code&gt; like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { Button } from &apos;./components/Button&apos;

function CounterActions({ setCount }) {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;Button
        onClick={() =&amp;gt; {
          setCount(false)
        }}
      &amp;gt;
        +
      &amp;lt;/Button&amp;gt;
      &amp;lt;Button
        onClick={() =&amp;gt; {
          setCount({})
        }}
      &amp;gt;
        -
      &amp;lt;/Button&amp;gt;
      &amp;lt;Button
        onClick={() =&amp;gt; {
          setCount(null)
        }}
      &amp;gt;
        reset
      &amp;lt;/Button&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It&apos;s chaos! Mayhem! &lt;code&gt;CounterActions&lt;/code&gt; can run amuck with all the power of that naked state setter getting passed down as a prop. We gotta stop that!&lt;/p&gt;
&lt;p&gt;&quot;Ok, just add some types. That&apos;ll prevent the misuse,&quot; you say.&lt;/p&gt;
&lt;p&gt;Sure, let&apos;s try it.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { Button } from &apos;./components/Button&apos;

function Counter() {
  const [count, setCount] = React.useState&amp;lt;number&amp;gt;(0)

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;div&amp;gt;{count}&amp;lt;/div&amp;gt;
      &amp;lt;CounterActions setCount={setCount} /&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}

function CounterActions({ setCount }) {
  const incrementCount = React.useCallback(() =&amp;gt; {
    setCount(s =&amp;gt; s * 3)
  }, [])

  const decrementCount = React.useCallback(() =&amp;gt; {
    setCount(s =&amp;gt; s / 2)
  }, [])

  const resetCount = React.useCallback(() =&amp;gt; {
    setCount(1000)
  }, [])

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;Button onClick={incrementCount}&amp;gt;+&amp;lt;/Button&amp;gt;
      &amp;lt;Button onClick={decrementCount}&amp;gt;-&amp;lt;/Button&amp;gt;
      &amp;lt;Button onClick={resetCount}&amp;gt;reset&amp;lt;/Button&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ahhhh! Even types haven&apos;t saved us from this mess. It&apos;s even worse. Passing the naked state setter means that now the logic of my &lt;code&gt;count&lt;/code&gt; state exists somewhere &lt;em&gt;else&lt;/em&gt; and I can&apos;t restrict how it&apos;s used.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;This is where declarative state updaters really shine.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Instead, let&apos;s define the API that we want &lt;code&gt;CounterActions&lt;/code&gt; to use. We don&apos;t care &lt;em&gt;how&lt;/em&gt; &lt;code&gt;CounterActions&lt;/code&gt; or any further children use it, but we know they can&apos;t misuse it. &amp;lt;Marker content=&quot;Too badly.&quot; /&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import CounterActions from &apos;./CounterActions&apos;

function Counter() {
  const [count, setCount] = React.useState(0)

  const incrementCount = React.useCallback(() =&amp;gt; {
    setCount(s =&amp;gt; s + 1)
  }, [])

  const decrementCount = React.useCallback(() =&amp;gt; {
    setCount(s =&amp;gt; s - 1)
  }, [])

  const resetCount = React.useCallback(() =&amp;gt; {
    setCount(0)
  }, [])

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;div&amp;gt;{count}&amp;lt;/div&amp;gt;
      &amp;lt;CounterActions
        incrementCount={incrementCount}
        decrementCount={decrementCount}
        resetCount={resetCount}
      /&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, I don&apos;t have to worry about how &lt;code&gt;CounterActions&lt;/code&gt; uses my updaters. They can&apos;t really screw it up. They may make a broken, less than optimal &lt;code&gt;Counter&lt;/code&gt;, but it won&apos;t be because they can arbitrarily update state. They can only use what I allow them to use. It&apos;s the perfect amount of power to pass to another component.&lt;/p&gt;
&lt;h3&gt;A step further&lt;/h3&gt;
&lt;p&gt;What makes declarative state updaters even more powerful is how easily they can be refactored into a good custom hook. I&apos;m actually going to do &lt;em&gt;two&lt;/em&gt; refactors here at once: first, move the logic into a custom hook, and second, swap three &lt;code&gt;useCallback&lt;/code&gt;s for a single &lt;code&gt;useMemo&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import CounterActions from &apos;./CounterActions&apos;

function useCounter() {
  const [count, setCount] = React.useState(0)

  const handlers = React.useMemo(
    () =&amp;gt; ({
      increment: () =&amp;gt; {
        setCount(s =&amp;gt; s + 1)
      },
      decrement: () =&amp;gt; {
        setCount(s =&amp;gt; s - 1)
      },
      reset: () =&amp;gt; {
        setCount(0)
      },
    }),
    [],
  )

  return [count, handlers]
}

function Counter() {
  const [count, { increment, decrement, reset }] = useCounter()

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;div&amp;gt;{count}&amp;lt;/div&amp;gt;
      &amp;lt;CounterActions
        incrementCount={increment}
        decrementCount={decrement}
        resetCount={reset}
      /&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Hopefully you can see how nice it is to wrap our naked state setters to create quality declarative state updaters.&lt;/p&gt;
&lt;h3&gt;Time for you to use your imagination&lt;/h3&gt;
&lt;p&gt;This is the part where I need you to think about how you&apos;re writing your code right now and apply the concepts here to the more important and likely complex work you are doing. Here&apos;s what I hope you take away.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Passing a naked state setter to children might be dangerous, even with types&lt;/li&gt;
&lt;li&gt;Declarative state updaters put you in control and prevent misuse&lt;/li&gt;
&lt;li&gt;Declarative state updaters are easy to refactor into custom hooks&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So go on, wrap those naked state setters up with some thing.&lt;/p&gt;
</content:encoded><category>React</category><category>Prefer</category></item><item><title>How I Structure My React Projects</title><link>https://kyleshevlin.com/how-i-structure-my-react-projects/</link><guid isPermaLink="true">https://kyleshevlin.com/how-i-structure-my-react-projects/</guid><description>React and modern JavaScript gives you the freedom to structure your React projects however you want. Learn how I structure mine.</description><pubDate>Thu, 01 Jul 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import SocialPost from &apos;../../../components/SocialPost.astro&apos;&lt;/p&gt;
&lt;p&gt;Recently, my friend Chance and I had this exchange on Twitter:&lt;/p&gt;
&lt;p&gt;&amp;lt;SocialPost
authorName=&quot;Chance Strickland&quot;
authorHandle=&quot;@chance.dev&quot;
authorProfile=&quot;https://bsky.app/profile/chance.dev&quot;
avatarUrl=&quot;https://cdn.bsky.app/img/avatar/plain/did:plc:ka6432pfe364n2kjrfhi7aro/bafkreib6ezxyvfqhf63242ir67o47u4cepbct55umevxlnhduh7yslc25a@jpeg&quot;
date=&quot;2021-06-11&quot;
content={&lt;code&gt;I&apos;ve been teaching workshops on React for a few months now, and one thing almost every team asks about at some point is folder structure and &quot;best practices&quot;&lt;/code&gt;}
/&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;SocialPost
authorName=&quot;Kyle Shevlin&quot;
authorHandle=&quot;@kyleshevl.in&quot;
authorProfile=&quot;https://bsky.app/profile/kyleshevl.in&quot;
avatarUrl=&quot;/images/kyle-headshot.jpg&quot;
date=&quot;2021-06-11&quot;
content={`
Do you shrug and go &quot;it really doesn&apos;t matter, just pick one and be consistent&quot;?&lt;/p&gt;
&lt;p&gt;Cause that&apos;s what I would do.
`}
/&amp;gt;&lt;/p&gt;
&lt;p&gt;It&apos;s true. It really doesn&apos;t matter. That said, I&apos;m going to share a few of my preferences and why they are what they are.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Warning&lt;/strong&gt;: &lt;em&gt;These are my opinions. You don&apos;t have to agree with them. If you don&apos;t agree with them, that&apos;s ok. Just know, I&apos;m not going to engage in an argument with you about these opinions.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;Single file components&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Don&apos;t&lt;/strong&gt; have a folder named &lt;code&gt;MyComponent&lt;/code&gt; with an &lt;code&gt;index.tsx&lt;/code&gt;, &lt;code&gt;styles.ts|css&lt;/code&gt;, and &lt;code&gt;types.ts&lt;/code&gt; file, etc.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Do&lt;/strong&gt; have a file named &lt;code&gt;MyComponent.js|jsx|tsx&lt;/code&gt; and have all related styles and types in the same file.&lt;/p&gt;
&lt;h4&gt;Why?&lt;/h4&gt;
&lt;p&gt;First, it is a waste of time and annoying AF to have to search for a file in my editor by typing &lt;code&gt;MyComponent&lt;/code&gt; followed by &lt;code&gt;index&lt;/code&gt; to ensure I get the right file.&lt;/p&gt;
&lt;p&gt;This is one of my least favorite features of &quot;convention over configuration&quot; frameworks like Ember and should be avoided in React projects. You end up with hundreds and hundreds of files that have the same name, &lt;code&gt;index.js&lt;/code&gt; or &lt;code&gt;component.js&lt;/code&gt; and you always have to do two-part searches. What an absolute waste of keystrokes. I know you may think that&apos;s trivial, but it adds up when you&apos;re searching for dozens and dozens of files every day. It&apos;s never good enough to just do &lt;code&gt;MyComponent&lt;/code&gt;. You need to add &lt;code&gt;styles&lt;/code&gt; or &lt;code&gt;types&lt;/code&gt; or use arrow keys to navigate a list to get the file you were looking for. What a waste!&lt;/p&gt;
&lt;p&gt;Second, having files that only exist to export tightly coupled information, like &lt;code&gt;styles&lt;/code&gt; and &lt;code&gt;types&lt;/code&gt; is equally wasteful and can lead to some organizational footguns. Put the info directly in the same file. You&apos;ll convey information faster, improve Intellisense speed, and more. Plus, you get the bonus of &lt;strong&gt;not&lt;/strong&gt; creating an export unless other modules &lt;em&gt;actually&lt;/em&gt; need that value. When you do the multi-file approach, you run the risk of people importing styles and types in an ad hoc fashion and it&apos;s a fast way to running into duplication and organizational messes.&lt;/p&gt;
&lt;h3&gt;Sub-components in same file, too&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Don&apos;t&lt;/strong&gt; make a separate file for a small sub-component that won&apos;t be reused by another part of the system.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Do&lt;/strong&gt; use sub-components where it makes sense, but keep them in the same file.&lt;/p&gt;
&lt;h4&gt;Why?&lt;/h4&gt;
&lt;p&gt;Related to single file components, if you are breaking up a bigger component into sub-components and those sub-components are relatively small and are not intended for reuse, keep those in the same file as well.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function BigComponent(props) {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;SubComponentA /&amp;gt;
      &amp;lt;SubComponentB someProp={props.someProp} /&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}

function SubComponentA() {
  return &amp;lt;div&amp;gt;Sub A&amp;lt;/div&amp;gt;
}

function SubComponentB({ someProp }) {
  return &amp;lt;div&amp;gt;{someProp}&amp;lt;/div&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So long as &lt;code&gt;SubComponentA&lt;/code&gt; and &lt;code&gt;SubComponentB&lt;/code&gt; have no reason to be exported or used elsewhere, there&apos;s nothing wrong with keeping them within the same file. In fact, it encourages you to break your monolithic components down into reasonable and understandable pieces.&lt;/p&gt;
&lt;p&gt;There is &lt;em&gt;one&lt;/em&gt; downside to this if you&apos;re using TypeScript. You will have to re-declare the types of your &lt;code&gt;props&lt;/code&gt; for every component you do some prop drilling for. Given that you can often define a &lt;code&gt;Props&lt;/code&gt; type, and then reuse the types in it with &lt;code&gt;Pick&amp;lt;&amp;gt;&lt;/code&gt; or something similar, I find this to be a reasonable tradeoff.&lt;/p&gt;
&lt;h3&gt;Feature folders&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Don&apos;t&lt;/strong&gt; &lt;em&gt;just&lt;/em&gt; have a folder named &lt;code&gt;components&lt;/code&gt; and throw everything in there.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Do&lt;/strong&gt; have a folder named &lt;code&gt;features&lt;/code&gt; where each sub-folder is a specific feature containing all the files related to that feature.&lt;/p&gt;
&lt;h4&gt;Why?&lt;/h4&gt;
&lt;p&gt;I think when you&apos;re first starting a project or doing a side project, it&apos;s fine to have a single &lt;code&gt;components&lt;/code&gt; folder and throw everything into it. But soon enough, you&apos;ll realize you have a set of components that are &lt;code&gt;shared&lt;/code&gt; and many components that are really just one-off abstractions for a single feature. Keeping these in the same folder misrepresents how these components should be used in your system.&lt;/p&gt;
&lt;p&gt;I have found it better to take those components related to a single feature to give that feature a name and contain all the files for that feature in that folder. Doing so, allows you to treat the feature similar to a package, exporting &lt;em&gt;precisely&lt;/em&gt; what you intend to the rest of your system. You can even write &lt;code&gt;eslint&lt;/code&gt; rules that prevent people from importing values that are nested further than the top level of your &lt;code&gt;features&lt;/code&gt; folder. It forces you to think about the interfaces of your system and to define useful boundaries.&lt;/p&gt;
&lt;p&gt;This also has the benefit of more accurately representing your organizational information. I have found this to be a useful means of helping people onboard to complex projects. Rather than asking them to try and piece everything together from across your codebase, it is easy to pick a feature and explore that sub-tree of your system.&lt;/p&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;Don&apos;t create extra files just to export something that&apos;s only used by a single component, like styles and types. Use single file components to encourage exporting &lt;em&gt;precisely&lt;/em&gt; what the rest of the system needs &lt;em&gt;and&lt;/em&gt; improve file search by a few keystrokes each time.&lt;/p&gt;
&lt;p&gt;Similarly, keep sub-components in the same file until they become useful abstractions for the system.&lt;/p&gt;
&lt;p&gt;When you do have these useful components to break out, determine if they belong to part of your &lt;code&gt;shared&lt;/code&gt; system &amp;lt;Marker content=&quot;Perhaps your design system?&quot; /&amp;gt;, or really belong solely to a feature. Use feature folders to identify boundaries in your system.&lt;/p&gt;
</content:encoded><category>React</category></item><item><title>What are &amp;ldquo;Magic Values&amp;rdquo;?</title><link>https://kyleshevlin.com/what-are-magic-values/</link><guid isPermaLink="true">https://kyleshevlin.com/what-are-magic-values/</guid><description>Learn what &quot;magic values&quot; are in programming and how to avoid them to improve the quality of your code.</description><pubDate>Sat, 26 Jun 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I recently did a code review for an aspiring developer and instructed them to &quot;get rid of the &apos;magic values&apos; in their code.&quot; It dawned on me that it might not have been obvious what I meant, so I figured I would take a few moments, and paragraphs, to explain.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A &quot;magic value&quot; is a string or number used in a program that is essential to its proper function but provides no context or explanation for why it is what it is.&lt;/strong&gt; The best explanation is that it &quot;magically&quot; works.&lt;/p&gt;
&lt;p&gt;We know that there is no magic in programming, &amp;lt;Marker content=&quot;Though it certainly seems like it at times.&quot; /&amp;gt; and so we should do our best to remove &quot;magic&quot; from our code so that future you or others understand what we write today more clearly.&lt;/p&gt;
&lt;p&gt;Here are some common &quot;magic values&quot; I save as variables in my code.&lt;/p&gt;
&lt;h3&gt;Time related numbers&lt;/h3&gt;
&lt;p&gt;Let&apos;s say we are comparing two &lt;code&gt;Date&lt;/code&gt;s and we want to see if they are within three days of each other. We could do:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function isWithinThreeDays(date1, date2) {
  const difference = Math.abs(date1 - date2)
  return difference &amp;lt;= 259200000
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, you &lt;em&gt;might&lt;/em&gt; be clever enough to figure out that &lt;code&gt;259200000&lt;/code&gt; is the number of milliseconds in three days, but I doubt you would figure it out with a quick glance. Better is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const DAY_IN_MS = 1000 * 60 * 60 * 24

function isWithinThreeDays(date1, date2) {
  const difference = Math.abs(date1 - date2)
  return difference &amp;lt;= DAY_IN_MS * 3
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now our number isn&apos;t so &quot;magic&quot; anymore. It&apos;s a lot easier to understand that we&apos;re comparing &lt;code&gt;difference&lt;/code&gt; with three days worth of milliseconds.&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;localStorage&lt;/code&gt; keys&lt;/h3&gt;
&lt;p&gt;If I ever have to store something in &lt;code&gt;localStorage&lt;/code&gt; for an app, I make sure to turn my storage key into a constant variable. This way I have a single string declared, but a variable I can use over and over and over and know with certainty it will be correct. No typos possible.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const STORAGE_KEY = &apos;kyleshevlin:theme&apos;

const currentTheme = localStorage.getItem(STORAGE_KEY)

const updateTheme = theme =&amp;gt; localStorage.setItem(STORAGE_KEY, theme)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Regexes&lt;/h3&gt;
&lt;p&gt;Assuming you are a human, you probably can&apos;t read complicated regexes with full comprehension at a glance. Better to give your patterns a really good variable name and use that in your program. Would you rather have:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function isValidEmail(email) {
  return /^(([^&amp;lt;&amp;gt;()[\]\\.,;:\s@&quot;]+(\.[^&amp;lt;&amp;gt;()[\]\\.,;:\s@&quot;]+)*)|(&quot;.+&quot;))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(
    email.toLowerCase()
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or this?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// You can even go the extra mile and leave a comment about the pattern
// or the URL where you found it: https://stackoverflow.com/questions/46155/how-to-validate-an-email-address-in-javascript
const VALID_EMAIL_PATTERN = /^(([^&amp;lt;&amp;gt;()[\]\\.,;:\s@&quot;]+(\.[^&amp;lt;&amp;gt;()[\]\\.,;:\s@&quot;]+)*)|(&quot;.+&quot;))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/

function isValidEmail(email) {
  return VALID_EMAIL_PATTERN.test(email.toLowerCase())
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;Avoid &quot;magic values&quot; in your code. Don&apos;t be afraid to pull strings, numbers and more out and give them some context with a great name. It&apos;ll prevent bugs in your code from typos, and make your programs easier to understand in the future.&lt;/p&gt;
</content:encoded><category>JavaScript</category><category>Software Engineering</category></item><item><title>`useMemo` and Stable Values</title><link>https://kyleshevlin.com/usememo-and-stable-values/</link><guid isPermaLink="true">https://kyleshevlin.com/usememo-and-stable-values/</guid><description>A short explanation on how I use `React.useMemo` to stabilize values for re-renders.</description><pubDate>Tue, 08 Jun 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The most common pattern I use when writing custom React hooks is to return a tuple of &lt;code&gt;[state, handlers]&lt;/code&gt;. &lt;code&gt;state&lt;/code&gt; is the value held by the hook, and &lt;code&gt;handlers&lt;/code&gt; is an object with methods that update the state. &amp;lt;Marker content=&quot;I really need to write a post about this pattern next.&quot; /&amp;gt; The way I write the &lt;code&gt;handlers&lt;/code&gt; object typically raises some questions. &amp;lt;Marker content=&quot;And potentially a few eyebrows.&quot; /&amp;gt; I&apos;ll show you an example from a basic &lt;code&gt;useSwitch&lt;/code&gt; hook.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function useSwitch(initialState = false) {
  const [state, setState] = React.useState(initialState)

  // PAY ATTENTION HERE
  const handlers = React.useMemo(
    () =&amp;gt; ({
      on: () =&amp;gt; {
        setState(true)
      },
      off: () =&amp;gt; {
        setState(false)
      },
      toggle: () =&amp;gt; {
        setState(s =&amp;gt; !s)
      },
      reset: () =&amp;gt; {
        setState(initialState)
      },
    }),
    [initialState]
  )

  return [state, handlers]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The typical question I get, and why I&apos;m writing this post, is &quot;Why did you use &lt;code&gt;useMemo&lt;/code&gt; instead of several &lt;code&gt;useCallback&lt;/code&gt;s?&quot;&lt;/p&gt;
&lt;p&gt;The answer has two parts, but both are straightforward:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;useMemo&lt;/code&gt; is the simplest way I know to create a &lt;strong&gt;stable value&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;handlers&lt;/code&gt; object of methods is the nicest API I can provide my hook users&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Creating stable values&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;useMemo&lt;/code&gt; returns a memoized value. &lt;a href=&quot;/memoization&quot;&gt;Learn about memoization here&lt;/a&gt; if you need to first. This means that as long as the dependencies don&apos;t change, &lt;code&gt;useMemo&lt;/code&gt; will return the cached value from when it was previously computed. It is made &lt;a href=&quot;https://reactjs.org/docs/hooks-reference.html#usememo&quot;&gt;clear in the docs&lt;/a&gt; that this is &lt;em&gt;not&lt;/em&gt; a guarantee, but for all intents and purposes, we can treat it like it is one. &amp;lt;Marker content=&quot;Recalculations when no dependencies have changed are rare.&quot; /&amp;gt; Therefore, we can use &lt;code&gt;useMemo&lt;/code&gt; to eliminate value changes that may cause unnecessary renders downstream. I have found &lt;code&gt;useMemo&lt;/code&gt; especially useful for values stored by reference: arrays, objects, sets, etc, and hence why I use it for my &lt;code&gt;handlers&lt;/code&gt; object.&lt;/p&gt;
&lt;h3&gt;Nice APIs&lt;/h3&gt;
&lt;p&gt;Often, the abbreviation API is reserved for the interface for getting items from a database or a service, but often I think about what I&apos;m returning from a function as an API as well. I think this is the best way to think about custom React hooks. Ask yourself, &quot;What API am I giving users of this?&quot; as you design it.&lt;/p&gt;
&lt;p&gt;When it comes to custom hooks, the API pattern of a tuple of &lt;code&gt;[state, handlers]&lt;/code&gt; is very simple, yet flexible for the user. Perhaps my user only needs one method from &lt;code&gt;handlers&lt;/code&gt;. Or needs to rename a method to be more semantically accurate for their purposes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Door() {
  const [isOpen, { toggle }] = useSwitch(false)

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;p&amp;gt;The door is {isOpen ? &apos;open&apos; : &apos;closed&apos;}.&amp;lt;/p&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;Button onClick={toggle}&amp;gt;Toggle door&amp;lt;/Button&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Imagine if I &lt;em&gt;did not&lt;/em&gt; use an object for my &lt;code&gt;handlers&lt;/code&gt;? What if we wrote it as a collection of &lt;code&gt;useCallback&lt;/code&gt;s instead?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function useSwitch(initialState = false) {
  const [state, setState] = React.useState(initialState)

  const on = React.useCallback(() =&amp;gt; {
    setState(true)
  }, [])

  const off = React.useCallback(() =&amp;gt; {
    setState(false)
  }, [])

  const toggle = React.useCallback(() =&amp;gt; {
    setState(s =&amp;gt; !s)
  }, [])

  const reset = React.useCallback(() =&amp;gt; {
    setState(initialState)
  }, [initialState])

  return [state /* WHAT DO I DO HERE? */]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Do I return each callback as a positional item in the tuple? No! That would be a pain in the ass.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function useSwitch(initialState = false) {
  // ... all the code from before
  return [state, on, off, toggle, reset]
}

function Door() {
  // you can skip items while array destructuring by not assigning the value
  // at that index a variable name
  const [isOpen, , , toggle] = useSwitch(false)

  // ... the rest of the code
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So we&apos;re back to putting them in an object:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function useSwitch(initialState = false) {
  // ... all the code from before
  return [state, { on, off, toggle, reset }]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But that object is getting recreated every render. &amp;lt;Marker content=&quot;So is the array literal, but try not to fixate on that too much. You can stabilize that, too, if you&apos;d like.&quot; /&amp;gt; Might as well use &lt;code&gt;useMemo&lt;/code&gt; and return a stable object. They&apos;re practically never going to change anyways!&lt;/p&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;useMemo&lt;/code&gt; is a way of creating stable values. It can be useful for values stored by reference, like an object of methods. Use it to optimize the performance of downstream consumers of that value. That&apos;s it.&lt;/p&gt;
</content:encoded><category>React</category></item><item><title>Symbolic Logic</title><link>https://kyleshevlin.com/symbolic-logic/</link><guid isPermaLink="true">https://kyleshevlin.com/symbolic-logic/</guid><description>Symbolic logic, the study of reducing arguments to an algebraic notation, can be useful knowledge for debugging and reasoning about programs.</description><pubDate>Wed, 12 May 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In college, I double majored in Philosophy and Mathematics. A required class for both of those majors was one called Symbolic Logic, or often referred to as Propositional Logic. The course teaches you to break arguments down into an algebraic notation and follow a set of principles to come to logically sound conclusions.&lt;/p&gt;
&lt;p&gt;I have found that as a software engineer I frequently use the principles this course taught me in my programming. I may not look at some code and specifically say out loud, &quot;That&apos;s a &lt;em&gt;modus ponens&lt;/em&gt;&quot; or &quot;That&apos;s a hypothetical syllogism&quot;, but I know they&apos;re there. &amp;lt;Marker content={&lt;code&gt;I have said, &quot;I can use DeMorgan&apos;s Law here,&quot; many times.&lt;/code&gt;} /&amp;gt;&lt;/p&gt;
&lt;p&gt;My hope with this post isn&apos;t to radically change your ability to code, but rather give you some vocabulary for discussing logic in your programs and more.&lt;/p&gt;
&lt;h3&gt;Foundational knowledge&lt;/h3&gt;
&lt;p&gt;There are a few things you need to know before reading the rest of this post. I&apos;m going to express all of these logical principles with pseudo-code as best as I can. This accomplishes two things (at least). First, it makes it easier for me to type (rather than using the formal symbols more commonly used in textbooks on the subject). Second, it is my hope that using a code-like syntax will help you relate the concepts to your coding work more easily, therefore improving the learning of the concepts.&lt;/p&gt;
&lt;p&gt;In my pseudo-code, I will be using the traditional letters used in symbolic logic, &lt;code&gt;p&lt;/code&gt; and &lt;code&gt;q&lt;/code&gt;, as placeholders for propositions. You can think of them as variables in our logical equations. To the best of my knowledge, &lt;code&gt;p&lt;/code&gt; was chosen as an abbreviation of &quot;proposition&quot;, and then letters are chosen by alphabetical order. Just like real variable names, you can choose to replace them with something more meaningful if that helps you.&lt;/p&gt;
&lt;p&gt;Here is a small legend of my pseudo-code:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;p&lt;/code&gt; or &lt;code&gt;q&lt;/code&gt; represent propositions, or elements of an argument&lt;/li&gt;
&lt;li&gt;&lt;code&gt;=&amp;gt;&lt;/code&gt; is used for &quot;entails&quot;. It can also be read as &quot;If &lt;code&gt;p&lt;/code&gt;, then &lt;code&gt;q&lt;/code&gt;&quot;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;---&lt;/code&gt; is used to indicate the end of the original set of propositions. What follows are conclusions derived from those propositions.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;!&lt;/code&gt; is used for &quot;negation&quot;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;amp;&lt;/code&gt; is used for &quot;and&quot;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;|&lt;/code&gt; is used for &quot;or&quot;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;===&lt;/code&gt; is used for &quot;material equivalence&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Certain conclusions can only be derived from applying other logical principles. When a principle is applied, an abbreviation of the principle&apos;s name, as well as the line numbers of the propositions required to impart that principle, will be noted next to the conclusion.&lt;/p&gt;
&lt;h3&gt;Rules of Inference&lt;/h3&gt;
&lt;p&gt;The first set of logical rules we are going to discuss can be categorized as &quot;rules of inference&quot;. That is, from the information at hand, we can logically deduce a set of conclusions. This set of logical principles may be useful in debugging programs, as they will teach you to arrive at sound conclusions given the information you have. Let&apos;s get started.&lt;/p&gt;
&lt;h4&gt;&lt;em&gt;Modus Ponens&lt;/em&gt;&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;Modus ponens&lt;/em&gt; is the most foundational rule of inference we can learn. I would tell you what the Latin means, but honestly, I think it would only add confusion rather than clarity, so I&apos;ll leave you to read the &lt;a href=&quot;https://en.wikipedia.org/wiki/Modus_ponens&quot;&gt;wiki on it&lt;/a&gt; on your own. The rule reads as follows:&lt;/p&gt;
&lt;p&gt;If &lt;code&gt;p&lt;/code&gt;, then &lt;code&gt;q&lt;/code&gt;. &lt;code&gt;p&lt;/code&gt; is true, therefore &lt;code&gt;q&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;And in our symbolic logic format, it looks like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1. p =&amp;gt; q
2. p
---
3. q   1,2 M.P.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If one proposition entails another and the first proposition is true, we can conclude that the second proposition is true. We use this all of the time in programming:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if (data) {
  doSomethingWith(data)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This principle is also used frequently when debugging code. If you do not have the result you would expect from a condition, then you must not have a truthful condition.&lt;/p&gt;
&lt;p&gt;The opposite, if I have the result I expect, then I must have a truthful condition, &lt;strong&gt;cannot&lt;/strong&gt; be logically deduced and is a common fallacy known as &quot;affirming the consequent&quot;. The reason this fails is that there may be other propositions that entail &lt;code&gt;q&lt;/code&gt; other than &lt;code&gt;p&lt;/code&gt;. Be careful when you program in making this fallacy. Getting the right result doesn&apos;t necessarily guarantee it got there by the path you expected. Always verify.&lt;/p&gt;
&lt;h4&gt;&lt;em&gt;Modus Tollens&lt;/em&gt;&lt;/h4&gt;
&lt;p&gt;Our next rule of inference is &lt;em&gt;modus tollens&lt;/em&gt;, whose Latin meaning might also cause more confusion than clarity, &lt;a href=&quot;https://en.wikipedia.org/wiki/Modus_tollens&quot;&gt;wiki here&lt;/a&gt;. It is closely related to &lt;em&gt;modus ponens&lt;/em&gt;. It follows:&lt;/p&gt;
&lt;p&gt;If &lt;code&gt;p&lt;/code&gt;, then &lt;code&gt;q&lt;/code&gt;. Not &lt;code&gt;q&lt;/code&gt;, therefore not &lt;code&gt;p&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;And in symbolic form, reads as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1. p =&amp;gt; q
2. !q
---
3. !p   1,2 M.T.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I have always found &lt;em&gt;modus tollens&lt;/em&gt; fascinating. Heuristically, we would gravitate towards saying, &quot;Not &lt;code&gt;p&lt;/code&gt; entails not &lt;code&gt;q&lt;/code&gt;&quot;, but this isn&apos;t quite true. Why? Because other elements of the universe can cause &lt;code&gt;q&lt;/code&gt;. We only know with certainty that the truthful condition of &lt;code&gt;p&lt;/code&gt; entails the consequent of &lt;code&gt;q&lt;/code&gt;. Thus, we also know with certainty, that the absence of &lt;code&gt;q&lt;/code&gt; ensures the absence of &lt;code&gt;p&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In programming, if we know that we have written a condition correctly, and we do not get the desired result, than we can deduce we have not met our condition. Worse than not meeting the requirements our condition, is knowing we have not satisfied our condition and, yet, our desired result still occurs. That, my friends, is a bug.&lt;/p&gt;
&lt;h4&gt;Conjunction and Simplification&lt;/h4&gt;
&lt;p&gt;No more Latin principles. I promise. Our next rules can be considered partners, and therefore will be taught together.&lt;/p&gt;
&lt;p&gt;conjunction is the combining of two propositions: &lt;code&gt;p&lt;/code&gt;, &lt;code&gt;q&lt;/code&gt;, therefore &lt;code&gt;p &amp;amp; q&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1. p
2. q
---
3. p &amp;amp; q   1,2 Con.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Simplification is taking a conjunction and reducing it to one of its propositions: &lt;code&gt;p &amp;amp; q&lt;/code&gt;, therefore &lt;code&gt;p&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1. p &amp;amp; q
---
2. p   1 Simp.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In programming, we create a number of conjunctions and simplifications all the time. A conjunction could be creating a condition based on two different values, and a simplification could be the destructuring of a key/value from an object.&lt;/p&gt;
&lt;h4&gt;Hypothetical Syllogism&lt;/h4&gt;
&lt;p&gt;This logical principle is sometimes known as &quot;double &lt;em&gt;modus ponens&lt;/em&gt;&quot;, you&apos;ll soon see why.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;p&lt;/code&gt; entails &lt;code&gt;q&lt;/code&gt; and &lt;code&gt;q&lt;/code&gt; entails &lt;code&gt;r&lt;/code&gt;. Therefore, &lt;code&gt;p&lt;/code&gt; entails &lt;code&gt;r&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1. p =&amp;gt; q
2. q =&amp;gt; r
---
3. p =&amp;gt; r   1,2 H.S.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For me, hypothetical syllogism &lt;em&gt;just makes sense&lt;/em&gt;, which has always made it a bit difficult to explain to others. Essentially, it&apos;s a chain of &lt;em&gt;modus ponens&lt;/em&gt;, and removing the middle link in that chain.&lt;/p&gt;
&lt;p&gt;It is closely related to the transitive property. For example, in math, if you had &lt;code&gt;x &amp;gt; y&lt;/code&gt; and &lt;code&gt;y &amp;gt; z&lt;/code&gt;, then you can infer that &lt;code&gt;x &amp;gt; z&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In programming, correct usage of hypothetical syllogism may show you that you&apos;re able to reduce a few steps in a particular program, recognizing that one antecedent, &lt;code&gt;p&lt;/code&gt; entails a further consequent, &lt;code&gt;r&lt;/code&gt;.&lt;/p&gt;
&lt;h4&gt;Absorption&lt;/h4&gt;
&lt;p&gt;This one is probably the first oddball we&apos;re going to encounter and it might not be terribly useful for programming, though there might be times it is useful in debugging. Absorption goes as follows:&lt;/p&gt;
&lt;p&gt;If &lt;code&gt;p&lt;/code&gt;, then &lt;code&gt;q&lt;/code&gt;. Therefore, if &lt;code&gt;p&lt;/code&gt;, then &lt;code&gt;p &amp;amp; q&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1. p =&amp;gt; q
---
2. p =&amp;gt; p &amp;amp; q   1 Abs.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The premise of this principle builds upon a conjunction. If a condition leads to a result, then it is true that having that condition means having both the condition and the result. Another way to think about this is, the condition doesn&apos;t &lt;em&gt;disappear&lt;/em&gt; because it has led to a result. It is still present, and therefore, can be combined with the result to make new inferences.&lt;/p&gt;
&lt;h4&gt;Disjunctive Syllogism&lt;/h4&gt;
&lt;p&gt;This one might seem odd at first, so I&apos;ll give you an insight right away. The key to understanding disjunctive syllogism is understanding that when &lt;code&gt;|&lt;/code&gt; is used, it guarantees that &lt;em&gt;one&lt;/em&gt; of the premises is true. The rule goes as follows:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;p&lt;/code&gt; or &lt;code&gt;q&lt;/code&gt;. Not &lt;code&gt;p&lt;/code&gt;. Therefore, &lt;code&gt;q&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If we have a scenario where we have one premise or another, and we know for certain that we do not have one of them, we can deduce that we have the other. In our symbolic format, it looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1. p | q
2. !p
---
3. q   1,2 D.S.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This one might be a bit harder to use directly while programming. The best scenario I can think of is if you have a condition that&apos;s being met based on an &lt;code&gt;||&lt;/code&gt;, and you know for certain that one of the operands is &lt;code&gt;false&lt;/code&gt;, then you know the other is &lt;code&gt;true&lt;/code&gt;.&lt;/p&gt;
&lt;h4&gt;Constructive Dilemma&lt;/h4&gt;
&lt;p&gt;This rule of inference is is essentially combining &lt;em&gt;modus ponens&lt;/em&gt; with disjunctive syllogism. The rule goes:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;p&lt;/code&gt; entails &lt;code&gt;q&lt;/code&gt;, and &lt;code&gt;r&lt;/code&gt; entails &lt;code&gt;s&lt;/code&gt;. &lt;code&gt;p | r&lt;/code&gt;. Therefore, &lt;code&gt;q | s&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;We have two entailment clauses, this antecedent leads to that consequent. If we have a premise that says we have one or the other antecedent, in this case &lt;code&gt;p | r&lt;/code&gt;, then it follows that we have one or the other consequent &lt;code&gt;q | s&lt;/code&gt;. In symbolic form, it looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1. (p =&amp;gt; q) &amp;amp; (r =&amp;gt; s)
2. p | r
---
3. q | s   1,2 C.D.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A constructive dilemma essentially occurs whenever we have multiple conditional statements in some code. If we have multiple &lt;code&gt;if&lt;/code&gt; statements, we can think of those as entailments clauses. Because we know the set of antecedents, we also know the set of consequents that come from those &lt;code&gt;if&lt;/code&gt; statements.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function passwordStrength(str) {
  if (!str) return
  if (meetsTheseConditions(str)) return &apos;weak&apos;
  if (meetsTheseOtherConditions(str)) return &apos;strong&apos;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here we have three &lt;code&gt;if&lt;/code&gt; statements and the set of their consequents contains &lt;code&gt;weak&lt;/code&gt;, &lt;code&gt;strong&lt;/code&gt;, or &lt;code&gt;undefined&lt;/code&gt;. If we extrapolate this, we can see we have multiple constructive dilemmas.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1. noString =&amp;gt; undefined
2. weakString =&amp;gt; &apos;weak&apos;
3. strongString =&amp;gt; &apos;strong&apos;
---
4. (noString =&amp;gt; undefined) &amp;amp; (weakString =&amp;gt; &apos;weak&apos;)   1,2 Conj.
5. (noString =&amp;gt; undefined) &amp;amp; (strongString =&amp;gt; &apos;strong&apos;)   1,3 Conj.
6. (weakString =&amp;gt; &apos;weak&apos;) &amp;amp; (strongString =&amp;gt; &apos;strong&apos;)  2,3 Conj.
7. undefined | &apos;weak&apos;   4 C.D.
8. undefined | &apos;strong&apos;   5 C.D.
9. &apos;weak&apos; | &apos;strong&apos;   6 C.D.
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Addition&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;p&lt;/code&gt;, therefore &lt;code&gt;p | q&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This one&apos;s odd, but useful for meeting the requirements for other logical principles. Essentially, if you have a proposition, then you have that proposition &lt;em&gt;or&lt;/em&gt; any other proposition in the universe.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1. p
---
2. p | q   1 Add.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I&apos;ll come up with a rudimentary symbolic logic problem to show you what I mean. Let&apos;s combine addition with constructive dilemma. I&apos;ll give a set of premises and a conclusion we should be able to reach.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1. (p =&amp;gt; q) &amp;amp; (r =&amp;gt; s)
2. p
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;How do we prove the conclusion &lt;code&gt;q | s&lt;/code&gt;? We can do the following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;3. p | r   2 Add.
4. q | s   1,3 C.D.
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Rules of Replacement&lt;/h3&gt;
&lt;p&gt;The next set of principles we will learn are known as &quot;rules of replacement&quot;. These rules will teach us logically sound ways of swapping one set of premises for another. These rules can often be applied when trying to improve the legibility or even the performance of some code.&lt;/p&gt;
&lt;h4&gt;Double Negation&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;p === !!p&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;We are all not unfamiliar with this concept, right? &amp;lt;Marker content=&quot;See what I did there?&quot; /&amp;gt; Or would it be better to ask, &quot;We are all familiar with this concept, right?&quot;&lt;/p&gt;
&lt;p&gt;The most common time you&apos;ll see this in coding is if you come across the &quot;double bang&quot; &lt;code&gt;!!&lt;/code&gt;. This is often used in JavaScript to coerce a value into a boolean. It is the equivalent of calling &lt;code&gt;Boolean(value)&lt;/code&gt;. I prefer to use &lt;code&gt;Boolean()&lt;/code&gt;. It&apos;s easier to read.&lt;/p&gt;
&lt;h4&gt;Commutation&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;p | q === q | p&lt;/code&gt; as well as &lt;code&gt;p &amp;amp; q === q &amp;amp; p&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The rule of commutation means that, for certain logical operations, the order of the arguments does not matter. &lt;code&gt;|&lt;/code&gt; and &lt;code&gt;&amp;amp;&lt;/code&gt; are commutative operations. In mathematics, &lt;code&gt;+&lt;/code&gt; and &lt;code&gt;*&lt;/code&gt; are commutative.&lt;/p&gt;
&lt;p&gt;This rule can actually be useful in optimizing our program&apos;s performance. In JavaScript, when using a logical operand such as &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; or &lt;code&gt;||&lt;/code&gt;, we can improve performance by making the left side of the operation a case that is most like to &quot;short circuit&quot; the operation.&lt;/p&gt;
&lt;p&gt;Short circuiting a logical operation occurs when the left side of the infix operator guarantess the result. If the left side of conjunction is &lt;code&gt;false&lt;/code&gt;, as in &lt;code&gt;false &amp;amp;&amp;amp; ...&lt;/code&gt;, then the right side is irrelevant and not evaluated. Similarly, if the left side of a disjunction is &lt;code&gt;true&lt;/code&gt;, as in &lt;code&gt;true || ...&lt;/code&gt;, then the right side is irrelevant and not evaluated. We can use this to our advantage. Let&apos;s make an example.&lt;/p&gt;
&lt;p&gt;Let&apos;s say I want to determine if I should wear my rain jacket. I only wear my rain jacket when it&apos;s both cold and raining.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const requiresRainJacket = weather =&amp;gt; isCold(weather) &amp;amp;&amp;amp; isRaining(weather)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, consider the order of functions here. As written, we&apos;ll only get to the &lt;code&gt;isRaining&lt;/code&gt; check if it&apos;s cold. Is this the best order? I live in a pretty cool climate, it could probably evaluate that function to &lt;code&gt;true&lt;/code&gt; for 7-8 months of the year. &amp;lt;Marker content=&quot;I run pretty cold, wear a hoodie most of the year&quot; /&amp;gt; Two-thirds of the time, our function won&apos;t short circuit. Arguably, the &lt;code&gt;isRaining&lt;/code&gt; check is &lt;em&gt;more&lt;/em&gt; important, and more likely to short circuit than the &lt;code&gt;isCool&lt;/code&gt; check. So we can gain a &lt;em&gt;slight&lt;/em&gt; improvement by flipping the conditions.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const requiresRainJacket = weather =&amp;gt; isRaining(weather) &amp;amp;&amp;amp; isCold(weather)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Tautology&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;p === p | p&lt;/code&gt; as well as &lt;code&gt;p === p &amp;amp; p&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This one is quite possibly my favorite. &amp;lt;Marker content=&quot;It also has pretty much no practical use in programming. Sorry.&quot; /&amp;gt; A tautology is when we say that some thing is &lt;em&gt;that&lt;/em&gt; thing. Like, the weekend &lt;em&gt;is&lt;/em&gt; the end of the week. It&apos;s the kind of thing that when you were a kid you might have responded with a loud and emphatic, &quot;Duhhh!&quot;.&lt;/p&gt;
&lt;p&gt;In symbolic logic, we can use tautologies to achieve propositions that enable the inference of other propositions.&lt;/p&gt;
&lt;h4&gt;Association&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;(p | (q | r)) === ((p | q) | r)&lt;/code&gt; and &lt;code&gt;(p &amp;amp; (q &amp;amp; r)) === ((p &amp;amp; q) &amp;amp; r)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This rule of replacement may have you thinking we&apos;re writing a LISP with all the parentheses. This is similar to commutation, in that the rule of association says that, for certain logical operations, the grouping of operations does not matter. Again, this is similar to how in mathematics, if all the operations of an equation are &lt;code&gt;+&lt;/code&gt; or &lt;code&gt;*&lt;/code&gt;, it doesn&apos;t matter which one you do first.&lt;/p&gt;
&lt;p&gt;It&apos;s not often that this will come up in programming. In fact, it&apos;s more likely to come up when something is &lt;em&gt;not&lt;/em&gt; associative. In other words, sometimes you&apos;ll find a bug when you&apos;re parentheses group conditions in the wrong way. It&apos;s quite likely if the operations are associative, than your formatter may remove the groupings altogether.&lt;/p&gt;
&lt;h4&gt;Transposition&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;p =&amp;gt; q === !q =&amp;gt; !p&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Transposition is a replacement that we can see derives from &lt;em&gt;modus tollens&lt;/em&gt;. In programming, sometimes it is easier to read or write that the negation of one thing results in the negation of the other. Another way to think about this is &quot;absence&quot;. Sometimes it can be easier to say, &quot;The absence of this condition results in the absence of this other condition&quot;. Hopefully, that&apos;s some food for thought.&lt;/p&gt;
&lt;h4&gt;Material Implication&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;p =&amp;gt; q === !p | q&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This rule of replacement is the logical conclusion of a &lt;em&gt;modus ponens&lt;/em&gt;. If we have an entailment, where a condition leads to a result, then we can conclude that, at any given time, we either don&apos;t have a truthful condition or we have the result.&lt;/p&gt;
&lt;p&gt;In programming, we can recognize that either a condition isn&apos;t met or its result exists.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// There is no universe where the condition is false
// &amp;amp;&amp;amp; the result exists simultaneously. They are mutually
// exclusive propositions

if (condition) {
  return result
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Exportation&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;(p &amp;amp; q) =&amp;gt; r === p =&amp;gt; (q =&amp;gt; r)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;When I first started writing this rule of replacement, I thought, &quot;There&apos;s no way this is useful&quot;, but then I realized that exportation happens all the time. The rule works like this: If a consequent is the result of a conjunction, then we can simplify that conjunction, and deduce that one condition leads to the entailment of the rest. &amp;lt;Marker content=&quot;Confusing, I know. Give me a minute to explain.&quot; /&amp;gt;&lt;/p&gt;
&lt;p&gt;A simpler way to understand this, is probably just to see it. Have you ever written code like this?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if (thisCondition) {
  if (thisOtherCondition) {
    // ... some result
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you have, then you&apos;ve written the right side of an exportation. Can you see it? The logical replacement is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if (thisCondition &amp;amp;&amp;amp; thisOtherCondition) {
  // ... some result
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, I bet you&apos;ve done that refactor &lt;em&gt;a lot&lt;/em&gt;. Combine this with &quot;short circuiting&quot;, and you may have vastly improved some nasty nested &lt;code&gt;if-else&lt;/code&gt; code. Might I suggest you read my post &lt;a href=&quot;/when-elses-make-your-code-worse&quot;&gt;&quot;When &lt;code&gt;else&lt;/code&gt;s Make Your Code Worse&quot;&lt;/a&gt; some time.&lt;/p&gt;
&lt;h4&gt;Material Equivalence&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;(p === q) === ((p =&amp;gt; q) &amp;amp; (q =&amp;gt; p))&lt;/code&gt; and &lt;code&gt;(p === q) === ((p &amp;amp; q) | (!p &amp;amp; !q))&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This one is fairly complex looking, but breaking it down makes it more digestible.&lt;/p&gt;
&lt;p&gt;Two propositions are equivalent if it can be demonstrated that they entail one another. Two propositions are also equivalent if it can be demonstrated that their conjunction is true or the conjunction of their negations is true.&lt;/p&gt;
&lt;h4&gt;Distribution&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;(p &amp;amp; (q | r)) === ((p &amp;amp; q) | (p &amp;amp; r))&lt;/code&gt; and &lt;code&gt;(p | (q &amp;amp; r)) === ((p | q) &amp;amp; (p | r))&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The rule of distribution is the same for math as it is for symbolic logic. You might recall from an algebra class having an equation that looked like &lt;code&gt;3(2x + 4y) = 42&lt;/code&gt;. You might be required to distribute the &lt;code&gt;3&lt;/code&gt; to make it &lt;code&gt;6x + 12y = 42&lt;/code&gt;. Or the opposite, factoring out the &lt;code&gt;3&lt;/code&gt; if you had been given the latter equation. It works the same way for logic.&lt;/p&gt;
&lt;p&gt;You can see this in complicated conditional code sometimes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if (conditionA) {
  if (conditionB || conditionC) {
    // ... some result
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That&apos;s the same as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if ((conditionA &amp;amp;&amp;amp; conditionB) || (conditionA &amp;amp;&amp;amp; conditionC)) {
  // ... some result
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;De Morgan&apos;s Theorems&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;!(p &amp;amp; q) === (!p | !q)&lt;/code&gt; and &lt;code&gt;!(p | q) === (!p &amp;amp; !q)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Saving the best &amp;lt;Marker content=&quot;Best is debatable.&quot; /&amp;gt; and most useful for last. You should probably memorize this one.&lt;/p&gt;
&lt;p&gt;The negation of the conjunction of two premises is equivalent to the disjunction of the negation of each premise. Also, the negation of the disjunction of two premises is equivalent to the conjunction of the negation of each premise.&lt;/p&gt;
&lt;p&gt;Simple, right?&lt;/p&gt;
&lt;p&gt;Let&apos;s use a code example to make it simpler. Let&apos;s say we have an &lt;code&gt;item&lt;/code&gt; and we want to determine if it&apos;s &lt;code&gt;notForSale&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const notForSale = !(inStock(item) &amp;amp;&amp;amp; hasPrice(item))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This might be easier to read and understand as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const notForSale = !inStock(item) || !hasPrice(item)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Same thing goes for &lt;code&gt;||&lt;/code&gt;s. Maybe we want to determine if an event is coming soon:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const isUpcomingSoon = !(inThePast(event) || isBeyondThreshold(event))

// is the same as
const isUpcomingSoon = !inThePast(event) &amp;amp;&amp;amp; !isBeyondThreshold(event)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Knowing De Morgan&apos;s Theorems can help you refactor tricky conditionals into more legible code for you and your team.&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;And that&apos;s it. Everything there is to learn about symbolic logic. &amp;lt;Marker content=&quot;It&apos;s not.&quot; /&amp;gt; Truthfully, this is just scratching the surface. I hope that there&apos;s something in this post that inspires you and maybe helps you in a refactor or two.&lt;/p&gt;
</content:encoded><category>Software Engineering</category></item><item><title>Set Theory</title><link>https://kyleshevlin.com/set-theory/</link><guid isPermaLink="true">https://kyleshevlin.com/set-theory/</guid><description>Learn the fundamentals of Sets and how understanding them may benefit you as a software engineer and programmer.</description><pubDate>Wed, 21 Apr 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I find Sets and set theory to be a fascinating concept, both in the abstract &amp;lt;Marker content=&quot;As a mathematical and philosophical concept.&quot; /&amp;gt; and in the concrete &amp;lt;Marker content=&quot;I enjoy using them in JavaScript&quot; /&amp;gt;, and one that I find more and more useful as time goes on. I&apos;ve wanted to write an introductory post on the topic for a while now and hope it might inspire a similar interest in Sets for you.&lt;/p&gt;
&lt;h3&gt;What is a Set?&lt;/h3&gt;
&lt;p&gt;A Set is a collection of unique elements. Those elements can be literally anything. There exists the set of all integers that are factors of 3, the set of all aquatic mammals, the set of all of &lt;em&gt;my&lt;/em&gt; siblings.&lt;/p&gt;
&lt;p&gt;A Set can be full of many elements, such as the set of all blades of grass in my lawn &amp;lt;Marker content=&quot;Sorry, looking at my backyard as I write this!&quot; /&amp;gt;, or a set can be empty, such as the set of all humans living on planets other than Earth.&lt;/p&gt;
&lt;p&gt;Sets, &lt;strong&gt;in the abstract&lt;/strong&gt;, also don&apos;t have a sense of &quot;order&quot;. If I&apos;m talking about the set of all whole numbers between the values of &lt;code&gt;1&lt;/code&gt; and &lt;code&gt;5&lt;/code&gt;, they do not &lt;em&gt;necessarily&lt;/em&gt; need to come in the order: &lt;code&gt;1, 2, 3, 4, 5&lt;/code&gt;. They can be thought of just as equally in the order: &lt;code&gt;2, 1, 4, 3, 5&lt;/code&gt; or any other order. &amp;lt;Marker content=&quot;In the concrete, a &amp;lt;code&amp;gt;Set&amp;lt;/code&amp;gt; data structure in JavaScript does have order and can be iterated over with &amp;lt;code&amp;gt;for..of&amp;lt;/code&amp;gt;&quot; /&amp;gt; In this way, Sets are like &lt;a href=&quot;http://web.engr.oregonstate.edu/~sinisa/courses/OSU/CS261/CS261_Textbook/Chapter08.pdf&quot;&gt;bag data structures&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Throughout the rest of this post, I will be using drawings to aid in my explanation, so to get started, here&apos;s a Set:&lt;/p&gt;
&lt;p&gt;&amp;lt;Image
invertable
alt=&quot;A circle representing a &apos;set&apos;, filled in with color&quot;
src=&quot;/images/set-theory/Set.jpg&quot;
/&amp;gt;&lt;/p&gt;
&lt;p&gt;It is important to note that Sets often exist within a universe:&lt;/p&gt;
&lt;p&gt;&amp;lt;Image
invertable
alt=&quot;A circle representing a &apos;set&apos;, surrounded by a square representing the &apos;universe&apos; the set lives in&quot;
src=&quot;/images/set-theory/Set+Universe.jpg&quot;
/&amp;gt;&lt;/p&gt;
&lt;h3&gt;Sets interacting with other Sets&lt;/h3&gt;
&lt;p&gt;Sets become far more interesting (and useful) when we consider how they interact with one another.&lt;/p&gt;
&lt;h4&gt;Unions&lt;/h4&gt;
&lt;p&gt;The union of Set A and Set B is the Set containing &lt;em&gt;all&lt;/em&gt; the elements from Set A &lt;em&gt;and&lt;/em&gt; all the elements from Set B.&lt;/p&gt;
&lt;p&gt;&amp;lt;Image
invertable
alt=&quot;Two slightly overlapping circles, all filled in with color&quot;
src=&quot;/images/set-theory/Union.jpg&quot;
/&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function union(setA, setB) {
  // Make a copy
  const result = new Set(setA)

  for (let element of setB) {
    result.add(element)
  }

  return result
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Intersections&lt;/h4&gt;
&lt;p&gt;The intersection of Set A and Set B is the Set containing the elements in Set A &lt;em&gt;that are also&lt;/em&gt; in Set B. You may recognize this as a Venn Diagram.&lt;/p&gt;
&lt;p&gt;&amp;lt;Image
invertable
alt=&quot;Two slightly overlapping circles, only the overlap is colored in&quot;
src=&quot;/images/set-theory/Intersection.jpg&quot;
/&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function intersection(setA, setB) {
  const result = new Set()

  for (let element of setA) {
    if (setB.has(element)) {
      result.add(element)
    }
  }

  return result
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Differences&lt;/h4&gt;
&lt;p&gt;The difference of Set A and Set B is the Set containing all the elements from Set A that are &lt;em&gt;not&lt;/em&gt; in Set B.&lt;/p&gt;
&lt;p&gt;&amp;lt;Image
invertable
alt=&quot;Two slightly overlapping circles, only the left circle, minus the overlap, is colored in&quot;
src=&quot;/images/set-theory/Difference.jpg&quot;
/&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function difference(setA, setB) {
  const result = new Set()

  for (let element of setA) {
    if (!setB.has(element)) {
      result.add(element)
    }
  }

  return result
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that the &lt;code&gt;difference&lt;/code&gt; between two sets is dependent upon the order of the arguments. That is, given that Set A and Set B are not equal sets, then &lt;code&gt;difference(setA, setB)&lt;/code&gt; will not be equal to &lt;code&gt;difference(setB, setA)&lt;/code&gt;&lt;/p&gt;
&lt;h4&gt;Symmetric differences&lt;/h4&gt;
&lt;p&gt;The symmetric difference of Set A and Set B is the Set containing all the elements that are &lt;em&gt;not shared&lt;/em&gt; by Set A and Set B.&lt;/p&gt;
&lt;p&gt;&amp;lt;Image
invertable
alt=&quot;Two slightly overalapping circles, everything but the overlap is colored in&quot;
src=&quot;/images/set-theory/Symmetric_Difference.jpg&quot;
/&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function symmetricDifference(setA, setB) {
  const result = new Set()

  for (let element of setA) {
    if (!setB.has(element)) {
      result.add(element)
    }
  }

  for (let element of setB) {
    if (!setA.has(element)) {
      result.add(element)
    }
  }

  return result
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note, unlike &lt;code&gt;difference&lt;/code&gt;, &lt;code&gt;symmetricDifference&lt;/code&gt; will achieve the same result regardless of argument order. In this case, &lt;code&gt;symmetricDifference(setA, setB)&lt;/code&gt; will result in the same set as &lt;code&gt;symmetricDifference(setB, setA)&lt;/code&gt;.&lt;/p&gt;
&lt;h4&gt;Complements&lt;/h4&gt;
&lt;p&gt;The complement of a Set A is the Set containing all of the elements &lt;em&gt;not&lt;/em&gt; in Set A. By default, this would be all the other elements in the universe, but when constrained, complements can be useful.&lt;/p&gt;
&lt;p&gt;&amp;lt;Image
invertable
alt=&quot;Two adjacent universe squares with the same circle as a set inside each. In the first, the set is colored in, in the second, everything in the universe except for the set is colored in&quot;
src=&quot;/images/set-theory/Complement.jpg&quot;
/&amp;gt;&lt;/p&gt;
&lt;p&gt;For example, the symmetric difference of Set A and Set B is equivalent to the complement of the intersection of Set A and Set B. We can figure this out by first creating the union of Set A and Set B, then their intersection, and then getting the difference of those two results.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const all = union(setA, setB)
const shared = intersection(setA, setB)
const notShared = difference(all, shared)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Subsets and Supersets&lt;/h4&gt;
&lt;p&gt;Set A is a subset of Set B if every element of Set A is in Set B.&lt;/p&gt;
&lt;p&gt;&amp;lt;Image
invertable
alt=&quot;Two concentric circles, one containing the other, colored different colors. Set A is fully inside Set B, and thus A is a subset of B, and B is a superset of A&quot;
src=&quot;/images/set-theory/Subset+Superset.jpg&quot;
/&amp;gt;&lt;/p&gt;
&lt;p&gt;We can make use of &lt;code&gt;Array.prototype.every&lt;/code&gt; to help us with this one.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function subset(setA, setB) {
  return [...setA].every(element =&amp;gt; setB.has(element))
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Set A is a superset of Set B if Set B is a subset of Set A.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function superset(setA, setB) {
  return [...setB].every(element =&amp;gt; setA.has(element))
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Subsets and supersets are useful when categorizing elements. For example, &lt;code&gt;React&lt;/code&gt; is a subset of &lt;code&gt;JavaScript&lt;/code&gt;. If someone tells me that they know &lt;code&gt;React&lt;/code&gt;, I can safely deduce that they know some &lt;code&gt;JavaScript&lt;/code&gt; as well. However, if someone tells me they know &lt;code&gt;JavaScript&lt;/code&gt;, I cannot deduce that they know some &lt;code&gt;React&lt;/code&gt;. They might, they might not.&lt;/p&gt;
&lt;h3&gt;Disjointed Sets&lt;/h3&gt;
&lt;p&gt;Set A and Set B are considered disjointed if they share no elements.&lt;/p&gt;
&lt;p&gt;&amp;lt;Image
invertable
alt=&quot;Two circles with no overlap&quot;
src=&quot;/images/set-theory/Disjoint.jpg&quot;
/&amp;gt;&lt;/p&gt;
&lt;p&gt;Another way to think about disjointed sets is that their intersection is the empty set, and therefore has a &lt;code&gt;size&lt;/code&gt; of &lt;code&gt;0&lt;/code&gt;. We can use that to determine if two sets are disjointed or not.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function disjoint(setA, setB) {
  return intersection(setA, setB).size === 0
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is not uncommon to create disjointed unions, as we will soon see.&lt;/p&gt;
&lt;h3&gt;Where am I using Sets without maybe realizing it?&lt;/h3&gt;
&lt;p&gt;Type systems!&lt;/p&gt;
&lt;p&gt;When you describe a &lt;code&gt;value&lt;/code&gt; as the type &lt;code&gt;string&lt;/code&gt;, what you&apos;re really saying is that this &lt;code&gt;value&lt;/code&gt; belongs to the Set of all &lt;code&gt;string&lt;/code&gt;s. When you type an &lt;code&gt;array&lt;/code&gt; as &lt;code&gt;Array&amp;lt;number&amp;gt;&lt;/code&gt;, you&apos;re saying that this &lt;code&gt;array&lt;/code&gt; belongs to the Set of all arrays containing numbers.&lt;/p&gt;
&lt;p&gt;This is why types that use &lt;code&gt;|&lt;/code&gt; and &lt;code&gt;&amp;amp;&lt;/code&gt; are called union types and intersection types respectively.&lt;/p&gt;
&lt;p&gt;If I have a type that is &lt;code&gt;string | number&lt;/code&gt;, I&apos;m really saying that this item belongs to the union of the set of all strings and the set of all numbers. This is a disjointed union, since it&apos;s impossible for a value to be both shared by the set of strings and the set of numbers. &amp;lt;Marker content=&quot;The string of a number is still a string, at least for the sake of types and sets.&quot; /&amp;gt;&lt;/p&gt;
&lt;h3&gt;Are there practical uses?&lt;/h3&gt;
&lt;p&gt;Quite a few, but you have to get used to looking for them. I have used sets for tag/category systems (I use &lt;code&gt;Set&lt;/code&gt;s for my tags on this site). I&apos;ve used them for making efficient filtering systems, too. It&apos;s sometimes easiest to think of filtering items in terms of unions and intersections.&lt;/p&gt;
&lt;p&gt;Another place you&apos;ve probably seen them over and over is in vector drawing tools. Take a look at Figma for instance. If I make two vector shapes, select them both and then look at my options, don&apos;t these look strangely familiar? They even use some of the same words to describe the operation.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;At its core, manipulating vector graphics is as simple as doing some Set operations. Every shape is a Set of points, and we can use the operations to manipulate those points into complex shapes.&lt;/p&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;Sets are a collection of unique elements. Learning the fundamentals of Sets and set theory may open up some new ways of thinking of operating with data for you. Your mileage may vary. At the very least, I hope you find words like &quot;unions&quot; and &quot;intersections&quot; less intimidating (if they ever were at all).&lt;/p&gt;
&lt;h3&gt;Resources&lt;/h3&gt;
&lt;p&gt;There&apos;s one specific library I like to share with people in regards to &lt;code&gt;Set&lt;/code&gt;s that I want to share with you: &lt;a href=&quot;https://github.com/terkelg/zet&quot;&gt;Zet&lt;/a&gt;. It&apos;s incredibly simple and excellent. I encourage you to read the source code as well.&lt;/p&gt;
&lt;h3&gt;Additional Notes&lt;/h3&gt;
&lt;p&gt;It&apos;s worth noting that there are proposals to improve &lt;code&gt;Set&lt;/code&gt;s in JavaScript in the works: &lt;a href=&quot;https://github.com/tc39/proposal-set-methods&quot;&gt;https://github.com/tc39/proposal-set-methods&lt;/a&gt;. The work here will replace the need for libraries like Zet in the future.&lt;/p&gt;
</content:encoded><category>JavaScript</category><category>Computer Science</category></item><item><title>What is a Tuple?</title><link>https://kyleshevlin.com/what-is-a-tuple/</link><guid isPermaLink="true">https://kyleshevlin.com/what-is-a-tuple/</guid><description>Learn the concept of a tuple, an ordered, finite list of items that represents an implicit key/value store, and where you might already be using them in JavaScript.</description><pubDate>Thu, 01 Apr 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;As a JavaScript developer, we don&apos;t have an official &lt;code&gt;Tuple&lt;/code&gt; data type like we do &lt;code&gt;Array&lt;/code&gt; or &lt;code&gt;Object&lt;/code&gt;, but that doesn&apos;t mean we don&apos;t have tuples in our code. In a post I&apos;m working on, I realized I have several tuples in my code and it might be worth taking a minute to explain what a tuple is.&lt;/p&gt;
&lt;p&gt;We get tuples from mathematics. A tuple is a finite, ordered list of elements. In JavaScript, this would be likely represented as an array. I can create a tuple to represent a person like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const personTuple = [&apos;Kyle&apos;, 35, &apos;Portland, OR&apos;]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Looking at &lt;code&gt;personTuple&lt;/code&gt;, we can see that it is a finite length of 3 items, and that those items are in a particular order: &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;age&lt;/code&gt;, and &lt;code&gt;location&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;When might I use a tuple?&lt;/h3&gt;
&lt;p&gt;A tuple can be a convenient way to create and use key/value data.&lt;/p&gt;
&lt;p&gt;&quot;But Kyle, where are the keys? I don&apos;t see any!&quot;&lt;/p&gt;
&lt;p&gt;Good question.&lt;/p&gt;
&lt;p&gt;If objects are &lt;em&gt;explicit&lt;/em&gt; key/value stores, we can think of tuples as &lt;em&gt;implied&lt;/em&gt; key/value stores. Remember, a tuple is an ordered list. We can&apos;t jumble up the items of the list without breaking the contract of the tuple. Therefore, we can infer the keys of a tuple by the order of the list.&lt;/p&gt;
&lt;p&gt;For example, if I have a function that receives a &lt;code&gt;personTuple&lt;/code&gt;, I should be able to safely array destructure and get the right order of values every time.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function personIntro(personTuple) {
  const [name, age, location] = personTuple

  return `Hi, my name is ${name}. I am ${age} years old from ${location}.`
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Array destructuring makes the implicit key/value store of the tuple pretty clear.&lt;/p&gt;
&lt;h3&gt;Wait, are we using tuples all the time?&lt;/h3&gt;
&lt;p&gt;You are if you&apos;re using React! Think about what is returned to you everytime you use &lt;code&gt;useState&lt;/code&gt; or &lt;code&gt;useReducer&lt;/code&gt;. It&apos;s a tuple!&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const [state, setState] = React.useState()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What is &lt;code&gt;[state, setState]&lt;/code&gt; but a tuple? It is a &lt;code&gt;[value, setter]&lt;/code&gt; tuple. Same goes for &lt;code&gt;useReducer&lt;/code&gt;, but swap &lt;code&gt;setter&lt;/code&gt; for &lt;code&gt;dispatcher&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If I create a custom hook that returns &lt;code&gt;[state, handlers]&lt;/code&gt;, what have I done but created a tuple?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function useSwitch(initialState = false) {
  const [state, setState] = React.useState(initialState)

  const handlers = React.useMemo(
    () =&amp;gt; ({
      on: () =&amp;gt; {
        setState(true)
      },
      off: () =&amp;gt; {
        setState(false)
      },
      toggle: () =&amp;gt; {
        setState(s =&amp;gt; !s)
      },
    }),
    [],
  )

  return [state, handlers]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Turns out tuples are everywhere.&lt;/p&gt;
&lt;h3&gt;What makes a tuple different than an array?&lt;/h3&gt;
&lt;p&gt;An array is generally a list of items of unknown and unforeseen length. It can hold a few items, a lot of items, or no items at all.&lt;/p&gt;
&lt;p&gt;It&apos;s also more common for an array to be homogenous. That is, all the items in the list are the same type. You have an array of strings, an array of numbers, an array of person objects.&lt;/p&gt;
&lt;p&gt;Tuples, on the other hand, are lists of items of known, foreseen length. They have a finite number of items. They are more often hetergenous, as well. Our &lt;code&gt;personTuple&lt;/code&gt; from before had two strings and a number.&lt;/p&gt;
&lt;h3&gt;Tuples and type systems in JS&lt;/h3&gt;
&lt;p&gt;The distinctions between arrays and tuples are rather clear when using a type system with JavaScript, such as TypeScript or Flow. If we have an array of numbers, we may type it in either of the following ways in TypeScript.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const nums: Array&amp;lt;number&amp;gt; = [1, 2, 3, 4, 5, 6]

const nums2: number[] = [1, 2, 3, 4, 5, 6]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In either case, it&apos;s pretty clear that what we&apos;re returning is a homogenous array of numbers. It doesn&apos;t matter what length the array is, just that each item in it is of the same type.&lt;/p&gt;
&lt;p&gt;Compare this to typing a custom React hook that returns &lt;code&gt;state&lt;/code&gt; and &lt;code&gt;handlers&lt;/code&gt; as a tuple.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type SwitchTuple = [
  state: boolean,
  handlers: {
    on: () =&amp;gt; void
    off: () =&amp;gt; void
    toggle: () =&amp;gt; void
  },
]

function useSwitch(initialState = false): SwitchTuple {
  const [state, setState] = React.useState(initialState)

  const handlers = React.useMemo(
    () =&amp;gt; ({
      on: () =&amp;gt; {
        setState(true)
      },
      off: () =&amp;gt; {
        setState(false)
      },
      toggle: () =&amp;gt; {
        setState(s =&amp;gt; !s)
      },
    }),
    [],
  )

  return [state, handlers]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Instead of a homogenous array type, like &lt;code&gt;number[]&lt;/code&gt;, we&apos;ve instead given it a tuple type, clearly demarcating the &lt;code&gt;state&lt;/code&gt; and &lt;code&gt;handlers&lt;/code&gt; to be returned.&lt;/p&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;Tuples are ordered lists of finite length that can be used as implicit key/value stores. While JavaScript doesn&apos;t have a Tuple yet (&lt;a href=&quot;https://github.com/tc39/proposal-record-tuple&quot;&gt;there is a TC39 proposal to add it&lt;/a&gt;), you might already be using them. You may find them useful for particular algorithms, writing custom hooks and more.&lt;/p&gt;
</content:encoded><category>JavaScript</category><category>React</category><category>React Hooks</category></item><item><title>Conditional React Hooks</title><link>https://kyleshevlin.com/conditional-react-hooks/</link><guid isPermaLink="true">https://kyleshevlin.com/conditional-react-hooks/</guid><description>Learn how to conditionally use React Hooks by conditionally rendering a &quot;renderless component&quot;.</description><pubDate>Tue, 30 Mar 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;You want to conditionally call a hook, but you can&apos;t do that because of &lt;a href=&quot;https://reactjs.org/docs/hooks-rules.html&quot;&gt;&lt;em&gt;rules&lt;/em&gt;&lt;/a&gt;. What do you do?&lt;/p&gt;
&lt;p&gt;The answer is remarkably simple: &lt;strong&gt;Conditionally render a renderless component that uses the custom hook&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Many years ago, I coined the phrase &quot;renderless component&quot; in &lt;a href=&quot;/renderless-components&quot;&gt;this blog post&lt;/a&gt;. It&apos;s a component that uses the lifecycle methods to update app state but has no associated UI. It renders &lt;code&gt;null&lt;/code&gt;, hence &quot;renderless&quot;. These days, replace &quot;lifecycle methods&quot; with &quot;custom hooks&quot;, and the same concept applies and, therefore, we can achieve the same result.&lt;/p&gt;
&lt;p&gt;If we call a custom hook in a component:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function AutoSave({ data }) {
  useAutoSave(data)
  return null
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And then conditionally render that component in another component:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Document({ data, shouldAutoSave }) {
  return (
    &amp;lt;div&amp;gt;
      {shouldAutoSave &amp;amp;&amp;amp; &amp;lt;AutoSave data={data} /&amp;gt;}
      &amp;lt;div&amp;gt;
        &amp;lt;Editor data={data} /&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I can&apos;t tell you when or why you may need to do this, but it&apos;s a little tool to throw in your toolbelt and pull out when the occasion calls for it.&lt;/p&gt;
</content:encoded><category>React</category><category>React Hooks</category></item><item><title>Debounce and Throttle Callbacks with React Hooks</title><link>https://kyleshevlin.com/debounce-and-throttle-callbacks-with-react-hooks/</link><guid isPermaLink="true">https://kyleshevlin.com/debounce-and-throttle-callbacks-with-react-hooks/</guid><description>Learn how to debounce or throttle a callback function with React hooks while avoiding an exhaustive deps ESLint error</description><pubDate>Tue, 23 Mar 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This one will be short and to the point. I recently ran into a problem while trying to create a debounced callback with React hooks. If you&apos;re using the &lt;code&gt;react-hooks&lt;/code&gt; ESLint package with the recommended settings, then it will warn you that you can&apos;t do the following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import React from &apos;react&apos;
import { debounce } from &apos;lodash&apos;

function Search({ onSearch }) {
  const [value, setValue] = React.useState(&apos;&apos;)

  // This use of `useCallback` has a problem
  const debouncedSearch = React.useCallback(
    debounce(val =&amp;gt; {
      onSearch(val)
    }, 750),
    [onSearch]
  )

  const handleChange = React.useCallback(
    e =&amp;gt; {
      setValue(e.target.value)
      debouncedSearch(e.target.value)
    },
    [debouncedSearch]
  )

  return &amp;lt;input type=&quot;text&quot; value={value} onChange={handleChange} /&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This &lt;em&gt;looks&lt;/em&gt; fine, but here&apos;s the warning:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Error: React Hook useCallback received a function whose dependencies are unknown. Pass an inline function instead react-hooks/exhaustive-deps&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;useCallback&lt;/code&gt; expects an inline function. Handing it the returned function from a &lt;code&gt;debounce&lt;/code&gt; or &lt;code&gt;throttle&lt;/code&gt; doesn&apos;t cut the mustard. Why? The ESLint rule can&apos;t figure out what the exhaustive dependencies should be. How do we fix this?&lt;/p&gt;
&lt;p&gt;It might seem odd, but &lt;code&gt;useMemo&lt;/code&gt; comes to the rescue.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Search({ onSearch }) {
  const [value, setValue] = React.useState(&apos;&apos;)

  // This is the solution
  const debouncedSearch = React.useMemo(
    () =&amp;gt;
      debounce(val =&amp;gt; {
        onSearch(val)
      }, 750),
    [onSearch]
  )

  const handleChange = React.useCallback(
    e =&amp;gt; {
      setValue(e.target.value)
      debouncedSearch(e.target.value)
    },
    [debouncedSearch]
  )

  return &amp;lt;input type=&quot;text&quot; value={value} onChange={handleChange} /&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Think about it. &lt;code&gt;useMemo&lt;/code&gt; is used to store a memoized value that should only be recalculated when the dependencies change. So what if that memoized value is a function?&lt;/p&gt;
&lt;p&gt;It wasn&apos;t obvious to me to do this at first, but it makes sense. We want the returned function, and we want it to have the correct exhaustive dependencies, and update whenever they change. &lt;code&gt;useMemo&lt;/code&gt; does exactly that.&lt;/p&gt;
&lt;p&gt;You can use this same technique with &lt;code&gt;throttle&lt;/code&gt;, too. Really any higher ordered function that returns a function. Sky is the limit.&lt;/p&gt;
&lt;p&gt;Lastly, credit where it&apos;s due. I came across this idea from &lt;a href=&quot;https://github.com/facebook/react/issues/19240#issuecomment-652945246&quot;&gt;this GitHub comment&lt;/a&gt;. Maybe give it a thumbs up if you found this helpful.&lt;/p&gt;
</content:encoded><category>React</category><category>React Hooks</category></item><item><title>How to Use React Context Effectively</title><link>https://kyleshevlin.com/how-to-use-react-context-effectively/</link><guid isPermaLink="true">https://kyleshevlin.com/how-to-use-react-context-effectively/</guid><description>Learn how to use React Context effectively in your web applications by using custom hooks and memoization.</description><pubDate>Thu, 11 Mar 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;React Context has always been a somewhat controversial tool. It was an experimental API for the longest time, but was eventually made a standard part of the API. Now with React Hooks, React Context is easier to use than ever, but that also makes it easy to use poorly. In this post, I want to go over how I personally use React Context. I think you&apos;ll find it succinct and useful.&lt;/p&gt;
&lt;h3&gt;What is React Context?&lt;/h3&gt;
&lt;p&gt;Conceptually, I think of React Context as a &lt;strong&gt;wormhole&lt;/strong&gt; component. It&apos;s designed to get a &lt;code&gt;value&lt;/code&gt; from a &lt;code&gt;Provider&lt;/code&gt; to all its distantly-related child &lt;code&gt;Consumer&lt;/code&gt;s, without passing the &lt;code&gt;value&lt;/code&gt; through all the components in between. In short, it&apos;s a way to avoid &quot;prop drilling&quot;.&lt;/p&gt;
&lt;h3&gt;How to create a Context&lt;/h3&gt;
&lt;p&gt;A Context is created with the &lt;code&gt;React.createContext&lt;/code&gt; method.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const MyContext = React.createContext()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;My first tip. Don&apos;t bother with providing a &lt;code&gt;defaultValue&lt;/code&gt;. If you&apos;re consuming context without a &lt;code&gt;Provider&lt;/code&gt; higher in the tree, either you&apos;re making a big mistake or you know exactly what you&apos;re doing. With no insult intended, it&apos;s more likely that you&apos;re making a mistake and not providing a &lt;code&gt;defaultValue&lt;/code&gt; will provide a signal that there&apos;s a problem you need to fix. &amp;lt;Marker content=&quot;The exception to this is if you must provide a default value for a type system. Hopefully the types save your bacon in that scenario then.&quot; /&amp;gt;&lt;/p&gt;
&lt;p&gt;Creating a Context returns an object with two properties, &lt;code&gt;Provider&lt;/code&gt; and &lt;code&gt;Consumer&lt;/code&gt;, both of which are components. &lt;code&gt;Provider&lt;/code&gt;s are parent components that receive a &lt;code&gt;value&lt;/code&gt; prop that they wormhole to all their &lt;code&gt;Consumer&lt;/code&gt; children. Here&apos;s a quick example using a &lt;code&gt;ThemeContext&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const ThemeContext = React.createContext()

function App() {
  return (
    &amp;lt;ThemeContext.Provider value=&quot;light&quot;&amp;gt;
      &amp;lt;Header /&amp;gt;
      &amp;lt;Main /&amp;gt;
      &amp;lt;Footer /&amp;gt;
    &amp;lt;/ThemeContext.Provider&amp;gt;
  )
}

function Header() {
  return (
    &amp;lt;ThemeContext.Consumer&amp;gt;
      {theme =&amp;gt; {
        return (
          &amp;lt;header
            style={{
              backgroundColor: theme === &apos;light&apos; ? &apos;#eee&apos; : &apos;#111&apos;,
            }}
          &amp;gt;
            &amp;lt;Nav /&amp;gt;
          &amp;lt;/header&amp;gt;
        )
      }}
    &amp;lt;/ThemeContext.Consumer&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As you can see, the &lt;code&gt;Header&lt;/code&gt; component consumes the &lt;code&gt;ThemeContext&lt;/code&gt; with a &lt;code&gt;Consumer&lt;/code&gt; component. The &lt;code&gt;theme&lt;/code&gt; makes its way to the &lt;code&gt;Header&lt;/code&gt; without needing to pass the value in as a prop. Now that you&apos;ve seen how the &lt;code&gt;Consumer&lt;/code&gt; component works, with the component and the render prop API, I want you to forget it. Obliterate it from your memory. I&apos;m going to show you a better way to consume a Context soon enough.&lt;/p&gt;
&lt;p&gt;Now that we understand roughly how to create and use a React Context, let&apos;s discuss some of the philosophy behind using it well.&lt;/p&gt;
&lt;h3&gt;Think locally before globally&lt;/h3&gt;
&lt;p&gt;It is tempting, once you learn React Context, to use it as a global store. It certainly can function that way and might even be effective, but I personally do &lt;strong&gt;not&lt;/strong&gt; think of it this way. At least, it&apos;s not my first thought when I need global data.&lt;/p&gt;
&lt;p&gt;In my opinion, Contexts should be related to a single concern and not a gathering place for all your data. Therefore, I find I use Context more often when working on a localized concern, such as a particular feature in my app.&lt;/p&gt;
&lt;p&gt;It is possible to use globally, but you should at least pause before you do and consider if there&apos;s an alternative that might be more useful for your situation. If there is not, then that&apos;s fine. Don&apos;t sweat it and proceed with Context.&lt;/p&gt;
&lt;p&gt;As we&apos;ll discuss soon, React Context can lead to a lot of rerenders if the data passed to the &lt;code&gt;value&lt;/code&gt; prop changes frequently. If I must use a Context Provider at a high level in the tree, such as a &lt;code&gt;ThemeProvider&lt;/code&gt;, I want to make sure this component does not change &lt;code&gt;value&lt;/code&gt; often so that my app performs well.&lt;/p&gt;
&lt;h3&gt;Always export your own &lt;code&gt;Provider&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;I cannot remember a single time in my years of writing React where there was a good reason for me &lt;em&gt;not&lt;/em&gt; to create a custom &lt;code&gt;Provider&lt;/code&gt; for a context. I do this like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const ThemeContext = React.createContext()

export function ThemeProvider({ children }) {
  return &amp;lt;ThemeContext.Provider value=&quot;light&quot;&amp;gt;{children}&amp;lt;/ThemeContext.Provider&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Why do I do this? I do this so that I have full control over &lt;code&gt;value&lt;/code&gt;. I do not want to give users of my &lt;code&gt;Provider&lt;/code&gt; options that I do not explicitly control. I can give them props that will allow them to alter whatever &lt;code&gt;value&lt;/code&gt; is eventually set to, but I am still in control. This prevents a number of future problems and encapsulates the concerns of the Context well.&lt;/p&gt;
&lt;h3&gt;Expose an API&lt;/h3&gt;
&lt;p&gt;The point of creating a Context, at least to me, is to define specifically how you want the &lt;code&gt;Consumer&lt;/code&gt;s to be able to interact with their corresponding &lt;code&gt;Provider&lt;/code&gt;s. Another way to say this is, if I&apos;m going to provide &lt;code&gt;Consumer&lt;/code&gt;s with some state, I&apos;m also going to provide them with the &lt;code&gt;handlers&lt;/code&gt; for that state. I&apos;m a big fan of providing specific state updaters to the consumers of my components, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const ThemeContext = React.createContext()

export function ThemeProvider({ children }) {
  const [theme, setTheme] = React.useState(&apos;light&apos;)

  const handlers = React.useMemo(
    () =&amp;gt; ({
      lighten: () =&amp;gt; {
        setTheme(&apos;light&apos;)
      },
      darken: () =&amp;gt; {
        setTheme(&apos;dark&apos;)
      },
      toggle: () =&amp;gt; {
        setTheme(s =&amp;gt; (s === &apos;light&apos; ? &apos;dark&apos; : &apos;light&apos;))
      },
    }),
    [],
  )

  return (
    &amp;lt;ThemeContext.Provider value={[theme, handlers]}&amp;gt;
      {children}
    &amp;lt;/ThemeContext.Provider&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This might seem verbose to some of you, but by creating a &lt;code&gt;handlers&lt;/code&gt; object with specific updaters for the theme state, we can guarantee that our theme state is never updated to a non-supported theme value.&lt;/p&gt;
&lt;h3&gt;Create a custom hook for your Context&lt;/h3&gt;
&lt;p&gt;There was a short window of time where we needed to use the &lt;code&gt;Context.Consumer&lt;/code&gt; render prop pattern, but I haven&apos;t used it since React Hooks made consuming context significantly easier.&lt;/p&gt;
&lt;p&gt;Rather than pass my Context object around and passing it into &lt;code&gt;React.useContext&lt;/code&gt; in every component that needs it, I export a custom hook from the same file I create the Context instead, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export const useThemeContext = () =&amp;gt; React.useContext(ThemeContext)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, any component that needs to consume the &lt;code&gt;ThemeContext&lt;/code&gt; can import &lt;code&gt;useThemeContext&lt;/code&gt; and use it. Like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Header() {
  const [theme, { toggle }] = useThemeContext()

  return (
    &amp;lt;header
      style={{
        backgroundColor: theme === &apos;light&apos; ? &apos;#eee&apos; : &apos;#111&apos;,
      }}
    &amp;gt;
      &amp;lt;Nav /&amp;gt;
      &amp;lt;button onClick={toggle}&amp;gt;Toggle theme&amp;lt;/button&amp;gt;
    &amp;lt;/header&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Optimize components that consume your custom hook&lt;/h3&gt;
&lt;p&gt;From the React docs:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;All consumers that are descendants of a Provider will re-render whenever the Provider’s &lt;code&gt;value&lt;/code&gt; prop changes.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Remember that quote. All Consumers rerender when the Provider updates, &lt;em&gt;regardless of whether it is necessary or not&lt;/em&gt;. This means, if you&apos;re not careful, you could be causing a lot of unnecessary rerenders in your application. React makes us, the users of React, responsible for preventing unnecessary rerenders, so how do we do this for components that consume a context?&lt;/p&gt;
&lt;p&gt;There are primarily two ways to accomplish. Both use memoization but in different ways.&lt;/p&gt;
&lt;p&gt;The first way is to turn the component that consumes the context into a &quot;container component&quot; and to use &lt;code&gt;React.memo&lt;/code&gt; on the &quot;presentational component&quot; that the container returns. Like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export function HeaderContainer({ children }) {
  const [theme, { toggle }] = useThemeContext()

  return &amp;lt;Header theme={theme} toggleTheme={toggle} /&amp;gt;
}

const Header = React.memo(function Header({ theme, toggleTheme }) {
  return (
    &amp;lt;header
      style={{
        backgroundColor: theme === &apos;light&apos; ? &apos;#eee&apos; : &apos;#111&apos;,
      }}
    &amp;gt;
      &amp;lt;Nav /&amp;gt;
      &amp;lt;button onClick={toggleTheme}&amp;gt;Toggle theme&amp;lt;/button&amp;gt;
    &amp;lt;/header&amp;gt;
  )
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This works because we turn the &lt;code&gt;value&lt;/code&gt; of the context into &lt;code&gt;props&lt;/code&gt; that are passed to a memoized component. The memoized component only updates if the &lt;code&gt;props&lt;/code&gt; change.&lt;/p&gt;
&lt;p&gt;The second technique does not require an extra component, but instead uses &lt;code&gt;React.useMemo&lt;/code&gt; to memoize what we return from the component that consumes the context. Like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Header() {
  const [theme, { toggle }] = useThemeContext()

  return React.useMemo(
    () =&amp;gt; (
      &amp;lt;header
        style={{
          backgroundColor: theme === &apos;light&apos; ? &apos;#eee&apos; : &apos;#111&apos;,
        }}
      &amp;gt;
        &amp;lt;Nav /&amp;gt;
        &amp;lt;button onClick={toggle}&amp;gt;Toggle theme&amp;lt;/button&amp;gt;
      &amp;lt;/header&amp;gt;
    ),
    [theme, toggle],
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This strategy works by memoizing the output of our component. It only recalculates our output if one of the &lt;code&gt;ThemeContext&lt;/code&gt; related values changes. &amp;lt;Marker content=&quot;It is likely someone will say, “That&apos;s not true!” and they would be pedantic, but also correct. The React docs mention that values memoized with &amp;lt;code&amp;gt;useMemo&amp;lt;/code&amp;gt; might be recalculated without the dependencies changing, but it works how we expect most of the time and will never calculate incorrectly, so don&apos;t worry about it.&quot; /&amp;gt;&lt;/p&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;That&apos;s it. That&apos;s how I use React Context effectively. To recap:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Don&apos;t worry about a default value&lt;/li&gt;
&lt;li&gt;Think locally and small before globally&lt;/li&gt;
&lt;li&gt;Make your own Provider&lt;/li&gt;
&lt;li&gt;Expose an API&lt;/li&gt;
&lt;li&gt;Export a custom hook, don&apos;t bother with a Consumer render prop component&lt;/li&gt;
&lt;li&gt;Memoize the components that consume the context, either by:
&lt;ul&gt;
&lt;li&gt;Container and &lt;code&gt;React.memo&lt;/code&gt;ized presentational components&lt;/li&gt;
&lt;li&gt;&lt;code&gt;React.useMemo&lt;/code&gt; the component&apos;s output&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Hope this helps you use React Context more effectively in your apps.&lt;/p&gt;
</content:encoded><category>React</category><category>React Hooks</category><category>JavaScript</category></item><item><title>Facade Pattern</title><link>https://kyleshevlin.com/facade-pattern/</link><guid isPermaLink="true">https://kyleshevlin.com/facade-pattern/</guid><description>Learn how the &quot;facade pattern&quot; can be used in JavaScript to make it easier to swap libraries, increase code flexibility, and hide complexity in your applications.</description><pubDate>Wed, 17 Feb 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;We live in exciting times (for JavaScript developers). There&apos;s almost a library for everything you can imagine on &lt;a href=&quot;https://npmjs.com&quot;&gt;npm&lt;/a&gt; and you can add packages to your projects so quickly. It&apos;s really quite a bit of fun when you take a second to think about it.&lt;/p&gt;
&lt;p&gt;However, this ability to quickly grab and use packages hides some technical debt you &lt;em&gt;might&lt;/em&gt; be creating when you do so. There&apos;s a reason these packages are called &quot;dependencies&quot;, and if you&apos;re not careful, you can wind up dependent upon something that is terribly difficult to manage or remove later.&lt;/p&gt;
&lt;p&gt;To that end, I want to introduce you to a pattern of programming called the &quot;facade pattern&quot;. I get the term from the &quot;Gang of Four&quot; (aka GoF) book, &lt;a href=&quot;https://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612?dchild=1&amp;amp;keywords=design+patterns&amp;amp;qid=1613630581&amp;amp;sr=8-4&amp;amp;linkCode=ll1&amp;amp;tag=kyleshevlin-20&amp;amp;linkId=caa9cd1b6f46468d77c7b2e6d3ac3650&amp;amp;language=en_US&amp;amp;ref_=as_li_ss_tl&quot;&gt;Design Patterns&lt;/a&gt;. It&apos;s a classic piece of computer science literature on the topic of object oriented programming. I don&apos;t talk much about OOP, but there are plenty of patterns and goodies to borrow from it. Use the link above if you&apos;d like to check it out.&lt;/p&gt;
&lt;p&gt;Essentially, the facade pattern is this: we add a layer of abstraction between the consumer of some code and the implementation of that code. In regards to packages like I&apos;m describing above, it&apos;s creating a wrapping function or class that uses the package (or several). There are at least 2 reasons to do this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Greater control of the exposed API&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Often a facade pattern is used to simplify a more complex class, object, or function&apos;s implementation from the consumer of the facade.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;To give yourself the flexibility to later swap packages and other implementation details without affecting the code that uses the facade&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With the facade pattern, we&apos;re able to hide details &quot;under the hood&quot;, changing them when necessary without affecting the API exposed by the facade and consumed by the rest of your application. I want to explore these two reasons in this post.&lt;/p&gt;
&lt;h3&gt;When to Use a Facade Pattern&lt;/h3&gt;
&lt;p&gt;There are some libraries so essential to your work that wrapping them in a facade would provide no benefit. If your project is built in React, it doesn&apos;t make sense to wrap the &lt;code&gt;React&lt;/code&gt; library in a facade because you&apos;ll probably want access to its entire API and you won&apos;t be swapping out any implementation details under the hood of your facade. React would be such an essential part of your project that if you change it, you &lt;em&gt;want&lt;/em&gt; to have to change everything else, too.&lt;/p&gt;
&lt;p&gt;On the other hand, libraries for fetching data, date formatting, and more can make good candidates for the facade pattern. Let&apos;s look at fetching data as an example.&lt;/p&gt;
&lt;p&gt;For a long time, and perhaps in many of your apps still, the &lt;code&gt;axios&lt;/code&gt; library was a popular way to fetch data. You might have used it directly in some code somewhere like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import React from &apos;react&apos;
import axios from &apos;axios&apos;

function DetailPage({ id }) {
  const [data, setData] = React.useState(null)

  React.useEffect(() =&amp;gt; {
    axios
      .get(`your/api/url/pages/${id}`)
      .then(res =&amp;gt; res.json())
      .then(json =&amp;gt; {
        setData(json)
      })
  }, [id])

  return data !== null &amp;amp;&amp;amp; &amp;lt;div&amp;gt;{JSON.stringify(data, null, 2)}&amp;lt;/div&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, imagine you have dozens, maybe hundreds or more components that are similar. They&apos;re fetching and posting data around your app, all using &lt;code&gt;axios&lt;/code&gt; directly.&lt;/p&gt;
&lt;p&gt;One day, your team decides that you want to drop the &lt;code&gt;axios&lt;/code&gt; dependency and switch to using &lt;code&gt;fetch&lt;/code&gt; instead. What&apos;s your immediate thought? I bet it&apos;s something like, &quot;Oh shit! Now I have to change &lt;em&gt;every single place we use &lt;code&gt;axios&lt;/code&gt;&lt;/em&gt;!&quot;&lt;/p&gt;
&lt;p&gt;Not a fun thought to have.&lt;/p&gt;
&lt;p&gt;You might get lucky. You might be able to write a codemod that can manage the problem, but what if you never put yourself in that situation in the first place? If we use a facade pattern, we can hide &lt;code&gt;axios&lt;/code&gt; under the hood, only consuming it in a single place. Something like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// API.js
import axios from &apos;axios&apos;

export default class API {
  get(url) {
    return axios.get(url)
  }

  post(url, options) {
    return axios.post(url, options)
  }

  // other methods, you get the idea...
}

// DetailPage.js
import React from &apos;react&apos;
import API from &apos;./API&apos;

function DetailPage({ id }) {
  const [data, setData] = React.useState(null)

  React.useEffect(() =&amp;gt; {
    API.get(`your/api/url/pages/${id}`)
      .then(res =&amp;gt; res.json())
      .then(json =&amp;gt; {
        setData(json)
      })
  }, [id])

  return data !== null &amp;amp;&amp;amp; &amp;lt;div&amp;gt;{JSON.stringify(data, null, 2)}&amp;lt;/div&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now if we want to replace &lt;code&gt;axios&lt;/code&gt;, we simply update the implementation details of our &lt;code&gt;API&lt;/code&gt; facade without having any affect on our components. Let&apos;s replace it with native &lt;code&gt;fetch&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// API.js
export default class API {
  get(url) {
    return fetch(url)
  }

  post(url, options) {
    return fetch(url, {
      method: &apos;POST&apos;,
      ...options,
    })
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Not only was it really painless to swap the implementation, it allowed us to manage some details and complexity that the consumers of our facade don&apos;t need. In this case, we bake in the &lt;code&gt;method&lt;/code&gt; value of &lt;code&gt;POST&lt;/code&gt; on the &lt;code&gt;post&lt;/code&gt; method, so that our users don&apos;t have to change the instances of &lt;code&gt;API.post()&lt;/code&gt; in the application.&lt;/p&gt;
&lt;p&gt;Now, because of our facade, if another great library for fetching data comes along that has features we want over native &lt;code&gt;fetch&lt;/code&gt;, we can update the implementation of &lt;code&gt;API&lt;/code&gt; with out needing to change any of our components that use it.&lt;/p&gt;
&lt;h3&gt;Additional Thoughts&lt;/h3&gt;
&lt;p&gt;Admittedly, I haven&apos;t had a chance to really try this pattern out on a massive codebase. I want to be upfront with you about that. I have been thinking about it a lot, though, because of some of the challenges I &lt;em&gt;have&lt;/em&gt; seen at work. It&apos;s really easy to stuck for years using some outdated library because it has become too essential to the application. I think using this pattern on key parts of your project could save you from a massive overhaul in a few years.&lt;/p&gt;
&lt;p&gt;For example, right now your project might use the &lt;code&gt;moment&lt;/code&gt; library, but you&apos;d like to try &lt;code&gt;date-fns&lt;/code&gt; instead. A facade would make that possible. You probably only use about 25% of the library anyways, so only expose what you need from it. With a facade already in place, it will certainly make it easy to switch to &lt;code&gt;Temporal&lt;/code&gt; when it lands. &amp;lt;Marker content={&lt;code&gt;&amp;lt;code&amp;gt;Temporal&amp;lt;/code&amp;gt; is a new datetime object coming to JavaScript. You can read more here: &amp;lt;a href=&quot;https://github.com/tc39/proposal-temporal&quot;&amp;gt;https://github.com/tc39/proposal-temporal&amp;lt;/a&amp;gt;&lt;/code&gt;} /&amp;gt;&lt;/p&gt;
&lt;p&gt;There are some tradeoffs to consider, too. You are adding a layer of abstraction that will likely require documentation. How else will you and your team know how to use the facade? Also, creating code means you&apos;re responsible for its maintenance and improvements. It&apos;s not as simple as just using another method or function from the library. You have to put in the work to update the facade if there are features of the underlying library you want to use. But it still might be a tradeoff worth making, hiding complexity that can be swapped or improved in the future. You&apos;ll have to decide for yourself.&lt;/p&gt;
</content:encoded><category>JavaScript</category><category>React</category><category>Computer Science</category><category>Software Engineering</category></item><item><title>useEncapsulation</title><link>https://kyleshevlin.com/use-encapsulation/</link><guid isPermaLink="true">https://kyleshevlin.com/use-encapsulation/</guid><description>Improve the quality of your codebase with encapsulation and custom React hooks.</description><pubDate>Thu, 28 Jan 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import SocialPost from &apos;../../../components/SocialPost.astro&apos;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update November 22nd, 2021:&lt;/strong&gt; I added a recording of my CascadiaJS on this topic to the end of this post. Enjoy!&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Recently, I shared this tweet:&lt;/p&gt;
&lt;p&gt;&amp;lt;SocialPost
authorName=&quot;Kyle Shevlin&quot;
authorHandle=&quot;@kyleshevl.in&quot;
authorProfile=&quot;https://bsky.app/profile/kyleshevl.in&quot;
avatarUrl=&quot;/images/kyle-headshot.jpg&quot;
date=&quot;2020-11-23&quot;
content={`
🔥 take I haven&apos;t fully thought through incoming: Every use of useEffect should be in a custom hook with a damn good name.&lt;/p&gt;
&lt;p&gt;It&apos;s frequently difficult to read &amp;amp; comprehend intention of the code when effects are strewn about. Better to encapsulate and provide context.
`}
/&amp;gt;&lt;/p&gt;
&lt;p&gt;This tweet was my response to some refactoring of our codebase, but having more than a month now to practice this a few more times, I&apos;m convinced this pattern is the right way to go. I&apos;ll go further and say &lt;strong&gt;most uses of React hooks should be encapsulated in a custom hook&lt;/strong&gt;, and I&apos;m going to try and convince you of that on this post.&lt;/p&gt;
&lt;p&gt;Before we get started, it will benefit you greatly if you read my post on &lt;a href=&quot;/encapsulation&quot;&gt;encapsulation&lt;/a&gt; first. In that post, I argue that the primary purpose of a function is to encapuslate all the elements of a concern together into a single structure. We&apos;re going to apply this pattern to how we work with React Hooks.&lt;/p&gt;
&lt;h3&gt;The Problem&lt;/h3&gt;
&lt;p&gt;Given the nature of our work, that requirements change frequently and therefore code changes frequently, too, it is not surprising that our codebases become messy. Our logic gets strewn about like tools left on a workbench. The problem is that hidden in the mess of functions and objects is important information that is getting lost. Important historical decisions left without explanation or context and more. I&apos;ll try to come up with a contrived example quickly.&lt;/p&gt;
&lt;p&gt;Imagine we have a &lt;code&gt;Component&lt;/code&gt; that can be toggled into two states: &lt;code&gt;off&lt;/code&gt; and &lt;code&gt;on&lt;/code&gt;. We&apos;ll use React Hooks to set this up.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Component() {
  const [state, setState] = React.useState(&apos;off&apos;)

  const on = React.useCallback(() =&amp;gt; {
    setState(&apos;on&apos;)
  }, [])

  const off = React.useCallback(() =&amp;gt; {
    setState(&apos;off&apos;)
  }, [])

  const toggle = React.useCallback(() =&amp;gt; {
    setState(s =&amp;gt; (s === &apos;on&apos; ? &apos;off&apos; : &apos;on&apos;))
  }, [])

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;div&amp;gt;State: {state}&amp;lt;/div&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;button type=&quot;button&quot; onClick={on}&amp;gt;
          Turn On
        &amp;lt;/button&amp;gt;
        &amp;lt;button type=&quot;button&quot; onClick={off}&amp;gt;
          Turn Off
        &amp;lt;/button&amp;gt;
        &amp;lt;button type=&quot;button&quot; onClick={toggle}&amp;gt;
          Toggle
        &amp;lt;/button&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Alright, so far so good. Our &lt;code&gt;Component&lt;/code&gt; is pretty simple so far and it feels like all of its concerns are handled in an orderly way. But requirements change and now perhaps our component also needs an input field (don&apos;t ask me why, I told you this is contrived).&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Component() {
  const [toggleState, setToggleState] = React.useState(&apos;off&apos;)
  const [inputState, setInputState] = React.useState(&apos;&apos;)

  const on = React.useCallback(() =&amp;gt; {
    setToggleState(&apos;on&apos;)
  }, [])

  const off = React.useCallback(() =&amp;gt; {
    setToggleState(&apos;off&apos;)
  }, [])

  const toggle = React.useCallback(() =&amp;gt; {
    setToggleState(s =&amp;gt; (s === &apos;on&apos; ? &apos;off&apos; : &apos;on&apos;))
  }, [])

  const handleInputChange = React.useCallback(e =&amp;gt; {
    setInputState(e.target.value)
  }, [])

  const resetInput = React.useCallback(() =&amp;gt; {
    setInputState(&apos;&apos;)
  }, [])

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;div&amp;gt;State: {toggleState}&amp;lt;/div&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;button type=&quot;button&quot; onClick={on}&amp;gt;
          Turn On
        &amp;lt;/button&amp;gt;
        &amp;lt;button type=&quot;button&quot; onClick={off}&amp;gt;
          Turn Off
        &amp;lt;/button&amp;gt;
        &amp;lt;button type=&quot;button&quot; onClick={toggle}&amp;gt;
          Toggle
        &amp;lt;/button&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;label htmlFor=&quot;randomWord&quot;&amp;gt;Random Word&amp;lt;/label&amp;gt;
        &amp;lt;input
          type=&quot;text&quot;
          id=&quot;randomWord&quot;
          onChange={handleInputChange}
          value={inputState}
        /&amp;gt;
        &amp;lt;button type=&quot;button&quot; onClick={resetInput}&amp;gt;
          Reset Input
        &amp;lt;/button&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Are you starting to see the problem I&apos;m seeing? Even though we wrote relatively clean and clear code, we have started to create a &lt;strong&gt;gap&lt;/strong&gt; between related implementation details.&lt;/p&gt;
&lt;p&gt;We &lt;em&gt;need&lt;/em&gt; to call our hooks in the same order every render of &lt;code&gt;Component&lt;/code&gt;. Those are the rules. To accomplish this, we&apos;ve followed a common organizational pattern with our declarations of state near the top of our component and our various event handlers further down. But in following this pattern, we&apos;ve separated the toggle state and its event handlers with the interruption of declaring another instance of &lt;code&gt;useState&lt;/code&gt;. Even worse, our input state is separated from its related handlers by three unrelated function declarations. &lt;strong&gt;Just imagine this in your codebase and I&apos;m sure you&apos;ve seen far worse!&lt;/strong&gt; This can quickly become a nightmare.&lt;/p&gt;
&lt;p&gt;There is, fortunately, a very simple solution: &lt;strong&gt;custom hooks&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;Why Custom Hooks are the Solution&lt;/h3&gt;
&lt;p&gt;A custom hook is &lt;em&gt;just a function&lt;/em&gt; and functions are structures we can use to encapsulate the related elements of a concern and expose an API to our function&apos;s consumer. In the case of our &lt;code&gt;Component&lt;/code&gt;, these custom hooks are fairly simple to create.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function useOnOff() {
  const [state, setState] = React.useState(&apos;off&apos;)

  const handlers = React.useMemo(
    () =&amp;gt; ({
      on: () =&amp;gt; {
        setState(&apos;on&apos;)
      },
      off: () =&amp;gt; {
        setState(&apos;off&apos;)
      },
      toggle: () =&amp;gt; {
        setState(s =&amp;gt; (s === &apos;on&apos; ? &apos;off&apos; : &apos;on&apos;))
      },
    }),
    [],
  )

  return [state, handlers]
}

function useInput() {
  const [state, setState] = React.useState(&apos;&apos;)

  const handlers = React.useMemo(
    () =&amp;gt; ({
      handleInputChange: e =&amp;gt; {
        setState(e.target.value)
      },
      resetInput: () =&amp;gt; {
        setState(&apos;&apos;)
      },
    }),
    [],
  )

  return [state, handlers]
}

function Component() {
  const [toggleState, { on, off, toggle }] = useOnOff()
  const [inputState, { handleInputChange, resetInput }] = useInput()

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;div&amp;gt;State: {toggleState}&amp;lt;/div&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;button type=&quot;button&quot; onClick={on}&amp;gt;
          Turn On
        &amp;lt;/button&amp;gt;
        &amp;lt;button type=&quot;button&quot; onClick={off}&amp;gt;
          Turn Off
        &amp;lt;/button&amp;gt;
        &amp;lt;button type=&quot;button&quot; onClick={toggle}&amp;gt;
          Toggle
        &amp;lt;/button&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;label htmlFor=&quot;randomWord&quot;&amp;gt;Random Word&amp;lt;/label&amp;gt;
        &amp;lt;input
          type=&quot;text&quot;
          id=&quot;randomWord&quot;
          onChange={handleInputChange}
          value={inputState}
        /&amp;gt;
        &amp;lt;button type=&quot;button&quot; onClick={resetInput}&amp;gt;
          Reset Input
        &amp;lt;/button&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Take notice, our &lt;code&gt;Component&lt;/code&gt; now only consumes custom hooks. These custom hooks give us a little more context to what they mean, and we don&apos;t have the implementation details of our state handler functions sitting in the middle of our component function.&lt;/p&gt;
&lt;p&gt;Another benefit of this pattern is that dependencies quickly become obvious &lt;em&gt;because they end up being arguments to our custom hooks&lt;/em&gt;. What if our &lt;code&gt;useInput&lt;/code&gt; hook should begin with an initial state other than an empty string and we use that for resetting the input as well?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function useInput(initialState = &apos;&apos;) {
  const [state, setState] = React.useState(initialState)

  const handlers = React.useMemo(
    () =&amp;gt; ({
      handleInputChange: e =&amp;gt; {
        setState(e.target.value)
      },
      resetInput: () =&amp;gt; {
        setState(initialState)
      },
    }),
    [initialState],
  )

  return [state, handlers]
}

function Component({ startingWord }) {
  //...
  const [inputState, { handleInputChange, resetInput }] = useInput(startingWord)
  //...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are even more benefits. By adding this layer of abstraction between our component and the standard React hooks, we can change the implementation of our custom hook&apos;s API without changing the component. Perhaps I want to use a reducer instead of &lt;code&gt;useState&lt;/code&gt; for our &lt;code&gt;useOnOff&lt;/code&gt; hook: &amp;lt;Marker content=&quot;I know this example is ridiculous. If I ever think of a better one, I&apos;ll update the post.&quot; /&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function onOffReducer(state, action) {
  switch (action) {
    case &apos;ON&apos;:
      return &apos;on&apos;
    case &apos;OFF&apos;:
      return &apos;off&apos;
    case &apos;TOGGLE&apos;:
      return state === &apos;on&apos; ? &apos;off&apos; : &apos;on&apos;
    default:
      return state
  }
}

function useOnOff() {
  const [state, dispatch] = React.useReducer(onOffReducer, &apos;off&apos;)

  const handlers = React.useMemo(
    () =&amp;gt; ({
      on: () =&amp;gt; {
        dispatch(&apos;ON&apos;)
      },
      off: () =&amp;gt; {
        dispatch(&apos;OFF&apos;)
      },
      toggle: () =&amp;gt; {
        dispatch(&apos;TOGGLE&apos;)
      },
    }),
    [],
  )

  return [state, handlers]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Obviously, this type of change might be completely unnecessary for my example, but I hope you can recognize where this layer of abstraction might be useful to you when you have to change the implementation details of a hook. We were able to replace the entire state management of our hook without changing the API, which means our component behaves the same way, even though the implementation of that behavior has changed quite a bit.&lt;/p&gt;
&lt;h3&gt;How to Enforce this Pattern&lt;/h3&gt;
&lt;p&gt;What good is a pattern if you can&apos;t come up with a way to get others to use it? To steer them down the good path? We can do that for this pattern with an ESLint plugin and rule. Thus, I give you the &lt;code&gt;eslint-plugin-use-encapsulation&lt;/code&gt; and the &lt;code&gt;prefer-custom-hooks&lt;/code&gt; rule! You can find it here: &lt;a href=&quot;https://github.com/kyleshevlin/eslint-plugin-use-encapsulation&quot;&gt;https://github.com/kyleshevlin/eslint-plugin-use-encapsulation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Following the installation instructions, you&apos;ll see that &lt;code&gt;prefer-custom-hooks&lt;/code&gt; will warn you whenever you use a React hook directly inside a component. The only way around the warning (other than disabling the rule), is to use the React hooks from within a custom hook.&lt;/p&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;By opting to write all the hooks consumed by your components as custom ones, you will be providing future devs (including yourself) useful context by encapsulating all the pieces of a concern into a single function. By doing this, you gain all the benefits of proper encapsulation and make your components more declarative. You might even gain a few useful reusable hooks in the process.&lt;/p&gt;
&lt;h3&gt;useEncapsulation Talk at CascadiaJS&lt;/h3&gt;
&lt;p&gt;I recently gave a talk on this topic at the CascadiaJS conference and wanted to share that recording with you. Enjoy!&lt;/p&gt;
&lt;p&gt;&amp;lt;YouTubeEmbed src=&quot;https://www.youtube.com/embed/cyM70d9IpSg&quot; /&amp;gt;&lt;/p&gt;
</content:encoded><category>JavaScript</category><category>React</category><category>React Hooks</category><category>Computer Science</category></item><item><title>Encapsulation</title><link>https://kyleshevlin.com/encapsulation/</link><guid isPermaLink="true">https://kyleshevlin.com/encapsulation/</guid><description>Typically, functions are written for their reusability, but I want to convince you that the reason to reach for a function is to encapsulate a concern.</description><pubDate>Tue, 29 Dec 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This post will be short and sweet, yet it is my sincere hope that after reading this blog post, you will think about functions a little differently than you did before.&lt;/p&gt;
&lt;p&gt;Functions are one of the first abstractions a programmer learns. Second only to variables. We learn functions as a means of repeating a set of instructions, and later how to parameterize that set of instructions with function arguments. Perhaps you were even taught something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function sayHello(name) {
  return &apos;Hello, &apos; + name
}

sayHello(&apos;Kyle&apos;) // Hello, Kyle
sayHello(&apos;friend&apos;) // Hello, friend
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, you have a function you can &lt;em&gt;reuse&lt;/em&gt;. Reusability was and is touted as the great benefit of functions. The primacy of this benefit is touted everywhere with lesson upon lesson on DRY code. &amp;lt;Marker content={&lt;code&gt;DRY stands for &quot;don&apos;t repeat yourself&quot;.&lt;/code&gt;} /&amp;gt; However, I will contend that reusability is &lt;strong&gt;not&lt;/strong&gt; the primary purpose of a function. No, reusability is rather a wonderful property of functions that comes as the result of their true primary purpose: &lt;strong&gt;encapsulation&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;What is “encapsulation”?&lt;/h3&gt;
&lt;p&gt;&quot;Encapsulation&quot; is the act of taking all the elements of a concern and containing them within a structure. The most common structure of encapsulation is a function, as I will discuss here, but you can also think of modules, objects and classes (and more) as structures for encapsulation (if used well).&lt;/p&gt;
&lt;p&gt;But what do I mean by all the elements of a concern? Let&apos;s come up with an example of some code suffering from a lack of encapsulation.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function createBudgetSummary(transactions) {
  const { length } = transactions
  let income = 0
  let spent = 0

  transactions.forEach(transaction =&amp;gt; {
    const { inflow, outflow } = transaction
    if (inflow) {
      income += inflow.amount
    }
    if (outflow) {
      spent += outflow.amount
    }
  })

  const format = new Intl.NumberFormat(&apos;en-US&apos;, {
    style: &apos;currency&apos;,
    currency: &apos;USD&apos;,
    minimumFractionDigits: 2,
  }).format

  let difference = income - spent

  income = format(income)
  spent = format(spent)
  difference = format(difference)

  const inflection = length === 1 ? &apos;transaction&apos; : &apos;transactions&apos;

  let summary = `After ${length} ${inflection}, your total is ${difference}\n`
  summary += `Your income totaled ${income}.\n`
  summary += `Your spending totaled ${spent}.\n`

  return summary
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Quite a bit going on in there. It&apos;s mostly legible. A programmer can follow what&apos;s happening in the function, but there are related bits strewn about, a lot of mutated variables, and it&apos;s very imperative. What if that function read like this instead?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function createBudgetSummary(
  transactions,
  summaryFormatter = defaultSummaryFormatter,
) {
  const income = getIncome(transactions)
  const spent = getSpent(transactions)
  const summary = summaryFormatter({
    quantity: transactions.length,
    income,
    spent,
  })

  return summary
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Is it easier or harder to understand this function than the previous one? Easier, right? Each line declares what&apos;s happening explicitly. Get the income. Get the expenses. Format the summary. You don&apos;t have to decipher what a bunch of lines of code, possibly scattered around the body of the function, intend to do. You just read it top to bottom, from the function name to function name.&lt;/p&gt;
&lt;p&gt;But I can hear you say, &quot;But Kyle! All you did was &lt;em&gt;hide&lt;/em&gt; a bunch of details in functions!&quot;&lt;/p&gt;
&lt;p&gt;You&apos;re partly right. I did &lt;em&gt;move&lt;/em&gt; the details elsewhere, but I didn&apos;t &lt;em&gt;hide&lt;/em&gt; them. I &lt;strong&gt;encapsulated&lt;/strong&gt; them in functions focused on that particular concern. You want to see? Here are the other functions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const formatForUSD = value =&amp;gt; {
  return new Intl.NumberFormat(&apos;en-US&apos;, {
    style: &apos;currency&apos;,
    currency: &apos;USD&apos;,
    minimumFractionDigits: 2,
  }).format(value)
}

const inflect =
  (singular, plural = singular + &apos;s&apos;) =&amp;gt;
  quantity =&amp;gt;
    quantity === 1 ? singular : plural

const getIncome = transactions =&amp;gt; {
  return transactions.reduce(
    (acc, { inflow }) =&amp;gt; (inflow ? acc + inflow.amount : acc),
    0,
  )
}

const getSpent = transactions =&amp;gt; {
  return transactions.reduce(
    (acc, { outflow }) =&amp;gt; (outflow ? acc + outflow.amount : acc),
    0,
  )
}

const defaultSummaryFormatter = ({ quantity, income, spent }) =&amp;gt; {
  const inflection = inflect(&apos;transaction&apos;)(quantity)
  const difference = income - spent

  // I&apos;m spltting this on 3 lines for blog legibility
  // You could do this as a multiline template string, no problem
  let summary = `After ${length} ${inflection}, your total is ${difference}\n`
  summary += `Your income totaled ${formatForUSD(income)}.\n`
  summary += `Your spending totaled ${formatForUSD(spent)}.\n`

  return summary
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&quot;What&apos;s so great about this?!&quot; you exclaim. &quot;It&apos;s more lines of code!&quot;&lt;/p&gt;
&lt;p&gt;True, but every function is simpler, focused, and tells you what concern it encapsulates. By writing our code this way, we gain a number of benefits:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Easier to digest&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;By focusing on encapsulation, we make our functions focused, small and containing all the elements they need to do their job. In our original code, we destructured &lt;code&gt;length&lt;/code&gt; really early on in the function body, even though it wasn&apos;t used for 15 lines or so. As a human, this adds an unnecessary strain to remember where these bits of info are. It&apos;s simpler to create functions that keep these elements tightly located to where they are needed. By doing so, our code becomes more legible and more declarative. I like to think of it as the function names tell a story.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Mental offloading of information&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This one you might disagree with, but I find if I have good functions, I don&apos;t always have to understand their details to know what&apos;s important to me at that given moment.&lt;/p&gt;
&lt;p&gt;If I&apos;m looking at &lt;code&gt;createBudgetSummary&lt;/code&gt; and I&apos;m trying to change the format of the summary, I don&apos;t need to know how the program gets the &lt;code&gt;income&lt;/code&gt;, I just know there&apos;s a function that &lt;em&gt;does&lt;/em&gt; &lt;code&gt;getIncome&lt;/code&gt;. I can offload that information, or never take it on to begin with. Those details aren&apos;t important to me &lt;em&gt;until&lt;/em&gt; I either need to change &lt;code&gt;income&lt;/code&gt; or have found a bug in its implementation (which I can easily write a test for). I can make changes to &lt;code&gt;getIncome&lt;/code&gt;, without changing the API of &lt;code&gt;summaryFormatter&lt;/code&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Easier to refactor&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let&apos;s say you just hate &lt;code&gt;Array.prototype.reduce&lt;/code&gt;. &amp;lt;Marker content=&quot;There&apos;s a whole cult of &amp;lt;code&amp;gt;reduce&amp;lt;/code&amp;gt; haters on Twitter. I don&apos;t blame them, but I do like to poke and prod them a bit. 😁&quot; /&amp;gt; Nothing stops you from writing:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const getIncome = transactions =&amp;gt; {
  let total = 0

  transactions.forEach(({ inflow }) =&amp;gt; {
    if (inflow) total += inflow.amount
  })

  return total
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It becomes trivial to change implementation details without having an impact on other parts of the code.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We can recognize opportunities for flexibility more easily&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Take a look at &lt;code&gt;defaultSummaryFormatter&lt;/code&gt;. This isn&apos;t part of the original code. But once you realize what the purpose of those final lines of code are, you can see an opportunity to make our &lt;code&gt;createBudgetSummary&lt;/code&gt; function more flexible and powerful. By using dependency injection with a default parameter, it&apos;s trivial to change what format we output, so long as the &lt;code&gt;summaryFormatter&lt;/code&gt; makes use of the same data.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We gained reusable functions&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We didn&apos;t set out to make reusable functions, but we got a few anyways. &lt;code&gt;inflect&lt;/code&gt; is a highly reusable function because it encapsulates a single idea: return the right word. The way I wrote it, you can create any number of &lt;code&gt;inflector&lt;/code&gt; functions wherever you need one.&lt;/p&gt;
&lt;p&gt;There are even more opportunities to create further encapsulated functions. We could break our &lt;code&gt;formatForUSD&lt;/code&gt; function and break it down into an abstraction to make more formatters, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const makeCurrencyFormatter = (locale, currency) =&amp;gt; {
  return new Intl.NumberFormat(locale, {
    style: &apos;currency&apos;,
    currency,
    minimumFractionDigits: 2,
  }).format
}

const formatForUSD = makeCurrencyFormatter(&apos;en-US&apos;, &apos;USD&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, you can easily make other currency formatters for other locales and currencies.&lt;/p&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;Encapsulation is the act of gathering all the elements of a single concern and containing them within a structure. In this post, we focused on functions. By encapsulating concerns and giving them good names, we made our code more declarative, easier to read, and easier to refactor. Furthermore, by properly encapsulating concerns, we found opportunities to make the code more flexible and gained even more reusability.&lt;/p&gt;
</content:encoded><category>JavaScript</category><category>React</category><category>Computer Science</category><category>Refactoring</category></item><item><title>Use Old School State</title><link>https://kyleshevlin.com/use-old-school-state/</link><guid isPermaLink="true">https://kyleshevlin.com/use-old-school-state/</guid><description>Let&apos;s kick it old school and create a custom React hook that takes a callback second argument for `setState`.</description><pubDate>Thu, 17 Dec 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import FirstCounter from &apos;./_FirstCounter&apos;
import SecondCounter from &apos;./_SecondCounter&apos;
import FirstDoubleStepper from &apos;./_FirstDoubleStepper&apos;
import SecondDoubleStepper from &apos;./_SecondDoubleStepper&apos;
import ThirdDoubleStepper from &apos;./_ThirdDoubleStepper&apos;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Disclaimer&lt;/strong&gt;: I have no idea if this is a good idea. Just something you can do if you want.&lt;/p&gt;
&lt;p&gt;If you&apos;re like me, you&apos;ve been writing React for quite some time. While I don&apos;t spend much time writing class components these days, &amp;lt;Marker content=&quot;I still work with plenty of class components regularly.&quot; /&amp;gt; you might recall that you can pass a second argument to &lt;code&gt;this.setState&lt;/code&gt;, a callback function that is called after the state update.&lt;/p&gt;
&lt;p&gt;This callback function was a simple way to sequence some functionality. Set some state, do something once it has happened. What if we could recreate some of that simple magic with hooks? &amp;lt;Marker content=&quot;It&apos;s not magic. Sadly, with code as with life, it never is.&quot; /&amp;gt;&lt;/p&gt;
&lt;p&gt;Generally, with hooks we would have this as two parts. An instance of &lt;code&gt;React.useState&lt;/code&gt; to manage the state changes, and an instance of &lt;code&gt;React.useEffect&lt;/code&gt; to respond when the state changes. It might even be better and simpler to write your code this way (hence my opening disclaimer).&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const [state, setState] = React.useState(/* initialState */)

React.useEffect(() =&amp;gt; {
  // do something with `state` here
}, [state])
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can create a custom hook that encapuslates these two parts. I&apos;ll warn you ahead of time. We&apos;re going to make a first attempt, run into a problem and fix it later. Let&apos;s do this step by step. First our hook function as a wrapper for &lt;code&gt;useState&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function useOldSchoolState(initialState) {
  return React.useState(initialState)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cool. What&apos;s our next requirement? That &lt;code&gt;setState&lt;/code&gt; allow an optional second argument. We can do this by creating a &lt;code&gt;wrappedSetState&lt;/code&gt; and returning that.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function useOldSchoolState(initialState) {
  const [state, setState] = React.useState(initialState)

  const wrappedSetState = React.useCallback((update, callback) =&amp;gt; {
    setState(update)

    if (callback) {
      callback()
    }
  }, [])

  return [state, wrappedSetState]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This looks pretty good, &lt;em&gt;but&lt;/em&gt; there&apos;s a problem. The &lt;code&gt;callback&lt;/code&gt; is supposed to run &lt;em&gt;after&lt;/em&gt; the state update has taken effect. Which is a perfect word for how we&apos;re going to solve this issue, with an &lt;code&gt;useEffect&lt;/code&gt; hook.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;React.useEffect&lt;/code&gt; always runs &lt;em&gt;after&lt;/em&gt; render, and components re-render after a state update. So, if we move the callback to a &lt;code&gt;useEffect&lt;/code&gt; hook, it will ensure that it runs after our state has updated. We need to come up with a way to store the callback function and call it in the &lt;code&gt;useEffect&lt;/code&gt; hook.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function useOldSchoolState(initialState) {
  const [state, setState] = React.useState(initialState)
  const callbackRef = React.useRef(null)

  const wrappedSetState = React.useCallback((update, callback) =&amp;gt; {
    setState(update)

    if (callback) {
      callbackRef.current = callback
    }
  }, [])

  React.useEffect(() =&amp;gt; {
    if (callbackRef.current) {
      callbackRef.current()
      callbackRef.current = null
    }
  })

  return [state, wrappedSetState]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Sweet. Now we can run a callback after the state update. Let&apos;s make an arbitrary example. A &lt;code&gt;Counter&lt;/code&gt; that logs out a message.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Counter() {
  const [state, setState] = useOldSchoolState(0)

  const inc = () =&amp;gt; {
    setState(
      s =&amp;gt; s + 1,
      () =&amp;gt; {
        console.log(`Count went up to ${state}`)
      },
    )
  }

  const dec = () =&amp;gt; {
    setState(
      s =&amp;gt; s - 1,
      () =&amp;gt; {
        console.log(`Count went down to ${state}`)
      },
    )
  }

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;div&amp;gt;Count: {state}&amp;lt;/div&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;Button onClick={inc}&amp;gt;+&amp;lt;/Button&amp;gt;
        &amp;lt;Button onClick={dec}&amp;gt;-&amp;lt;/Button&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However, one might notice there&apos;s a small problem, one that would be avoided in the class component version. Can you spot it? &amp;lt;Marker content=&quot;Hint: check the console.&quot; /&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;FirstCounter client:load /&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;p&gt;In class components, &lt;code&gt;this&lt;/code&gt; refers to the instance of the component, so if we were to try and get values derived from &lt;code&gt;this&lt;/code&gt;, such as &lt;code&gt;this.state&lt;/code&gt; and this occurs in a function called &lt;em&gt;after&lt;/em&gt; the state was updated, then we would get the &lt;em&gt;updated values for &lt;code&gt;this.state&lt;/code&gt;&lt;/em&gt;. But if we try and access &lt;code&gt;state&lt;/code&gt; in our callback, it will be incorrect. It will be the whatever &lt;code&gt;state&lt;/code&gt; was at the time &lt;code&gt;setState&lt;/code&gt; was called due to the closure created. In other words, we cannot access the updated state by using &lt;code&gt;state&lt;/code&gt; in the callback function. What if the action we&apos;d like to depends on that updated state?&lt;/p&gt;
&lt;p&gt;Remember how &lt;code&gt;useEffect&lt;/code&gt; runs &lt;em&gt;after&lt;/em&gt; the state update triggered a render. This means that the value of &lt;code&gt;state&lt;/code&gt; inside our &lt;code&gt;useOldSchoolState&lt;/code&gt; hook is when the effect is run is the &lt;code&gt;nextState&lt;/code&gt; in comparison to the value of &lt;code&gt;state&lt;/code&gt; at the time the callback was created and &lt;code&gt;state&lt;/code&gt; closed over. Thus, if we pass &lt;code&gt;state&lt;/code&gt; in our &lt;code&gt;useOldSchoolState&lt;/code&gt; to the callback, we&apos;ll have access to the &lt;code&gt;nextState&lt;/code&gt; in the callback. Like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function useOldSchoolState(initialState) {
  const [state, setState] = React.useState(initialState)
  const callbackRef = React.useRef(null)

  const wrappedSetState = React.useCallback((update, callback) =&amp;gt; {
    setState(update)

    if (callback) {
      callbackRef.current = callback
    }
  }, [])

  React.useEffect(() =&amp;gt; {
    if (callbackRef.current) {
      callbackRef.current(state)
      callbackRef.current = null
    }
  }, [state])

  return [state, wrappedSetState]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now that we are passing the updated state to the callback, let&apos;s update our &lt;code&gt;Counter&lt;/code&gt; component to make use of this.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Counter() {
  const [state, setState] = useOldSchoolState(0)

  const inc = () =&amp;gt; {
    setState(
      s =&amp;gt; s + 1,
      nextState =&amp;gt; {
        console.log(`Count went up to ${nextState}`)
      },
    )
  }

  const dec = () =&amp;gt; {
    setState(
      s =&amp;gt; s - 1,
      nextState =&amp;gt; {
        console.log(`Count went down to ${nextState}`)
      },
    )
  }

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;div&amp;gt;Count: {state}&amp;lt;/div&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;Button onClick={inc}&amp;gt;+&amp;lt;/Button&amp;gt;
        &amp;lt;Button onClick={dec}&amp;gt;-&amp;lt;/Button&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;SecondCounter client:load /&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;p&gt;Excellent. Now our &lt;code&gt;Counter&lt;/code&gt; will log out the correct value in the callback. However, there is yet one more problem with this approach. What happens if we call &lt;code&gt;setState&lt;/code&gt; inside of our callback, and furthermore, what happens if we provide this second &lt;code&gt;setState&lt;/code&gt; a callback as well?&lt;/p&gt;
&lt;p&gt;Let&apos;s make a new component and try it out. We&apos;ll make a contrived &lt;code&gt;DoubleStepper&lt;/code&gt;, but it&apos;ll make my point:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function DoubleStepper() {
  const [state, setState] = useOldSchoolState(0)

  cons step = () =&amp;gt; {
    setState(
      s =&amp;gt; s + 1,
      ns1 =&amp;gt; {
        console.log(&apos;first callback&apos;, ns1)
        setState(
          s =&amp;gt; s + 1,
          ns2 =&amp;gt; {
            console.log(&apos;second callback&apos;, ns2)
          }
        )
      }
    )
  }

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;div&amp;gt;Steps: {state}&amp;lt;/div&amp;gt;
      &amp;lt;Button onClick={step}&amp;gt;Step&amp;lt;/Button&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&apos;s break that down really quick. When we trigger &lt;code&gt;step&lt;/code&gt;, the first &lt;code&gt;setState&lt;/code&gt; shall update the state by &lt;code&gt;1&lt;/code&gt; and callback with the next state. Inside of that callback, we&apos;ll call &lt;code&gt;setState&lt;/code&gt; again, which will also update the state by &lt;code&gt;1&lt;/code&gt; and has a callback that should display the second state update.&lt;/p&gt;
&lt;p&gt;But does it?&lt;/p&gt;
&lt;p&gt;Try it out and find out. Make sure you check the console.&lt;/p&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;FirstDoubleStepper client:load /&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;p&gt;Well, what do you know? It doesn&apos;t work right, does it? What&apos;s going on? Adding a few &lt;code&gt;console.log&lt;/code&gt;s to our &lt;code&gt;useOldSchoolState&lt;/code&gt; code will make this clear:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function useOldSchoolState(initialState) {
  const [state, setState] = React.useState(initialState)
  const callbackRef = React.useRef(null)

  const wrappedSetState = React.useCallback((update, callback) =&amp;gt; {
    console.log(&apos;starting wrappedSetState&apos;)
    setState(update)

    if (callback) {
      console.log(&apos;setting callbackRef&apos;)
      callbackRef.current = callback
    }
  }, [])

  React.useEffect(() =&amp;gt; {
    console.log(&apos;starting effect&apos;)
    if (callbackRef.current) {
      callbackRef.current(state)
      console.log(&apos;nullifying callbackRef&apos;)
      callbackRef.current = null
    }
  }, [state])

  return [state, wrappedSetState]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now try it.&lt;/p&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;SecondDoubleStepper client:load /&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;p&gt;When we click the button of our &lt;code&gt;DoubleStepper&lt;/code&gt; component, we see the following logs:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// starting wrappedSetState
// setting callbackRef
// starting effect
// first callback 1
// starting wrappedSetState
// setting callbackRef
// nullifying callbackRef
// starting effect
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice that &lt;code&gt;nullifying callbackRef&lt;/code&gt; only occurs once, when we might expect it to occur twice. What&apos;s worse is that our ref is nullified &lt;em&gt;after&lt;/em&gt; having set the ref for the next callback, but &lt;em&gt;before&lt;/em&gt; that callback has a chance to be called in the next effect. What we need is a way to sequence callbacks in an orderly fashion. What can we do to manage that?&lt;/p&gt;
&lt;p&gt;We can add a simple &lt;code&gt;queue&lt;/code&gt; data structure, and only process one callback at a time in the queue.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function createQueue() {
  const queue = []

  return {
    add(item) {
      queue.unshift(item)
    },
    remove() {
      return queue.pop()
    },
    get length() {
      return queue.length
    },
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is a very simple &lt;code&gt;queue&lt;/code&gt; with no bells and whistles. Let&apos;s use it to store callbacks, and then &lt;code&gt;remove&lt;/code&gt; callbacks one by one instead, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function useOldSchoolState(initialState) {
  const [state, setState] = React.useState(initialState)
  const queue = React.useRef(createQueue())

  const wrappedSetState = React.useCallback((update, callback) =&amp;gt; {
    setState(update)

    if (callback) {
      queue.current.add(callback)
    }
  }, [])

  React.useEffect(() =&amp;gt; {
    if (queue.current.length) {
      queue.current.remove()(state)
    }
  }, [queue.current.length, state])

  return [state, wrappedSetState]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;ThirdDoubleStepper client:load /&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;p&gt;Now, we manage to only run one callback per effect, which in the case of the &lt;code&gt;DoubleStepper&lt;/code&gt; gets it working as expected. I haven&apos;t tested this on even more challenging scenarios, so I can&apos;t make guarantees regarding how bulletproof this implementation is, but I am satisfied with the exploration for now.&lt;/p&gt;
&lt;p&gt;Admittedly, that was quite a bit of work for a seemingly simple hook, but I think the work was worthwhile. It forced me (and hopefully you) to think about breaking the problem down, and fixing pieces of it step by step.&lt;/p&gt;
</content:encoded><category>React</category><category>JavaScript</category></item><item><title>Helpful Debugging Hooks</title><link>https://kyleshevlin.com/helpful-debugging-hooks/</link><guid isPermaLink="true">https://kyleshevlin.com/helpful-debugging-hooks/</guid><description>Learn some helpful debugging hooks for improving React component performance.</description><pubDate>Fri, 04 Dec 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import ChangeExample from &apos;./_ChangeExample&apos;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update 08/19/2021&lt;/strong&gt;: I created and published a package of these hooks so you can import them and use them without having to write them yourselves. Install them with:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npm install use-debugger-hooks
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can see the repo here: &lt;a href=&quot;https://github.com/kyleshevlin/use-debugger-hooks&quot;&gt;https://github.com/kyleshevlin/use-debugger-hooks&lt;/a&gt;. Hope this helps you with your debugging!&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Recently, I needed to do some debugging to improve a few components that were rerendering unexpectedly. In that process of research and trial &amp;amp; error, I came away with a few useful hooks that I want to share with you.&lt;/p&gt;
&lt;p&gt;In short, every time &lt;code&gt;props&lt;/code&gt; or &lt;code&gt;state&lt;/code&gt; changes in a React component, it will rerender. This is, unequivocally, a good thing. When a component is rendering more often than expected &lt;strong&gt;and it&apos;s an actual performance problem for your app&lt;/strong&gt;, then you need to determine what &lt;code&gt;props&lt;/code&gt;, &lt;code&gt;state&lt;/code&gt; or other values are changing between renders. In order to do this, you first need a way of retaining the previous value of something.&lt;/p&gt;
&lt;p&gt;This can be accomplished with use of &lt;code&gt;useRef&lt;/code&gt; and &lt;code&gt;useEffect&lt;/code&gt; in a custom &lt;code&gt;usePrevious&lt;/code&gt; hook.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function usePrevious(value) {
  const ref = React.useRef()

  React.useEffect(() =&amp;gt; {
    ref.current = value
  }, [value])

  return ref.current
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This hook isn&apos;t new at all. In fact, you can find it in the &lt;a href=&quot;https://reactjs.org/docs/hooks-faq.html#how-to-get-the-previous-props-or-state&quot;&gt;official React docs&lt;/a&gt; as well as other places. This hook works because &lt;code&gt;useEffect&lt;/code&gt; is always run &lt;em&gt;after&lt;/em&gt; render. So during the current render phase we get the previously stored value, then the &lt;code&gt;useEffect&lt;/code&gt; runs to update the value. Pretty cool.&lt;/p&gt;
&lt;p&gt;Now that we can store a previous value, we want to determine if the current value and previous value are different, and if they are different, let&apos;s log that information out. To do so, let&apos;s create another custom hook: what I call &lt;code&gt;useLogChanges&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function useLogChanges(value) {
  const previousValue = usePrevious(value)
  const changes = getChanges(previousValue, value)

  if (changes.length) {
    changes.forEach(change =&amp;gt; {
      console.log(change)
    })
  }
}

function getChanges(previousValue, currentValue) {
  // Handle non-null objects
  if (
    typeof previousValue === &apos;object&apos; &amp;amp;&amp;amp;
    previousValue !== null &amp;amp;&amp;amp;
    typeof currentValue === &apos;object&apos; &amp;amp;&amp;amp;
    currentValue !== null
  ) {
    return Object.entries(currentValue).reduce((acc, cur) =&amp;gt; {
      const [key, value] = cur
      const oldValue = previousValue[key]

      if (value !== oldValue) {
        acc.push({
          name: key,
          previousValue: oldValue,
          currentValue: value,
        })
      }

      return acc
    }, [])
  }

  // Handle primitive values
  if (previousValue !== currentValue) {
    return [{ previousValue, currentValue }]
  }

  return []
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Great. I pulled out the &lt;code&gt;getChanges&lt;/code&gt; function since we really don&apos;t need the implementation details cluttering the &lt;code&gt;useLogChanges&lt;/code&gt; hook. That reads simply enough now. You can pass this hook any value and log out changes with each render. We could do something like this to debug a component&apos;s &lt;code&gt;props&lt;/code&gt; for example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function MyComponent(props) {
  useLogChanges(props)

  return &amp;lt;OtherComponent {...props} /&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, every time &lt;code&gt;MyComponent&lt;/code&gt; rerenders, we will be informed what props changed that caused the rerender.&lt;/p&gt;
&lt;p&gt;Here&apos;s a very rudimentary example. This component just generates a random number and passes it to a child component every time you press the button. The child component uses &lt;code&gt;useLogChanges&lt;/code&gt; on its &lt;code&gt;props&lt;/code&gt;. The changes to the &lt;code&gt;props&lt;/code&gt; will be logged out with each render. Open the console, and give it a try.&lt;/p&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;ChangeExample /&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;p&gt;But what about side effects? Can I also use &lt;code&gt;useLogChanges&lt;/code&gt; to debug when effects run? Absolutely.&lt;/p&gt;
&lt;p&gt;Let&apos;s make use of &lt;code&gt;useLogChanges&lt;/code&gt; inside a &lt;code&gt;useEffectDebugger&lt;/code&gt; hook.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function useEffectDebugger(effect, dependencies) {
  useLogChanges(dependencies)
  React.useEffect(effect, dependencies)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now you have a drop in replacement for &lt;code&gt;useEffect&lt;/code&gt; that will tell you which dependency changed to cause an effect to run. If you really wanted, you could make drop in replacements for any of the standard React library hooks with this pattern.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function useCallbackDebugger(callback, dependencies) {
  useLogChanges(dependencies)
  return React.useCallback(callback, dependencies)
}

function useMemoDebugger(memoizer, dependencies) {
  useLogChanges(dependencies)
  return React.useMemo(memoizer, dependencies)
}

// ...etc
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That&apos;s all there is to it. Nothing fancy. Just a little hooks composition for you. I hope you find this helpful in your React component debugging!&lt;/p&gt;
</content:encoded><category>React</category><category>React Hooks</category><category>JavaScript</category></item><item><title>Headlight Vision</title><link>https://kyleshevlin.com/headlight-vision/</link><guid isPermaLink="true">https://kyleshevlin.com/headlight-vision/</guid><description>Do you ever feel like you&apos;re always stuck in someone else&apos;s rearview, failing to ever catch up to them? Might be time to change your persective.</description><pubDate>Tue, 10 Nov 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I&apos;ve been struggling a lot lately with my inner self-talk. It&apos;s never been all that fantastic but even worse than usual lately. I think this is the result of the difficult year we&apos;re all facing and a new venture I&apos;m undertaking that has me really doubting myself.&lt;/p&gt;
&lt;p&gt;&quot;Great opener, Kyle! Really got us in good spirits!&quot; you say.&lt;/p&gt;
&lt;p&gt;I know, but bear with me. Part of why I get like this is I am &lt;em&gt;wired&lt;/em&gt; to look at people more successful than me and compare myself to them. I could write endlessly about people I admire and could never be like. Whenever I get like this, stuck in my comparisons, I try and think about a metaphor that my friend &lt;a href=&quot;https://twitter.com/jlengstorf&quot;&gt;Jason Lengstorf&lt;/a&gt; shared with me a year or two ago that I think is just brilliant.&lt;/p&gt;
&lt;p&gt;When you&apos;re struggling with confidence and doubt, and perhaps feeling further behind than your peers, consider this scenario:&lt;/p&gt;
&lt;p&gt;Imagine you&apos;re in a car, driving down a dark road in the middle of the night. Naturally, you have your headlights on.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;When you&apos;re driving at night and you have your headlights on, what &lt;em&gt;exactly&lt;/em&gt; can you see?&lt;/p&gt;
&lt;p&gt;Turns out, not a whole lot.&lt;/p&gt;
&lt;p&gt;You can only see what is more or less &lt;em&gt;directly&lt;/em&gt; in front of you. You can see a few other cars that are further on their journey than you are. &lt;em&gt;Why&lt;/em&gt; are they further ahead?&lt;/p&gt;
&lt;p&gt;Maybe they had a head start, maybe they have a fancier car, maybe they&apos;re a better driver, who knows? But notice, really &lt;em&gt;notice&lt;/em&gt;, that what you see in this tiny sliver of light shooting out from the front of your car, is but a small fragment of what&apos;s actually out there in the dark.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;If it wasn&apos;t dark, and we didn&apos;t need our headlights, and we looked around in all directions, what would we see?&lt;/p&gt;
&lt;p&gt;We would see that there are &lt;em&gt;many&lt;/em&gt; people driving outside of our headlight vision, in all sorts of directions.&lt;/p&gt;
&lt;p&gt;There are some way to the left. There are some way to the right.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;And multitudes and multitudes more people behind us.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;There are even people who aren&apos;t on the road yet that soon will be.&lt;/p&gt;
&lt;p&gt;If you&apos;re always driving in the dark with your headlights on, you&apos;ll only notice the people directly ahead of you.&lt;/p&gt;
&lt;p&gt;Sure, you can strive after them. Put your foot on the gas pedal and go, but there&apos;s almost certainly always someone else still out in front. It&apos;s exhausting to try and keep up and there&apos;s a good chance you&apos;ll run out of gas. You will probably feel, as I often do, like shit because you aren&apos;t where they are.&lt;/p&gt;
&lt;p&gt;If and when this happens, remember that you need some daylight and a broader perspective. Remember there are people all around you, and what you do may not make an impression on those ahead of you, it will be tough to see in a rear-view mirror, but can make a huge difference to the people left, right, and behind you.&lt;/p&gt;
&lt;p&gt;Keep them in mind. Don&apos;t get locked into your headlights. And drive safe.&lt;/p&gt;
</content:encoded><category>Thoughts</category></item><item><title>Pattern Matching in JavaScript</title><link>https://kyleshevlin.com/pattern-matching/</link><guid isPermaLink="true">https://kyleshevlin.com/pattern-matching/</guid><description>In this post, Kyle Shevlin demonstrates using a switch statement to replicate a form of pattern matching in JavaScript.</description><pubDate>Sun, 18 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Today, I want to share with you a coding pattern I frequently use when writing conditional JavaScript. I&apos;ve made several tweets about it throughout the years and it&apos;s high time that I finally write a blog post that I can use as a reference. In fact, I use this pattern so often that my manager at work started to call it the &quot;Kyle pattern&quot;. It shouldn&apos;t be called that, but I&apos;ll take it as a compliment.&lt;/p&gt;
&lt;p&gt;I call what I&apos;m about to show you &quot;a poor person&apos;s pattern matching&quot; or &quot;makeshift pattern matching&quot;. It&apos;s not quite the real thing, but it does a pretty good job of coming close to it and is plenty useful.&lt;/p&gt;
&lt;p&gt;Before you go further, you should understand &lt;code&gt;switch&lt;/code&gt; statements pretty well. If you&apos;re not familiar with how they work in JavaScript, &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/switch&quot;&gt;I recommend reading the MDN docs on &lt;code&gt;switch&lt;/code&gt;&lt;/a&gt;. With that, let&apos;s get to it.&lt;/p&gt;
&lt;h3&gt;What is &quot;pattern matching&quot;?&lt;/h3&gt;
&lt;p&gt;I first encountered &quot;pattern matching&quot; when I started to learn &lt;a href=&quot;https://reasonml.github.io/&quot;&gt;ReasonML&lt;/a&gt; a few years ago. In ReasonML, a strongly typed functional language, you have &lt;em&gt;variants&lt;/em&gt;. A variant is a union type, but unlike TypeScript, we can have conditional logic based on the &lt;em&gt;type&lt;/em&gt; of value passed in, not just the value itself. This is a really powerful mechanism for handling conditional functionality in our programs.&lt;/p&gt;
&lt;p&gt;With ReasonML&apos;s &lt;code&gt;switch&lt;/code&gt;, when we pass in a value, we look at the value&apos;s type and choose different logical paths accordingly. On their home page, they share this example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type schoolPerson = Teacher | Director | Student(string);

let greeting = person =&amp;gt;
  switch (person) {
  | Teacher =&amp;gt; &quot;Hey Professor!&quot;
  | Director =&amp;gt; &quot;Hello Director.&quot;
  | Student(&quot;Richard&quot;) =&amp;gt; &quot;Still here Ricky?&quot;
  | Student(anyOtherName) =&amp;gt; &quot;Hey, &quot; ++ anyOtherName ++ &quot;.&quot;
  }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;Note&amp;gt;&lt;/p&gt;
&lt;p&gt;The syntax highlighter I am using, &lt;a href=&quot;https://shiki.style&quot;&gt;Shiki&lt;/a&gt;, doesn&apos;t currently support ReasonML. If you know where I can find a Textmate grammar for ReasonML, let me know and I&apos;ll make a pull request to the project. As a stopgap measure, here&apos;s the equivalent code written in OCaml, which is what the ReasonML syntax is based on.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type school_person = Teacher | Director | Student of string

let greeting person =
  match person with
  | Teacher -&amp;gt; &quot;Hey Professor!&quot;
  | Director -&amp;gt; &quot;Hello Director.&quot;
  | Student &quot;Richard&quot; -&amp;gt; &quot;Still here Ricky?&quot;
  | Student any_other_name -&amp;gt; &quot;Hey, &quot; ^ any_other_name ^ &quot;.&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;/Note&amp;gt;&lt;/p&gt;
&lt;p&gt;This mechanism quickly becomes the most robust way of doing conditional logic as you use the language. As you work with it, you get comfortable thinking in variants instead of thinking in &lt;code&gt;if/else&lt;/code&gt;s or ternaries. But ReasonML&apos;s &lt;code&gt;switch&lt;/code&gt; and JavaScript&apos;s &lt;code&gt;switch&lt;/code&gt; are a bit different, so how can we recreate some of this magic in JavaScript?&lt;/p&gt;
&lt;h3&gt;Flipping &lt;code&gt;switch&lt;/code&gt; on its head&lt;/h3&gt;
&lt;p&gt;When using a &lt;code&gt;switch&lt;/code&gt; statement in JavaScript, we most commonly use the &lt;em&gt;expression&lt;/em&gt; (the part in parentheses, which makes this parenthetical kind of meta) as if it&apos;s the left half of a strictly equals check (&lt;code&gt;===&lt;/code&gt;), and each &lt;code&gt;case&lt;/code&gt; as the right half. An example of this I expect a lot of you to be familiar with would be a state reducer &lt;em&gt;a la&lt;/em&gt; Redux and/or React.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const reducer = (state, action) =&amp;gt; {
  switch (action.type) {
    case &apos;DATA_REQUESTED&apos;:
      return { ...state, status: &apos;loading&apos; }

    case &apos;DATA_RECEIVED&apos;:
      return { ...state, data: action.payload.data, status: &apos;loaded&apos; }

    case &apos;DATA_FAILED&apos;:
      return { ...state, error: action.payload.error, status: &apos;error&apos; }

    default:
      return state
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As we make calls to &lt;code&gt;reducer&lt;/code&gt;, our &lt;code&gt;switch&lt;/code&gt; tries to match the &lt;code&gt;action.type&lt;/code&gt; to the &lt;code&gt;case&lt;/code&gt; with the same string. However, this limits how useful our &lt;code&gt;switch&lt;/code&gt; can be because we can only operate on a single value in the expression. Is there a way around this limitation?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;There sure is.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Rhetorical question incoming. What are we doing with the &lt;code&gt;switch&lt;/code&gt; expression and the &lt;code&gt;case&lt;/code&gt;s &lt;em&gt;exactly&lt;/em&gt;? We&apos;re strictly comparing (&lt;code&gt;===&lt;/code&gt;) two values and seeing if they come out &lt;code&gt;true&lt;/code&gt; or &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Instead&lt;/em&gt;, what if we use &lt;code&gt;switch (true)&lt;/code&gt; and make each of our &lt;code&gt;case&lt;/code&gt;s an expression? This opens up some possibilities.&lt;/p&gt;
&lt;p&gt;With each &lt;code&gt;case&lt;/code&gt; as an expression, we can do things we couldn&apos;t before, such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Do multiple comparisons on the same value&lt;/li&gt;
&lt;li&gt;Use predicate functions to match cases &amp;lt;Marker content=&quot;A predicate is a function that returns a boolean.&quot; /&amp;gt;&lt;/li&gt;
&lt;li&gt;Use multiple values in those predicate functions&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;RegExp.prototype.test&lt;/code&gt; to match patterns&lt;/li&gt;
&lt;li&gt;and whatever else you can dream up&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The key to using &lt;code&gt;switch (true)&lt;/code&gt; in this way is to think of each &lt;code&gt;case&lt;/code&gt; expression as a pattern. Sure, we can&apos;t match on variants in the wonderful way that ReasonML can, but we can use the tools we have to get the matches we want. Let&apos;s look at some examples.&lt;/p&gt;
&lt;p&gt;In this first example, I&apos;ve created an &lt;code&gt;areWeThereYet&lt;/code&gt; function. It generates responses to that annoying question based on the &lt;code&gt;milesToGo&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function areWeThereYet(milesToGo) {
  switch (true) {
    case milesToGo &amp;lt;= 1:
      return &quot;We&apos;re hereeeee!&quot;

    case milesToGo &amp;lt;= 10:
      return &apos;Almost. Just a little further.&apos;

    case milesToGo &amp;lt;= 100:
      return &apos;A little more than an hour.&apos;

    case milesToGo &amp;lt;= 250:
      return &apos;Just a half day away.&apos;

    default:
      return &quot;We&apos;re not even close so stop asking!&quot;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Personally, I find this easier to read than the same code with &lt;code&gt;if/else if/else&lt;/code&gt;s. You might disagree, that&apos;s ok. Stick with me.&lt;/p&gt;
&lt;p&gt;The next thing that makes &lt;code&gt;switch (true)&lt;/code&gt; similar to pattern matching is the ability to now use functions in each &lt;code&gt;case&lt;/code&gt; to generate matches. Let&apos;s consider the ReasonML example above, and adapt it a bit to JavaScript.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// I need you to use your imagination here, and pretend
// that all of these predicate functions exist and work correctly :)
const greeting = person =&amp;gt; {
  switch (true) {
    case isTeacher(person):
      return &apos;Hey Professor!&apos;

    case isDirector(person):
      return &apos;Hello Director.&apos;

    case isRicky(person):
      return &apos;Still here Ricky?&apos;

    case isStudent(person):
      return `Hey, ${person.name}.`
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are other benefits to using a &lt;code&gt;switch&lt;/code&gt; this way, such as &lt;code&gt;case&lt;/code&gt; fall-throughs. Rather than writing it as an OR expression (&lt;code&gt;||&lt;/code&gt;), you could write two &lt;code&gt;case&lt;/code&gt;s that use fall-throughs to respond the same way. I&apos;ll &quot;sanitize&quot; a little snippet of an idea from work to show this.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Again, use your imagination and envision a larger switch
switch (true) {
  // ...other cases

  case isEcommerceItems(items):
  case isCMSItems(items):
    return prepareForCollectionList(items)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are a few other patterns to try with this, but I feel like I&apos;ve given you a pretty good idea of how to get started. I&apos;m trusting you to try it out and practice the pattern.&lt;/p&gt;
&lt;p&gt;If you want an idea to get started with, you might try to solve the &quot;Gilded Rose&quot; kata with &lt;code&gt;switch (true)&lt;/code&gt; and regexes. &amp;lt;Marker content=&quot;Just Google &apos;Gilded Rose&apos;. You&apos;ll get a bazillion hits.&quot; /&amp;gt; I was once given this kata as an interview question and I found my pattern matching trick to be a useful way to solve the problem.&lt;/p&gt;
&lt;h3&gt;Additional Notes&lt;/h3&gt;
&lt;p&gt;There is a TC39 proposal to add pattern matching to JavaScript, but it&apos;s been stalled at Stage 1 for quite some time. You can find the &lt;a href=&quot;https://github.com/tc39/proposal-pattern-matching&quot;&gt;proposal repo here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;There is an interesting package called &lt;a href=&quot;https://github.com/suchipi/safety-match&quot;&gt;&lt;code&gt;safety-match&lt;/code&gt;&lt;/a&gt; created by my Webflow coworker &lt;a href=&quot;https://twitter.com/suchipi&quot;&gt;@suchipi&lt;/a&gt;. Check it out if you&apos;re interested in pattern matching with TypeScript.&lt;/p&gt;
&lt;p&gt;Another popular TypeScript package for pattern matching is &lt;a href=&quot;https://github.com/gvergnaud/ts-pattern&quot;&gt;&lt;code&gt;ts-pattern&lt;/code&gt;&lt;/a&gt;. It&apos;s highlighted feature is that it can be &lt;em&gt;exhuastive&lt;/em&gt;, ensuring every possible type case is covered.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; Years after writing this post, I decided to try and make a simple, type-safe pattern matching library of my own. I called it &lt;code&gt;kase&lt;/code&gt;. It&apos;s not remarkably more useful than simply using &lt;code&gt;switch (true)&lt;/code&gt;, but it was an interesting exercise that involved some TypeScript shenanigans with the &quot;builder pattern&quot;. You can find it here: &lt;a href=&quot;https://github.com/kyleshevlin/kase&quot;&gt;https://github.com/kyleshevlin/kase&lt;/a&gt;&lt;/p&gt;
</content:encoded><category>JavaScript</category></item><item><title>Generator Functions</title><link>https://kyleshevlin.com/generator-functions/</link><guid isPermaLink="true">https://kyleshevlin.com/generator-functions/</guid><description>In this interactive article, Kyle Shevlin explains a seldom used feature of JavaScript: generator functions. Learn the basics of how they work and how they might be useful.</description><pubDate>Sat, 12 Sep 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import Collatz from &apos;./_Collatz&apos;
import SimplePayment from &apos;./_SimplePayment&apos;&lt;/p&gt;
&lt;p&gt;Have you ever heard of the &lt;a href=&quot;https://science.howstuffworks.com/life/inside-the-mind/human-brain/baader-meinhof-phenomenon.htm&quot;&gt;Baader-Meinhof phenomenon&lt;/a&gt;? It&apos;s a cognitive illusion where once you become aware of some &lt;em&gt;thing&lt;/em&gt;, you see that &lt;em&gt;thing&lt;/em&gt; every where. It&apos;s called an illusion because the thing was always there, you were just unaware of its presence.&lt;/p&gt;
&lt;p&gt;I feel like generator functions are a bit of a Baader-Meinhof phenomenon for me. I never had a use for them, but once I figured out a single use for them, now I see reasons to use them everywhere. &amp;lt;Marker content=&quot;Maybe not the strongest segue, but bear with me.&quot; /&amp;gt;&lt;/p&gt;
&lt;p&gt;I recently used them while doing some maze generation experiments during some time off. Check out the &lt;a href=&quot;https://twitter.com/kyleshevlin/status/1284547126379175938?s=20&quot;&gt;tweets in this thread&lt;/a&gt; if that interests you. They were perfect for the problem I had at hand, and I want to take some time to explain what they are and why they might be useful to you.&lt;/p&gt;
&lt;h3&gt;What&apos;s a Generator Function?&lt;/h3&gt;
&lt;p&gt;A generator function is a special function, denoted by the use of the &lt;code&gt;*&lt;/code&gt; in its declaration.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function* myFirstGenerator() {
  // do stuff here
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This function is &lt;em&gt;different&lt;/em&gt;. Calling this function will not return the value of your function&apos;s body. Not right away, at least. More on this shortly. Instead, it returns a &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator&quot;&gt;&lt;code&gt;Generator&lt;/code&gt; object&lt;/a&gt;. This object has several methods on it, but the one we&apos;re most concerned with is the &lt;code&gt;next&lt;/code&gt; method. Calling &lt;code&gt;next()&lt;/code&gt; on our generator object is how we return the next generated result from our generator function.&lt;/p&gt;
&lt;p&gt;This result is an object with two properties: &lt;code&gt;value&lt;/code&gt; and &lt;code&gt;done&lt;/code&gt;. Let&apos;s discuss how we get these &lt;code&gt;value&lt;/code&gt;s first.&lt;/p&gt;
&lt;p&gt;The most common way we will &quot;return&quot; values from a generator functions is with the &lt;code&gt;yield&lt;/code&gt; keyword. Let&apos;s give it a try in a &lt;em&gt;very&lt;/em&gt; rudimentary way.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function* myFirstGenerator() {
  yield 42
}

const generatorObject = myFirstGenerator()

console.log(generatorObject.next()) // { value: 42, done: false }
console.log(generatorObject.next()) // { value: undefined, done: true }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I want to draw your attention to a few things. First, as I pointed out, we call our generator function to get our &lt;code&gt;generatorObject&lt;/code&gt;. Calling &lt;code&gt;next&lt;/code&gt; returns an object with the &lt;code&gt;yield&lt;/code&gt;ed &lt;code&gt;value&lt;/code&gt; and a &lt;code&gt;done&lt;/code&gt; property. But why is &lt;code&gt;done&lt;/code&gt; &lt;code&gt;false&lt;/code&gt; on the first &lt;code&gt;yield&lt;/code&gt;? There&apos;s nothing else returned in our function body, right?&lt;/p&gt;
&lt;p&gt;Wrong.&lt;/p&gt;
&lt;p&gt;Just like all normal JavaScript functions, there is an implicit &lt;code&gt;return undefined&lt;/code&gt; if there isn&apos;t an explicit &lt;code&gt;return&lt;/code&gt; statement in the function body. This implicit &lt;code&gt;return undefined&lt;/code&gt; is what we get on the second call of the &lt;code&gt;next&lt;/code&gt; method. Hence why &lt;code&gt;value&lt;/code&gt; is &lt;code&gt;undefined&lt;/code&gt; and &lt;code&gt;done&lt;/code&gt; is now &lt;code&gt;true&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;From this, we can deduce that using &lt;code&gt;return&lt;/code&gt; instead of &lt;code&gt;yield&lt;/code&gt; is how to stop a generator.&lt;/p&gt;
&lt;p&gt;Let&apos;s combine the use of &lt;code&gt;return&lt;/code&gt; with &lt;em&gt;multiple&lt;/em&gt; &lt;code&gt;yield&lt;/code&gt;s. Yes, that&apos;s right. You can &lt;code&gt;yield&lt;/code&gt; as many times as you would like in a generator function.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function* countTo(number) {
  let i = 0

  while (i &amp;lt; number - 1) {
    i++
    yield i
  }

  return number
}

const countTo3 = countTo(3)

console.log(countTo3.next()) // { value: 1, done: false }
console.log(countTo3.next()) // { value: 2, done: false }
console.log(countTo3.next()) // { value: 3, done: true }
// Let&apos;s call it an extra time to see what happens
console.log(countTo3.next()) // { value: undefined, done: true }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As you can see, our function &quot;counts&quot; as we expect and is &lt;code&gt;done&lt;/code&gt; when we expect, too.&lt;/p&gt;
&lt;h3&gt;Something Mildly More Interesting&lt;/h3&gt;
&lt;p&gt;Let&apos;s try this on something mildly more interesting. Are you familiar with the &lt;a href=&quot;https://en.wikipedia.org/wiki/Collatz_conjecture&quot;&gt;Collatz conjecture&lt;/a&gt;. It&apos;s an algorithm in mathematics that returns a sequence of numbers. The algorithm is as follows:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Given any positive integer, if the number is even, divide it by 2, otherwise, multiply it by 3 and add 1. Repeat until you arrive at 1.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Writing this algorithm as a generator function is pretty straightforward &lt;em&gt;and&lt;/em&gt; we can generate each step in the sequence.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const isOdd = num =&amp;gt; Boolean(num % 2)
const collatz = num =&amp;gt; (isOdd(num) ? 3 * num + 1 : num / 2)

function* collatzSequence(num) {
  let current = num

  while (current !== 1) {
    yield current
    current = collatz(current)
  }

  return current
}

const sequence = collatzSequence(17)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I want to draw your attention to something I find interesting about how we&apos;re able to write this algorithm with a generator. Because the function essentially pauses execution on the &lt;code&gt;yield&lt;/code&gt; statement, we&apos;re able to &lt;code&gt;yield&lt;/code&gt; the current number &lt;em&gt;before&lt;/em&gt; mutating the &lt;code&gt;current&lt;/code&gt; variable with the next &lt;code&gt;collatz&lt;/code&gt; result. I&apos;ve made a simple React component that will allow you to try out different numbers and generate the Collatz sequence.&lt;/p&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;Collatz client:load /&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;p&gt;Isn&apos;t that interesting? We&apos;re able to get each step in the sequence very easily, and the code is pretty simple to write as well.&lt;/p&gt;
&lt;h3&gt;Something Practical&lt;/h3&gt;
&lt;p&gt;Alright, let&apos;s make one more generator function, but use it to solve a practical problem. In fact, I&apos;m going to use it to solve the very problem that inspired me to write this blog post: &lt;strong&gt;loan repayment&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;If you follow me on Twitter, you probably know of my trevails with student loans. We&apos;ve been paying them off aggressively for years, and still have a few more years to go, but how many to be exact? And how much will an extra $100 here or there help me? All questions that can be answered with a small program. So let&apos;s build a simplified version of it.&lt;/p&gt;
&lt;p&gt;A loan has a &lt;code&gt;principal&lt;/code&gt; (starting amount), an &lt;code&gt;interestRate&lt;/code&gt;, a compounding period (how often it compounds), and a &lt;code&gt;payment&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Let&apos;s start with the simplest part, a few helper functions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Basic compounding formula
const compound = (amount, rate) =&amp;gt; amount + amount * rate

// Keeps floats to a max of 2 places past the decimal
const to2 = num =&amp;gt; Number(num.toFixed(2))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, let&apos;s set about writing a &lt;code&gt;makePayment&lt;/code&gt; generator function. I&apos;ll bake some details specific to student loans in the function, and make comments when I&apos;m doing so.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function* makePayment(principal, rate, payment) {
  // Student loans compound daily, so we create a daily interest rate
  // by dividing our annual rate with the number of days in a year
  const dailyInterestRate = rate / 365
  let remaining = principal
  let totalInterestPaid = 0
  let paymentsCount = 0

  while (remaining &amp;gt; 0) {
    let beginWith = remaining
    let endWith = remaining

    // For simplification, we&apos;re going to treat each payment period
    // as 30 days long
    for (let i = 0; i &amp;lt; 30; i++) {
      endWith = compound(endWith, dailyInterestRate)
    }

    // Student loans pay the accrued interest first, then the principal
    // We&apos;re keeping this formula rudimentary, but this let&apos;s us see what
    // interest accrued since the last payment
    const interestAccrual = to2(endWith - beginWith)
    totalInterestPaid = to2(totalInterestPaid + interestAccrual)

    endWith = to2(endWith - payment)
    remaining = to2(endWith)
    paymentsCount++

    if (endWith &amp;lt;= 0) {
      endWith = 0
      remaining = 0

      return {
        beginWith,
        endWith,
        interestAccrual,
        paymentsCount,
        totalInterestPaid,
      }
    }

    yield {
      beginWith,
      endWith,
      interestAccrual,
      paymentsCount,
      totalInterestPaid,
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;SimplePayment client:load /&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;p&gt;As of the time of this writing, looks like I have about ~33 payments to go. It&apos;s pretty cool to see how much changing the payment can change how long it will take to pay the rest of the loan.&lt;/p&gt;
&lt;p&gt;If I wanted to spend more time on this in this particular post, you could make some very cool data visualizations with generator functions sequencing each update to the visualization. Perhaps I&apos;ll explore this in a future post.&lt;/p&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;Generator functions are a special function that allow you to pause execution, &lt;code&gt;yield&lt;/code&gt;ing multiple (if not infinite) values from them. You might have to stretch your imagination to find a good use for them, but they&apos;re a handy tool to have in your tool chest.&lt;/p&gt;
&lt;p&gt;If you&apos;d like to read more about them, I suggest looking at the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*&quot;&gt;MDN docs&lt;/a&gt; on them.&lt;/p&gt;
&lt;h3&gt;Caveat&lt;/h3&gt;
&lt;p&gt;Generator functions will not work in any version of IE. Womp womp.&lt;/p&gt;
</content:encoded><category>JavaScript</category></item><item><title>Multiple Boolean Props are a Code Smell</title><link>https://kyleshevlin.com/multiple-boolean-props-are-a-code-smell/</link><guid isPermaLink="true">https://kyleshevlin.com/multiple-boolean-props-are-a-code-smell/</guid><description>Having a component that receives multiple props that are booleans can be a sign of a code smell. It&apos;s likely your component now contains impossible states that should be avoided. Moving those props to a single prop that receives an enumerated set of strings is a better approach.</description><pubDate>Fri, 28 Aug 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import CommonButton from &apos;./_CommonButton&apos;
import BetterButton from &apos;./_BetterButton&apos;&lt;/p&gt;
&lt;p&gt;You learn a lot working on a large, complicated codebase for an extended period of time. It&apos;s the kind of environment that exposes you to particular patterns often enough to develop thoughts and opinions around them. I want to share a quick opinion I have regarding a particular pattern here: &lt;strong&gt;multiple boolean &lt;code&gt;props&lt;/code&gt; or &lt;code&gt;state&lt;/code&gt; in a component is probably a code smell&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Imagine a &lt;code&gt;CommonButton&lt;/code&gt; component for an application. This &lt;code&gt;CommonButton&lt;/code&gt; has a &lt;code&gt;default&lt;/code&gt; way of rendering:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;CommonButton&amp;gt;Click Me!&amp;lt;/CommonButton&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;CommonButton client:load&amp;gt;Click Me!&amp;lt;/CommonButton&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;p&gt;Now, imagine our app needs to change the background of the Button depending on the information that button needs to convey. Let&apos;s have a few different variations: a &lt;code&gt;primary&lt;/code&gt;, &lt;code&gt;warning&lt;/code&gt;, and &lt;code&gt;danger&lt;/code&gt; styles. We could do this by passing our &lt;code&gt;CommonButton&lt;/code&gt; a prop of that name.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;CommonButton primary&amp;gt;Click Me!&amp;lt;/CommonButton&amp;gt;
&amp;lt;CommonButton warning&amp;gt;Click Me!&amp;lt;/CommonButton&amp;gt;
&amp;lt;CommonButton danger&amp;gt;Click Me!&amp;lt;/CommonButton&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What should this code look like? Maybe something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function CommonButton({
  children,
  onClick = () =&amp;gt; {},
  primary,
  warning,
  danger,
  type = &apos;button&apos;,
}) {
  let backgroundColor = &apos;#33a1cc&apos;
  if (primary) backgroundColor = &apos;#17b890&apos;
  if (warning) backgroundColor = &apos;#ffd166&apos;
  if (danger) backgroundColor = &apos;#f0544f&apos;

  return (
    &amp;lt;button onClick={onClick} type={type} style={{ backgroundColor }}&amp;gt;
      {children}
    &amp;lt;/button&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And then when we render our buttons from before, we would get:&lt;/p&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;div className=&quot;flex gap-2&quot;&amp;gt;
&amp;lt;CommonButton client:load primary&amp;gt;
Click Me!
&amp;lt;/CommonButton&amp;gt;
&amp;lt;CommonButton client:load warning&amp;gt;
Click Me!
&amp;lt;/CommonButton&amp;gt;
&amp;lt;CommonButton client:load danger&amp;gt;
Click Me!
&amp;lt;/CommonButton&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;p&gt;That looks great, but there are some serious problems with this approach that make it rather smelly. The problem that bothers my coding olfactory senses the most is the existence of &lt;em&gt;impossible states&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;What should happen if the consumer does the following?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;CommonButton danger primary warning&amp;gt;
  Click Me!
&amp;lt;/CommonButton&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Should it render as green, yellow, or red? Let&apos;s find out.&lt;/p&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;CommonButton client:load danger primary warning&amp;gt;
Click Me!
&amp;lt;/CommonButton&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;p&gt;If you put more than one of these boolean props in place, what happens? You see a leaking of the implementation details! Whatever way the component creator has decided to reconcile these impossible states is exposed. In this case, I wrote it so that &lt;code&gt;danger&lt;/code&gt; was the last state checked that updates the background color. Therefore, the &lt;code&gt;danger&lt;/code&gt; prop takes priority over all the other props, regardless of the order they are passed in.&lt;/p&gt;
&lt;p&gt;Now, admittedly, this is not how we intend our component to be used. &quot;The consumer should use the component correctly!&quot; you might yell. True. They probably should, but we shouldn&apos;t write code that depends on others to &lt;em&gt;just not make mistakes&lt;/em&gt;. Especially when we can programmatically defend against the problem in a simple way.&lt;/p&gt;
&lt;p&gt;We could possibly stop the abuse of our &lt;code&gt;CommonButton&lt;/code&gt; through an error/warning or even an ESLint rule, but there&apos;s a much easier thing that we can do. &lt;strong&gt;Get rid of the multiple boolean props&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Whenever we have multiple boolean props, especially ones related to the same concern, these should really be expressed as a single prop with an enumerated set of strings as the possible values. Let&apos;s make a &lt;code&gt;BetterButton&lt;/code&gt; that follows this pattern.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const BUTTON_BGS = {
  default: &apos;#33a1cc&apos;,
  primary: &apos;#17b890&apos;,
  warning: &apos;#ffd166&apos;,
  danger: &apos;#f0544f&apos;,
}

function BetterButton({
  children,
  onClick = () =&amp;gt; {},
  type = &apos;button&apos;,
  variant = &apos;default&apos;,
}) {
  const backgroundColor = BUTTON_BGS[variant] || BUTTON_BGS.default

  return (
    &amp;lt;button onClick={onClick} style={{ backgroundColor }} type={type}&amp;gt;
      {children}
    &amp;lt;/button&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This button not only moves our props into a single concern, but allows us to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Move our styles into an enum&lt;/li&gt;
&lt;li&gt;Handle incorrect variants gracefully&lt;/li&gt;
&lt;li&gt;Make impossible states impossible&lt;/li&gt;
&lt;li&gt;Makes later extension as simple as adding a variant&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now, our buttons look like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;BetterButton variant=&quot;primary&quot;&amp;gt;Click Me!&amp;lt;/BetterButton&amp;gt;
&amp;lt;BetterButton variant=&quot;warning&quot;&amp;gt;Click Me!&amp;lt;/BetterButton&amp;gt;
&amp;lt;BetterButton variant=&quot;danger&quot;&amp;gt;Click Me!&amp;lt;/BetterButton&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;div className=&quot;flex gap-2&quot;&amp;gt;
&amp;lt;BetterButton client:load variant=&quot;primary&quot;&amp;gt;
Click Me!
&amp;lt;/BetterButton&amp;gt;
&amp;lt;BetterButton client:load variant=&quot;warning&quot;&amp;gt;
Click Me!
&amp;lt;/BetterButton&amp;gt;
&amp;lt;BetterButton client:load variant=&quot;danger&quot;&amp;gt;
Click Me!
&amp;lt;/BetterButton&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;p&gt;Even better, when you try and give it some garbage as a &lt;code&gt;variant&lt;/code&gt;, it doesn&apos;t leak our implementation details, it just uses the default styling.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;BetterButton variant=&quot;primary warning danger&quot;&amp;gt;Click Me!&amp;lt;/BetterButton&amp;gt;
&amp;lt;BetterButton variant=&quot;garbage&quot;&amp;gt;Click Me!&amp;lt;/BetterButton&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;div className=&quot;flex gap-2&quot;&amp;gt;
&amp;lt;BetterButton client:load variant=&quot;primary warning danger&quot;&amp;gt;
Click Me!
&amp;lt;/BetterButton&amp;gt;
&amp;lt;BetterButton client:load variant=&quot;garbage&quot;&amp;gt;
Click Me!
&amp;lt;/BetterButton&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;p&gt;This also applies to situations where you have multiple booleans around different concerns coming in. It&apos;s likely that what you really have are a number of finite &quot;states&quot; your component can be in, and it would be better to derive that state and pass it in as a prop, rather than muddy your code with conditional checks for your many booleans.&lt;/p&gt;
&lt;p&gt;Again, this is just my opinion. I don&apos;t have any way of definitively proving that this approach is better, but I&apos;ve found it to be useful for me in my career. Hope you also find this information useful.&lt;/p&gt;
</content:encoded><category>JavaScript</category><category>React</category></item><item><title>Mental Model of Use Effect</title><link>https://kyleshevlin.com/mental-model-of-use-effect/</link><guid isPermaLink="true">https://kyleshevlin.com/mental-model-of-use-effect/</guid><description>The React.useEffect hook can be challenging to get right. One way to easily mess it up is to incorrectly use the dependency array. This post demonstrates how to think about it correctly.</description><pubDate>Wed, 26 Aug 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;One thing I have found challenging about &lt;code&gt;React.useEffect&lt;/code&gt; is the mental model regarding the dependencies array.&lt;/p&gt;
&lt;p&gt;It&apos;s very easy to get it in your head to use the dependency array as a means to constrain the calling of the effect, essentially treating it as a guard or conditional.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;If this value changes, do that effect.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The problem is that you&apos;ll often run into issues where you only want to run an effect when a single value changes, and thus you&apos;ll be tempted to leave out the other dependencies from the dependency array. Next thing you know, you&apos;ll be facing an ESLint warning about it. &amp;lt;Marker content=&quot;Assuming you&apos;re using ESLint with the React Hooks plugin.&quot; /&amp;gt; Like with the following code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;React.useEffect(() =&amp;gt; {
  // Pretend these values are in the parent scope
  const diff = prevQuantity - quantity
  someHandlerFunction(diff)
}, [quantity])
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This, more or less, works like we want it to. When &lt;code&gt;quantity&lt;/code&gt; changes, we call the effect and call the handling function. However, this will also warn you that you haven&apos;t added all the dependencies. You might think, &quot;I don&apos;t &lt;em&gt;want&lt;/em&gt; this effect to run when the handler function changes! That&apos;ll break the code!&quot;&lt;/p&gt;
&lt;p&gt;Trust me, I get stuck in this loop a lot, too.&lt;/p&gt;
&lt;p&gt;Here&apos;s what you need to understand. Simply put, not calling the effect whenever a dependency changes means you&apos;ll have stale values and functions. It &lt;em&gt;will&lt;/em&gt; lead to bugs.&lt;/p&gt;
&lt;p&gt;Instead, you must make the mental shift to:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Call this effect whenever the dependencies change, &lt;em&gt;but&lt;/em&gt; add a conditional in the effect function that only triggers the changes you need, when you need them to happen.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The more correct code looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;React.useEffect(() =&amp;gt; {
  if (prevQuantity !== quantity) {
    const diff = prevQuantity - quantity
    someHandlerFunction(diff)
  }
}, [prevQuantity, quantity, someHandlerFunction])
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we can call the effect whenever a dependency changes, while still not calling our handler function when we don&apos;t intend to.&lt;/p&gt;
&lt;p&gt;Fixing this small mental model issue &amp;lt;Marker content=&quot;An issue for me. Maybe not for you.&quot; /&amp;gt; helps you avoid the ESLint warnings and write better code. Hope this helps you.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Update - August 27, 2020&lt;/h3&gt;
&lt;p&gt;I had an additional thought regarding this topic and wanted to add it to the post. Another way to think about the &lt;code&gt;useEffect&lt;/code&gt; hook is to write the code as if the hook and the dependency array wasn&apos;t there first, and then wrap it in the hook and add the dependencies later.&lt;/p&gt;
&lt;p&gt;If I think about this outside of the hook, my mental model for the functionality is, &quot;If there&apos;s a difference between these two values, send the difference to this handling function.&quot; When we write that code, it looks like the body of our effect, but it makes sense in isolation.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if (prevQuantity !== quantity) {
  const diff = prevQuantity - quantity
  someHandlerFunction(diff)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now that we&apos;ve written the functionality we desire, the next step is to put React in charge of tracking all of these values for us.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// highlight-next-line
React.useEffect(() =&amp;gt; {
  if (prevQuantity !== quantity) {
    const diff = prevQuantity - quantity
    someHandlerFunction(diff)
  }
  // highlight-next-line
}, [prevQuantity, quantity, someHandlerFunction])
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Hope this little update also helps you in your mental understanding of the &lt;code&gt;useEffect&lt;/code&gt; hook.&lt;/p&gt;
</content:encoded><category>JavaScript</category><category>React</category><category>React Hooks</category></item><item><title>Tic-Tac-Toe in React</title><link>https://kyleshevlin.com/tic-tac-toe/</link><guid isPermaLink="true">https://kyleshevlin.com/tic-tac-toe/</guid><description>In this blog post, Kyle Shevlin teaches you how to build tic-tac-toe in React using CSS grid and the `useReducer` hook.</description><pubDate>Sun, 02 Aug 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import BlankGrid from &apos;./_BlankGrid&apos;
import FirstGame from &apos;./_FirstGame&apos;
import SecondGame from &apos;./_SecondGame&apos;
import ThirdGame from &apos;./_ThirdGame&apos;
import FourthGame from &apos;./_FourthGame&apos;&lt;/p&gt;
&lt;p&gt;If video content is more your thing than reading a technical article, you can watch my collection of egghead lessons teaching the material found in this blog post. No matter which you prefer, I hope you enjoy the content.&lt;/p&gt;
&lt;p&gt;&amp;lt;EggheadEmbed
src=&quot;https://egghead.io/lessons/javascript-create-a-2-dimensional-grid-for-our-tic-tac-toe-game/embed?pl=tic-tac-toe-in-react-387f&quot;
title=&quot;Tic Tac Toe in React egghead Collection&quot;
/&amp;gt;&lt;/p&gt;
&lt;p&gt;A few weeks ago, I took some time off from work. I was feeling a little burnt out and needed to rest and have some fun. Sometimes that means not coding at all. Other times, it means coding some silly stuff of no real importance. Turns out, coding is still fun after all! I decided to do the latter on my staycation and code up a bunch of silly games. I&apos;m going to share the simplest one with you here: tic-tac-toe.&lt;/p&gt;
&lt;p&gt;Before we get started, I want to say that even though I don&apos;t build games for a living (or even really as a hobby), coding up a game from time to time is a great way to learn some new skills and patterns. It&apos;s also excellent exercise for your brain and trains you to think algorithmically. In fact, I once was asked to code tic-tac-toe in a job interview, so don&apos;t scoff at this post. It might help you land a job some day.&lt;/p&gt;
&lt;p&gt;Tic-tac-toe is a very simple game, and because it&apos;s so simple, it makes for a good introduction to some of the principles of grid and turn-based games.&lt;/p&gt;
&lt;p&gt;Let&apos;s start with a top-level &lt;code&gt;Game&lt;/code&gt; component that will store the state of our tic-tac-toe game. For now, it&apos;s just an empty function that returns &lt;code&gt;null&lt;/code&gt;, but it won&apos;t be this way for long.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Game() {
  return null
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Tic-tac-toe consists of a 3x3 grid on which the players put &lt;code&gt;X&lt;/code&gt;s and &lt;code&gt;O&lt;/code&gt;s. We need a way to generate this grid and display the state of the data with a &lt;code&gt;Grid&lt;/code&gt; component. We could do this a number of ways, but I&apos;m going to create a 2-dimensional array of values. We will keep it very simple. Those values can only be &lt;code&gt;null&lt;/code&gt;, &lt;code&gt;X&lt;/code&gt;, or &lt;code&gt;O&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For the sake of those new to 2-dimensional grids, I&apos;m going to break this down piece by piece, or rather index by index. When we create games with a 2-dimensional array, the outermost array is the &lt;code&gt;grid&lt;/code&gt;. The &lt;code&gt;grid&lt;/code&gt; consists of &lt;code&gt;rows&lt;/code&gt; which are also arrays. This is why it&apos;s called a 2-dimensional array. You might also come across the term &quot;matrix&quot; for this data structure.&lt;/p&gt;
&lt;p&gt;A &lt;code&gt;row&lt;/code&gt; consists of values. Each value in the &lt;code&gt;row&lt;/code&gt; is a &lt;code&gt;column&lt;/code&gt; in our &lt;code&gt;grid&lt;/code&gt;. I typically think of each &lt;code&gt;column&lt;/code&gt; value as a &lt;code&gt;cell&lt;/code&gt; and refer to it as such in my game&apos;s program.&lt;/p&gt;
&lt;p&gt;When we start a game of tic-tac-toe, our board consists of 3 &lt;code&gt;rows&lt;/code&gt; and 3 &lt;code&gt;columns&lt;/code&gt;, where every &lt;code&gt;cell&lt;/code&gt; is the value of &lt;code&gt;null&lt;/code&gt;. So our grid looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const grid = [
  [null, null, null],
  [null, null, null],
  [null, null, null],
]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For a game like tic-tac-toe, it is simple enough to manually create a starting grid like this. But, as you build more games, you will find that making a function to generate a grid for you will be quite helpful. My &lt;code&gt;generateGrid&lt;/code&gt; function looks like this: &amp;lt;Marker content=&quot;You can make all sorts of varieties of this function. Do what suits your needs best&quot; /&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function generateGrid(rows, columns, mapper) {
  return Array(rows)
    .fill()
    .map(() =&amp;gt; Array(columns).fill().map(mapper))
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can make a function specific for a tic-tac-toe game by baking in a few values:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const newTicTacToeGrid = () =&amp;gt; generateGrid(3, 3, () =&amp;gt; null)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&apos;s add a &lt;code&gt;newTicTacToeGrid&lt;/code&gt; to our &lt;code&gt;Game&lt;/code&gt; component so that we&apos;ll be able to pass it down eventually into other components.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Game() {
  // This will eventually be a stateful grid
  const grid = newTicTacToeGrid()

  return null
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now that we can easily generate our tic-tac-toe grid, we need to render it. Coincidentally enough, using CSS Grid to display our &lt;code&gt;grid&lt;/code&gt; works very well. Here&apos;s one of the ways I might approach this with React:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Grid({ grid }) {
  return (
    // Wrapping the grid with a div of inline-block means that the grid
    // takes up only the space defined by the size of the cells, while
    // still allowing us to use fractional values for the grid-template-*
    // properties
    &amp;lt;div style={{ display: &apos;inline-block&apos; }}&amp;gt;
      &amp;lt;div
        style={{
          // We set a background color to be revealed as the lines
          // of the board with the `grid-gap` property
          backgroundColor: &apos;#000&apos;,
          display: &apos;grid&apos;,
          // Our rows are equal to the length of our grid
          gridTemplateRows: `repeat(${grid.length}, 1fr)`,
          // Our columns are equal to the length of a row
          gridTemplateColumns: `repeat(${grid[0].length}, 1fr)`,
          gridGap: 2,
        }}
      &amp;gt;
        {grid.map((row, rowIdx) =&amp;gt;
          row.map((cell, colIdx) =&amp;gt; (
            // We put the colIdx first because that is our X-axis value
            // and the rowIdx second because that is our Y-axis value
            // Getting in the habit makes using 2d grids much easier
            &amp;lt;Cell key={`${colIdx}-${rowIdx}`} cell={cell} /&amp;gt;
          )),
        )}
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}

const cellStyle = {
  backgroundColor: &apos;#fff&apos;,
  height: 75,
  width: 75,
}

function Cell({ cell }) {
  return &amp;lt;div style={cellStyle}&amp;gt;{cell}&amp;lt;/div&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The comments in the code block above explain most of my decisions, but just to recap quickly, we use CSS Grid to layout our &lt;code&gt;rows&lt;/code&gt; and &lt;code&gt;columns&lt;/code&gt;. We can do that by setting the &lt;code&gt;grid-template-rows&lt;/code&gt; property equal to the length of our &lt;code&gt;grid&lt;/code&gt; array, and making &lt;code&gt;grid-template-columns&lt;/code&gt; equal to the length of the first &lt;code&gt;row&lt;/code&gt; in our grid.&lt;/p&gt;
&lt;p&gt;Since this is tic-tac-toe, we style it by giving the grid a background color and using the &lt;code&gt;grid-gap&lt;/code&gt; property to &quot;reveal&quot; the grid lines by making each of our cells an offsetting background color. This is a clever and simple way to avoid having to write various &lt;code&gt;border&lt;/code&gt;s for each cell.&lt;/p&gt;
&lt;p&gt;Let&apos;s also be sure to pass &lt;code&gt;grid&lt;/code&gt; from our &lt;code&gt;Game&lt;/code&gt; component down into our &lt;code&gt;Grid&lt;/code&gt; component.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Game() {
  const game = newTicTacToeGrid()
  return &amp;lt;Grid grid={grid} /&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now when we render &lt;code&gt;Game&lt;/code&gt;, it should look like something like this:&lt;/p&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;BlankGrid client:load /&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;p&gt;Now that we have our grid, we should make our &lt;code&gt;Cell&lt;/code&gt;s interactive. I&apos;m going to add a button to each cell to make it clickable and accessible. I&apos;m also going to pass a &lt;code&gt;handleClick&lt;/code&gt; event handler function into the component to be used with the button&apos;s &lt;code&gt;onClick&lt;/code&gt; property.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;handleClick&lt;/code&gt; will be passed down as a prop from our top level &lt;code&gt;Game&lt;/code&gt; component through the &lt;code&gt;Grid&lt;/code&gt; to get to the &lt;code&gt;Cell&lt;/code&gt;. We could also accomplish this with hooks or context, but I don&apos;t mind prop-drilling when our UI hierarchy is this small.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Game() {
  const grid = newTicTacToeGrid()
  const handleClick = () =&amp;gt; {}

  return (
    &amp;lt;div style={{ display: &apos;inline-block&apos; }}&amp;gt;
      &amp;lt;Grid grid={grid} handleClick={handleClick} /&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}

function Cell({ cell, handleClick }) {
  return (
    &amp;lt;div style={cellStyle}&amp;gt;
      &amp;lt;button type=&quot;button&quot; onClick={handleClick}&amp;gt;
        {cell}
      &amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, what should &lt;code&gt;handleClick&lt;/code&gt; do? &lt;code&gt;handleClick&lt;/code&gt; should take the coordinates of the cell clicked, and dispatch this action whatever is handling our state to determine the next state. This sounds like a good use case for &lt;code&gt;useReducer&lt;/code&gt;. &amp;lt;Marker content=&quot;I will refactor this to use a state machine in the future. Don&apos;t worry.&quot; /&amp;gt; Let&apos;s update &lt;code&gt;handleClick&lt;/code&gt; to accept &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; arguments and pass them on to some state management. This will add quite a bit of code, but I&apos;ll explain it in a bit.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Simple way to deeply clone an array or object
const clone = x =&amp;gt; JSON.parse(JSON.stringify(x))

// An enum for the next turn in our game
const NEXT_TURN = {
  O: &apos;X&apos;,
  X: &apos;O&apos;,
}

const initialState = {
  grid: newTicTacToeGrid(),
  turn: &apos;X&apos;,
}

const reducer = (state, action) =&amp;gt; {
  switch (action.type) {
    case &apos;CLICK&apos;: {
      const { x, y } = action.payload
      // Since we need immutable updates, I often find the simplest thing to do
      // is to clone the current state, and then use mutations on the clone to
      // make updates for the next state
      const nextState = clone(state)
      const { grid, turn } = nextState

      // If the cell already has a value, clicking on it should do nothing
      // Also, pay attention, because our rows are first, the `y` value is the
      // first index, the `x` value second. This takes some getting used to.
      if (grid[y][x]) {
        return state
      }

      // If we&apos;re here in our program, we can assign this cell to the current
      // `turn` value
      grid[y][x] = turn

      // Now that we&apos;ve used this turn, we need to set the next turn. It might
      // be overkill, but I&apos;ve used an object enum to do this.
      nextState.turn = NEXT_TURN[turn]

      // We&apos;ll add checks for winning or drawing soon

      return nextState
    }

    default:
      return state
  }
}

function Game() {
  const [state, dispatch] = React.useReducer(reducer, initialState)
  const { grid } = state

  const handleClick = (x, y) =&amp;gt; {
    dispatch({ type: &apos;CLICK&apos;, payload: { x, y } })
  }

  return &amp;lt;Grid grid={grid} /&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&apos;s break this code down. We start with &lt;code&gt;clone&lt;/code&gt; which is a helper function I will use to deeply clone the state so I can make mutations on the clone and return that. Remember, we need to make immutable updates with a reducer, so that it renders the new state.&lt;/p&gt;
&lt;p&gt;Next, I create a simple enum to be able to easily get the next turn. You could probably do this with a simple ternary, but there are other places this information will be useful in the future.&lt;/p&gt;
&lt;p&gt;After that, we create our &lt;code&gt;initialState&lt;/code&gt; and a &lt;code&gt;reducer&lt;/code&gt;. Our &lt;code&gt;initialState&lt;/code&gt; has our &lt;code&gt;grid&lt;/code&gt; and the current &lt;code&gt;turn&lt;/code&gt;, and our reducer handles only one action at the time being, &lt;code&gt;CLICK&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;On a &lt;code&gt;CLICK&lt;/code&gt; action, we use the &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; values of the payload to determine the next state. If the &lt;code&gt;grid&lt;/code&gt; cell at those coordinates has a value, we return the current state so we don&apos;t trigger an update. Otherwise, we can set the value of that &lt;code&gt;cell&lt;/code&gt; to the current &lt;code&gt;turn&lt;/code&gt;, update the &lt;code&gt;nextState.turn&lt;/code&gt; property and return the &lt;code&gt;nextState&lt;/code&gt;. Putting this all together, we should have a &lt;code&gt;Game&lt;/code&gt; that works like this:&lt;/p&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;FirstGame client:load /&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;p&gt;Awesome. Our game is working... kind of. We can fill up the squares, but we don&apos;t have any means of resetting the game if we want to (or a draw occurs), and we don&apos;t have a way of determining if someone has won the game. Heck, we don&apos;t even know who&apos;s turn it is! Let&apos;s add these features next.&lt;/p&gt;
&lt;p&gt;Let&apos;s start with the simplest of those tasks, whose turn it is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Game() {
  const [state, dispatch] = React.useReducer(reducer, initialState)
  // highlight-next-line
  const { grid, turn } = state

  const handleClick = (x, y) =&amp;gt; {
    dispatch({ type: &apos;CLICK&apos;, payload: { x, y } })
  }

  return (
    &amp;lt;div style={{ textAlign: &apos;center&apos; }}&amp;gt;
      {/* highlight-next-line */}
      &amp;lt;div&amp;gt;Next up: {turn}&amp;lt;/div&amp;gt;
      &amp;lt;Grid Cell={ButtonCell} grid={grid} handleClick={handleClick} /&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And let&apos;s add a &lt;code&gt;reset&lt;/code&gt; button, too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Changing this into a function ensures that we get a new state object
// and run any of the functions inside of it. This is useful in other games
// where the starting grid may have randomized bits of state
// highlight-range{1-4}
const getInitialState = () =&amp;gt; ({
  grid: newTicTacToeGrid(),
  turn: &apos;X&apos;
})

const reducer (state, action) =&amp;gt; {
  switch (action.type) {
    // highlight-range{1-2}
    case &apos;RESET&apos;:
      return getInitialState()

    //... remains the same
  }
}

function Game() {
  const [state, dispatch] = React.useReducer(reducer, getInitialState())
  const { grid, turn } = state

  const handleClick = (x, y) =&amp;gt; {
    dispatch({ type: &apos;CLICK&apos;, payload: { x, y } })
  }

  const reset = () =&amp;gt; {
    dispatch({ type: &apos;RESET&apos; })
  }

  return (
    &amp;lt;div style={{ textAlign: &apos;center&apos; }}&amp;gt;
      &amp;lt;div style={{ display: &apos;flex&apos;, justifyContent: &apos;space-between&apos; }}&amp;gt;
        &amp;lt;div&amp;gt;Next up: {turn}&amp;lt;/div&amp;gt;
        {/* highlight-next-line */}
        &amp;lt;button onClick={reset} type=&quot;button&quot;&amp;gt;Reset&amp;lt;/button&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;Grid Cell={ButtonCell} grid={grid} handleClick={handleClick} /&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, our tic-tac-toe game looks like this:&lt;/p&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;SecondGame client:load /&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;p&gt;This is great. You, the reader and user can play, but it&apos;d be really nice if the game told you if you won or not. Checking for win conditions is probably the most important part of creating a game like this (and is likely what the interviewer is looking for if you&apos;re asked to make a game like this).&lt;/p&gt;
&lt;p&gt;We need to create an efficient algorithm that checks for the game at each step for a win. What are the win conditions of tic-tac-toe?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The game is won when 3 cells in a line contain the same value&lt;/li&gt;
&lt;li&gt;A line is defined as a row, column, or diagonal&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let&apos;s break this down. At any given time, we need to check if three values are equal. There also happens to be only 8 lines in our game: 3 rows, 3 columns, and 2 diagonals. With these two observations, we can create a simple algorithm to determine if the game has been won at any point.&lt;/p&gt;
&lt;p&gt;We&apos;ll start by making a helper function to evaluate our three values. We know if a square is &lt;code&gt;null&lt;/code&gt;, we can return &lt;code&gt;false&lt;/code&gt; immediately. Then we just need to know if all three values are the same. Since we&apos;re using the strings &lt;code&gt;X&lt;/code&gt; and &lt;code&gt;O&lt;/code&gt;, this is very simple to do: &amp;lt;Marker content=&quot;If you&apos;re a fan of fancy terms, I am using the &amp;lt;em&amp;gt;transitive property&amp;lt;/em&amp;gt; to deduce that &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt; is equal to &amp;lt;code&amp;gt;c&amp;lt;/code&amp;gt;.&quot; /&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const checkThree = (a, b, c) =&amp;gt; {
  // If any of the values are null, return false
  if (!a || !b || !c) return false
  return a === b &amp;amp;&amp;amp; b === c
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, we need to create our 8 lines, get the values at those indices, and run &lt;code&gt;checkThree&lt;/code&gt; on each line. I&apos;m going to add a helper function that will &lt;code&gt;flatten&lt;/code&gt; our 2-dimensional array into a 1-dimensional array. This will make this our checks a little bit easier to do. Flattening an array like this might be too inefficient in certain situations, so be careful and pay attention to the performance of your program, but in general, this a good trick to know. &amp;lt;Marker content=&quot;As of ES2019, JavaScript added &amp;lt;code&amp;gt;Array.prototype.flat()&amp;lt;/code&amp;gt; to the language. If you&apos;re environment can handle this standard, you can easily use it instead.&quot; /&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Depending on your JavaScript environment, you can potentially
// use Array.prototype.flat to do this
const flatten = array =&amp;gt; array.reduce((acc, cur) =&amp;gt; [...acc, ...cur], [])

function checkForWin(flatGrid) {
  // Because our grid is flat, we can use array destructuring to
  // define variables for each square, I will use the points on a
  // compass as my variable names
  const [nw, n, ne, w, c, e, sw, s, se] = flatGrid

  // Then we simply run `checkThree` on each row, column and diagonal
  // If it&apos;s true for any of them, the game has been won!
  return (
    checkThree(nw, n, ne) ||
    checkThree(w, c, e) ||
    checkThree(sw, s, se) ||
    checkThree(nw, w, sw) ||
    checkThree(n, c, s) ||
    checkThree(ne, e, se) ||
    checkThree(nw, c, se) ||
    checkThree(ne, c, sw)
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We want to add our &lt;code&gt;checkForWin&lt;/code&gt; function inside the &lt;code&gt;CLICK&lt;/code&gt; case of our reducer. This will enable us to transition the game state into a winning state as soon as a win is detected. However, we have not setup any state that tracks whether the game has been won or not yet. We&apos;ll also want to add a &lt;code&gt;status&lt;/code&gt; property to our state that we can update when a win is found.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const getInitialState = () =&amp;gt; ({
  grid: newTicTacToeGrid(),
  // highlight-next-line
  status: &apos;inProgress&apos;,
  turn: &apos;X&apos;,
})

const reducer (state, action) =&amp;gt; {
  switch (action.type) {
    //... still the same

    case &apos;CLICK&apos;: {
      const { x, y } = action.payload
      const nextState = clone(state)
      const { grid, turn } = nextState

      if (grid[y][x]) {
        return state
      }

      grid[y][x] = turn

      // highlight-next-line
      const flatGrid = flatten(grid)

      // highlight-range{1-4}
      if (checkForWin(flatGrid)) {
        nextState.status = &apos;success&apos;
        return nextState
      }

      nextState.turn = NEXT_TURN[turn]

      return nextState
    }

    //... still the same
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now that we have a &lt;code&gt;status&lt;/code&gt;, we can use it in our &lt;code&gt;Game&lt;/code&gt; component to display when we have a winner. I prefer to use &lt;a href=&quot;/enumerate-dont-booleanate&quot;&gt;enums over booleans&lt;/a&gt; for tracking states, and generally this results in making enumerated objects to respond to those states. In order to render some text when the game is won, I&apos;ll create a &lt;code&gt;GAME_STATUS_TEXT&lt;/code&gt; enum. This enum is a method for each game &lt;code&gt;status&lt;/code&gt; we have. This method can can receive the current &lt;code&gt;turn&lt;/code&gt; as an argument, and render whatever is necessary. Almost always, this will return &lt;code&gt;null&lt;/code&gt;, but when someone wins, we can tell them.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// highlight-range{1-4}
const GAME_STATUS_TEXT = {
  inProgress: () =&amp;gt; null,
  success: turn =&amp;gt; `${turn} won!`,
}

function Game() {
  const [state, dispatch] = React.useReducer(reducer, getInitialState())
  // highlight-next-line
  const { grid, status, turn } = state

  const handleClick = (x, y) =&amp;gt; {
    dispatch({ type: &apos;CLICK&apos;, payload: { x, y } })
  }

  const reset = () =&amp;gt; {
    dispatch({ type: &apos;RESET&apos; })
  }

  return (
    &amp;lt;div style={{ textAlign: &apos;center&apos; }}&amp;gt;
      &amp;lt;div style={{ display: &apos;flex&apos;, justifyContent: &apos;space-between&apos; }}&amp;gt;
        &amp;lt;div&amp;gt;Next up: {turn}&amp;lt;/div&amp;gt;
        {/* highlight-next-line */}
        &amp;lt;div&amp;gt;{GAME_STATUS_TEXT[status](turn)}&amp;lt;/div&amp;gt;
        &amp;lt;button onClick={reset} type=&quot;button&quot;&amp;gt;
          Reset
        &amp;lt;/button&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;Grid Cell={ButtonCell} grid={grid} handleClick={handleClick} /&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Before we check out this iteration of the game, I want to add something to our reducer to prevent a user from clicking anything but the reset button after a game has been won. By preventing this, I prevent some awkward state where after the first player has won the game, the second player can&apos;t &quot;steal&quot; by clicking a square that gives them three in a row. I also want to show this to demonstrate that a reducer does &lt;em&gt;not&lt;/em&gt; have to be just a &lt;code&gt;switch&lt;/code&gt; statement.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const reducer = (state, action) =&amp;gt; {
  if (state.status === &apos;success&apos; &amp;amp;&amp;amp; action.type !== &apos;RESET&apos;) {
    return state
  }

  //... still the same
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now the only action a user can take when the game has been won is to reset the game. This seems fair to me. Check it out:&lt;/p&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;ThirdGame client:load /&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;p&gt;There is just one more thing I want to add to this game. I would like the game to reset immediately when the board is filled with a draw. Doing this just seems like a nice touch to add.&lt;/p&gt;
&lt;p&gt;We could do the work of trying to figure out when a game cannot be won and indicate that the game is drawn to the users, but I will leave that to you to try and figure out and implement. For now, let&apos;s add a &lt;code&gt;checkForDraw&lt;/code&gt; function to our game to bring this to completion.&lt;/p&gt;
&lt;p&gt;Adding &lt;code&gt;checkForDraw&lt;/code&gt; is simpler than it might seem. First, we need to know that the game has not been won. The game can&apos;t be a draw if it&apos;s been won. We can reuse &lt;code&gt;checkForWin&lt;/code&gt; for that. &amp;lt;Marker content=&quot;It would be slightly more efficient to use the result of &amp;lt;code&amp;gt;checkForWin&amp;lt;/code&amp;gt; so that we&apos;re not running the function twice in every loop. I leave that to you to implement.&quot; /&amp;gt;&lt;/p&gt;
&lt;p&gt;Once we know that the game has not been won, we need to determine if the grid has been completely filled in. Given that our values are &lt;code&gt;null&lt;/code&gt;, &lt;code&gt;X&lt;/code&gt;, or &lt;code&gt;O&lt;/code&gt;, we can determine this by filtering our &lt;code&gt;flatGrid&lt;/code&gt; with the &lt;code&gt;Boolean&lt;/code&gt; constructor. If the filtered grid has a length that is less than the length of the &lt;code&gt;flatGrid&lt;/code&gt;, then we know we have &lt;code&gt;null&lt;/code&gt; squares and the game is not drawn yet.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function checkForDraw(flatGrid) {
  return (
    !checkForWin(flatGrid) &amp;amp;&amp;amp;
    flatGrid.filter(Boolean).length === flatGrid.length
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We add this into our &lt;code&gt;CLICK&lt;/code&gt; case in our &lt;code&gt;reducer&lt;/code&gt;, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const reducer (state, action) =&amp;gt; {
  switch (action.type) {
    //... still the same

    case &apos;CLICK&apos;: {
      const { x, y } = action.payload
      const nextState = clone(state)
      const { grid, turn } = nextState

      if (grid[y][x]) {
        return state
      }

      grid[y][x] = turn

      const flatGrid = flatten(grid)

      if (checkForWin(flatGrid)) {
        nextState.status = &apos;success&apos;
        return nextState
      }

      // highlight-range{1-3}
      if (checkForDraw(flatGrid)) {
        return getInitialState()
      }

      nextState.turn = NEXT_TURN[turn]

      return nextState
    }

    //... still the same
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;FourthGame client:load /&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;There you have it! A working game of tic-tac-toe in React in about 130ish lines of code. I&apos;m pretty generous with the whitespace usage.&lt;/p&gt;
&lt;p&gt;Now, what was the point of all this? It certainly wasn&apos;t to try and make something you can do in a matter of seconds on a piece of paper with a pencil. It was to get our brains to think about solving problems, and more importantly, figuring out what those fundamental problems are. &lt;em&gt;This&lt;/em&gt; is programming. Breaking requirements and ideas down until they can be turned into code.&lt;/p&gt;
&lt;p&gt;Learning to code tic-tac-toe can be a gateway to all sorts of other learning. You can now practice building other games, or learn other algorithms. You can even take what you know here and apply it to other languages. Learning to code the same app in different ways is also good practice for your brain.&lt;/p&gt;
&lt;p&gt;I encourage you to try and take this a step further some how. Make it better. Make it faster. I would love to see what you come up with.&lt;/p&gt;
</content:encoded><category>React</category><category>JavaScript</category></item><item><title>Using `React.memo` to Avoid Unnecessary Rerenders</title><link>https://kyleshevlin.com/using-react-memo-to-avoid-unnecessary-rerenders/</link><guid isPermaLink="true">https://kyleshevlin.com/using-react-memo-to-avoid-unnecessary-rerenders/</guid><description>We can use the top level `React.memo` API to avoid unnecessary rerenders of our function components in a React app. In this post, Kyle Shevlin will teach you how it works.</description><pubDate>Tue, 16 Jun 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import {
Profile,
MemoizedProfile,
Parent,
ObjectParent,
RefParent,
OtherObjectParent,
} from &apos;./_Profile&apos;&lt;/p&gt;
&lt;p&gt;In my last post, I talked about the concept of &lt;a href=&quot;/memoization&quot;&gt;memoization&lt;/a&gt; and how the technique is used to avoid calculating a previously calculated result of a function. I also made mention of the two memoization functions in React. This post is going to focus on &lt;code&gt;React.memo&lt;/code&gt; and how to use it to avoid unnecessary rerenders of React components.&lt;/p&gt;
&lt;p&gt;When Hooks were introduced to React in late 2018, we were also given some new top-level functions in the React API. One of those new functions is &lt;code&gt;React.memo&lt;/code&gt;. It is the function component equivalent of using &lt;code&gt;PureComponent&lt;/code&gt; for a class component.&lt;/p&gt;
&lt;p&gt;If your component is a pure function, i.e. given the same inputs you get the same output, you can wrap the component in &lt;code&gt;React.memo&lt;/code&gt; to prevent the component from rerendering if &lt;code&gt;props&lt;/code&gt; haven&apos;t changed. &amp;lt;Marker content=&quot;It will still rerender if &lt;code&gt;state&lt;/code&gt; or &lt;code&gt;context&lt;/code&gt; changes.&quot; /&amp;gt; Let&apos;s create a simple &lt;code&gt;Profile&lt;/code&gt; component that we can memoize to demonstrate.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Profile({ name, location }) {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;div&amp;gt;{name}&amp;lt;/div&amp;gt;
      &amp;lt;div&amp;gt;{location}&amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}

const MemoizedProfile = React.memo(Profile)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If I add a few styles, give each component the same props, and render both of these components side by side, they will look perfectly identical.&lt;/p&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;div className=&quot;flex gap-4&quot;&amp;gt;
&amp;lt;div className=&quot;shrink grow basis-1/2&quot;&amp;gt;
&amp;lt;Profile
client:only=&quot;react&quot;
name=&quot;Kyle Shevlin&quot;
location=&quot;Portland, OR&quot;
/&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;div className=&quot;shrink grow basis-1/2&quot;&amp;gt;
&amp;lt;MemoizedProfile
client:only=&quot;react&quot;
name=&quot;Kyle Shevlin&quot;
location=&quot;Portland, OR&quot;
/&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;p&gt;Great. That&apos;s what we expect. There&apos;s nothing fancy about the initial render of a component with props. We give it a set of values, we expect the output to be the correct result.&lt;/p&gt;
&lt;p&gt;Where &lt;code&gt;React.memo&lt;/code&gt; becomes useful is when we introduce a parent component. In React, if a component updates, then it rerenders &lt;em&gt;everything&lt;/em&gt; in that component. This is necessary. The new state of the component may affect anything rendered below it. &lt;em&gt;This rerendering happens regardless of whether the child component has experienced a change or not&lt;/em&gt;. That&apos;s where &lt;code&gt;React.memo&lt;/code&gt; comes into play.&lt;/p&gt;
&lt;p&gt;A memoized component will skip rendering if its &lt;code&gt;props&lt;/code&gt; have not changed. We can easily demonstrate this, and I get to share one of my simple little hacks for detecting unnecessary rerenders in the process.&lt;/p&gt;
&lt;p&gt;We&apos;re going to change &lt;code&gt;Profile&lt;/code&gt; slightly. We&apos;re going to give it a random background color every time it renders. &amp;lt;Marker content=&quot;Think of this as the equivalent of using &lt;code&gt;outline: 1px solid red&lt;/code&gt; when debugging CSS.&quot; /&amp;gt; This is simple to write and do. Just make sure to remove it when you&apos;re ready to ship your code.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const random255 = () =&amp;gt; Math.floor(Math.random() * 255)
const randomRGBA = () =&amp;gt; {
  const r = random255()
  const g = random255()
  const b = random255()

  return `rgba(${r}, ${g}, ${b}, 0.3)`
}

function Profile({ name, location }) {
  return (
    &amp;lt;div style={{ backgroundColor: randomRGBA() }}&amp;gt;
      &amp;lt;div&amp;gt;{name}&amp;lt;/div&amp;gt;
      &amp;lt;div&amp;gt;{location}&amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}

const MemoizedProfile = React.memo(Profile)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, every time the component renders, a new background color will be applied. Let&apos;s create a &lt;code&gt;Parent&lt;/code&gt; component that has a frivolous state change that should cause the &lt;code&gt;Profile&lt;/code&gt; components to rerender.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Parent({ children }) {
  const [, setState] = React.useState(false)
  const forceUpdate = () =&amp;gt; setState(x =&amp;gt; !x)

  return (
    &amp;lt;&amp;gt;
      &amp;lt;button onClick={forceUpdate}&amp;gt;Force Update&amp;lt;/button&amp;gt;
      &amp;lt;div
        style={{
          display: &apos;grid&apos;,
          gridGap: bs(1),
          gridTemplateColumns: &apos;1fr 1fr&apos;,
          marginTop: bs(0.5),
        }}
      &amp;gt;
        &amp;lt;Profile name=&quot;Kyle Shevlin&quot; location=&quot;Portland, OR&quot; /&amp;gt;
        &amp;lt;MemoizedProfile name=&quot;Kyle Shevlin&quot; location=&quot;Portland, OR&quot; /&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;Parent client:only=&quot;react&quot; /&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;p&gt;Notice that when you click &quot;Force Update&quot;, only the regular &lt;code&gt;Profile&lt;/code&gt; component updates. The memoized version does not. In the right scenarios, this can become a real performance boost.&lt;/p&gt;
&lt;h3&gt;What Does &quot;Same Props&quot; Mean?&lt;/h3&gt;
&lt;p&gt;We&apos;re going to make a small change to our &lt;code&gt;Profile&lt;/code&gt; component again to demonstrate an important concept.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Pay attention to how we&apos;ve changed props
function Profile({ person }) {
  const { name, location } = person

  return (
    &amp;lt;div style={{ backgroundColor: randomRGBA() }}&amp;gt;
      &amp;lt;div&amp;gt;{name}&amp;lt;/div&amp;gt;
      &amp;lt;div&amp;gt;{location}&amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We&apos;ve moved &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;location&lt;/code&gt; into a &lt;code&gt;person&lt;/code&gt; object. You can imagine this scenario happening often in any React app. You have an array of objects and you pass the whole object as a prop to a child component. How does this change how our memoized component works? Let&apos;s update our &lt;code&gt;Parent&lt;/code&gt; component to now pass these objects into the component instead.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Parent({ children }) {
  const [, setState] = React.useState(false)
  const forceUpdate = () =&amp;gt; setState(x =&amp;gt; !x)

  return (
    &amp;lt;&amp;gt;
      &amp;lt;button onClick={forceUpdate}&amp;gt;Force Update&amp;lt;/button&amp;gt;
      &amp;lt;div
        style={{
          display: &apos;grid&apos;,
          gridGap: bs(1),
          gridTemplateColumns: &apos;1fr 1fr&apos;,
          marginTop: bs(0.5),
        }}
      &amp;gt;
        &amp;lt;Profile
          person={{
            name: &apos;Kyle Shevlin&apos;,
            location: &apos;Portland, OR&apos;,
          }}
        /&amp;gt;
        &amp;lt;MemoizedProfile
          person={{
            name: &apos;Kyle Shevlin&apos;,
            location: &apos;Portland, OR&apos;,
          }}
        /&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now let&apos;s give this set of components a try. Click the &quot;Force Update&quot; button below and pay attention to what updates.&lt;/p&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;ObjectParent client:only=&quot;react&quot; /&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;p&gt;Both components update! Why does this happen?&lt;/p&gt;
&lt;p&gt;Even though the &lt;code&gt;props&lt;/code&gt; are the same values with every update, the object passed into each component on every render is a new object. Objects are strictly compared by reference, not by their shape of keys and values. The simplest way to demonstrate this is to put this into your browser console and see the result&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{} === {}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is the same check that &lt;code&gt;React.memo&lt;/code&gt; and &lt;code&gt;PureComponent&lt;/code&gt; make and is called a &quot;shallow comparison&quot; of objects. Because we&apos;re creating new objects with each render to pass into our &lt;code&gt;Profile&lt;/code&gt; components, this comparison always results in React needing to update. Hence why they both rerender every time that the &lt;code&gt;Parent&lt;/code&gt; component updates.&lt;/p&gt;
&lt;p&gt;To drive this point home, let&apos;s store these objects as &lt;code&gt;refs&lt;/code&gt; inside of the component. A &lt;code&gt;ref&lt;/code&gt; in React is an object that will not lose its reference across renders. By storing an object as a &lt;code&gt;ref&lt;/code&gt;, we guarantee that we get the same object (referentially) with each render.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Parent({ children }) {
  const [, setState] = React.useState(false)
  const forceUpdate = () =&amp;gt; setState(x =&amp;gt; !x)
  const personRef = React.useRef({
    name: &apos;Kyle Shevlin&apos;,
    location: &apos;Portland, OR&apos;,
  })

  return (
    &amp;lt;&amp;gt;
      &amp;lt;button onClick={forceUpdate}&amp;gt;Force Update&amp;lt;/button&amp;gt;
      &amp;lt;div
        style={{
          display: &apos;grid&apos;,
          gridGap: bs(1),
          gridTemplateColumns: &apos;1fr 1fr&apos;,
          marginTop: bs(0.5),
        }}
      &amp;gt;
        &amp;lt;Profile person={personRef.current} /&amp;gt;
        &amp;lt;MemoizedProfile person={personRef.current} /&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;RefParent client:only=&quot;react&quot; /&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;p&gt;Now our memoized component is back to working as we expect. Because the object&apos;s reference is the same with each render, it skips rerendering. It&apos;s important to understand this fact, as it might have an impact on how you design your components.&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;React.memo&lt;/code&gt;&apos;s Second Argument&lt;/h3&gt;
&lt;p&gt;Using a &lt;code&gt;ref&lt;/code&gt; like we just did is not how I would recommend handling this situation. It was simply to demonstrate a point. This section is also primarily to demonstrate a point. Use what I&apos;m about to show you &lt;em&gt;sparingly&lt;/em&gt;. Following general best practices will keep you from needing this feature often.&lt;/p&gt;
&lt;p&gt;Suppose we &lt;em&gt;must&lt;/em&gt; pass an object into a component, and we know that often these objects will be &quot;deeply equal&quot; even if they aren&apos;t the same reference. We can use the second argument to &lt;code&gt;React.memo&lt;/code&gt; to supply an &lt;code&gt;areEqual&lt;/code&gt; function that determines if a component should rerender or not. This function is similar to implementing &lt;code&gt;shouldComponentUpdate&lt;/code&gt; on a class component, in that we compare the &lt;code&gt;previousProps&lt;/code&gt; to the &lt;code&gt;nextProps&lt;/code&gt;, but &lt;strong&gt;opposite&lt;/strong&gt; in what we want to return from the function. We want the &lt;code&gt;areEqual&lt;/code&gt; function to return &lt;code&gt;true&lt;/code&gt; when the component &lt;em&gt;should &lt;strong&gt;not&lt;/strong&gt;&lt;/em&gt; update. Let&apos;s update how we memoize &lt;code&gt;Profile&lt;/code&gt; accordingly:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const personsAreEqual = (prevProps, nextProps) =&amp;gt; {
  return (
    prevProps.person.name === nextProps.person.name &amp;amp;&amp;amp;
    prevProps.person.location === nextProps.person.location
  )
}

const MemoizedProfile = React.memo(Profile, personsAreEqual)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, if we use that in our example, we&apos;ll see that even without &lt;code&gt;refs&lt;/code&gt;, our components behave as we expect.&lt;/p&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;OtherObjectParent client:only=&quot;react&quot; /&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;We can improve the performance of our React apps by avoiding unnecessary rerenders with &lt;code&gt;React.memo&lt;/code&gt;. We have to understand what it means to pass the &quot;same props&quot; to our components, though, in order to achieve this performance boost.&lt;/p&gt;
</content:encoded><category>React</category><category>JavaScript</category></item><item><title>Memoization: What, Why, and How</title><link>https://kyleshevlin.com/memoization/</link><guid isPermaLink="true">https://kyleshevlin.com/memoization/</guid><pubDate>Thu, 11 Jun 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import Adder from &apos;./_Adder&apos;
import Factorializer from &apos;./_Factorializer&apos;&lt;/p&gt;
&lt;p&gt;Recently, I spent an hour with one of my protégés &amp;lt;Marker content={&lt;code&gt;&quot;Mentee&quot; is not a word. &amp;lt;a href=&quot;https://twitter.com/kyleshevlin/status/1253460305885016065?s=20&quot;&amp;gt;I&apos;ve stated this before&amp;lt;/a&amp;gt;.&lt;/code&gt;} /&amp;gt; demonstrating some common advanced techniques we use at Webflow. One of the techniques I showed them was &lt;strong&gt;memoization&lt;/strong&gt;. &amp;lt;Marker content=&quot;Not a typo.&quot; /&amp;gt; Let&apos;s learn what memoization is, why you might use it, and how do we write it from scratch.&lt;/p&gt;
&lt;p&gt;Memoization is a technique that enhances a function by creating and using a &lt;code&gt;cache&lt;/code&gt; to store and retrieve results of that function. Memoization uses the arguments of a function to create a &lt;code&gt;key&lt;/code&gt; for the &lt;code&gt;cache&lt;/code&gt;. The first time a memoized function is called with a set of arguments, those arguments are turned into a &lt;code&gt;key&lt;/code&gt; and the result of the function is stored as the value for that &lt;code&gt;key&lt;/code&gt; in the &lt;code&gt;cache&lt;/code&gt;. Then, on subsequent calls of the function with the same arguments, we can retrieve that previously calculated value from the &lt;code&gt;cache&lt;/code&gt; and return it before we ever do the work of calculating the result. This improves the performance of our function, since hitting the &lt;code&gt;cache&lt;/code&gt; is a constant time operation (&lt;code&gt;O(1)&lt;/code&gt; in big O notation).&lt;/p&gt;
&lt;p&gt;We can use memoization on any &lt;a href=&quot;/just-enough-fp-pure-functions&quot;&gt;pure function&lt;/a&gt; and it&apos;s not too difficult to implement either. Let&apos;s create a &lt;a href=&quot;/just-enough-fp-higher-order-functions&quot;&gt;higher order function&lt;/a&gt; that will allow us to create a memoized version of a pure function.&lt;/p&gt;
&lt;p&gt;Typically, we want to use memoization on functions with expensive calculations and we&apos;ll talk about why later, but for the sake of writing our &lt;code&gt;memoize&lt;/code&gt; function, I&apos;m going to use a very simple pure function.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function add(x, y) {
  return x + y
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Can&apos;t get much simpler than an &lt;code&gt;add&lt;/code&gt; function! Since it&apos;s a pure function, we can guarantee that the same inputs always lead to the same output. So if we&apos;re able to create a cache that will use the function arguments as a key and store the results of the function as a value, we can retrieve that value from the cache knowing it&apos;s the same as the result of running the function.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function memoize(fn) {
  // We create a cache inside the closure of the `memoize` function
  // This creates a new cache for each function we pass
  // to `memoize`. We&apos;ll discuss other cache strategies later
  const cache = {}

  // The goal is to return a function with an identical
  // signature as the one passed in
  return (...args) =&amp;gt; {
    // We need to create a key for our cache. A simple way to do this is
    // to join the args with a delimiter that clearly separates arguments
    // This way the arguments (12, 3) don&apos;t create the same key as (1, 23)
    const key = args.map(JSON.stringify).join(&apos;---&apos;)

    if (cache[key] !== undefined) {
      // Just for our example, let&apos;s make it clear we returned a value
      // from the cache
      console.log(&apos;from cache&apos;)
      return cache[key]
    }

    const result = fn(...args)
    cache[key] = result

    return result
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&apos;s break that down. &lt;code&gt;memoize&lt;/code&gt; receives a function as an argument. It then creates a cache in closure. This will store the results of our function in memory to be retrieved later.&lt;/p&gt;
&lt;p&gt;Next, we return a function that can receive whatever &lt;code&gt;args&lt;/code&gt; the original function receives. Inside of the function we are returning, we create a &lt;code&gt;key&lt;/code&gt; for our cache. In this case, I chose to stringify and join the arguments with a delimiter. This delimiter prevents similar arguments from accidentally being the same key. Without a delimiter, calling &lt;code&gt;add(2, 34)&lt;/code&gt; and &lt;code&gt;add(23, 4)&lt;/code&gt; would result in the &lt;code&gt;key&lt;/code&gt; &lt;code&gt;234&lt;/code&gt;. We would end up with a mistaken cache hit for the second call, and even worse, our result would be incorrect.&lt;/p&gt;
&lt;p&gt;Next, if there is a defined value at the &lt;code&gt;cache[key]&lt;/code&gt;, we return it and skip calculating the result. Otherwise, we calculate the &lt;code&gt;result&lt;/code&gt;, store it in the &lt;code&gt;cache&lt;/code&gt;, and then return it.&lt;/p&gt;
&lt;p&gt;Now, let&apos;s create a memoized &lt;code&gt;add&lt;/code&gt; function and use it.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const memoizedAdd = memoize(add)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Seriously. Adding memoization to a pure function is that simple. &amp;lt;Marker content=&quot;There are exceptions. Functions that receive arrays and objects as arguments may want to employ a different caching strategy. I&apos;ll discuss this further later in the post&quot; /&amp;gt;&lt;/p&gt;
&lt;p&gt;Let&apos;s try it out. I&apos;ve made a component below that allows you to give it two numbers to add together and it will tell you every time the result comes from the cache instead of being calculated. Try swapping the &lt;code&gt;X&lt;/code&gt; and &lt;code&gt;Y&lt;/code&gt; values and see that it doesn&apos;t hit the &lt;code&gt;cache&lt;/code&gt; because the &lt;code&gt;key&lt;/code&gt;s generated are different.&lt;/p&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;Adder client:load /&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;h3&gt;Why Use Memoization?&lt;/h3&gt;
&lt;p&gt;Memoization is a tradeoff exchanging space (memory) for time. The purpose of this tradeoff is to gain a performance benefit by skipping the calculation of the function&apos;s result, i.e. save time. Thus, it only makes sense to use memoization where memory is not a concern and the original calculation is both expensive and often called with the same arguments. Our &lt;code&gt;add&lt;/code&gt; function was a bad example. It&apos;s not an expensive calculation at all. Let&apos;s create a slightly better example.&lt;/p&gt;
&lt;p&gt;I&apos;ve used this example before in my writing, but a &lt;code&gt;factorial&lt;/code&gt; function might be a good candidate for memoization. It&apos;s recursive, which means that &lt;code&gt;factorial&lt;/code&gt; will be called with the same argument frequently. In fact, if it&apos;s ever been called with a number &lt;em&gt;greater than&lt;/em&gt; the current argument, it will simply return the value from the cache, since it&apos;s already been calculated before. Let&apos;s write the factorial function.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const factorial = memoize(n =&amp;gt; {
  if (n === 0) {
    return 1
  }

  return n * factorial(n - 1)
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Below, I&apos;ve added a component that demonstrates how this works. With this component, every result of &lt;code&gt;factorial&lt;/code&gt; is cached and I display the cache as it grows. Notice the cache doesn&apos;t change when you call a number less than a previous argument because no new values were added to the cache and the value was immediately retrieved and returned.&lt;/p&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;Factorializer client:load /&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;h3&gt;Memoization and React&lt;/h3&gt;
&lt;p&gt;I recognized a few years ago &amp;lt;Marker content={&lt;code&gt;And even mentioned it in a talk &amp;lt;a href=&quot;https://www.youtube.com/watch?t=2910&amp;amp;v=0QdUsOSt60s&quot;&amp;gt;here&amp;lt;/a&amp;gt;.&lt;/code&gt;} /&amp;gt; that React function components could be memoized. Of course, I wasn&apos;t forward thinking enough to recognize that this was a feature coming to React in the future. That said, memoizing in React is quite a bit different than memoizing a function like we have thus far. Rather than creating a large cache of many results, we can think of the caches in React&apos;s memoization as a cache of a single result.&lt;/p&gt;
&lt;p&gt;React now ships with two memoization mechanisms. The first, &lt;code&gt;React.memo&lt;/code&gt;, is for memoizing function components as I just described. If the &lt;code&gt;props&lt;/code&gt; don&apos;t change, the component won&apos;t rerender. This is the function equivalent of using the &lt;code&gt;PureComponent&lt;/code&gt; class or implementing a shallow props check of &lt;code&gt;this.props === prevProps&lt;/code&gt; in the &lt;code&gt;shouldComponentUpdate&lt;/code&gt; lifecycle. I&apos;d like to discuss &lt;code&gt;React.memo&lt;/code&gt; further in a future post, so I&apos;ll save that conversation for there.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;React.useMemo&lt;/code&gt;, the hook, is the other memoizing function. We give &lt;code&gt;React.useMemo&lt;/code&gt; a &quot;create&quot; function &amp;lt;Marker content={&lt;code&gt;Their words, &amp;lt;a href=&quot;https://reactjs.org/docs/hooks-reference.html#usememo&quot;&amp;gt;in the docs&amp;lt;/a&amp;gt;.&lt;/code&gt;} /&amp;gt; that it will call and cache the returned value. However, we don&apos;t give this function any arguments. Instead, we use values within the scope of the component, various &lt;code&gt;props&lt;/code&gt; and &lt;code&gt;state&lt;/code&gt; to derive our value. Then, our &lt;code&gt;useMemo&lt;/code&gt; hook only recalculates the value if any of these dependencies change.&lt;/p&gt;
&lt;p&gt;Both of these memoization mechanisms are quite different than the technique I presented earlier. Think of them the differences this way. Our &lt;code&gt;memoize&lt;/code&gt; function is designed to have a cache that continues to grow as more results are generated. We haven&apos;t limited our cache in anyway (though we could). React, on the other hand, has given you a cache, but it&apos;s precisely the size of one result. When the values that achieved that result are changed, then the function is run again and the cache of one is set with a new value. This is perfect for preventing extraneous rerenders and it&apos;s good to understand these differences.&lt;/p&gt;
&lt;h3&gt;Memoization and Other Caches&lt;/h3&gt;
&lt;p&gt;In my &lt;code&gt;memoize&lt;/code&gt; function, I used a plain old JavaScript object to create key/value pairs. This required that I turn the arguments into a string to act as a key. There might be occasions where this is impractical or unnecessary. It might be useful to make your cache using a &lt;code&gt;Map&lt;/code&gt; or a &lt;code&gt;WeakMap&lt;/code&gt; instead.&lt;/p&gt;
&lt;p&gt;A &lt;code&gt;Map&lt;/code&gt; can essentially use any value as a key, including a function. A &lt;code&gt;WeakMap&lt;/code&gt; can only use objects as keys, but allows for garbage collection of those objects. Both can be useful in the right situation.&lt;/p&gt;
&lt;p&gt;We use a memoizing function at Webflow that makes use of a &lt;code&gt;WeakMap&lt;/code&gt; cache. The gist of it &amp;lt;Marker content=&quot;Since I don&apos;t want to give away too many secrets&quot; /&amp;gt; is that because we make updates to objects immutably, we can guarantee that two objects that are referentially equal are also deeply equal. We use these objects as keys in a &lt;code&gt;WeakMap&lt;/code&gt; cache, and use their reference to retrieve the value. This requires understanding mutations and immutability, but greatly improves performance in some of the areas of our app. I encourage you to do some further research on your own to understand different caching strategies for memoization.&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Memoization is a trade off of space for time. It&apos;s used to cache the result of a function so that the next time it&apos;s called with the same arguments, we can just return the answer. We don&apos;t need to calculate it again. This technique is useful when we have an expensive calculation that will be called frequently with the same arguments. It&apos;s used more often than you might realize and is a useful tool to have in your tool belt.&lt;/p&gt;
</content:encoded><category>JavaScript</category><category>React</category><category>Computer Science</category></item><item><title>The Three Kinds of React State</title><link>https://kyleshevlin.com/three-kinds-of-react-state/</link><guid isPermaLink="true">https://kyleshevlin.com/three-kinds-of-react-state/</guid><description>Learn the three ways to manage state in React applications from Kyle Shevlin</description><pubDate>Fri, 29 May 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import LocalCounter from &apos;./_LocalCounter&apos;
import ParentalCounter from &apos;./_ParentalCounter&apos;
import {
CounterProvider,
RemoteCounter,
Single,
TwoInOne,
} from &apos;./_RemoteCounter&apos;&lt;/p&gt;
&lt;p&gt;No matter what it is you&apos;re building with React, when you boil it down, there are only &lt;em&gt;three&lt;/em&gt; ways you can manage data &amp;lt;Marker content={&lt;code&gt;More often called &quot;state&quot;, but I don&apos;t want to conflate React &quot;state&quot; with &quot;states&quot; in state machines which I write about often. They aren&apos;t exactly the same thing.&lt;/code&gt;} /&amp;gt; in a React app: &lt;a href=&quot;#locally&quot;&gt;locally&lt;/a&gt;, &lt;a href=&quot;#parentally&quot;&gt;parentally&lt;/a&gt;, and &lt;a href=&quot;#remotely&quot;&gt;remotely&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Locally&lt;/h3&gt;
&lt;p&gt;The local management of data happens within the component itself. This is most commonly done with &lt;code&gt;useState&lt;/code&gt;, &lt;code&gt;useReducer&lt;/code&gt;, or if using a class component, &lt;code&gt;this.state&lt;/code&gt;. The data and its updaters are encapsulated within the scope of the component. It&apos;s simple and overplayed, but a &lt;code&gt;Counter&lt;/code&gt; component can be a useful example here.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Counter({ initialValue = 0 }) {
  const [count, setCount] = React.useState(initialValue)

  const increment = () =&amp;gt; setCount(c =&amp;gt; c + 1)
  const decrement = () =&amp;gt; setCount(c =&amp;gt; c - 1)
  const reset = () =&amp;gt; setCount(initialValue)

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;div&amp;gt;Count: {count}&amp;lt;/div&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;button type=&quot;button&quot; onClick={increment}&amp;gt;
          +1
        &amp;lt;/button&amp;gt;
        &amp;lt;button type=&quot;button&quot; onClick={decrement}&amp;gt;
          -1
        &amp;lt;/button&amp;gt;
        &amp;lt;button type=&quot;button&quot; onClick={reset}&amp;gt;
          reset
        &amp;lt;/button&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;LocalCounter client:load /&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;h3&gt;Parentally&lt;/h3&gt;
&lt;p&gt;The parental management of data happens when the data and its updaters are passed in as props from somewhere higher in the component tree. In the case of our counter, it is as simple as moving the data and updating functions to a parent controlling component, and passing them in as props to a controlled child component.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function CounterController({ initialValue = 0 }) {
  const [count, setCount] = React.useState(initialValue)

  const increment = () =&amp;gt; setCount(c =&amp;gt; c + 1)
  const decrement = () =&amp;gt; setCount(c =&amp;gt; c - 1)
  const reset = () =&amp;gt; setCount(initialValue)

  return (
    &amp;lt;Counter
      count={count}
      increment={increment}
      decrement={decrement}
      reset={reset}
    /&amp;gt;
  )
}

function Counter({ count, increment, decrement, reset }) {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;div&amp;gt;Count: {count}&amp;lt;/div&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;button type=&quot;button&quot; onClick={increment}&amp;gt;
          +1
        &amp;lt;/button&amp;gt;
        &amp;lt;button type=&quot;button&quot; onClick={decrement}&amp;gt;
          -1
        &amp;lt;/button&amp;gt;
        &amp;lt;button type=&quot;button&quot; onClick={reset}&amp;gt;
          reset
        &amp;lt;/button&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;ParentalCounter client:load /&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;p&gt;This component behaves exactly the same as the other one, but there might be a good reason to store the data in a parent component. Perhaps it needs to be accessed by other children, or it&apos;s easier to test the child component by being able to pass props into it rather than assert on its internal behavior. The reason for the separation of the data and its management from its presentation isn&apos;t terribly important at this moment. Understanding the concepts of this pattern is what matters.&lt;/p&gt;
&lt;h3&gt;Remotely&lt;/h3&gt;
&lt;p&gt;The remote management of data happens when we store and update data outside of the ancestry of a component tree. This is a very broad area of data management with many solutions. Common ones are Redux or the React Context API. The important part of this concept is that the data and its updaters are &lt;em&gt;at a distance&lt;/em&gt; from the consuming component and require some mechanism for supplying the data to the consumer.&lt;/p&gt;
&lt;p&gt;I&apos;m going to use React&apos;s Context API to demonstrate. We&apos;re going to create a &lt;code&gt;CounterContext&lt;/code&gt; and consume it with our &lt;code&gt;Counter&lt;/code&gt; component.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const CounterContext = React.createContext()

function CounterProvider({ children, initialValue = 0 }) {
  const [count, setCount] = React.useState(initialValue)

  const increment = () =&amp;gt; setCount(c =&amp;gt; c + 1)
  const decrement = () =&amp;gt; setCount(c =&amp;gt; c - 1)
  const reset = () =&amp;gt; setCount(initialValue)

  return (
    &amp;lt;CounterContext.Provider
      value={{
        count,
        decrement,
        increment,
        reset,
      }}
    &amp;gt;
      {children}
    &amp;lt;/CounterContext.Provider&amp;gt;
  )
}

const useCounterContext = () =&amp;gt; React.useContext(CounterContext)

function RemoteCounter() {
  const { count, decrement, increment, reset } = useCounterContext()

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;div&amp;gt;Count: {count}&amp;lt;/div&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;button type=&quot;button&quot; onClick={increment}&amp;gt;
          +1
        &amp;lt;/button&amp;gt;
        &amp;lt;button type=&quot;button&quot; onClick={decrement}&amp;gt;
          -1
        &amp;lt;/button&amp;gt;
        &amp;lt;button type=&quot;button&quot; onClick={reset}&amp;gt;
          reset
        &amp;lt;/button&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}

function App() {
  return (
    &amp;lt;CounterProvider&amp;gt;
      &amp;lt;RemoteCounter /&amp;gt;
    &amp;lt;/CounterProvider&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;Single client:only=&quot;react&quot; /&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;p&gt;What is interesting about our &lt;code&gt;RemoteCounter&lt;/code&gt; example is that because it consumes data managed remotely, instances of &lt;code&gt;RemoteCounter&lt;/code&gt; within the same &lt;code&gt;CounterProvider&lt;/code&gt; read and update the same data. Here are two &lt;code&gt;RemoteCounter&lt;/code&gt;s within a single &lt;code&gt;CounterProvider&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;TwoInOne client:only=&quot;react&quot; /&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;p&gt;We could accomplish something similar having components read and write to a global store in our application. Again, how data is managed remotely is not what&apos;s important here, understanding the pattern is what matters.&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;It doesn&apos;t matter how complicated an application you are building. There are &lt;em&gt;still&lt;/em&gt; only three patterns for data management in a React application. Master these patterns. You will use them over and over and over again.&lt;/p&gt;
</content:encoded><category>React</category></item><item><title>Adding Guards to a `useReducer` Finite State Machine</title><link>https://kyleshevlin.com/adding-guards-to-a-use-reducer-finite-state-machine/</link><guid isPermaLink="true">https://kyleshevlin.com/adding-guards-to-a-use-reducer-finite-state-machine/</guid><pubDate>Wed, 27 May 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import LightBulbWithFuse from &apos;./_LightBulbWithFuse&apos;
import IndestructableBulb from &apos;./_IndestructableBulb&apos;&lt;/p&gt;
&lt;p&gt;The next part in our &lt;code&gt;useReducer&lt;/code&gt; finite state machine journey is adding &quot;guards&quot;. If you haven&apos;t read the previous posts in this collection, I encourage you to do so before reading ahead. Those posts are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/how-to-use-usereducer-as-a-finite-state-machine&quot;&gt;How to Use &lt;code&gt;useReducer&lt;/code&gt; as a Finite State Machine&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/adding-infinite-states-to-a-use-reducer-finite-state-machine&quot;&gt;Adding Infinite States to a &lt;code&gt;useReducer&lt;/code&gt; Finite State Machine&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A &quot;guard&quot; is a predicate function &amp;lt;Marker content=&quot;A function that returns a boolean.&quot; /&amp;gt; used to conditionally determine if a state transition should happen. In simpler terms, if the guard function returns &lt;code&gt;true&lt;/code&gt;, take the transition, otherwise do not.&lt;/p&gt;
&lt;p&gt;Guards can be used to prevent &lt;em&gt;any&lt;/em&gt; transition from taking place. For example, a trying to push open a locked door won&apos;t do anything at all. Or they can be used to take one transition instead of another. The &quot;happy path&quot; leads to one state, the &quot;sad path&quot; to another.&lt;/p&gt;
&lt;p&gt;In order to support guards, we&apos;re going to need to be able to indicate that a transition has a guard. This means that we&apos;re going to have to make a change to the &lt;code&gt;state&lt;/code&gt; an &lt;code&gt;event&lt;/code&gt; is targeting.&lt;/p&gt;
&lt;p&gt;Thus far, we&apos;ve only had simple transitions. For example, the event &lt;code&gt;BREAK&lt;/code&gt; has the value &lt;code&gt;broken&lt;/code&gt;, indicating that this event transitions to the &lt;code&gt;broken&lt;/code&gt; state. I would like this string to be a shorthand for an object, where the string points to the event&apos;s &lt;code&gt;target&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// This...
const BREAK_EVENT = { BREAK: &apos;broken&apos; }

// is equivalent to this
const BREAK_EVENT = { BREAK: { target: &apos;broken&apos; } }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To accomplish this, we need another function, similar to &lt;code&gt;toEventObject&lt;/code&gt; in the previous post. We can call this one &lt;code&gt;toTransitionObject&lt;/code&gt;. It&apos;ll basically be the same.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const toTransitionObject = transition =&amp;gt;
  typeof transition === &apos;string&apos; ? { target: transition } : transition
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This normalizes the shape of our transitions. Let&apos;s make use of this inside of our &lt;code&gt;stateReducer&lt;/code&gt;. There will be bigger changes later, but it&apos;ll be good to start with this one while it&apos;s a simple change.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const stateReducer = (state, event) =&amp;gt; {
  const nextState = NEXT_STATE_GRAPH[state.current][event.type]

  // We don&apos;t want to use `toTransitionObject` on undefined, so guard &amp;amp; early
  // return here if there&apos;s no transition
  if (!nextState) return

  const { target } = toTransitionObject(nextState)

  return target
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now that our finite state machine utilizes &lt;code&gt;target&lt;/code&gt;, we can add new properties to this object and utilize them in determining if a transition should be taken. This is how we&apos;re going to start utilizing guards.&lt;/p&gt;
&lt;p&gt;Let&apos;s add a &lt;code&gt;cond&lt;/code&gt; property whose value is a predicate function. When the predicate returns &lt;code&gt;true&lt;/code&gt;, we&apos;ll return the &lt;code&gt;target&lt;/code&gt;, otherwise no transition will be taken.&lt;/p&gt;
&lt;p&gt;To implement this, let&apos;s imagine briefly that our light bulb is indestructable. We&apos;re going to give our &lt;code&gt;BREAK&lt;/code&gt; event a transition whose &lt;code&gt;cond&lt;/code&gt; property always returns &lt;code&gt;false&lt;/code&gt;, and therefore is never taken.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const BREAK_EVENT = {
  BREAK: {
    target: &apos;broken&apos;,
    cond: () =&amp;gt; false,
  },
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, let&apos;s write the code necessary to respect this &lt;code&gt;cond&lt;/code&gt;ition and not take this transition. This will involve modifying the &lt;code&gt;stateReducer&lt;/code&gt; further.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const stateReducer = (state, event) =&amp;gt; {
  const nextState = NEXT_STATE_GRAPH[state.current][event.type]

  if (!nextState) return

  const possibleTransition = toTransitionObject(nextState)
  // Use default assignment to guarantee that `cond`
  // is a function and returns true if it&apos;s undefined
  const { target, cond = () =&amp;gt; true } = possibleTransition

  if (cond()) {
    return target
  }

  return
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With that in place, our light bulb should be currently indestructable. Try it out here.&lt;/p&gt;
&lt;p&gt;&amp;lt;IndestructableBulb client:load /&amp;gt;&lt;/p&gt;
&lt;p&gt;No matter how many times you click that &lt;code&gt;BREAK&lt;/code&gt; button, it&apos;s not going to break. While an indestructable bulb is awesome, &amp;lt;Marker content=&quot;There&apos;s a bulb that&apos;s been on practically non-stop for over 100 years. Check it out &amp;lt;a href=&apos;https://99percentinvisible.org/episode/there-is-a-light-that-never-goes-out/&apos;&amp;gt;There Is a Light That Never Goes Out&amp;lt;/a&amp;gt;.&quot; /&amp;gt; it&apos;s pretty unlikely. One thing we can do is add a fuse before our light bulb that might prevent it from breaking.&lt;/p&gt;
&lt;p&gt;In this case, we can add a &lt;code&gt;hasFuse&lt;/code&gt; value to our &lt;code&gt;data&lt;/code&gt; and check it&apos;s value as our &lt;code&gt;cond&lt;/code&gt; predicate function. If our light bulb happens to have a fuse, we&apos;re going to transition to a new state, &lt;code&gt;brokenFuse&lt;/code&gt;, instead of &lt;code&gt;broken&lt;/code&gt;. Also, we&apos;ll rename &lt;code&gt;broken&lt;/code&gt; to &lt;code&gt;brokenBulb&lt;/code&gt; to be slightly more accurate.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const initialState = {
  current: &apos;unlit&apos;,
  data: {
    color: &apos;white&apos;,
    hasFuse: true,
  },
}

const BREAK_EVENT = {
  BREAK: {
    target: &apos;brokenFuse&apos;,
    cond: data =&amp;gt; data.hasFuse,
  },
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But wait! Didn&apos;t I say we want to transition to &lt;code&gt;brokenBulb&lt;/code&gt; in the case where there isn&apos;t a fuse? &amp;lt;Marker content=&quot;I did.&quot; /&amp;gt; We need a way to have &lt;em&gt;multiple targets&lt;/em&gt; for an event.&lt;/p&gt;
&lt;p&gt;The most obvious data structure for this is an array of transition objects. Let&apos;s write that, and make our code use it next.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const BREAK_EVENT = {
  BREAK: [{ target: &apos;brokenFuse&apos;, cond: data =&amp;gt; data.hasFuse }, &apos;brokenBulb&apos;],
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now our &lt;code&gt;BREAK_EVENT&lt;/code&gt; has two &lt;code&gt;target&lt;/code&gt;s. If our bulb has a fuse, the machine will transition to &lt;code&gt;brokenFuse&lt;/code&gt;, otherwise it&apos;ll transition to &lt;code&gt;brokenBulb&lt;/code&gt;. But our machine doesn&apos;t know how to handle an array of transition objects yet. How do we adjust our code so that it can handle either an array or an object?&lt;/p&gt;
&lt;p&gt;We could write the code with a condition that checks for the type and acts accordingly, but a simpler solution is to normalize all of our transitions into an array of transition objects. This means that we want these two structures to essentially be equivalent:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// This
const RESET_EVENT = {
  RESET: &apos;unlit&apos;,
}

// is equivalent to this
const RESET_EVENT = {
  RESET: [&apos;unlit&apos;],
}

// which is equivalent to this
const RESET_EVENT = {
  RESET: [{ target: &apos;unlit&apos; }],
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In order to achieve this, we&apos;re going to make yet another normalizing function, &lt;code&gt;toArray&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const toArray = value =&amp;gt; (Array.isArray(value) ? value : [value])
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This simple function ensures that we&apos;re always dealing with an array of transitions. Now we need to add it to our &lt;code&gt;stateReducer&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Notice we now need to pass our data into the reducer
const stateReducer = (state, event, data) =&amp;gt; {
  const transitionValue = NEXT_STATE_GRAPH[state.current][event.type]

  // There is no transition to make
  if (!transitionValue) return

  const possibleTransitions = toArray(transitionValue).map(toTransitionObject)

  // We&apos;re going to use for..of so we can return as
  // early as possible
  for (const transition of possibleTransitions) {
    const { target, cond = () =&amp;gt; true } = transition

    // We know we need the `data` for our predicate function
    // We also may want information on the event object as well
    if (cond(data, event)) {
      return target
    }
  }

  // No `cond` succeeded
  return
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We&apos;re not quite done, we need to update our parent &lt;code&gt;reducer&lt;/code&gt; function to pass &lt;code&gt;data&lt;/code&gt; into our &lt;code&gt;stateReducer&lt;/code&gt; function.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const reducer = (state, event) =&amp;gt; {
  const eventObj = toEventObject(event)
  const nextData = dataReducer(state.data, eventObj)
  const nextState = stateReducer(state, eventObj, nextData)

  if (!nextState) return state

  return {
    current: nextState,
    data: nextData,
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We moved the calculation of any new &lt;code&gt;data&lt;/code&gt; up in the &lt;code&gt;reducer&lt;/code&gt; so that we can use the latest &lt;code&gt;data&lt;/code&gt; in our &lt;code&gt;nextState&lt;/code&gt; calculation and pass it in to be used by our guards.&lt;/p&gt;
&lt;p&gt;We can do one more &quot;optimization&quot; if we&apos;d like. Just like we have a &lt;code&gt;DATA_UPDATERS&lt;/code&gt; map, we can make one for our guards as well. Then we can use a string identifier and retrieve our guard. This will make guards reusable in multiple states.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const GUARDS = {
  hasFuse: data =&amp;gt; data.hasFuse,
}

//... our break event

const BREAK_EVENT = {
  BREAK: [
    {
      target: &apos;brokenFuse&apos;,
      cond: &apos;hasFuse&apos;,
    },
    &apos;brokenBulb&apos;,
  ],
}

//... and in our stateReducer
for (const transition of possibleTransitions) {
  const { target, cond = () =&amp;gt; true } = transition
  const condFn = typeof cond === &apos;string&apos; ? GUARDS[cond] : cond

  if (condFn(data, event)) {
    return target
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And with that, we&apos;ve successfully added guards to our &lt;code&gt;useReducer&lt;/code&gt; finite state machine. Pretty impressive what we can do with a little effort. You can try out our light bulb with a fuse in the component below.&lt;/p&gt;
&lt;p&gt;&amp;lt;LightBulbWithFuse client:load /&amp;gt;&lt;/p&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;Adding guards allows us to conditionally transition states. This enables us to create powerful state machines that handle logic flows for us with the structure of the data, &lt;strong&gt;not with a bunch of conditionals in our event handling code&lt;/strong&gt;. This is one of the key insights of state machines. The structure &lt;em&gt;is&lt;/em&gt; the logic, and we don&apos;t have to accommodate further for it.&lt;/p&gt;
&lt;p&gt;In order to enable guards, we had to do the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Normalize transition objects&lt;/li&gt;
&lt;li&gt;Introduce the &lt;code&gt;cond&lt;/code&gt; property, a predicate function for conditional transitions&lt;/li&gt;
&lt;li&gt;Normalize &lt;code&gt;possibleTransitions&lt;/code&gt; as an array to simplify our &lt;code&gt;reducer&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the next post in this collection, we&apos;ll either try and clean this up a bit so we can make a package of it to pass around our application, or we&apos;ll swap out &lt;code&gt;useReducer&lt;/code&gt; for &lt;a href=&quot;https://github.com/davidkpiano/useEffectReducer&quot;&gt;&lt;code&gt;useEffectReducer&lt;/code&gt;&lt;/a&gt; so that we can properly have actions. I haven&apos;t decided yet.&lt;/p&gt;
</content:encoded><category>React</category><category>React Hooks</category><category>State Machines</category></item><item><title>Break Out Your Component Logic with Hooks</title><link>https://kyleshevlin.com/break-out-your-component-logic-with-hooks/</link><guid isPermaLink="true">https://kyleshevlin.com/break-out-your-component-logic-with-hooks/</guid><description>In this post, Kyle Shevlin demonstrates how to decouple the logic of a React component from its user interface through the use of a custom hook. This enables the encapsulation and reuse of a concern, contextualized for the particular use case.</description><pubDate>Tue, 19 May 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import TogglingItem from &apos;./_TogglingItem&apos;
import ExplicitItem from &apos;./_ExplicitItem&apos;
import ItemsUsingCustomHook from &apos;./_ItemsUsingCustomHook&apos;&lt;/p&gt;
&lt;p&gt;Lately, I have had the opportunity to work on some new features at Webflow. It&apos;s exciting to build new things for your customers. It&apos;s &lt;em&gt;also&lt;/em&gt; exciting because I&apos;ve had the opportunity to finally dive head-first into React Hooks and learn and explore some new patterns. Some have been winners, some have been losers, but the education has been a lot of fun, regardless.&lt;/p&gt;
&lt;p&gt;One pattern I&apos;ve come to appreciate is breaking out the logic of a component into a custom hook, and then, only destructuring the parts of the hook&apos;s API my component needs. This decoupling allows my hook to be useful in multiple situations, while ensuring my component has no extraneous functionality. I want to teach you how I approach this.&lt;/p&gt;
&lt;h3&gt;Our Example&lt;/h3&gt;
&lt;p&gt;Let&apos;s start with an example where the logic and the UI that&apos;s rendered are coupled, that is, the logic that drives the UI is contained in the component itself. My recent work has involved a lot of &quot;item selection&quot;, so we&apos;ll make an item that &lt;code&gt;isSelected&lt;/code&gt; or isn&apos;t. &amp;lt;Marker content=&quot;I am avoiding using states and state machines on purpose. I want to explicitly use a binary, in this case a boolean, for my example.&quot; /&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Item() {
  const [isSelected, setSelected] = React.useState(false)

  const toggleSelection = () =&amp;gt; {
    setSelected(x =&amp;gt; !x)
  }

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;div&amp;gt;Is selected? {String(isSelected)}&amp;lt;/div&amp;gt;
      &amp;lt;button type=&quot;button&quot; onClick={toggleSelection}&amp;gt;
        Toggle
      &amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;TogglingItem client:load /&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;p&gt;Great, our component works as expected.&lt;/p&gt;
&lt;p&gt;Now, imagine you have been asked to make a similar component, but with &lt;em&gt;explicit&lt;/em&gt; &lt;code&gt;select&lt;/code&gt; and &lt;code&gt;unselect&lt;/code&gt; buttons. Let&apos;s write that component, too. &amp;lt;Marker content=&quot;I am being purposefully verbose for didactic purposes&quot; /&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function SimilarItem() {
  const [isSelected, setSelected] = React.useState(false)

  const select = () =&amp;gt; {
    setSelected(true)
  }

  const unselect = () =&amp;gt; {
    setSelected(false)
  }

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;div&amp;gt;Is selected? {String(isSelected)}&amp;lt;/div&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;button type=&quot;button&quot; onClick={select}&amp;gt;
          Select
        &amp;lt;/button&amp;gt;
        &amp;lt;button type=&quot;button&quot; onClick={unselect}&amp;gt;
          Unselect
        &amp;lt;/button&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;ExplicitItem client:load /&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;p&gt;That component works as well, but we&apos;ve repeated quite a bit of code. In both examples, we&apos;re using essentially the same logic, deriving a different API from that logic, and exposing it to our UI. This seems like a great opportunity to abstract the logic away from our component to reduce duplication.&lt;/p&gt;
&lt;h3&gt;Creating a Custom Hook&lt;/h3&gt;
&lt;p&gt;We want to pull the logic out of our component and into a custom hook that our component can then consume. When I do a refactor like this, I attempt to do it step-by-step, keeping the code working the entire time. Let&apos;s try and do that here with our first &lt;code&gt;Item&lt;/code&gt;. The first step in this refactor is to pull some of the logic into a custom hook.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// I&apos;ll give this a better name soon, but for now, this works
function useItemLogic() {
  const [isSelected, setSelected] = React.useState(false)

  const toggleSelection = () =&amp;gt; {
    setSelected(state =&amp;gt; !state)
  }

  return {
    isSelected,
    toggleSelection,
  }
}

function Item() {
  const { isSelected, toggleSelection } = useItemLogic()

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;div&amp;gt;Is selected? {String(isSelected)}&amp;lt;/div&amp;gt;
      &amp;lt;button type=&quot;button&quot; onClick={toggleSelection}&amp;gt;
        Toggle
      &amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is a good start, but it&apos;s not abstract enough yet and can&apos;t be used in our &lt;code&gt;SimilarItem&lt;/code&gt; as it is. What&apos;s different between our two items?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The state setting functions.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Let&apos;s add these explicit functions to our &lt;code&gt;useItemLogic&lt;/code&gt; hook.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function useItemLogic() {
  const [isSelected, setSelected] = React.useState(false)

  const select = () =&amp;gt; {
    setSelected(true)
  }

  const unselect = () =&amp;gt; {
    setSelected(false)
  }

  const toggleSelection = () =&amp;gt; {
    setSelected(state =&amp;gt; !state)
  }

  return {
    isSelected,
    select,
    toggleSelection,
    unselect,
  }
}

function Item() {
  const { isSelected, toggleSelection } = useItemLogic()

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;div&amp;gt;Is selected? {String(isSelected)}&amp;lt;/div&amp;gt;
      &amp;lt;button type=&quot;button&quot; onClick={toggleSelection}&amp;gt;
        Toggle
      &amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}

function SimilarItem() {
  const { isSelected, select, unselect } = useItemLogic()

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;div&amp;gt;Is selected? {String(isSelected)}&amp;lt;/div&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;button type=&quot;button&quot; onClick={select}&amp;gt;
          Select
        &amp;lt;/button&amp;gt;
        &amp;lt;button type=&quot;button&quot; onClick={unselect}&amp;gt;
          Unselect
        &amp;lt;/button&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Great, now our logic is separated and working in both our components, but it really isn&apos;t named well at all. For starters, &lt;code&gt;useItemLogic&lt;/code&gt; doesn&apos;t convey anything about the API, which is fine if this were not intended for reuse, but it is. Also, names like &lt;code&gt;isSelected&lt;/code&gt; and &lt;code&gt;toggleSelection&lt;/code&gt; imply more about the actual state maintained in our hook than is true. Our hook merely contains a &lt;em&gt;binary&lt;/em&gt;, in this case, a boolean. So let&apos;s rename parts of our abstraction to reflect this information.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// We parameterize the initialState and provide a default value of false
function useBooleanAPI(initialState = false) {
  // Using the Boolean constructor ensures that the hook cannot be
  // given an initial state of the wrong type
  const [state, setState] = React.useState(Boolean(initialState))

  const setTrue = () =&amp;gt; {
    setState(true)
  }

  const setFalse = () =&amp;gt; {
    setState(false)
  }

  const toggle = () =&amp;gt; {
    setState(x =&amp;gt; !x)
  }

  return {
    setFalse,
    setTrue,
    state,
    toggle,
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, that we have a generalized abstraction for our hook, we can use only the parts of the interface that are important to our component &lt;em&gt;and&lt;/em&gt; rename the APIs so they provide more context to our component&apos;s use case.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Item() {
  const { state: isSelected, toggle: toggleSelection } = useBooleanAPI()

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;div&amp;gt;Is selected? {String(isSelected)}&amp;lt;/div&amp;gt;
      &amp;lt;button type=&quot;button&quot; onClick={toggleSelection}&amp;gt;
        Toggle
      &amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}

function SimilarItem() {
  const {
    state: isSelected,
    setFalse: unselect,
    setTrue: select,
  } = useBooleanAPI()

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;div&amp;gt;Is selected? {String(isSelected)}&amp;lt;/div&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;button type=&quot;button&quot; onClick={select}&amp;gt;
          On
        &amp;lt;/button&amp;gt;
        &amp;lt;button type=&quot;button&quot; onClick={unselect}&amp;gt;
          Off
        &amp;lt;/button&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;ItemsUsingCustomHook client:load /&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;p&gt;Now, both our components consume the same interface, but have the freedom to use only the parts of that interface it requires and to rename parts of that functionality to reflect the context in which they are used. Not only that, but our individual components became smaller and a bit simpler to understand. We no longer have our logic tightly coupled to our component.&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;React Hooks are an excellent way to practice decoupling our user interface from the logic driving it. We can create abstractions that can be consumed and contextualized by other components. This allows us to encapsulate concerns, enable reuse, and keep the surface area of our components small. I hope you can see the benefits of this pattern and how you might use it to refactor and decouple your own components.&lt;/p&gt;
</content:encoded><category>React</category><category>React Hooks</category><category>Refactoring</category></item><item><title>Adding Infinite States to a `useReducer` Finite State Machine</title><link>https://kyleshevlin.com/adding-infinite-states-to-a-use-reducer-finite-state-machine/</link><guid isPermaLink="true">https://kyleshevlin.com/adding-infinite-states-to-a-use-reducer-finite-state-machine/</guid><description>In this post, Kyle Shevlin explains how to store and update infinite state data in a finite state machine built upon the useReducer React Hook.</description><pubDate>Fri, 15 May 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import HueLightBulb from &apos;./_HueLightBulb&apos;&lt;/p&gt;
&lt;p&gt;Before reading this post, I encourage you to read &lt;a href=&quot;/how-to-use-usereducer-as-a-finite-state-machine&quot;&gt;How to Use &lt;code&gt;useReducer&lt;/code&gt; as a Finite State Machine&lt;/a&gt; if you haven&apos;t already. In that post, I demonstrate how to make the React Hook &lt;code&gt;useReducer&lt;/code&gt; behave like a finite state machine using a statechart-like graph. I&apos;m going to expand upon that work today.&lt;/p&gt;
&lt;p&gt;The next thing we need to add to our &lt;code&gt;useReducer&lt;/code&gt;-based finite state machine is contextual data. Not all data can be modeled as a set of finite states (nor should it). Consider the humble &lt;code&gt;&amp;lt;input /&amp;gt;&lt;/code&gt;. A user can provide an infinite number of strings as a &lt;code&gt;value&lt;/code&gt; to the input. By definition, we cannot model the infinite with the finite, and thus we need a way to store infinite contextual data in our machine. It will be very useful to us when we add guards and conditions in a future post.&lt;/p&gt;
&lt;p&gt;In XState, infinite state data is stored on the &lt;code&gt;context&lt;/code&gt; object of the state machine. Because React also has a concept of &lt;code&gt;context&lt;/code&gt; and I do not wish to conflate the two concepts, so I will simply call this &lt;code&gt;data&lt;/code&gt;. This means that our state machine&apos;s &lt;code&gt;state&lt;/code&gt; is not the only thing being returned by our &lt;code&gt;reducer&lt;/code&gt; anymore, and so we need a name for that as well. In this post, I will call this &lt;code&gt;current&lt;/code&gt;, as in the &quot;current state&quot;. Let&apos;s make these our first changes to our state machine. We&apos;ll continue to use the &lt;code&gt;LightBulb&lt;/code&gt; from the previous post as the object that we are modeling.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const initial = {
  current: &apos;unlit&apos;,
  data: {},
}

//...

const reducer = (state, event) =&amp;gt; {
  const { current } = state
  const nextState = NEXT_STATE_GRAPH[current][event]

  return nextState !== undefined ? nextState : state
}

//...

function LightBulb() {
  const [state, send] = useReducer(reducer, initial)
  const { current } = state

  return (
    &amp;lt;div&amp;gt;
      State: {current}
      &amp;lt;button type=&quot;button&quot; onClick={() =&amp;gt; send(&apos;TOGGLE&apos;)}&amp;gt;
        Toggle
      &amp;lt;/button&amp;gt;
      &amp;lt;button type=&quot;button&quot; onClick={() =&amp;gt; send(&apos;BREAK&apos;)}&amp;gt;
        Break
      &amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Our light bulb continues to work as it did before, so now let&apos;s modify it so that we need to store some &lt;code&gt;data&lt;/code&gt; and make use of it. Here is the specification we&apos;re going to build into our reducer:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If the &lt;code&gt;nextState&lt;/code&gt; is &lt;code&gt;undefined&lt;/code&gt;, do not update the &lt;code&gt;current&lt;/code&gt; state or &lt;code&gt;data&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Otherwise, update the &lt;code&gt;state&lt;/code&gt; and update the &lt;code&gt;data&lt;/code&gt; if necessary&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let&apos;s modify our &lt;code&gt;reducer&lt;/code&gt; to accommodate this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const reducer = (state, event) =&amp;gt; {
  const { current, data } = state
  const nextState = NEXT_STATE_GRAPH[current][event]

  if (!nextState) return state

  const nextData = data // we need to write the code that will update this still

  return {
    current: nextState,
    data: nextData,
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We&apos;ve laid the foundation for updating &lt;code&gt;data&lt;/code&gt; in response to an &lt;code&gt;event&lt;/code&gt;, but our code does not support passing &lt;code&gt;data&lt;/code&gt; along with an &lt;code&gt;event&lt;/code&gt; yet. At the moment, an &lt;code&gt;event&lt;/code&gt; is merely a string. We need to be able to pass more information along with the event. How can we support being able to use a string for an event, and also pass &lt;code&gt;data&lt;/code&gt; with it?&lt;/p&gt;
&lt;p&gt;By making every &lt;code&gt;event&lt;/code&gt; an object under the hood.&lt;/p&gt;
&lt;p&gt;This is one of my favorite features of XState and a pattern that&apos;s easy to borrow. All we need to do is turn an &lt;code&gt;event&lt;/code&gt; like &lt;code&gt;TOGGLE&lt;/code&gt; into an object like &lt;code&gt;{ type: &apos;TOGGLE&apos; }&lt;/code&gt; under the hood. This will allow the user to supply simple strings if no data needs to be on the event, or an object with the additional data. We accomplish this by normalizing the events into the same shape.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const toEventObject = event =&amp;gt;
  typeof event === &apos;string&apos; ? { type: event } : event
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We now use &lt;code&gt;toEventObject&lt;/code&gt; in our &lt;code&gt;reducer&lt;/code&gt; to normalize the &lt;code&gt;event&lt;/code&gt; before using it to determine the &lt;code&gt;nextState&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const reducer = (state, event) =&amp;gt; {
  event = toEventObject(event)
  const { current, data } = state
  const nextState = NEXT_STATE_GRAPH[current][event.type]

  if (!nextState) return state

  const nextData = data

  return {
    current: nextState,
    data: nextData,
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now that we&apos;ve normalized the &lt;code&gt;event&lt;/code&gt; into an object, we&apos;ll be able to pass along extra data on that object when we &lt;code&gt;send&lt;/code&gt; &lt;code&gt;event&lt;/code&gt;s to our machine. Let&apos;s modify our example so that our &lt;code&gt;LightBulb&lt;/code&gt; needs some contextual data. Let&apos;s add &lt;code&gt;color&lt;/code&gt; to our light bulb so that when it&apos;s &lt;code&gt;lit&lt;/code&gt;, we can change the &lt;code&gt;color&lt;/code&gt; with a &lt;code&gt;CHANGE_COLOR&lt;/code&gt; event.&lt;/p&gt;
&lt;p&gt;This is where I&apos;m going to introduce several things and start to make some deviations from XState, so bear with me.&lt;/p&gt;
&lt;p&gt;We now have an event that will not change the state of the light bulb. Sending a &lt;code&gt;CHANGE_COLOR&lt;/code&gt; event should keep us in a &lt;code&gt;lit&lt;/code&gt; state. Since our state graph depends on having a defined value for an event, we need to add the &lt;code&gt;CHANGE_COLOR&lt;/code&gt; event to our &lt;code&gt;NEXT_STATE_GRAPH&lt;/code&gt; object. I&apos;m going to add a &lt;code&gt;RESET&lt;/code&gt; event while we&apos;re at it, and use &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Spread_in_object_literals&quot;&gt;object spreading&lt;/a&gt; to dry up some events that are used in multiple states.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const BREAK_EVENT = { BREAK: &apos;broken&apos; }
const RESET_EVENT = { RESET: initialState.current }

const NEXT_STATE_GRAPH = {
  lit: {
    ...BREAK_EVENT,
    ...RESET_EVENT,
    CHANGE_COLOR: &apos;lit&apos;, // Notice we stay in the same state
    TOGGLE: &apos;unlit&apos;,
  },
  unlit: {
    ...BREAK_EVENT,
    ...RESET_EVENT,
    TOGGLE: &apos;lit&apos;,
  },
  broken: {
    ...RESET_EVENT,
  },
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We also need a way for &lt;code&gt;CHANGE_COLOR&lt;/code&gt; to trigger an update to our &lt;code&gt;data&lt;/code&gt;. The way I&apos;m choosing to do this is with an object called &lt;code&gt;DATA_UPDATERS&lt;/code&gt;. Each &lt;code&gt;updater&lt;/code&gt; function will receive the current &lt;code&gt;data&lt;/code&gt; and the &lt;code&gt;event&lt;/code&gt; that triggered the &lt;code&gt;updater&lt;/code&gt; call.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const DATA_UPDATERS = {
  CHANGE_COLOR: (data, event) =&amp;gt; ({ ...data, color: event.color }),
  RESET: () =&amp;gt; initial.data,
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, we need to update our &lt;code&gt;reducer&lt;/code&gt; to actually use our &lt;code&gt;DATA_UPDATERS&lt;/code&gt;. I&apos;m going to make a slight refactor here as I do it where I will &quot;split the loops&quot; of our state reduction and our data reduction into two separate reducers.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const stateReducer = (state, event) =&amp;gt;
  NEXT_STATE_GRAPH[state.current][event.type]

const dataReducer = (data, event) =&amp;gt; {
  const updater = DATA_UPDATERS[event.type]
  return updater ? updater(data, event) : data
}

const reducer = (state, event) =&amp;gt; {
  event = toEventObject(event)
  const nextState = stateReducer(state, event)

  if (!nextState) return state

  const nextData = dataReducer(state.data, event)

  return {
    current: nextState,
    data: nextData,
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we can add some UI to our &lt;code&gt;HueLightBulb&lt;/code&gt; that supports changing colors.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const EVENTS = [&apos;TOGGLE&apos;, &apos;BREAK&apos;, &apos;RESET&apos;]
const COLORS = [
  { name: &apos;white&apos;, value: &apos;#feffeb&apos; },
  { name: &apos;red&apos;, value: &apos;#ff674f&apos; },
  { name: &apos;blue&apos;, value: &apos;#5cb6ff&apos; },
  { name: &apos;green&apos;, value: &apos;#8ff244&apos; },
]

function HueLightBulb() {
  const [state, send] = useReducer(reducer, initial)
  const { current, data } = state

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;span&amp;gt;State: {current}&amp;lt;/span&amp;gt; &amp;lt;span&amp;gt;Color: {data.color}&amp;lt;/span&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;span&amp;gt;Events&amp;lt;/span&amp;gt;
        &amp;lt;div&amp;gt;
          {EVENTS.map(event =&amp;gt; (
            &amp;lt;button key={event} type=&quot;button&quot; onClick={() =&amp;gt; send(event)}&amp;gt;
              {event}
            &amp;lt;/button&amp;gt;
          ))}
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;span&amp;gt;Change colors&amp;lt;/span&amp;gt;
        &amp;lt;div&amp;gt;
          {COLORS.map(({ name, value }) =&amp;gt; (
            &amp;lt;button
              key={name}
              type=&quot;button&quot;
              onClick={() =&amp;gt; send({ type: &apos;CHANGE_COLOR&apos;, color: value })}
            &amp;gt;
              {name}
            &amp;lt;/button&amp;gt;
          ))}
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we&apos;re able to change the colors of our bulb, but only when we are in the &lt;code&gt;lit&lt;/code&gt; state. We have a &lt;code&gt;useReducer&lt;/code&gt;-based state machine that can handle infinite state data!&lt;/p&gt;
&lt;p&gt;I made a component for you to play with that contains a few extra bells and whistles, including some SVGs that I made &amp;lt;Marker content=&quot;Be kind. I don&apos;t really have any vector art skills whatsoever&quot; /&amp;gt; to show all the states of our bulb.&lt;/p&gt;
&lt;p&gt;&amp;lt;HueLightBulb client:load /&amp;gt;&lt;/p&gt;
&lt;p&gt;If you prefer to tinker with the code itself, an iteration of this example exists on Codesandbox for you to fork: &lt;a href=&quot;https://codesandbox.io/s/usereducer-fsm-with-infinite-states-v2b1g&quot;&gt;https://codesandbox.io/s/usereducer-fsm-with-infinite-states-v2b1g&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Infinite data cannot be modeled as a finite set of states, but we still want to have the control and guarantees a state machine gives us about our program. We can achieve this by storing this extra &lt;code&gt;data&lt;/code&gt; in our &lt;code&gt;state&lt;/code&gt;. We can make updates to this &lt;code&gt;data&lt;/code&gt; through &lt;code&gt;event&lt;/code&gt; objects. We only make updates to our &lt;code&gt;data&lt;/code&gt; when our state graph allows it, and we guarantee the deterministic output of our &lt;code&gt;state&lt;/code&gt; through reducers for our &lt;code&gt;current&lt;/code&gt; state and our &lt;code&gt;data&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In a future post, we&apos;ll add the concept of guards to our state machine that will require some modifications to how we think of our contextual &lt;code&gt;data&lt;/code&gt;, but I hope this continues to inspire your imagination on how to write more robust programs in the mean time.&lt;/p&gt;
</content:encoded><category>React</category><category>React Hooks</category><category>State Machines</category></item><item><title>Can a State Machine be a String?</title><link>https://kyleshevlin.com/can-a-state-machine-be-a-string/</link><guid isPermaLink="true">https://kyleshevlin.com/can-a-state-machine-be-a-string/</guid><description>In this blog post, Kyle Shevlin walks through an experiment in writing a state machine as a string of text following test driven development.</description><pubDate>Thu, 07 May 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import LightBulb from &apos;./_LightBulb&apos;&lt;/p&gt;
&lt;p&gt;Near the end of last year, I was doing prep work for my first workshop on state machines. In my research, I came across this simple, but effective graph editor: &lt;a href=&quot;https://csacademy.com/app/graph_editor/&quot;&gt;https://csacademy.com/app/graph_editor/&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I was impressed with how simple it was to represent a graph with just a few lines of text. On the left side of the web page, under &quot;Graph Data&quot;, is a simple text input. You generate the graph by writing nodes next to each other. The light bulb example I used in the &lt;a href=&quot;/how-to-use-usereducer-as-a-finite-state-machine&quot;&gt;previous post&lt;/a&gt; is written like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;lit unlit
unlit lit
lit broken
unlit broken
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Which generates this graph image:&lt;/p&gt;
&lt;p&gt;&amp;lt;Image
invertable
alt=&quot;Mathematical graph of a light bulb&apos;s states&quot;
src=&quot;/images/state-machine-string/lightBulbGraph.png&quot;
/&amp;gt;&lt;/p&gt;
&lt;p&gt;I was blown away. A graph can be represented simply as a string if you followed a few rules. This got me thinking, &quot;Can I do the same for a state machine?&quot; Turns out you can.&lt;/p&gt;
&lt;p&gt;In order to represent a state machine as a string, we only need to make a couple adjustments.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We need to be able to derive an &lt;code&gt;id&lt;/code&gt; from our string&lt;/li&gt;
&lt;li&gt;We need to be able to indicate the &lt;code&gt;initial&lt;/code&gt; state&lt;/li&gt;
&lt;li&gt;We need to be able to indicate what &lt;code&gt;events&lt;/code&gt; will trigger transitions&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Accomplishing the first two criteria was pretty simple: dedicate the first two lines of our string to &lt;code&gt;id&lt;/code&gt; and &lt;code&gt;initial&lt;/code&gt; respectively. With our light bulb example, it would look like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;lightBulb
unlit
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Adding the events required having a way to define an &lt;em&gt;edge&lt;/em&gt; as an &lt;code&gt;event&lt;/code&gt; type. I chose to accomplish the same way a &lt;em&gt;weighted graph&lt;/em&gt; is represented as a string.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;lit unlit TOGGLE
unlit lit TOGGLE
lit broken BREAK
unlit broken BREAK
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, we need a function that will parse this text into a valid state machine. Let&apos;s setup the skeleton of that function.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function statechart(string) {
  return {} // We&apos;ll eventually return a valid statechart here.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, we should maybe write a couple tests to validate what we&apos;re accomplishing. Let&apos;s start with deriving the &lt;code&gt;id&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;describe(&apos;statechart&apos;, () =&amp;gt; {
  it(&apos;should derive an `id` from the first line&apos;, () =&amp;gt; {
    const chart = statechart(`
      lightBulb
    `)
    expect(chart.id).toEqual(&apos;lightBulb&apos;)
  })
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This, of course, fails because we haven&apos;t made any changes to the code to accomplish this. Let&apos;s write the simplest thing we can to get the test passing.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function statechart(string) {
  const id = string.trim()

  return {
    id,
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-8&quot;&amp;gt;
&amp;lt;Image
alt=&quot;First test run, all tests passing&quot;
src=&quot;/images/state-machine-string/first-test.jpg&quot;
/&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;That passes. Now we can add a second test for the &lt;code&gt;initial&lt;/code&gt; state.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;describe(&apos;statechart&apos;, () =&amp;gt; {
  // ...
  it(&apos;should derive an `initial` state from the second line&apos;, () =&amp;gt; {
    const chart = statechart(`
      lightBulb
      unlit
    `)
    expect(chart.initial).toEqual(&apos;unlit&apos;)
  })
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In order to get this test passing, we need to do something a bit more interesting. We need to split our &lt;code&gt;string&lt;/code&gt; on new lines in order to separate the two items: &lt;code&gt;id&lt;/code&gt; and &lt;code&gt;initial&lt;/code&gt; state. We also need to &lt;code&gt;trim&lt;/code&gt; those lines and get rid of the whitespace. Lastly, we want to filter out any empty strings.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function statechart(string) {
  const parsedString = string
    .split(/\n/)
    .map(s =&amp;gt; s.trim())
    .filter(Boolean)
  const [id, initial] = parsedString

  return {
    id,
    initial,
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-8&quot;&amp;gt;
&amp;lt;Image
alt=&quot;Second test run, all tests passing&quot;
src=&quot;/images/state-machine-string/second-test.jpg&quot;
/&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;That passes, too. Now let&apos;s go for it and add a test for handling our states.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;describe(&apos;statechart&apos;, () =&amp;gt; {
  //...
  it(&apos;should derive the `states` from the rest of the lines&apos;, () =&amp;gt; {
    const chart = statechart(`
      lightBulb
      unlit
      lit unlit TOGGLE
      unlit lit TOGGLE
      lit broken BREAK
      unlit break BREAK
    `)

    expect(chart.states).toEqual({
      lit: {
        on: {
          TOGGLE: &apos;unlit&apos;,
          BREAK: &apos;broken&apos;,
        },
      },
      unlit: {
        on: {
          TOGGLE: &apos;lit&apos;,
          BREAK: &apos;broken&apos;,
        },
      },
      broken: {},
    })
  })
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is where the crux of the work takes place. We&apos;ll start by collecting all the rest of the string into an array of &lt;code&gt;stateStrings&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const [id, initial, ...stateStrings] = parsedString
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;From here, we need to turn these into &lt;code&gt;stateNodes&lt;/code&gt;. We&apos;re going to turn these into an array of objects with a &lt;code&gt;start&lt;/code&gt;, &lt;code&gt;end&lt;/code&gt; and &lt;code&gt;event&lt;/code&gt; property. It&apos;ll make things easier down the road.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const stateNodes = stateStrings
  .map(s =&amp;gt; s.split(&apos; &apos;))
  .map(([start, end, event]) =&amp;gt; ({
    start,
    end,
    event,
  }))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we have a map of these nodes, we need to reduce that down to a single &lt;code&gt;states&lt;/code&gt; object.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function statechart(string) {
  // ...
  const states = stateNodes.reduce((acc, cur) =&amp;gt; {
    const { start, end, event } = cur

    // check if this starting node is in `acc` yet
    if (!acc[start]) {
      acc[start] = {
        on: {},
      }
    }

    // check if the `end` is a state yet
    if (!acc[end]) {
      acc[end] = {}
    }

    // Add the event and transition here, spread any previous
    // [event]: end key/value pairs
    acc[start].on = {
      ...acc[start].on,
      [event]: end,
    }

    return acc
  }, {})

  return {
    id,
    initial,
    states,
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;div class=&quot;my-8&quot;&amp;gt;
&amp;lt;Image
alt=&quot;Third test run, all tests passing&quot;
src=&quot;/images/state-machine-string/third-test.jpg&quot;
/&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;Sweet, this gets our tests all passing! Now we can try it out in a component.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import React from &apos;react&apos;
import { Machine } from &apos;xstate&apos;
import { useMachine } from &apos;@xstate/react&apos;
import statechart from &apos;./statechart&apos;

const chart = statechart(`
lightBulb
unlit
lit unlit TOGGLE
unlit lit TOGGLE
lit broken BREAK
unlit broken BREAK
lit unlit RESET
broken unlit RESET
`)

const lightBulbMachine = Machine(chart)

function LightBulb() {
  const [state, send] = useMachine(lightBulbMachine)

  return (
    &amp;lt;div&amp;gt;
      State: {state}
      &amp;lt;div&amp;gt;
        &amp;lt;Button onClick={() =&amp;gt; send(&apos;TOGGLE&apos;)}&amp;gt;Toggle&amp;lt;/Button&amp;gt;
        &amp;lt;Button onClick={() =&amp;gt; send(&apos;BREAK&apos;)}&amp;gt;Break&amp;lt;/Button&amp;gt;
        &amp;lt;Button onClick={() =&amp;gt; send(&apos;RESET&apos;)}&amp;gt;Reset&amp;lt;/Button&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And let&apos;s check it out here:&lt;/p&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;LightBulb client:load /&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;p&gt;If you want to see this code and play around with it, you can check out this Codesandbox: &lt;a href=&quot;https://codesandbox.io/s/fsm-as-a-string-g3rcp&quot;&gt;https://codesandbox.io/s/fsm-as-a-string-g3rcp&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Drawbacks to This Approach&lt;/h3&gt;
&lt;p&gt;I hope it&apos;s clear that this is simply an experiment. I don&apos;t see this as a long-term useful solution. That said, I want to admit the &lt;em&gt;many&lt;/em&gt; drawbacks that would happen from adopting this.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;No type safety with TypeScript or Flow&lt;/li&gt;
&lt;li&gt;No &lt;code&gt;guard&lt;/code&gt;s for conditional logic&lt;/li&gt;
&lt;li&gt;No hierarchical or parallel states&lt;/li&gt;
&lt;li&gt;No &lt;code&gt;actions&lt;/code&gt; for side effects&lt;/li&gt;
&lt;li&gt;No ability to add top-level &lt;code&gt;event&lt;/code&gt;s &amp;lt;Marker content=&quot;Like adding a RESET event to all states in our LightBulb machine by adding a top level &amp;lt;code&amp;gt;on&amp;lt;/code&amp;gt; object&quot; /&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;I think this approach would really only be useful to someone who wanted to save a few keystrokes in building their machines. I wouldn&apos;t recommend it to anyone!&lt;/p&gt;
&lt;p&gt;&lt;em&gt;But&lt;/em&gt;, I do recommend experimenting and seeing what you learn. My first iterations on this function involved using &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#Tagged_templates&quot;&gt;tagged templates&lt;/a&gt; and I learned a few things about writing those. It never hurts to spend some time trying something in a different way, and I hope this inspires you to try a few more experiments yourself.&lt;/p&gt;
</content:encoded><category>React</category><category>State Machines</category></item><item><title>How to Use `useReducer` as a Finite State Machine</title><link>https://kyleshevlin.com/how-to-use-usereducer-as-a-finite-state-machine/</link><guid isPermaLink="true">https://kyleshevlin.com/how-to-use-usereducer-as-a-finite-state-machine/</guid><description>In this post, Kyle Shevlin demonstrates a way to make React&apos;s `useReducer` hook behave like a finite state machine.</description><pubDate>Mon, 04 May 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import LightBulb from &apos;./_LightBulb&apos;&lt;/p&gt;
&lt;p&gt;I recently attempted to get XState into the Webflow codebase to manage some challenging and complex UIs but was met with resistance. No big deal, this is a part of work, consensus driving, disagreeing and committing, etc. If it hasn&apos;t happened to you yet, it will.&lt;/p&gt;
&lt;p&gt;One of the things you need when that happens is a good imagination. How do we make the tools we already have do the things we want in a reasonable way? I&apos;m going to help you with that today by showing you a way to make &lt;code&gt;useReducer&lt;/code&gt; behave like a simple finite state machine in React.&lt;/p&gt;
&lt;p&gt;I&apos;ve started using the following pattern in some of my work and I think it will help you. &amp;lt;Marker content=&quot;A few caveats up front. You won&apos;t have access to hierarchical state machines with this approach. You also will not have the ability to trigger side effects from state changes. I will discuss this briefly here, but plan to cover it in another blog post.&quot; /&amp;gt; If we look at the &lt;code&gt;reducer&lt;/code&gt; of &lt;code&gt;useReducer&lt;/code&gt; and a state machine, we can see that they are quite similar. They both take a current &lt;code&gt;state&lt;/code&gt; and an &lt;code&gt;event&lt;/code&gt; (Redux calls this an &lt;code&gt;action&lt;/code&gt;, but I will use &lt;code&gt;event&lt;/code&gt; throughout this post), and return the next state. The differences are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;code&gt;reducer&lt;/code&gt; does not restrict itself to a set of finite states&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;reducer&lt;/code&gt; has no mechanism for calling side effects from state transitions&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We can&apos;t do anything about the second point, and I will cover that in a future post on &lt;a href=&quot;https://github.com/davidkpiano/useEffectReducer&quot;&gt;&lt;code&gt;useEffectReducer&lt;/code&gt;&lt;/a&gt;, but we can do something about the first. We can create a graph of states that our &lt;code&gt;reducer&lt;/code&gt; will use to transition to the next state. I&apos;ll demonstrate how I approach this.&lt;/p&gt;
&lt;p&gt;I&apos;m going to use the example of a light bulb like I do in my &lt;a href=&quot;https://kyleshevl.in/xstate&quot;&gt;XState course&lt;/a&gt;. A bulb has three states: &lt;code&gt;lit&lt;/code&gt;, &lt;code&gt;unlit&lt;/code&gt;, and &lt;code&gt;broken&lt;/code&gt;. Let&apos;s make a &lt;code&gt;NEXT_STATE_GRAPH&lt;/code&gt; object starting with these states.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const NEXT_STATE_GRAPH = {
  lit: {},
  unlit: {},
  broken: {},
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, let&apos;s define the &lt;code&gt;events&lt;/code&gt; that will transition each &lt;code&gt;state&lt;/code&gt; to their next state.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const NEXT_STATE_GRAPH = {
  lit: {
    TOGGLE: &apos;unlit&apos;,
    BREAK: &apos;broken&apos;,
  },
  unlit: {
    TOGGLE: &apos;lit&apos;,
    BREAK: &apos;broken&apos;,
  },
  broken: {},
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, we&apos;re going to use this in the &lt;code&gt;reducer&lt;/code&gt; we will pass to &lt;code&gt;useReducer&lt;/code&gt; to get our next state.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const reducer = (state, event) =&amp;gt; {
  const nextState = NEXT_STATE_GRAPH[state][event]
  return nextState !== undefined ? nextState : state
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That&apos;s it! A &lt;code&gt;reducer&lt;/code&gt; doesn&apos;t need to be complicated or use a &lt;code&gt;switch&lt;/code&gt; statement. It just has to deterministically give you the next state. Let&apos;s apply this to a simple component.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function LightBulb() {
  // we can change `dispatch` to `send` to look more like using XState
  const [state, send] = useReducer(reducer, &apos;unlit&apos;)

  return (
    &amp;lt;div&amp;gt;
      State: {state}
      &amp;lt;button type=&quot;button&quot; onClick={() =&amp;gt; send(&apos;TOGGLE&apos;)}&amp;gt;
        Toggle
      &amp;lt;/button&amp;gt;
      &amp;lt;button type=&quot;button&quot; onClick={() =&amp;gt; send(&apos;BREAK&apos;)}&amp;gt;
        Break
      &amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can see it in action right here. Be sure to click buttons a state &lt;em&gt;shouldn&apos;t&lt;/em&gt; respond to as well! &amp;lt;Marker content=&quot;You can check out my blog repo for more details on how I implemented &amp;lt;code&amp;gt;reset&amp;lt;/code&amp;gt; in my reducer here.&quot; /&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;LightBulb client:load /&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;h3&gt;Types&lt;/h3&gt;
&lt;p&gt;One small issue I ran into while implementing this was that our type system, Flow, was not happy that I was using the failure of finding a key on an object to return &lt;code&gt;undefined&lt;/code&gt; on purpose. Type systems hate when you use a language feature like that. No problem, I made a simple fix by adjusting our &lt;code&gt;NEXT_STATE_GRAPH&lt;/code&gt; slightly.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Let&apos;s make an object of all our events with an undefined next state
const NON_RESPONSIVE_EVENTS = {
  BREAK: undefined,
  TOGGLE: undefined,
}

// Now let&apos;s spread that object into all our states
const NEXT_STATE_GRAPH = {
  lit: {
    ...NON_RESPONSIVE_EVENTS,
    BREAK: &apos;broken&apos;,
    TOGGLE: &apos;unlit&apos;,
  },
  unlit: {
    ...NON_RESPONSIVE_EVENTS,
    BREAK: &apos;broken&apos;,
    TOGGLE: &apos;lit&apos;,
  },
  broken: {
    ...NON_RESPONSIVE_EVENTS,
  },
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now each state node will have a key for any &lt;code&gt;event&lt;/code&gt; and explicitly returns &lt;code&gt;undefined&lt;/code&gt; in those situations where we do not want to make a state transition. We simply override the non-responsive &lt;code&gt;events&lt;/code&gt; with responsive ones below, taking advantage of how object spreading works. &amp;lt;Marker content=&quot;Key/value pairs that have the same key as a previous one will overwrite the previous value with the new one.&quot; /&amp;gt; This will appease any exhaustive check a type system demands.&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;There you have it, a simple finite state machine using &lt;code&gt;useReducer&lt;/code&gt;. I&apos;ll make another post soon on how to handle infinite state data alongside finite states with &lt;code&gt;useReducer&lt;/code&gt;, but this should be enough to get your brain juices flowing and experimenting with this approach.&lt;/p&gt;
</content:encoded><category>React</category><category>React Hooks</category><category>State Machines</category></item><item><title>Guidelines for State Machines and XState</title><link>https://kyleshevlin.com/guidelines-for-state-machines-and-xstate/</link><guid isPermaLink="true">https://kyleshevlin.com/guidelines-for-state-machines-and-xstate/</guid><description>Here are some guidelines for creating and using state machines with the XState library with React.</description><pubDate>Fri, 03 Apr 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;Table of Contents&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;#intro&quot;&gt;Intro&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#what-is-a-state-machine&quot;&gt;What is a State Machine?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#why-booleans-are-a-misguided-approach&quot;&gt;Why Booleans are a Misguided Approach&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#side-effects-with-state-machines&quot;&gt;Side Effects with State Machines&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#context-in-state-machines&quot;&gt;Context in State Machines&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#guards-and-conditions&quot;&gt;Guards and Conditions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#function-components--hooks&quot;&gt;Function Components &amp;amp; Hooks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#class-components&quot;&gt;Class Components&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#complex-machines&quot;&gt;Complex Machines&lt;/a&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;#hierarchical-machines&quot;&gt;Hierarchical Machines&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#parallel-machines&quot;&gt;Parallel Machines&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#visualizing-state-machines&quot;&gt;Visualizing State Machines&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#how-to-approach-creating-a-state-machine&quot;&gt;How to Approach Creating a State Machine&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#testing&quot;&gt;Testing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#resources&quot;&gt;Resources&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Intro&lt;/h3&gt;
&lt;p&gt;This exists as a living document to define some guidelines regarding state machines and their usage. These guidelines are by no means exhaustive, but hopefully set you on the right path. It is &lt;em&gt;highly recommended&lt;/em&gt; that you read the &lt;a href=&quot;https://xstate.js.org/docs&quot;&gt;XState docs&lt;/a&gt; for more information.&lt;/p&gt;
&lt;h3&gt;What is a State Machine?&lt;/h3&gt;
&lt;p&gt;A state machine, more specifically a &lt;em&gt;finite&lt;/em&gt; state machine, is a means of representing all the possible enumerated states of a system and the possible enumerated transitions between states in that system. That was a bit jargon heavy, so let&apos;s use a brief example to illuminate what this means.&lt;/p&gt;
&lt;p&gt;Consider a light bulb. A light bulb typically has two states: &lt;code&gt;lit&lt;/code&gt; and &lt;code&gt;unlit&lt;/code&gt;. When we have two states, we are often tempted to represent this state with a boolean, &lt;code&gt;true&lt;/code&gt; or &lt;code&gt;false&lt;/code&gt;, but often this is a misguided approach to state management. We will explore why in the next section. Instead, let&apos;s define these two states as objects.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const lit = {}
const unlit = {}

const states = {
  lit,
  unlit,
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, let&apos;s define the possible transitions for each state to the other states. I will follow the conventions of the XState library, in order to introduce the API to you.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const lit = {
  on: { TURN_OFF: &apos;unlit&apos; },
}
const unlit = {
  on: { TURN_ON: &apos;lit&apos; },
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We define &quot;events&quot; on the &lt;code&gt;on&lt;/code&gt; property of a state node in XState (and by convention, they are in scream case 😱). Machines respond to these events, but only when the current state has an enumerated event of the same type. In the context of this example, if an event of &lt;code&gt;type: &apos;TURN_OFF&apos;&lt;/code&gt; is sent to the machine, it will respond and transitions states only when we are in the &lt;code&gt;lit&lt;/code&gt; state. Sending the &lt;code&gt;TURN_OFF&lt;/code&gt; event to a light bulb that&apos;s in the &lt;code&gt;unlit&lt;/code&gt; state will have no effect.&lt;/p&gt;
&lt;p&gt;In this example, our events use the common shorthand of &lt;code&gt;EVENT_NAME: &apos;nextStateName&apos;&lt;/code&gt; In long form, this is equivalent to &lt;code&gt;EVENT_NAME: { target: &apos;nextStateName&apos; }&lt;/code&gt;. Use the shorthand if you do not need to add any &quot;actions&quot; or &quot;conditions&quot;, the longhand otherwise. &quot;Actions&quot; and &quot;conditions&quot; will be covered later in these guidelines.&lt;/p&gt;
&lt;p&gt;Let&apos;s combine what we&apos;ve written so far into an actual XState machine. Machines receive an &lt;code&gt;id&lt;/code&gt;, an &lt;code&gt;initial&lt;/code&gt; state, and a &lt;code&gt;states&lt;/code&gt; object of the enumerated state nodes.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { Machine } from &apos;xstate&apos;

const lit = {
  on: { TURN_OFF: &apos;unlit&apos; },
}

const unlit = {
  on: { TURN_ON: &apos;lit&apos; },
}

const states = {
  lit,
  unlit,
}

const lightBulbMachine = Machine({
  id: &apos;lightBulb&apos;,
  initial: &apos;unlit&apos;,
  states,
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&apos;s move our &lt;code&gt;lit&lt;/code&gt; and &lt;code&gt;unlit&lt;/code&gt; states directly into the &lt;code&gt;Machine&lt;/code&gt; config object to tidy this up:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { Machine } from &apos;xstate&apos;

const lightBulbMachine = Machine({
  id: &apos;lightBulb&apos;,
  initial: &apos;unlit&apos;,
  states: {
    lit: {
      on: { TURN_OFF: &apos;unlit&apos; },
    },
    unlit: {
      on: { TURN_ON: &apos;lit&apos; },
    },
  },
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Every machine has a &lt;code&gt;transition&lt;/code&gt; method, which receives a &lt;code&gt;state&lt;/code&gt; and an &lt;code&gt;event&lt;/code&gt; and returns the next state. &lt;em&gt;This is very similar to a reducer for Flux or Redux&lt;/em&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;lightBulbMachine.transition(&apos;lit&apos;, &apos;TURN_OFF&apos;).value // &apos;unlit&apos;
lightBulbMachine.transition(&apos;unlit&apos;, &apos;TURN_OFF&apos;).value // &apos;unlit&apos;
lightBulbMachine.transition(&apos;unlit&apos;, &apos;TURN_ON&apos;).value // &apos;lit&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Using the &lt;code&gt;transition&lt;/code&gt; method explicitly is not common for most state machine usage with XState. Instead, a &lt;code&gt;service&lt;/code&gt; is used to maintain the current state of the machine and &lt;code&gt;send&lt;/code&gt; events to the machine. This will be discussed further, specifically in the section on &lt;a href=&quot;#class-components&quot;&gt;Class Components&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Why Booleans are a Misguided Approach&lt;/h3&gt;
&lt;p&gt;Looking more closely at our light bulb, one might realize that there is actually a &lt;em&gt;third&lt;/em&gt; state that a light bulb can be in: &lt;code&gt;broken&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;A &lt;code&gt;broken&lt;/code&gt; light bulb is different than an &lt;code&gt;unlit&lt;/code&gt; light bulb and deserves its own state. If we were attempting to model a light bulb with these three states using booleans, we&apos;ll discover a problem right away.&lt;/p&gt;
&lt;p&gt;Most likely we would use two booleans to cover the possible states: &lt;code&gt;isLit&lt;/code&gt; and &lt;code&gt;isBroken&lt;/code&gt;. Since we are representing these states with booleans, each state has two possible outcomes. We can calculate the possible state permutations with the equation &lt;code&gt;2^n&lt;/code&gt;, where &lt;code&gt;n&lt;/code&gt; is the number of states (&lt;code&gt;2&lt;/code&gt; because the enumerated states of a boolean is &lt;code&gt;2&lt;/code&gt;: &lt;code&gt;true&lt;/code&gt; and &lt;code&gt;false&lt;/code&gt;). Thus, trying to cover our light bulb with two booleans reveals that we&apos;ve actually created &lt;em&gt;four&lt;/em&gt; states.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;isLit&lt;/th&gt;
&lt;th&gt;isBroken&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;td&gt;true&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;true&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;true&lt;/td&gt;
&lt;td&gt;true&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;But we only have three states in our model? Where did this fourth state come from? This fourth state is an &quot;impossible state&quot;, a state our system should not be capable of getting to. It occurs when we have &lt;code&gt;isLit &amp;amp;&amp;amp; isBroken&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now, we&apos;re decent programmers and can typically code around this with guards and conditional logic, but as we start to add booleans to manage state, that explosion of possible permutations continues at a rapid pace. In just a few iterations, the permutations grow: 2, 4, 8, 16, 32, 64, 128, etc.&lt;/p&gt;
&lt;p&gt;State machines avoid this problem by forcing us to enumerate only the &lt;em&gt;possible states and transitions&lt;/em&gt;, which more accurately models what we are trying to achieve anyways. Making an accurate light bulb devoid of impossible states is as simple as adding a new state node and some events to respond to.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { Machine } from &apos;xstate&apos;

const lightBulbMachine = Machine({
  id: &apos;lightBulb&apos;,
  initial: &apos;unlit&apos;,
  states: {
    lit: {
      on: {
        TURN_OFF: &apos;unlit&apos;,
        BREAK: &apos;broken&apos;,
      },
    },
    unlit: {
      on: {
        TURN_ON: &apos;lit&apos;,
        BREAK: &apos;broken&apos;,
      },
    },
    broken: {
      type: &apos;final&apos;,
    },
  },
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For a bonus touch, we add the &lt;code&gt;type: &apos;final&lt;/code&gt; to the &lt;code&gt;broken&lt;/code&gt; state. It is encouraged that you add this to any final state in your machine, though it is not necessary. It is useful in more complex situations where machines invoke other machines. That will not be covered in this guideline. Please refer to the XState docs about &lt;a href=&quot;https://xstate.js.org/docs/guides/communication.html#the-invoke-property&quot;&gt;Invoking Services&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Side Effects with State Machines&lt;/h3&gt;
&lt;p&gt;State machines respond to events. Events may or may not trigger a transition. As a result of transitions, we have the opportunity to produce side effects. These side effects are called &quot;actions&quot;.&lt;/p&gt;
&lt;p&gt;We can call actions at three moments in the state transition cycle, and they happen in this order.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;on &lt;code&gt;exit&lt;/code&gt; from a state&lt;/li&gt;
&lt;li&gt;on the transition to a state&lt;/li&gt;
&lt;li&gt;on &lt;code&gt;entry&lt;/code&gt; to a state&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let&apos;s fire actions of each kind in our light bulb example.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { Machine } from &apos;xstate&apos;

// We can break pieces of our chart out and compose them together
// just as we would any other object
const breakEvent = {
  BREAK: {
    // BREAK: &apos;broken&apos; is a shorthand for BREAK: { target: &apos;broken&apos; }
    target: &apos;broken&apos;,
    actions: [&apos;informUserOfBrokeLightBulb&apos;],
  },
}

const lightBulbMachine = Machine(
  {
    id: &apos;lightBulb&apos;,
    initial: &apos;unlit&apos;,
    states: {
      lit: {
        entry: &apos;enterLit&apos;, // If only a single action is taken, a string will suffice
        on: {
          TURN_OFF: &apos;unlit&apos;,
          ...breakEvent,
        },
      },
      unlit: {
        exit: [&apos;leaveUnlit&apos;],
        on: {
          TURN_ON: &apos;lit&apos;,
          ...breakEvent,
        },
      },
      broken: {
        type: &apos;final&apos;,
      },
    },
  },
  {
    actions: {
      // all actions receive the machine&apos;s `context` and the `event` that triggered the action.
      // More on context later
      enterLit: (context, event) =&amp;gt; {
        console.log(`Light bulb lit from ${JSON.stringify(event)}`)
      },
      leaveUnlit: () =&amp;gt; {
        console.log(&apos;We can do more than log stuff, this is just an example&apos;)
      },
      informUserOfBrokeLightBulb: (_, event) =&amp;gt; {
        // we can put more information on an event object, such as
        // { type: &apos;BREAK&apos;, bulbId: &apos;someUUIDOrSomething&apos; }
        contactUserAboutBrokenBulb(event.bulbId)
      },
    },
  },
)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We have defined all our actions as strings and made matching methods in the second argument to &lt;code&gt;Machine()&lt;/code&gt;. &lt;strong&gt;This is the preferred way to add actions to machines&lt;/strong&gt;. You &lt;em&gt;can&lt;/em&gt; write functions inline in &lt;code&gt;actions&lt;/code&gt; or &lt;code&gt;entry&lt;/code&gt; or &lt;code&gt;exit&lt;/code&gt;, &lt;strong&gt;however&lt;/strong&gt;, following the guideline of using strings will be &lt;em&gt;especially&lt;/em&gt; useful when we start combining XState and React.&lt;/p&gt;
&lt;h3&gt;Context in State Machines&lt;/h3&gt;
&lt;p&gt;The concept of &lt;code&gt;context&lt;/code&gt; has a different meaning in state machines than it does in React. In React, &lt;code&gt;context&lt;/code&gt; is a state held in closure to be referenced by many components via a providing and consuming component architecture. It is used to avoid excessive &quot;prop drilling&quot; among other things.&lt;/p&gt;
&lt;p&gt;In state machines, &lt;code&gt;context&lt;/code&gt; is used to store data that cannot be easily represented by finite states. In fact, it is most often used to keep track of &lt;em&gt;infinite&lt;/em&gt; states.&lt;/p&gt;
&lt;p&gt;Consider a text input. There exists an infinite number of strings that could be used as the &lt;code&gt;value&lt;/code&gt; of that input. It therefore would require an infinite number of states to model that system. This is simply impossible.&lt;/p&gt;
&lt;p&gt;That said, occasionally we need values that result in infinite states in order to accomplish a variety of tasks. Thus, &lt;code&gt;context&lt;/code&gt; in state machines.&lt;/p&gt;
&lt;p&gt;Think of &lt;code&gt;context&lt;/code&gt; in a state machine similar to how you think of &lt;code&gt;state&lt;/code&gt; in React. It is localized to the machine. It can be updated when necessary and can be referenced by the machine.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;context&lt;/code&gt; is added as a &lt;code&gt;context&lt;/code&gt; object on the &lt;code&gt;config&lt;/code&gt; object of a machine. Let&apos;s take our light bulb example and add a &lt;code&gt;color&lt;/code&gt; to it in context.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { Machine } from &apos;xstate&apos;

const lightBulbMachine = Machine({
  id: &apos;lightBulb&apos;,
  initial: &apos;unlit&apos;,
  // We&apos;ll add `context` here
  context: {
    color: &apos;#fff&apos;,
  },
  states: {
    lit: {
      on: {
        TURN_OFF: &apos;unlit&apos;,
        BREAK: &apos;broken&apos;,
      },
    },
    unlit: {
      on: {
        TURN_ON: &apos;lit&apos;,
        BREAK: &apos;broken&apos;,
      },
    },
    broken: {
      type: &apos;final&apos;,
    },
  },
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We&apos;ve added &lt;code&gt;color&lt;/code&gt; to context. Now, let&apos;s create an event to update the &lt;code&gt;color&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { assign, Machine } from &apos;xstate&apos;

const lightBulbMachine = Machine(
  {
    id: &apos;lightBulb&apos;,
    initial: &apos;unlit&apos;,
    // We&apos;ll add `context` here
    context: {
      color: &apos;#fff&apos;,
    },
    states: {
      lit: {
        on: {
          CHANGE_COLOR: {
            actions: [&apos;updateColor&apos;],
          },
          TURN_OFF: &apos;unlit&apos;,
          BREAK: &apos;broken&apos;,
        },
      },
      unlit: {
        on: {
          CHANGE_COLOR: {
            actions: [&apos;updateColor&apos;],
          },
          TURN_ON: &apos;lit&apos;,
          BREAK: &apos;broken&apos;,
        },
      },
      broken: {
        type: &apos;final&apos;,
      },
    },
  },
  {
    actions: {
      updateColor: assign((context, event) =&amp;gt; ({
        color: event.color,
      })),
    },
  },
)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We&apos;ve added a &lt;code&gt;CHANGE_COLOR&lt;/code&gt; event to the &lt;code&gt;lit&lt;/code&gt; and &lt;code&gt;unlit&lt;/code&gt; states. We can send a &lt;code&gt;color&lt;/code&gt; value on an event object. The machine responds to the event, calling the actions for that event. The action in this case is &lt;code&gt;updateColor&lt;/code&gt;, which is a special action known as an &lt;code&gt;assign&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;assign&lt;/code&gt; is a action creator function for XState used specifically to update &lt;code&gt;context&lt;/code&gt;. It works very similar to React&apos;s &lt;code&gt;setState&lt;/code&gt;. It has two APIs that will be familiar to React developers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;assign&lt;/code&gt; can take an object as an argument, merging it with the current &lt;code&gt;context&lt;/code&gt; to get the &lt;code&gt;nextContext&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;assign({
  color: &apos;#f00&apos;,
})
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;It can receive an updater function that returns an object to be merged with the current &lt;code&gt;context&lt;/code&gt; to get the &lt;code&gt;nextContext&lt;/code&gt;. This updater function receives the current &lt;code&gt;context&lt;/code&gt; and the &lt;code&gt;event&lt;/code&gt; as arguments.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;assign((context, event) =&amp;gt; ({
  color: event.color,
}))
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;A third API exists that is different from &lt;code&gt;React.setState&lt;/code&gt;, an object whose values are function updaters&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;assign({
  color: (context, event) =&amp;gt; event.color,
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Any of these APIs is fine to use. In some ways, it is simpler than &lt;code&gt;React.setState&lt;/code&gt; as there are no async issues to concern yourself with. There is one &quot;gotcha&quot; to understand about &lt;code&gt;assign&lt;/code&gt;s though. &lt;strong&gt;All &lt;code&gt;assign&lt;/code&gt;s are run &lt;em&gt;before&lt;/em&gt; other actions.&lt;/strong&gt; This is simple to understand when you consider that &lt;code&gt;Machine.transition&lt;/code&gt; is a pure function that receives a &lt;code&gt;state&lt;/code&gt;, &lt;code&gt;event&lt;/code&gt; and &lt;code&gt;context&lt;/code&gt; to derive the nextState. In order to give it the correct &lt;code&gt;context&lt;/code&gt;, &lt;code&gt;assign&lt;/code&gt;s must be run to determine the next state. Read more about this in the XState docs under &lt;a href=&quot;https://xstate.js.org/docs/guides/context.html#action-order&quot;&gt;Context - Action Order&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Now that we understand &lt;code&gt;assign&lt;/code&gt; actions, let&apos;s use it on our light bulb machine to change the color.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const nextState = lightBulbMachine.transition(&apos;lit&apos;, {
  type: &apos;CHANGE_COLOR&apos;,
  color: &apos;#f00&apos;,
}) // { value: &apos;lit&apos;, context: { color: &apos;#f00&apos; } }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Take notice that we have an event that &lt;em&gt;only&lt;/em&gt; triggers actions. It does not have a &lt;code&gt;target&lt;/code&gt; state. This is useful when we want to respond to events in a state without making a state transition.&lt;/p&gt;
&lt;h3&gt;Guards and Conditions&lt;/h3&gt;
&lt;p&gt;It won&apos;t be long before you come to a point where you would like to make a transition to a state conditional. This is accomplished through the use of a &lt;code&gt;guard&lt;/code&gt; function on the &lt;code&gt;cond&lt;/code&gt; property of a state node.&lt;/p&gt;
&lt;p&gt;Let&apos;s consider a fancier light bulb, one with a &quot;locking mechanism&quot; that prevents a user from turning it on. Perhaps it&apos;s a child&apos;s bedside lamp and we&apos;d like to prevent them from reading during the night. We can create a condition that prevents the transition to the &lt;code&gt;lit&lt;/code&gt; state to model this.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { Machine } from &apos;xstate&apos;

const lightBulbMachine = Machine({
  id: &apos;lightBulb&apos;,
  initial: &apos;unlit&apos;,
  states: {
    lit: {
      on: {
        TURN_OFF: &apos;unlit&apos;,
        BREAK: &apos;broken&apos;
      }
    },
    unlit: {
      on: {
        TURN_ON: {
          target: &apos;lit&apos;,
          cond: &apos;isDaylightHours&apos;
        ],
        BREAK: &apos;broken&apos;
      }
    },
    broken: {
      type: &apos;final&apos;
    }
  }
}, {
  guards: {
    isDaylightHours: (context, event) =&amp;gt; {
      return event.time.getHours() &amp;gt; 7 || event.time.getHours() &amp;lt; 21
    }
  }
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We&apos;ve created a &lt;code&gt;guard&lt;/code&gt; function named &lt;code&gt;isDaylightHours&lt;/code&gt;. It&apos;s a predicate function (a function that returns a boolean). We&apos;ve referenced that function on the &lt;code&gt;cond&lt;/code&gt; property of the &lt;code&gt;TURN_ON&lt;/code&gt; event in the &lt;code&gt;unlit&lt;/code&gt; state. If the guard returns &lt;code&gt;true&lt;/code&gt;, the transition is taken to &lt;code&gt;lit&lt;/code&gt;, otherwise it will remain &lt;code&gt;unlit&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Guards are a simple, yet effective way to model conditional state transitions. Be wary if your guard is really a child state of a parent state in disguise. This refers to hierarchical states, which will be covered in the &lt;a href=&quot;#hierarchical-machines&quot;&gt;Hierarchical Machines&lt;/a&gt; section.&lt;/p&gt;
&lt;h3&gt;Function Components &amp;amp; Hooks&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;@xstate/react&lt;/code&gt; package ships a very useful hook, &lt;code&gt;useMachine&lt;/code&gt;, that can be used in function components to easily instantiate a service for a machine. &lt;code&gt;useMachine&lt;/code&gt; accepts a &lt;code&gt;Machine&lt;/code&gt; as its first argument and an &lt;code&gt;options&lt;/code&gt; object as its second object. In this way, we&apos;re able to create a machine that defines our component&apos;s enumerated states and transitions &lt;em&gt;outside the scope of the function&lt;/em&gt;, but use any props or functions in the scope of the component within the &lt;code&gt;options&lt;/code&gt; object.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import React from &apos;react&apos;
import {Machine} from &apos;xstate&apos;
import {useMachine} from &apos;@xstate/react&apos;

const lightBulbMachine = Machine({
  id: &apos;lightBulb&apos;,
  initial: &apos;unlit&apos;,
  states: {
    lit: {
      on: {
        TURN_OFF: &apos;unlit&apos;,
        BREAK: &apos;broken&apos;
      }
    },
    unlit: {
      on: {
        TURN_ON: &apos;lit&apos;,
        BREAK: &apos;broken&apos;
      }
    },
    broken: {
      type: &apos;final&apos;
      entry: [&apos;logBroken&apos;]
    }
  }
})

const TEXTS_BY_STATE = {
  lit: &apos;LIGHT!&apos;,
  unlit: &apos;not light&apos;,
  broken: &apos;so borked&apos;
}

function LightBulb({ id }) {
  const [state, send] = useMachine(lightBulbMachine, {
    actions: {
      logBroken: () =&amp;gt; {
        console.log(`Light bulb with id: ${id} has broken`)
      }
    }
  })

  return (
    &amp;lt;div&amp;gt;
      {TEXTS_BY_STATE[state.value]}
      &amp;lt;div&amp;gt;
        &amp;lt;button onClick={() =&amp;gt; send(&apos;TURN_ON&apos;)} type=&quot;button&quot;&amp;gt;Turn On&amp;lt;/button&amp;gt;
        &amp;lt;button onClick={() =&amp;gt; send(&apos;TURN_OFF&apos;)} type=&quot;button&quot;&amp;gt;Turn Off&amp;lt;/button&amp;gt;
        &amp;lt;button onClick={() =&amp;gt; send(&apos;BREAK&apos;)} type=&quot;button&quot;&amp;gt;Break&amp;lt;/button&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the above example, we render all of the buttons regardless of what &lt;code&gt;state.value&lt;/code&gt; is. We can disable buttons based on the current state with &lt;code&gt;state.matches()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;state.matches()&lt;/code&gt; accepts a string or object representing a state and returns a boolean regarding if it matches or not. We can use it like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;return (
  &amp;lt;div&amp;gt;
    {TEXTS_BY_STATE[state.value]}
    &amp;lt;div&amp;gt;
      &amp;lt;button
        disabled={state.matches(&apos;lit&apos;)}
        onClick={() =&amp;gt; send(&apos;TURN_ON&apos;)}
        type=&quot;button&quot;
      &amp;gt;
        Turn On
      &amp;lt;/button&amp;gt;
      &amp;lt;button
        disabled={state.matches(&apos;unlit&apos;)}
        onClick={() =&amp;gt; send(&apos;TURN_OFF&apos;)}
        type=&quot;button&quot;
      &amp;gt;
        Turn Off
      &amp;lt;/button&amp;gt;
      &amp;lt;button
        disabled={state.matches(&apos;broken&apos;)}
        onClick={() =&amp;gt; send(&apos;BREAK&apos;)}
        type=&quot;button&quot;
      &amp;gt;
        Break
      &amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can extrapolate this API, the use of &lt;code&gt;state.value&lt;/code&gt; and &lt;code&gt;state.matches()&lt;/code&gt; to handle all condition based rendering and functionality in our components and more.&lt;/p&gt;
&lt;h3&gt;Class Components&lt;/h3&gt;
&lt;p&gt;It is possible to use XState with class components as well, but this will require a few extra steps and a new concept. The concept first.&lt;/p&gt;
&lt;p&gt;A state machine, specifically the &lt;code&gt;transition&lt;/code&gt; method on a machine, is a pure function. We give it a &lt;code&gt;state&lt;/code&gt; and an &lt;code&gt;event&lt;/code&gt; (and we can supply a &lt;code&gt;context&lt;/code&gt; as the third argument) and we should get the same next state every time. Being pure means that the machine itself does not store the current state. Instead, we are responsible for that. We can accomplish this through using a &lt;code&gt;service&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;A &lt;code&gt;service&lt;/code&gt; is used to maintain the current state. We also &lt;code&gt;send&lt;/code&gt; events to the &lt;code&gt;service&lt;/code&gt; (hence where &lt;code&gt;send&lt;/code&gt; comes from with the &lt;code&gt;useMachine&lt;/code&gt; hook) which are passed along the machine&apos;s &lt;code&gt;transition&lt;/code&gt; method internally. We can start a service by using the &lt;code&gt;interpret&lt;/code&gt; function from XState. Let&apos;s write our light bulb component as a class component.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import React from &apos;react&apos;
import {Machine, interpret} from &apos;xstate&apos;

const lightBulbMachine = Machine({
  id: &apos;lightBulb&apos;,
  initial: &apos;unlit&apos;,
  states: {
    lit: {
      on: {
        TURN_OFF: &apos;unlit&apos;,
        BREAK: &apos;broken&apos;
      }
    },
    unlit: {
      on: {
        TURN_ON: &apos;lit&apos;,
        BREAK: &apos;broken&apos;
      }
    },
    broken: {
      type: &apos;final&apos;
      entry: [&apos;logBroken&apos;]
    }
  }
})

const TEXTS_BY_STATE = {
  lit: &apos;LIGHT!&apos;,
  unlit: &apos;not light&apos;,
  broken: &apos;so borked&apos;
}

class LightBulb extends React.Component {
  state = {
    current: lightBulbMachine.initialState
  }

  config = {
    actions: {
      logBroken: () =&amp;gt; {
        const { id } = this.props
        console.log(`Light bulb with id: ${id} has broken`)
      }
    }
  }

  service = interpret(lightBulbMachine.withConfig(this.config))
    .onTransition(current =&amp;gt; {
      this.setState({ current })
    })

  componentDidMount() {
    this.service.start()
  }

  componentWillUnmount() {
    this.service.stop()
  }

  render() {
    const { current } = this.state
    const { send } = this.service

    return (
      &amp;lt;div&amp;gt;
        {TEXTS_BY_STATE[current.value]}
        &amp;lt;div&amp;gt;
          &amp;lt;button onClick={() =&amp;gt; send(&apos;TURN_ON&apos;)} type=&quot;button&quot;&amp;gt;Turn On&amp;lt;/button&amp;gt;
          &amp;lt;button onClick={() =&amp;gt; send(&apos;TURN_OFF&apos;)} type=&quot;button&quot;&amp;gt;Turn Off&amp;lt;/button&amp;gt;
          &amp;lt;button onClick={() =&amp;gt; send(&apos;BREAK&apos;)} type=&quot;button&quot;&amp;gt;Break&amp;lt;/button&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
    )
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I want you to take notice of a few key things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;We need to &lt;code&gt;start&lt;/code&gt; and &lt;code&gt;stop&lt;/code&gt; our service. This is because in complex state machines, there &lt;code&gt;activities&lt;/code&gt; and long running side effects that depend on these methods being called.&lt;/li&gt;
&lt;li&gt;We can configure our state machine with local &lt;code&gt;props&lt;/code&gt; and methods, but we must do so by extending the machine using the &lt;code&gt;withConfig&lt;/code&gt; method. This is different than the &lt;code&gt;useMachine&lt;/code&gt; hook, where we could supply a second argument to the function instead.&lt;/li&gt;
&lt;li&gt;We store the &lt;code&gt;current&lt;/code&gt; state in local React state. We use the &lt;code&gt;service&lt;/code&gt;&apos;s &lt;code&gt;onTransition&lt;/code&gt; method to keep state in sync in our component.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;While it is more code, it does mean that state machines can be introduced to legacy components without the need to update them to function components that can use the &lt;code&gt;useMachine&lt;/code&gt; hook.&lt;/p&gt;
&lt;h3&gt;Complex Machines&lt;/h3&gt;
&lt;p&gt;So far, our state machines have been relatively simple. They have been one level of states and one single system of states. At some point, it is likely you&apos;ll need something more complex. It is highly recommended you read the XState docs for a deep dive on more complex machines, but two common ones will be covered here: Hierarchical and Parallel machines.&lt;/p&gt;
&lt;h4&gt;Hierarchical Machines&lt;/h4&gt;
&lt;p&gt;As you&apos;re developing a machine, you may realize that some of your enumerated states are really &lt;em&gt;child states of a parent state&lt;/em&gt;. Let&apos;s extend our light bulb example further.&lt;/p&gt;
&lt;p&gt;Our light bulb has a new feature, it can shine at three different levels of brightness: &lt;code&gt;low&lt;/code&gt;, &lt;code&gt;normal&lt;/code&gt;, and &lt;code&gt;high&lt;/code&gt;. These states are child states (or &quot;substates&quot;) of our &lt;code&gt;lit&lt;/code&gt; state. Let&apos;s write a hierarchical state machine to convey this.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { Machine } from &apos;xstate&apos;

const lightBulbMachine = Machine({
  id: &apos;lightBulb&apos;,
  initial: &apos;unlit&apos;,
  states: {
    lit: {
      // Child states start here
      initial: &apos;normal&apos;,
      states: {
        low: {
          on: {
            INCREASE_BRIGHTNESS: &apos;normal&apos;,
          },
        },
        normal: {
          on: {
            DECREASE_BRIGHTNESS: &apos;low&apos;,
            INCREASE_BRIGHTNESS: &apos;high&apos;,
          },
        },
        high: {
          on: {
            DECREASE_BRIGHTNESS: &apos;normal&apos;,
          },
        },
      },
      // Child states end here
      on: {
        TURN_OFF: &apos;unlit&apos;,
        BREAK: &apos;broken&apos;,
      },
    },
    unlit: {
      on: {
        TURN_ON: &apos;lit&apos;,
        BREAK: &apos;broken&apos;,
      },
    },
    broken: {
      type: &apos;final&apos;,
    },
  },
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To create a hierarchical machine, we essentially create the same structure as a normal state machine, but nest it in the parent state. We add an &lt;code&gt;initial&lt;/code&gt; state and enumerate the child states under the &lt;code&gt;states&lt;/code&gt; property.&lt;/p&gt;
&lt;p&gt;Now if our light bulb is in the &lt;code&gt;lit&lt;/code&gt; state, it will initially start in the &lt;code&gt;{ lit: &apos;normal&apos; }&lt;/code&gt; state. We can send events to our machine to change the brightness.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;lightBulbMachine({ lit: &apos;normal&apos; }, &apos;INCREASE_BRIGHTNESS&apos;).value // { lit: &apos;high&apos; }
lightBulbMachine({ lit: &apos;high&apos; }, &apos;DECREASE_BRIGHTNESS&apos;).value // { lit: &apos;normal&apos; }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Hierarchical states are an excellent way to model states that should only exist as a child state of another state. This allows us to avoid a lot of conditional logic since our machine won&apos;t respond to events unless it is in the correct state.&lt;/p&gt;
&lt;h4&gt;Parallel Machines&lt;/h4&gt;
&lt;p&gt;Occasionally, you&apos;ll find your model requires a machine be in multiple states simultaneously. This is what a parallel machine is for. A parallel machine allows a machine to be in multiple states simultaneously and independently. Let&apos;s extend our light bulb further and turn it into one for the dance floor. Lights on the dance floor flash in various patterns, and they can oscillate in different ways. We&apos;ll focus on just those two parallel states in our example (which will also include a hierarchical state since these can only occur in the &lt;code&gt;lit&lt;/code&gt; state).&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { Machine } from &apos;xstate&apos;

const lightBulbMachine = Machine({
  id: &apos;lightBulb&apos;,
  initial: &apos;unlit&apos;,
  states: {
    lit: {
      // parallel child states start here
      type: &apos;parallel&apos;, // no initial state, requires `type: &apos;parallel&apos;` be set
      states: {
        // 1st parallel state
        pattern: {
          // We can easily have hierarchical child states inside our parent parallel state
          initial: &apos;steady&apos;,
          states: {
            steady: {
              on: {
                PULSE: &apos;pulsing&apos;,
                FLASH: &apos;flashing&apos;,
              },
            },
            pulsing: {
              on: {
                STEADY: &apos;steady&apos;,
                FLASH: &apos;flashing&apos;,
              },
            },
            flashing: {
              on: {
                STEADY: &apos;steady&apos;,
                PULSE: &apos;pulsing&apos;,
              },
            },
          },
        },
        // 2nd parallel state
        movement: {
          initial: &apos;stationary&apos;,
          states: {
            stationary: {
              on: { OSCILLATE: &apos;oscillating&apos; },
            },
            oscillating: {
              on: { STOP: &apos;stationary&apos; },
            },
          },
        },
      },
      // parallel child states end here
      on: {
        TURN_OFF: &apos;unlit&apos;,
        BREAK: &apos;broken&apos;,
      },
    },
    unlit: {
      on: {
        TURN_ON: &apos;lit&apos;,
        BREAK: &apos;broken&apos;,
      },
    },
    broken: {
      type: &apos;final&apos;,
    },
  },
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We added quite a bit of complexity here, but it&apos;s just the combination of parallel and hierarchical states that make it happen. Let&apos;s break it down.&lt;/p&gt;
&lt;p&gt;Under the &lt;code&gt;lit&lt;/code&gt; state, we add a couple parallel states: one for the light &lt;code&gt;pattern&lt;/code&gt; and one for the &lt;code&gt;movement&lt;/code&gt; of the bulb. The bulb is in both states simultaneously and independently. We can send events that affect one without affecting the other.&lt;/p&gt;
&lt;p&gt;Next, inside of each parallel state, we&apos;ve added a hierarchical state chart to govern the states held within each parallel state. This is precisely what we&apos;ve seen thus far. We have a subchart that controls the &lt;code&gt;pattern&lt;/code&gt; states, and one that governs the &lt;code&gt;movement&lt;/code&gt; states.&lt;/p&gt;
&lt;p&gt;If we were to examine the value returned by the &lt;code&gt;lit&lt;/code&gt; state, it would initially look like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;lightBulbMachine.transition(&apos;unlit&apos;, &apos;TURN_ON&apos;)
// {
//   value: {
//     lit: {
//       pattern: &apos;steady&apos;,
//       movement: &apos;stationary&apos;,
//     }
//   }
// }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice that the &lt;code&gt;lit&lt;/code&gt; state is an object with the states of all our parallel states contained within.&lt;/p&gt;
&lt;h3&gt;Visualizing State Machines&lt;/h3&gt;
&lt;p&gt;XState has a very handy visualizer at &lt;a href=&quot;https://xstate.js.org/viz&quot;&gt;xstate.js.org/viz&lt;/a&gt;. You can save machines as gists from the visualizer as well.&lt;/p&gt;
&lt;h3&gt;How to Approach Creating a State Machine&lt;/h3&gt;
&lt;p&gt;Here is a general heuristic of how to approach creating a state machine.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Enumerate the states of your program&lt;/li&gt;
&lt;li&gt;Enumerate the transitions between those states&lt;/li&gt;
&lt;li&gt;Examine if any of the states can only exist as a substate of another state. If so, know you can use a hierarchical state machine.&lt;/li&gt;
&lt;li&gt;Examine if any of the states can exist simultaneously and independently. If so, know you can use a parallel state machine.&lt;/li&gt;
&lt;li&gt;Create objects for all of your states&lt;/li&gt;
&lt;li&gt;Add the transitions to the &lt;code&gt;on&lt;/code&gt; property of those states&lt;/li&gt;
&lt;li&gt;Combine these into the &lt;code&gt;states&lt;/code&gt; property of your machine&lt;/li&gt;
&lt;li&gt;Add the &lt;code&gt;initial&lt;/code&gt; state to your machine&lt;/li&gt;
&lt;li&gt;Add an &lt;code&gt;id&lt;/code&gt; to your machine&lt;/li&gt;
&lt;li&gt;Start the service of your machine through either &lt;code&gt;interpret&lt;/code&gt; or &lt;code&gt;useMachine&lt;/code&gt; depending on your situation.&lt;/li&gt;
&lt;li&gt;Profit.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Testing&lt;/h3&gt;
&lt;p&gt;Tests can be written just as any other test would be written regarding UI interactions to verify expected behavior.&lt;/p&gt;
&lt;p&gt;There is also the &lt;code&gt;@xstate/test&lt;/code&gt; library that can &lt;em&gt;automatically generate all possible branches of your state machine&lt;/em&gt;. More will be added to this section in the future.&lt;/p&gt;
&lt;h3&gt;Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://xstate.js.org/docs&quot;&gt;XState Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://xstate.js.org/viz&quot;&gt;XState Viz&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://kyleshevl.in/xstate&quot;&gt;Introduction to State Machines and XState on egghead.io&lt;/a&gt; (if you have an egghead account. Access for Webflow engineers will come soon.)&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><category>React</category><category>State Machines</category></item><item><title>Managing Cyclomatic Complexity</title><link>https://kyleshevlin.com/managing-cyclomatic-complexity/</link><guid isPermaLink="true">https://kyleshevlin.com/managing-cyclomatic-complexity/</guid><description>Understanding cyclomatic complexity and how to manage it can level you up as a programmer</description><pubDate>Mon, 02 Mar 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I&apos;m not sure when I first learned about &quot;cyclomatic complexity&quot;. It&apos;s such an academic term that you can practically smell a classroom or library when you read or hear it. If I had understood the concept earlier in my career, I don&apos;t think I would have given it much thought.&lt;/p&gt;
&lt;p&gt;&quot;I&apos;ve got buttons to put on these web pages. Who cares about cycles? What the heck is a cycle anyways?!&quot; a younger, more naive Kyle may have exclaimed.&lt;/p&gt;
&lt;p&gt;I don&apos;t think that way anymore. In fact, I have been thinking about cyclomatic complexity almost daily for a little over six months. Over this time, I&apos;ve developed some thoughts and ideas on the topic that I want to share with you in this post. By the end, I hope I will have convinced you of the importance of cyclomatic complexity in writing maintainable applications.&lt;/p&gt;
&lt;p&gt;To get started, I have a simple question for you. How many logical paths are there through the following function? I assure you, it&apos;s not a trick question.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function double(num) {
  return num * 2
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I hope you came up with the answer &lt;strong&gt;one&lt;/strong&gt;. There is only one logical path through the function. We give it an input, we get an output.&lt;/p&gt;
&lt;p&gt;What if we add a conditional inside of the function? Let&apos;s use a well known function in mathematics for this example. How many logical paths are there in this function?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function collatz(num) {
  if (num % 2 === 0) {
    return num / 2
  }

  return 3 * num + 1
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Again, not a trick question, the answer is &lt;strong&gt;two&lt;/strong&gt;. There are two paths through this function. Either a number is an even number and we return the first branch, or a number is odd and we return the second branch.&lt;/p&gt;
&lt;p&gt;Another way to describe this function is that it takes 2 cycles through it to touch every logical branch of the program. These cycles are how we get the term &quot;cyclomatic&quot;. The more cycles, the greater the complexity.&lt;/p&gt;
&lt;p&gt;&amp;lt;Image
invertable
alt=&quot;A program with 2 branches&quot;
src=&quot;/images/complexity/two-cycles.jpg&quot;
/&amp;gt;&lt;/p&gt;
&lt;p&gt;Let&apos;s take a look at a far more complex example. This is known as the &quot;Gilded Rose&quot; kata &amp;lt;Marker content=&quot;A &quot;kata&quot; is a martial arts training exercise. It has been co-opted to describe coding exercises. It&apos;s probably why we can&apos;t get rid of the term &quot;coding ninjas.&quot;&quot; /&amp;gt;. You can Google it and find solutions to it all over &amp;lt;Marker content=&quot;And I recommend you do. I think it would be a good use of your time&quot; /&amp;gt;. I was once given a take home exercise that was basically this kata adjusted for items the company worked with. It looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class Item {
  constructor(name, sellIn, quality) {
    this.name = name
    this.sellIn = sellIn
    this.quality = quality
  }
}

class GildedRose {
  constructor() {
    this.items = []
  }

  addItem(item) {
    this.items.push(item)
  }

  updateQuality() {
    const { items } = this

    for (var i = 0; i &amp;lt; items.length; i++) {
      if (
        &apos;Aged Brie&apos; != items[i].name &amp;amp;&amp;amp;
        &apos;Backstage passes to a TAFKAL80ETC concert&apos; != items[i].name
      ) {
        if (items[i].quality &amp;gt; 0) {
          if (&apos;Sulfuras, Hand of Ragnaros&apos; != items[i].name) {
            items[i].quality = items[i].quality - 1
          }
        }
      } else {
        if (items[i].quality &amp;lt; 50) {
          items[i].quality = items[i].quality + 1
          if (&apos;Aged Brie&apos; == items[i].name) {
            if (items[i].sellIn &amp;lt; 6) {
              items[i].quality = items[i].quality + 1
            }
          }
          if (&apos;Aged Brie&apos; == items[i].name) {
            if (items[i].sellIn &amp;lt; 11) {
              items[i].quality = items[i].quality + 1
            }
          }
          if (&apos;Backstage passes to a TAFKAL80ETC concert&apos; == items[i].name) {
            if (items[i].sellIn &amp;lt; 11) {
              if (items[i].quality &amp;lt; 50) {
                items[i].quality = items[i].quality + 1
              }
            }
            if (items[i].sellIn &amp;lt; 6) {
              if (items[i].quality &amp;lt; 50) {
                items[i].quality = items[i].quality + 1
              }
            }
          }
        }
      }
      if (&apos;Sulfuras, Hand of Ragnaros&apos; != items[i].name) {
        items[i].sellIn = items[i].sellIn - 1
      }
      if (items[i].sellIn &amp;lt; 0) {
        if (&apos;Aged Brie&apos; != items[i].name) {
          if (&apos;Backstage passes to a TAFKAL80ETC concert&apos; != items[i].name) {
            if (items[i].quality &amp;gt; 0) {
              if (&apos;Sulfuras, Hand of Ragnaros&apos; != items[i].name) {
                items[i].quality = items[i].quality - 1
              }
            }
          } else {
            items[i].quality = items[i].quality - items[i].quality
          }
        } else {
          if (items[i].quality &amp;lt; 50) {
            items[i].quality = items[i].quality + 1
          }
          if (&apos;Aged Brie&apos; == items[i].name &amp;amp;&amp;amp; items[i].sellIn &amp;lt;= 0)
            items[i].quality = 0
        }
      }
      if (&apos;Sulfuras, Hand of Ragnaros&apos; != items[i].name)
        if (items[i].quality &amp;gt; 50) items[i].quality = 50
    }
    return items
  }
}

const rose = new GildedRose()

rose.addItem(new Item(&apos;+5 Dexterity Vest&apos;, 10, 20))
rose.addItem(new Item(&apos;Aged Brie&apos;, 2, 0))
rose.addItem(new Item(&apos;Elixir of the Mongoose&apos;, 5, 7))
rose.addItem(new Item(&apos;Sulfuras, Hand of Ragnaros&apos;, 0, 80))
rose.addItem(new Item(&apos;Backstage passes to a TAFKAL80ETC concert&apos;, 15, 20))
rose.addItem(new Item(&apos;Conjured Mana Cake&apos;, 3, 6))

rose.updateQuality()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Want to hazard a guess how many cycles the &lt;code&gt;updateQuality&lt;/code&gt; method has?&lt;/p&gt;
&lt;p&gt;I&apos;ll wait.&lt;/p&gt;
&lt;p&gt;Got it yet?&lt;/p&gt;
&lt;p&gt;It&apos;s 25! It takes 25 cycles to cover every branch of this function.&lt;/p&gt;
&lt;p&gt;For the record, it wasn&apos;t my amazing brain &amp;lt;Marker content=&quot;It&apos;s not that amazing.&quot; /&amp;gt; that could read that code and know the answer was 25. I used &lt;a href=&quot;https://jshint.com&quot;&gt;JSHint&lt;/a&gt; in the browser to check it out. Another good option would be to use the &lt;code&gt;complexity&lt;/code&gt; rule from &lt;a href=&quot;https://eslint.org/docs/rules/complexity&quot;&gt;ESLint&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I hope it just dawned on you that this also means you have to write 25 tests to have confident coverage regarding &lt;code&gt;updateQuality&lt;/code&gt;. A method this complex &lt;em&gt;demands&lt;/em&gt; good tests.&lt;/p&gt;
&lt;p&gt;Now, I don&apos;t plan to solve this problem for you in the rest of this post. In fact, I recommend watching &lt;a href=&quot;https://www.youtube.com/watch?v=8bZh5LMaSmE&quot;&gt;this video from Sandi Metz that covers the subject&lt;/a&gt;. Rather, I want to explore how I think about handling complexity in situations like these.&lt;/p&gt;
&lt;h3&gt;How Complexity Exists in A Program&lt;/h3&gt;
&lt;p&gt;Before we learn how to deal with complexity, we must first learn some truths about complexity. I&apos;m going to work through a bit of a metaphor here. I&apos;m not sure it will land with everyone, but I hope it helps some of you understand &quot;complexity&quot; in a new way.&lt;/p&gt;
&lt;p&gt;First, I want to be clear, that I am not describing subjective complexity. This is not about what programming style you prefer, or your preference for &lt;code&gt;for&lt;/code&gt; loops instead of &lt;code&gt;forEach&lt;/code&gt;. This is about an objective measurement of complexity in an application. &amp;lt;Marker content=&quot;The formula for calculating cyclomatic complexity is &amp;lt;code&amp;gt;E - N + 2P&amp;lt;/code&amp;gt;, where &amp;lt;code&amp;gt;E&amp;lt;/code&amp;gt; represents the edges of a control flow graph, &amp;lt;code&amp;gt;N&amp;lt;/code&amp;gt; the nodes of the graph, and &amp;lt;code&amp;gt;P&amp;lt;/code&amp;gt; the number of connected components of the graph. I don&apos;t want people to fixate on the formula in this conversation, so I encourage you to Google it and read more on your own. There is plenty of material out there.&quot; /&amp;gt;&lt;/p&gt;
&lt;p&gt;Every program has a minimum level of overall complexity that is required to exist. That is, without removing features from the program, it will have an aggregate complexity score of &lt;code&gt;X&lt;/code&gt;, where &lt;code&gt;X&lt;/code&gt; represents the minimum complexity required to accomplish that program. Let&apos;s imagine a program, as a collection of nodes.&lt;/p&gt;
&lt;p&gt;&amp;lt;Image
invertable
alt=&quot;A collection of nodes&quot;
src=&quot;/images/complexity/nodes.jpg&quot;
/&amp;gt;&lt;/p&gt;
&lt;p&gt;Now, we cannot reduce &lt;code&gt;X&lt;/code&gt; without changing the observable behavior of the program. If our program has even &lt;code&gt;X - 1&lt;/code&gt; nodes, it will not be the same program anymore. However, we are allowed to group the nodes of &lt;code&gt;X&lt;/code&gt; (these would typically be functions, classes, modules, etc.). &lt;em&gt;How&lt;/em&gt; we group them matters.&lt;/p&gt;
&lt;p&gt;We might group them in two big groups where the average complexity of our groups is very high.&lt;/p&gt;
&lt;p&gt;&amp;lt;Image
invertable
alt=&quot;Same collection of nodes in 2 groups&quot;
src=&quot;/images/complexity/2-large-groups.jpg&quot;
/&amp;gt;&lt;/p&gt;
&lt;p&gt;We also might group our nodes in many small groups, where the average complexity of those groups is very low.&lt;/p&gt;
&lt;p&gt;&amp;lt;Image
invertable
alt=&quot;Same collection of nodes in many small groups&quot;
src=&quot;/images/complexity/many-groups.jpg&quot;
/&amp;gt;&lt;/p&gt;
&lt;p&gt;Regardless of how we group the nodes of our program, the overall number of nodes, and therefore the overall complexity of the system, remains as the value &lt;code&gt;X&lt;/code&gt;. What &lt;em&gt;does&lt;/em&gt; change is the &lt;strong&gt;average complexity per group&lt;/strong&gt;. Understanding this is the starting point to managing complexity more purposefully in our programs.&lt;/p&gt;
&lt;h3&gt;In General, Aim for Low Complexity Per Group&lt;/h3&gt;
&lt;p&gt;The first thing we can recognize when managing complexity is that, in general, code with low complexity is easier to understand than code with high complexity. The first few examples I shared, the &lt;code&gt;double&lt;/code&gt; and &lt;code&gt;collatz&lt;/code&gt; functions are quite easy to understand. The Gilded Rose, however, is an almost impenetrable bit of code. I imagine some of the functions in your codebases look even worse (admit it).&lt;/p&gt;
&lt;p&gt;Functions with a low score are not only easy to understand, but are easier to test. Sometimes, they are so easy to understand you may not bother with a test at all (not that I advocate for that, but I understand the impulse). These low complexity scores also mean that whenever we need to make an adjustment to one of the groups, it is relatively easy to do so. Update a test, make some changes, and you&apos;re good to go. This gives us a lot of confidence in our programs.&lt;/p&gt;
&lt;p&gt;But I say &quot;in general&quot; on purpose. There are a few scenarios where it may make sense to allow a high level of complexity to exist in a particular group.&lt;/p&gt;
&lt;h3&gt;The Exception: Encapsulated Complexity&lt;/h3&gt;
&lt;p&gt;Since we cannot change the overall complexity of a program, we need to be aware of how we manage complexity in &quot;groups&quot; of our program. There &lt;em&gt;will&lt;/em&gt; come times where it may make sense to allow a particular &quot;group&quot; a high level of complexity.&lt;/p&gt;
&lt;p&gt;So what makes a good candidate for making an exception?&lt;/p&gt;
&lt;p&gt;I think the most common reason to allow a part of a program to have a high level of complexity is when there is a single conditional that has many results. Most often, this is a &lt;code&gt;switch&lt;/code&gt; case or something similar. The structure of that part of the program might look like this:&lt;/p&gt;
&lt;p&gt;&amp;lt;Image
invertable
alt=&quot;A program with a single input, single condition, and many outputs&quot;
src=&quot;/images/complexity/many-cycles.jpg&quot;
/&amp;gt;&lt;/p&gt;
&lt;p&gt;The reason this makes sense is that the condition and mapping to appropriate results has to happen &lt;em&gt;somewhere&lt;/em&gt; in our program. It might as well be in an &lt;em&gt;isolated&lt;/em&gt; and &lt;em&gt;encapsulated&lt;/em&gt; place. That place should often be a well named (and tested) function that only handles a single part of our program.&lt;/p&gt;
&lt;p&gt;The encapsulation of the complexity is key here. Remember, we cannot change &lt;code&gt;X&lt;/code&gt; (the overall complexity) and have the same program. We know we must have this complexity somewhere, but by grouping it like this, we reduce exposure of the &lt;em&gt;internal&lt;/em&gt; complexity to rest of our program. We essentially make a contract with ourselves and anyone who may work on this code in the future, &quot;We have contained the complexity, do not let it leak out.&quot;&lt;/p&gt;
&lt;p&gt;The most common example I can think of in modern web development would be a state reducer, &lt;em&gt;a la&lt;/em&gt; Redux or the &lt;code&gt;useReducer&lt;/code&gt; hook. For those who are not sure what a state reducer is, a state reducer is a function that accepts a &lt;code&gt;state&lt;/code&gt; and an &lt;code&gt;action&lt;/code&gt; argument and returns the &lt;code&gt;nextState&lt;/code&gt;. The &lt;code&gt;action&lt;/code&gt;s passed to this reducer might be of &lt;em&gt;many&lt;/em&gt; different types, and each must be accounted for. This results in a function that has a single condition (what &lt;code&gt;type&lt;/code&gt; of &lt;code&gt;action&lt;/code&gt; is this?), but many possible results. Breaking this apart might only make the program more difficult to use or reason about. Capturing it in a single function makes the most sense, even if the complexity score might be very high.&lt;/p&gt;
&lt;h3&gt;An Example From My Work&lt;/h3&gt;
&lt;p&gt;A few months ago, I came across a bit of code that had a high level of complexity for a single group. I&apos;m going to share the change I made, and hopefully you&apos;ll agree that it was the right way to manage the complexity.&lt;/p&gt;
&lt;p&gt;The code that follows is adapted from the Webflow codebase. Webflow&apos;s architecture involves a lot of &quot;nodes&quot; and these nodes contain various types of information that need to be validated, cleaned up, and transformed. At one particular point during those transformations, I found code that looks somewhat like this: &amp;lt;Marker content=&quot;This is not the exact code. It is similar to what it was. It no longer exists in the Webflow codebase so there&apos;s no need to snoop around the clientside bundle for it.&quot; /&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// This code uses ImmutableJS Maps, not standard JS Maps
// hence the method `update()` and more.
nodes.update(&apos;dynamicData&apos;, Immutable.Map(), dynamicData =&amp;gt; {
  const bindableData = dynamicData
    .get(&apos;bindable&apos;, Immutable.Map())
    .update(cleanUpBindings(bindingDep1, bindingDep2))

  if (bindableData.size &amp;gt; 0) {
    dynamicData = dynamicData.set(&apos;bindable&apos;, bindableData)
  } else {
    const originalBindings = dynamicData.get(&apos;bindable&apos;)

    dynamicData =
      originalBindings &amp;amp;&amp;amp; originalBindings.size === 0
        ? dynamicData
        : dynamicData.delete(&apos;bindable&apos;)
  }

  const conditionalData = dynamicData
    .get(&apos;conditions&apos;, Immutable.Map())
    .update(cleanUpConditions(conditionalDep1, conditionalDep2))

  dynamicData =
    conditionalData.size &amp;gt; 0
      ? dynamicData.set(&apos;conditions&apos;, conditionalData)
      : dynamicData.delete(&apos;conditions&apos;)

  const filterableData = dynamicData
    .get(&apos;filterable&apos;, Immutable.Map())
    .update(cleanUpFilters(filterDep1, filterDep2))

  if (filterableData.size &amp;gt; 0) {
    dynamicData = dynamicData.set(&apos;filterable&apos;, filterableData)
  } else {
    const originalFilter = dynamicData.get(&apos;filterable&apos;)
    dynamicData =
      originalFilter &amp;amp;&amp;amp; originalFilter.size === 0
        ? dynamicData
        : dynamicData.delete(&apos;filterable&apos;)
  }

  const sortableData = List()
    .concat(dynamicData.get(&apos;sortable&apos;, List()))
    .update(cleanUpSort(sortableDep1, sortableDep2))

  if (sortableData.size &amp;gt; 0) {
    dynamicData = dynamicData.set(&apos;sortable&apos;, sortableData)
  } else {
    dynamicData = dynamicData.delete(&apos;sortable&apos;)
  }

  return dynamicData
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There&apos;s a lot going on in this function, and I don&apos;t expect it to make a ton of sense right away. Let me try and break it down a little bit. This function receives a piece of data, &lt;code&gt;dynamicData&lt;/code&gt;, and mutates it as necessary based on which conditionals are met along the way. That&apos;s pretty standard for programming.&lt;/p&gt;
&lt;p&gt;The complexity score isn&apos;t terribly high, it&apos;s only a &lt;code&gt;7&lt;/code&gt;, but the code is still more difficult to reason about than necessary and has too many responsibilities. We can make this better. With some changes, this bit of code will be easier to understand and update in the future, while also reducing the average complexity per group.&lt;/p&gt;
&lt;p&gt;First, we need to identify what the groups are in this code. It turns out there are four distinct groups in this bit of code: one that updates the bindings, one that updates the conditions, one that updates the filters, and finally one that updates the sorts. Here they are as separate code blocks:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Bindings
const bindableData = dynamicData
  .get(&apos;bindable&apos;, Immutable.Map())
  .update(cleanUpBindings(bindingDep1, bindingDep2))

if (bindableData.size &amp;gt; 0) {
  dynamicData = dynamicData.set(&apos;bindable&apos;, bindableData)
} else {
  const originalBindings = dynamicData.get(&apos;bindable&apos;)

  dynamicData =
    originalBindings &amp;amp;&amp;amp; originalBindings.size === 0
      ? dynamicData
      : dynamicData.delete(&apos;bindable&apos;)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Conditions
const conditionalData = dynamicData
  .get(&apos;conditions&apos;, Immutable.Map())
  .update(cleanUpConditions(conditionalDep1, conditionalDep2))

dynamicData =
  conditionalData.size &amp;gt; 0
    ? dynamicData.set(&apos;conditions&apos;, conditionalData)
    : dynamicData.delete(&apos;conditions&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Filters
const filterableData = dynamicData
  .get(&apos;filterable&apos;, Immutable.Map())
  .update(cleanUpFilters(filterableDep1, filterableDep2))

if (filterableData.size &amp;gt; 0) {
  dynamicData = dynamicData.set(&apos;filterable&apos;, filterableData)
} else {
  const originalFilter = dynamicData.get(&apos;filterable&apos;)

  dynamicData =
    originalFilter &amp;amp;&amp;amp; originalFilter.size === 0
      ? dynamicData
      : dynamicData.delete(&apos;filterable&apos;)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// Sorts
const sortableData = List()
  .concat(dynamicData.get(&apos;sortable&apos;, Immutable.List()))
  .update(cleanUpSort(sortableDep1, sortableDep2))

if (sortableData.size &amp;gt; 0) {
  dynamicData = dynamicData.set(&apos;sortable&apos;, sortableData)
} else {
  dynamicData = dynamicData.delete(&apos;sortable&apos;)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If we pay attention, we can see that each of these groups takes &lt;code&gt;dynamicData&lt;/code&gt; and conditionally updates it. We can turn each of these groups into their own function that receives &lt;code&gt;dynamicData&lt;/code&gt; as an argument, and returns the transformed data. We need to gather all the other data necessary for each function, but that isn&apos;t too hard. Those functions look like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const updateBindings =
  ({ bindingDep1, bindingDep2 }) =&amp;gt;
  dynamicData =&amp;gt; {
    const bindableData = dynamicData
      .get(&apos;bindable&apos;, Immutable.Map())
      .update(cleanUpBindings(bindingDep1, bindingDep2))

    if (bindableData.size &amp;gt; 0) {
      return dynamicData.set(&apos;bindable&apos;, bindableData)
    } else {
      const originalData = dynamicData.get(&apos;bindable&apos;)

      return originalData &amp;amp;&amp;amp; originalData.size === 0
        ? dynamicData
        : dynamicData.delete(&apos;bindable&apos;)
    }
  }

const updateConditions =
  ({ conditionalDep1, conditionalDep2 }) =&amp;gt;
  dynamicData =&amp;gt; {
    const conditionalData = dynamicData
      .get(&apos;conditions&apos;, Immutable.Map())
      .update(cleanUpConditions(conditionalDep1, conditionalDep2))

    return conditionalData.size &amp;gt; 0
      ? dynamicData.set(&apos;conditions&apos;, conditionalData)
      : dynamicData.delete(&apos;conditions&apos;)
  }

const updateFilters =
  ({ filterableDep1, filterableDep2 }) =&amp;gt;
  dynamicData =&amp;gt; {
    const filterableData = dynamicData
      .get(&apos;filterable&apos;, Immutable.Map())
      .update(cleanUpFilters(filterableDep1, filterableDep2))

    if (filterableData.length) {
      return dynamicData.set(&apos;filterable&apos;, filterableData)
    } else {
      const originalData = dynamicData.get(&apos;filterable&apos;)

      return originalData &amp;amp;&amp;amp; originalData.size === 0
        ? dynamicData
        : dynamicData.delete(&apos;filterable&apos;)
    }
  }

const updateSorts =
  ({ sortableDep1, sortableDep2 }) =&amp;gt;
  dynamicData =&amp;gt; {
    const sortableData = dynamicData
      .get(&apos;sortable&apos;)
      .update(cleanUpSort(sortableDep1, sortableDep2))

    return sortableData.size &amp;gt; 0
      ? dynamicData.set(&apos;sortable&apos;, sortableData)
      : dynamicData.delete(&apos;sortable&apos;)
  }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now each function is an isolated bit of complexity. You might be wondering why each of these functions is a curried function (You can learn more about &lt;a href=&quot;/just-enough-fp-currying&quot;&gt;curried functions here&lt;/a&gt;). Currying these functions allows me to do two things.&lt;/p&gt;
&lt;p&gt;First, it allows me to supply all the extra arguments necessary to do the computation ahead of time. These are held in closure for the next function accepting &lt;code&gt;dynamicData&lt;/code&gt; as an argument.&lt;/p&gt;
&lt;p&gt;Second, it allows me to create a composition of these functions. Because the returned function from each updater here has the same signature (and returns the same signature), I can compose them together. I&apos;ve written about &lt;a href=&quot;/just-enough-fp-composition&quot;&gt;composition here&lt;/a&gt; and I encourage you to read that post. I will actually use the &lt;code&gt;pipe&lt;/code&gt; function for this example, so that we maintain left-to-right, top-to-bottom data flow through our composition. Our new update looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;nodes.update(&apos;dynamicData&apos;, Immutable.Map(), dynamicData =&amp;gt; {
  // These aren&apos;t the real arguments, just useful for the examples
  return pipe(
    updateBindings({
      bindingDep1,
      bindingDep2,
    }),
    updateConditions({
      conditionalDep1,
      conditionalDep2,
    }),
    updateFilters({
      filterableDep1,
      filterableDep2,
    }),
    updateSorts({
      sortableDep1,
      sortableDep2,
    }),
  )(dynamicData)
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;How much simpler is that bit of code? It even reads more like English because of how we&apos;ve named our functions. I need to make an update to the data. It will be piped through these four functions, each of which has a fairly low level of complexity, and return the result.&lt;/p&gt;
&lt;p&gt;We have not changed the overall complexity. It remained constant as it must, but we &lt;em&gt;have changed&lt;/em&gt; the average complexity per function to &lt;code&gt;1.5&lt;/code&gt;. That is significantly lower than a complexity score of &lt;code&gt;7&lt;/code&gt;. I&apos;m biased because I wrote the code, but I think this is objectively better to work with as well. What do you think?&lt;/p&gt;
&lt;h3&gt;Takeaway&lt;/h3&gt;
&lt;p&gt;Paying attention to cyclomatic complexity can be a game changer in your programming career. It can take you from being the kind of person that writes code that works (which is awesome), to writing code that is easier for you and others to make changes to (which is awesomer). Recognizing complexity and developing strategies for managing it are important for creating maintainable and reasonable programs.&lt;/p&gt;
&lt;p&gt;Remember, we can&apos;t change the overall complexity of a program without changing what the program is. &amp;lt;Marker content=&quot;Sometimes removing code &amp;lt;em&amp;gt;is&amp;lt;/em&amp;gt; the answer to complexity; just know it won&apos;t be the same program.&quot; /&amp;gt; Try to keep average complexity per group low. Many functions, classes, modules with low complexity is &lt;em&gt;often&lt;/em&gt; (but not always) easier to manage. Encapsulate high levels of complexity where necessary as an exception.&lt;/p&gt;
</content:encoded><category>Data Structures and Algorithms</category><category>Computer Science</category></item><item><title>Recursive React Components</title><link>https://kyleshevlin.com/recursive-react-components/</link><guid isPermaLink="true">https://kyleshevlin.com/recursive-react-components/</guid><description>React components are _just_ functions. We can use the same patterns on components that we do on other functions, including recursion. Let&apos;s make some recursive components.</description><pubDate>Thu, 20 Feb 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import BetterStyledTree from &apos;./_BetterStyledTree&apos;
import StyledTree from &apos;./_StyledTree&apos;
import UnstyledTree from &apos;./_UnstyledTree&apos;&lt;/p&gt;
&lt;p&gt;It can be easy to forget that React components are &lt;em&gt;just&lt;/em&gt; functions. They receive inputs, they give us an output, and they might trigger some side effects in the process. Because they are simply functions, we can use patterns with them that we use with other functions. Like &lt;strong&gt;recursion&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;What is recursion?&lt;/h3&gt;
&lt;p&gt;Recursion is the pattern of a function calling itself. A very common example of a recursive function is calculating a &lt;em&gt;factorial&lt;/em&gt; of a number. &amp;lt;Marker content=&quot;A factorial is a positive number multiplied by every number between itself and 1. So &amp;lt;code&amp;gt;6!&amp;lt;/code&amp;gt; is &amp;lt;code&amp;gt;6 * 5 * 4 * 3 * 2 * 1&amp;lt;/code&amp;gt;.&quot; /&amp;gt; Consider the following function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function factorial(number) {
  // This is the base case. I&apos;ll explain this shortly
  if (number &amp;lt;= 1) {
    return 1
  }

  return number * factorial(number - 1)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Our function receives a number to factorialize, but rather than use an iterative loop, such as a &lt;code&gt;for&lt;/code&gt; or &lt;code&gt;while&lt;/code&gt; loop, we take advantage of the fact that we can calculate the final result by utilizing the results of calling &lt;code&gt;factorial&lt;/code&gt; on smaller numbers. That is, we recognize the pattern:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;factorial(4) === 4 * factorial(3)
factorial(3) === 3 * factorial(2)
factorial(2) === 2 * factorial(1)
factorial(1) === 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If we take this list of equal values and reverse the order of the functions we see called, we can derive the function call stack of &lt;code&gt;factorial(4)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;factorial(4)&lt;/code&gt; leads to &lt;code&gt;factorial(3)&lt;/code&gt; getting called, which leads to &lt;code&gt;factorial(2)&lt;/code&gt; getting called, which leads to &lt;code&gt;factorial(1)&lt;/code&gt; getting called, which returns the value of &lt;code&gt;1&lt;/code&gt;, which is fed back into &lt;code&gt;factorial(2)&lt;/code&gt; which returns the value of &lt;code&gt;2&lt;/code&gt;, which is fed back into &lt;code&gt;factorial(3)&lt;/code&gt; which returns the value of &lt;code&gt;6&lt;/code&gt;, which is fed back into &lt;code&gt;factorial(4)&lt;/code&gt;, which returns the value of &lt;code&gt;24&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Easy, right?! &amp;lt;Marker content=&quot;It is. It just takes practice.&quot; /&amp;gt;&lt;/p&gt;
&lt;h3&gt;Base Cases&lt;/h3&gt;
&lt;p&gt;Consider for a moment if we commented out the following bit of code from our &lt;code&gt;factorial&lt;/code&gt; function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function factorial(number) {
  // if (number &amp;lt;= 1) {
  //   return 1
  // }

  return number * factorial(number - 1)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What would happen? Well, we&apos;d never get an answer. We&apos;d never get a call to &lt;code&gt;factorial&lt;/code&gt; that returned a value. We would continue to add &lt;code&gt;factorial&lt;/code&gt; calls to the call stack until we exceeded the maximum number of calls allowed on the stack. We would have a &quot;stack overflow&quot; (and yes, that is where the name comes from).&lt;/p&gt;
&lt;p&gt;Every recursive function needs to have a &lt;strong&gt;base case&lt;/strong&gt; that ends the recursion. In the case of &lt;code&gt;factorial&lt;/code&gt;, it&apos;s when we have a number less than or equal to 1 passed in for &lt;code&gt;number&lt;/code&gt;. This base case ends the chain of recursive calls, and starts the process of returning values up the stack to get the final result.&lt;/p&gt;
&lt;h3&gt;Recursion applied to components&lt;/h3&gt;
&lt;p&gt;Now that we understand recursive functions, let&apos;s apply this knowledge to components. A recursive component is a component that renders itself as one of its children. Let me give you an example.&lt;/p&gt;
&lt;p&gt;Consider a directory of folders. It might look something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;src
  |- css
  |- js
    |- utils
    |- components
public
  |- images
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;How can we represent this as data to pass to a recursive component? Pretty simply actually, we can use a &lt;strong&gt;tree&lt;/strong&gt;. A tree is a graph data structure where each child node has a single parent. For example, the HTML structure of a website is a tree. No element on a page has more than one parent (all they way up to the &lt;code&gt;&amp;lt;html&amp;gt;&lt;/code&gt; tag). We can make a tree structure for our &lt;code&gt;folders&lt;/code&gt; like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const folders = [
  { name: &apos;src&apos;, children: [
    { name: &apos;css&apos;, children: [] }
    { name: &apos;js&apos;, children: [
      { name: &apos;utils&apos;, children: [] },
      { name: &apos;components&apos;, children: [] }
    ]}
  ]},
  { name: &apos;public&apos;, children: [
    { name: &apos;images&apos;, children: [] }
  ]}
]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We have a top level of folders, and folders nested up those are on a &lt;code&gt;children&lt;/code&gt; property. Now that we have our data, how do we make use of it in a recursive component?&lt;/p&gt;
&lt;p&gt;Similar to how we recognized that &lt;code&gt;factorial&lt;/code&gt; can be solved by using the result of &lt;code&gt;factorial&lt;/code&gt; called on smaller numbers, we can recognize that a tree is the result of combining smaller trees. &amp;lt;Marker content=&quot;One might think of it as a fractal.&quot; /&amp;gt; Understanding this, we can make a &lt;code&gt;Tree&lt;/code&gt; component that will call itself to render smaller &lt;code&gt;Tree&lt;/code&gt;s.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function Tree({ items }) {
  // our base case, if we have no items, render nothing.
  if (!items || !items.length) {
    return null
  }

  return items.map(item =&amp;gt; (
    &amp;lt;React.Fragment key={item.name}&amp;gt;
      &amp;lt;div&amp;gt;{item.name}&amp;lt;/div&amp;gt;
      {/* And here&apos;s the recursion! */}
      &amp;lt;Tree items={item.children} /&amp;gt;
    &amp;lt;/React.Fragment&amp;gt;
  ))
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If we were to pass the folder data we created earlier to the component, that will look like this:&lt;/p&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;UnstyledTree
items={[
{
name: &apos;src&apos;,
children: [
{ name: &apos;css&apos;, children: [] },
{
name: &apos;js&apos;,
children: [
{ name: &apos;utils&apos;, children: [] },
{ name: &apos;components&apos;, children: [] },
],
},
],
},
{ name: &apos;public&apos;, children: [{ name: &apos;images&apos;, children: [] }] },
]}
/&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Wait!&lt;/strong&gt; That&apos;s not what we want to represent. That&apos;s just a flat list. What happened?&lt;/p&gt;
&lt;p&gt;Well, we forgot to style it. Let&apos;s track the &lt;code&gt;depth&lt;/code&gt; of the folder with each level and update the &lt;code&gt;padding-left&lt;/code&gt; CSS property accordingly.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// We add a `depth` property with a default value of 0
// That way we don&apos;t have to pass it to the top level of the tree
function Tree({ items, depth = 0 }) {
  if (!items || !items.length) {
    return null
  }

  return items.map(item =&amp;gt; (
    &amp;lt;React.Fragment key={item.name}&amp;gt;
      {/* Multiply the depth by a constant to create consistent spacing */}
      &amp;lt;div style={{ paddingLeft: depth * 15 }}&amp;gt;{item.name}&amp;lt;/div&amp;gt;
      &amp;lt;Tree items={item.children} depth={depth + 1} /&amp;gt;
    &amp;lt;/React.Fragment&amp;gt;
  ))
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice how simple it is to increment the &lt;code&gt;depth&lt;/code&gt; prop with recursion. Each layer deeper we go in the tree, the value is increased by 1. Let&apos;s take a look at our recursive component now:&lt;/p&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;StyledTree
items={[
{
name: &apos;src&apos;,
children: [
{ name: &apos;css&apos;, children: [] },
{
name: &apos;js&apos;,
children: [
{ name: &apos;utils&apos;, children: [] },
{ name: &apos;components&apos;, children: [] },
],
},
],
},
{ name: &apos;public&apos;, children: [{ name: &apos;images&apos;, children: [] }] },
]}
/&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;p&gt;That looks a bit more like the folder structure we all know and love. Let&apos;s add a few more touches to make it a bit nicer.&lt;/p&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;BetterStyledTree
items={[
{
name: &apos;src&apos;,
children: [
{ name: &apos;css&apos;, children: [] },
{
name: &apos;js&apos;,
children: [
{ name: &apos;utils&apos;, children: [] },
{ name: &apos;components&apos;, children: [] },
],
},
],
},
{ name: &apos;public&apos;, children: [{ name: &apos;images&apos;, children: [] }] },
]}
/&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
&lt;p&gt;That&apos;s starting to look like something you could use in a real UI. A little interactivity, displaying of files, and we&apos;d really have something.&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;I encourage you to get comfortable with recursion. It doesn&apos;t have to be scary. Often, it&apos;s the simplest and most elegant solution to a problem. Who knows, it might even help you pass a job interview one day. Don&apos;t be afraid to experiment with it in your React work, you may discover some interesting UIs because of it.&lt;/p&gt;
</content:encoded><category>React</category><category>Computer Science</category><category>Data Structures and Algorithms</category></item><item><title>Enumerate, Don&apos;t Booleanate</title><link>https://kyleshevlin.com/enumerate-dont-booleanate/</link><guid isPermaLink="true">https://kyleshevlin.com/enumerate-dont-booleanate/</guid><description>We learn how to use booleans early and often, but they are not the right tool for the job sometimes. A enum may solve our problems with greater precision.</description><pubDate>Sat, 25 Jan 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I want to teach you something that&apos;s taken me a few years to learn and a lot of trial and error. I could teach it to you in a couple tweets, but I want to take you on a bit of a journey instead. I want to show a problem, and show you different ways I would attempt to solve it as I go from &quot;naive Kyle&quot; (who am I kidding, I&apos;m probably still naive Kyle) to &quot;knows better Kyle&quot;.&lt;/p&gt;
&lt;p&gt;Let&apos;s imagine me just a few years back. I show up to work one morning and my project manager has a request for me.&lt;/p&gt;
&lt;p&gt;&quot;Kyle, our customers want donuts and they want them fast. They want a simple form that&apos;ll deliver them directly to their door. We already have their address. We only need them to select how many they want. Can you build this?&quot;&lt;/p&gt;
&lt;p&gt;&quot;Of course I can!&quot;&lt;/p&gt;
&lt;p&gt;I would head off to my work station and start building a form just as fast as I could and probably come up with something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import React from &apos;react&apos;

export default function DonutForm() {
  const [quantity, setQuantity] = React.useState(0)
  const [isSuccess, setSuccess] = React.useState(false)

  const handleSubmit = e =&amp;gt; {
    e.preventDefault()

    sendOrder({ quantity }).then(response =&amp;gt; {
      console.log(response)
      setSuccess(true)
    })
  }

  const handleChange = e =&amp;gt; {
    setQuantity(Number(e.target.value))
  }

  const reset = () =&amp;gt; {
    setQuantity(0)
    setSuccess(false)
  }

  return (
    &amp;lt;div className=&quot;donut_form-wrap&quot;&amp;gt;
      {isSuccess ? (
        &amp;lt;&amp;gt;
          &amp;lt;div&amp;gt;Donuts are on their way!&amp;lt;/div&amp;gt;
          &amp;lt;button type=&quot;button&quot; onClick={reset}&amp;gt;
            Reset
          &amp;lt;/button&amp;gt;
        &amp;lt;/&amp;gt;
      ) : (
        &amp;lt;form onSubmit={handleSubmit}&amp;gt;
          &amp;lt;h4&amp;gt;Get Yummy Donuts!&amp;lt;/h4&amp;gt;

          &amp;lt;div&amp;gt;
            &amp;lt;label htmlFor=&quot;donutFormQuantity&quot;&amp;gt;Quantity&amp;lt;/label&amp;gt;
            &amp;lt;input
              id=&quot;donutFormQuantity&quot;
              min={0}
              name=&quot;donutFormQuantity&quot;
              onChange={handleChange}
              step={1}
              type=&quot;number&quot;
              value={quantity}
            /&amp;gt;
          &amp;lt;/div&amp;gt;

          &amp;lt;button type=&quot;submit&quot;&amp;gt;Order&amp;lt;/button&amp;gt;
        &amp;lt;/form&amp;gt;
      )}
    &amp;lt;/div&amp;gt;
  )
}

function inflect(singular, plural, value) {
  return value === 1 ? singular : plural
}

// Pretend this is an API call that orders the donuts
function sendOrder({ quantity }) {
  return new Promise(resolve =&amp;gt; {
    setTimeout(() =&amp;gt; {
      resolve(`Ordered ${quantity} ${inflect(&apos;donut&apos;, &apos;donuts&apos;, quantity)}!`)
    }, 2000)
  })
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can see a running example of this code at: &lt;a href=&quot;https://codesandbox.io/s/hopeful-ritchie-lk7cs&quot;&gt;https://codesandbox.io/s/hopeful-ritchie-lk7cs&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Disregarding the anachronism that React existed when I started my career (let alone Hooks), this form is pretty decent. Naive Kyle even managed to think of &lt;code&gt;isSuccess&lt;/code&gt;, a bit of state that will tell the user that they successfully ordered their donuts. However, as often happens with projects, the scope wasn&apos;t fully defined or something important was forgotten. The project manager comes back to me,&lt;/p&gt;
&lt;p&gt;&quot;Kyle, that&apos;s great, but you forgot that sometimes the API is going to fail. As scary as it might be to tell people who want donuts that their donuts aren&apos;t on the way just yet, we gotta do it. We had one customer, Dinah, who tried to order some donuts, but didn&apos;t know that the order had failed. She just sat there, waiting for them to be delivered, until she shriveled up and died of donut starvation. Tragic, I know. We can&apos;t lose customers like that. Can you handle errors for us?&quot;&lt;/p&gt;
&lt;p&gt;&quot;Woah! Of course, I can!&quot;&lt;/p&gt;
&lt;p&gt;So back to the code we go to add some error handling. What&apos;s the first thing we do? Well, we add another bit of state to the component, of course:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const [quantity, setQuantity] = React.useState(0)
const [isSuccess, setSuccess] = React.useState(false)
const [error, setError] = React.useState(null)
//...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ok, we&apos;ve added a way to track the error. Great, now we need a way to set it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//...
const handleSubmit = e =&amp;gt; {
  e.preventDefault()

  if (error) {
    setError(null)
  }

  sendOrder({ quantity })
    .then(response =&amp;gt; {
      console.log(response)
      setSuccess(true)
    })
    .catch(err =&amp;gt; {
      setError(err)
      setSuccess(false) // just to be sure!
    })
}
//...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Great, we&apos;re setting the error when the &lt;code&gt;sendOrder&lt;/code&gt; promise rejects &lt;em&gt;and&lt;/em&gt; we were thoughtful enough to clear any existing error when we try to submit the form. Just one last thing we have to add:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;error ? &amp;lt;div className=&quot;error_wrap&quot;&amp;gt;{error}&amp;lt;/div&amp;gt; : null
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Perfect, now we display the error to the user and we only had to add one bit of state (that even though it&apos;s not technically a boolean, we actually coerce into a boolean &lt;em&gt;twice&lt;/em&gt;). Slightly less naive Kyle is proud. You can see a running example of this code at: &lt;a href=&quot;https://codesandbox.io/s/vibrant-kirch-w67vx&quot;&gt;https://codesandbox.io/s/vibrant-kirch-w67vx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Slightly less naive Kyle&apos;s project manager sees our progress and comes back with, &quot;Kyle, that&apos;s amazing! But you forgot that the API call takes some actual &lt;em&gt;time&lt;/em&gt;. Because you forgot to disable the submit button while an order is pending, Methuselah over there was so impatient for some donuts that he smashed the submit button 18 times before the order went through. That&apos;s right! 18 baker&apos;s dozens showed up at his door! Being the donut fiend he is, Methuselah ate &lt;em&gt;all of them&lt;/em&gt;. He&apos;s in a coma now, poor guy. May never wake up from his body handling all those donuts. We&apos;ve lost one of our best customers. You need to fix this.&quot;&lt;/p&gt;
&lt;p&gt;&quot;Oh damn! I&apos;ll fix it right away&quot;&lt;/p&gt;
&lt;p&gt;So back to the code we go to disable the submit button while an order is pending. Let&apos;s add another bit of state to track whether we are submitting or not.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const [quantity, setQuantity] = React.useState(0)
const [isSuccess, setSuccess] = React.useState(false)
const [error, setError] = React.useState(null)
const [isSubmitting, setSubmitting] = React.useState(false)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Alright, so we need to couple this to the submit button, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;button disabled={isSubmitting} type=&quot;submit&quot;&amp;gt;
  Submit
&amp;lt;/button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And lastly, we need to update when we are or aren&apos;t submitting:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const handleSubmit = e =&amp;gt; {
  e.preventDefault()
  setSubmitting(true)

  if (error) {
    setError(null)
  }

  sendOrder({ quantity })
    .then(response =&amp;gt; {
      console.log(response)
      setSuccess(true)
      setSubmitting(false) // Do we really need this here? We&apos;ll be on the success screen. ¯\_(ツ)_/¯
    })
    .catch(err =&amp;gt; {
      setError(err)
      setSuccess(false) // just to be sure!
      setSubmitting(false)
    })
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Awesome. Our form now tracks when it&apos;s submitting and prevents the user from ordering more donuts than intended. Huzzah! It works. You can see a running example of this code at: &lt;a href=&quot;https://codesandbox.io/s/lucid-noyce-832f0&quot;&gt;https://codesandbox.io/s/lucid-noyce-832f0&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;But, at this point, we need to ask ourselves a question: would you really want to be the next developer to work on this form?&lt;/p&gt;
&lt;p&gt;I don&apos;t think I&apos;d want to be. The code is convoluted. We&apos;re setting states left and right. We even have some setters in places where we aren&apos;t even sure if we need them. Why? Because we&apos;re &quot;good&quot; programmers and we&apos;re trying to avoid a problem that we haven&apos;t even give a name to yet. We&apos;re trying to avoid getting our component into &lt;strong&gt;impossible states&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;It should be impossible to order donuts while we&apos;re ordering donuts already. It should be impossible that we show an error while we are showing the user that they have been successful. We&apos;ve done so by using a bunch of booleans (and treated other values like booleans) in order to achieve this, but our component has undergone a bit of boolean explosion.&lt;/p&gt;
&lt;p&gt;Boolean explosion is when, through the use of booleans, we have introduced more states than are actually possible in our program. For every boolean we add to a program, we are adding 2^n states (where &lt;em&gt;n&lt;/em&gt; is the number of booleans). Let&apos;s just iterate on that a few times.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1 boolean === 2 states&lt;/li&gt;
&lt;li&gt;2 booleans === 4 states&lt;/li&gt;
&lt;li&gt;3 booleans === 8 states&lt;/li&gt;
&lt;li&gt;4 booleans === 16 states&lt;/li&gt;
&lt;li&gt;5 booleans === 32 states...&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can see that the number of states starts to grow very quickly. But do you &lt;em&gt;actually&lt;/em&gt; have that many states in your program? Our form currently uses three booleans, but does it really have eight states? No, most of those states are impossible. For example, we cannot be in a state where &lt;code&gt;isSuccess&lt;/code&gt;, &lt;code&gt;error&lt;/code&gt;, and &lt;code&gt;isSubmitting&lt;/code&gt; all coerce to &lt;code&gt;true&lt;/code&gt;. It&apos;s impossible.&lt;/p&gt;
&lt;p&gt;So why do we even give our programs the &lt;em&gt;opportunity&lt;/em&gt; to be in states that are impossible?&lt;/p&gt;
&lt;p&gt;Because we don&apos;t &lt;em&gt;enumerate&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Enumeration, the act of identifying a set of &lt;em&gt;things&lt;/em&gt; one by one, is simple, but effective way to make our programs a bit more robust. Slightly more experienced Kyle can show you how.&lt;/p&gt;
&lt;p&gt;Given the same requirements, slightly more experienced Kyle realizes that there are really only a handful full of states that our form can ever be in. Let&apos;s enumerate those:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const DONUT_FORM_STATES = {
  idle: &apos;idle&apos;,
  submitting: &apos;submitting&apos;,
  success: &apos;success&apos;,
  failure: &apos;failure&apos;,
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Turns out, our form can only be in 4 states, not the 8 possible states suggested by our previous use of booleans. Now, let&apos;s track this state in our component.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function DonutForm() {
  const [quantity, setQuantity] = React.useState(0)
  const [current, setCurrent] = React.useState(DONUT_FORM_STATES.idle)
  //...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The next thing slightly more experienced Kyle realizes is that we can only &lt;em&gt;transition&lt;/em&gt; to certain states from particular other states. For example, we can never go straight from &lt;code&gt;idle&lt;/code&gt; to &lt;code&gt;success&lt;/code&gt;. We need to be in &lt;code&gt;submitting&lt;/code&gt; to go to &lt;code&gt;success&lt;/code&gt;. So not only have we enumerated the possible states, but we need to enumerate the possible transitions between those states, too.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const DONUT_FORM_TRANSITIONS = {
  [DONUT_FORM_STATES.idle]: {
    SUBMIT: DONUT_FORM_STATES.submitting,
  },
  [DONUT_FORM_STATES.submitting]: {
    SUCCEED: DONUT_FORM_STATES.success,
    FAIL: DONUT_FORM_STATES.failure,
  },
  [DONUT_FORM_STATES.success]: {
    RESET: DONUT_FORM_STATES.idle,
  },
  [DONUT_FORM_STATES.failure]: {
    SUBMIT: DONUT_FORM_STATES.submitting,
  },
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At first this might seem a bit confusing, but don&apos;t worry. We are using &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer&quot;&gt;computed property names&lt;/a&gt; to guarantee the values in our states enum are the keys of our transitions enum. We also want to ensure that our next state target is one of enumerated states. Lastly, we&apos;ve added objects with &quot;events&quot; (the uppercased key) to each state which strictly defines what events a state will even respond to. That means we can create a function that &lt;em&gt;guarantees&lt;/em&gt; we correctly get the next state, given the current state and an event. Like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const transition = (state, event) =&amp;gt; {
  const nextState = DONUT_FORM_TRANSITIONS[state][event]
  return nextState ? nextState : state
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We need to add one last thing to make all these pieces come into place. We need a way of sending events to our enumerated transitions and updating to the next state. We need to define a &lt;code&gt;send&lt;/code&gt; function inside our component that makes use of our &lt;code&gt;transition&lt;/code&gt; function, and updates the current state.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const send = event =&amp;gt; {
  setCurrent(currentState =&amp;gt; transition(currentState, event))
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With all of this in place, we&apos;re ready to make the most robust donut form you&apos;ve seen (so far in this blog post). We&apos;re going to add the important parts to the functions and markup inside this component.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//...
const handleSubmit = e =&amp;gt; {
  e.preventDefault()

  send(&apos;SUBMIT&apos;)

  sendOrder({ quantity })
    .then(response =&amp;gt; {
      console.log(response)
      send(&apos;SUCCEED&apos;)
    })
    .catch(err =&amp;gt; {
      send(&apos;FAIL&apos;)
    })
}
//...
const reset = () =&amp;gt; {
  send(&apos;RESET&apos;)
}
//..
return (
  &amp;lt;div className=&quot;donut_form-wrap&quot;&amp;gt;
    {current === DONUT_FORM_STATES.success ? (
      &amp;lt;&amp;gt;
        &amp;lt;div&amp;gt;Donuts are on their way!&amp;lt;/div&amp;gt;
        &amp;lt;button type=&quot;button&quot; onClick={reset}&amp;gt;
          Reset
        &amp;lt;/button&amp;gt;
      &amp;lt;/&amp;gt;
    ) : (
      &amp;lt;form onSubmit={handleSubmit}&amp;gt;
        &amp;lt;h4&amp;gt;Get Yummy Donuts!&amp;lt;/h4&amp;gt;

        {current === DONUT_FORM_STATES.failure ? (
          &amp;lt;div className=&quot;error_wrap&quot;&amp;gt;Failed to order donuts&amp;lt;/div&amp;gt;
        ) : null}

        &amp;lt;div&amp;gt;
          &amp;lt;label htmlFor=&quot;donutFormQuantity&quot;&amp;gt;Quantity&amp;lt;/label&amp;gt;
          &amp;lt;input
            id=&quot;donutFormQuantity&quot;
            min={0}
            name=&quot;donutFormQuantity&quot;
            onChange={handleChange}
            step={1}
            type=&quot;number&quot;
            value={quantity}
          /&amp;gt;
        &amp;lt;/div&amp;gt;

        &amp;lt;button
          disabled={current === DONUT_FORM_STATES.submitting}
          type=&quot;submit&quot;
        &amp;gt;
          Order
        &amp;lt;/button&amp;gt;
      &amp;lt;/form&amp;gt;
    )}
  &amp;lt;/div&amp;gt;
)
//...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can see a running example of this code at: &lt;a href=&quot;https://codesandbox.io/s/vibrant-jackson-vy7qi&quot;&gt;https://codesandbox.io/s/vibrant-jackson-vy7qi&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Notice how simple it is to &lt;code&gt;send&lt;/code&gt; events and trust that our component is in the correct state. We also have far fewer checks and guards than we did before. By eliminating the &lt;em&gt;existence&lt;/em&gt; of impossible states, we&apos;ve created a program we can have a lot of confidence in.&lt;/p&gt;
&lt;p&gt;But, at this point, we need to ask ourselves a question: would you really want to be the next developer to work on this form?&lt;/p&gt;
&lt;p&gt;If I&apos;m honest, I&apos;d be &lt;em&gt;alright&lt;/em&gt; if this was where we stopped, but I do see some maintenance challenges. While we&apos;ve made a huge step forward by &lt;strong&gt;enumerating, not booleanating&lt;/strong&gt;, we have two enums to keep in sync, and had to create several functions that could probably be gathered together into a nice library with a friendly API.&lt;/p&gt;
&lt;p&gt;What we&apos;ve created through the enums and a few functions is create an &lt;em&gt;ad hoc&lt;/em&gt; finite state machine. We have all the possible states of the system, all the possible transitions, and a way to safely transition from state to state. These are all the components of a good state machine library. So for one final step in this article, let&apos;s implement this same form with a popular state machine library, &lt;a href=&quot;https://xstate.js.org&quot;&gt;XState&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;With XState, knows-even-a-little-bit-better Kyle can create a state chart that combines our enums together, making it easier to keep them in sync. Let&apos;s start by making a new variable we will call &lt;code&gt;chart&lt;/code&gt;. &lt;code&gt;chart&lt;/code&gt; will only have 3 properties, &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;initial&lt;/code&gt; and &lt;code&gt;states&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const chart = {
  id: &apos;donutForm&apos;,
  initial: &apos;&apos;,
  states: {},
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;initial&lt;/code&gt; is the initial state of our machine. In our case, our form starts in the initial state of &lt;code&gt;idle&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const chart = {
  id: &apos;donutForm&apos;,
  initial: &apos;idle&apos;,
  states: {},
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, the &lt;code&gt;states&lt;/code&gt; object will be an enum that combines our previous states and transitions enums together. Let&apos;s start by adding just our individual states to this object.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const chart = {
  id: &apos;donutForm&apos;,
  initial: &apos;idle&apos;,
  states: {
    idle: {},
    submitting: {},
    success: {},
    failure: {},
  },
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, we&apos;re going to add our events and transitions on the object values of their corresponding state, underneath the &lt;code&gt;on&lt;/code&gt; property. This way our code reads &quot;When &lt;code&gt;idle&lt;/code&gt;, &lt;code&gt;on&lt;/code&gt; the &lt;code&gt;SUBMIT&lt;/code&gt; event, transition to &lt;code&gt;submitting&lt;/code&gt;&quot;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const chart = {
  id: &apos;donutForm&apos;,
  initial: &apos;idle&apos;,
  states: {
    idle: {
      on: { SUBMIT: &apos;submitting&apos; },
    },
    submitting: {
      on: {
        SUCCEED: &apos;success&apos;,
        FAIL: &apos;failure&apos;,
      },
    },
    success: {
      on: { RESET: &apos;idle&apos; },
    },
    failure: {
      on: { SUBMIT: &apos;submitting&apos; },
    },
  },
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, we&apos;re going to add a few libraries to our code that will let us use XState in our React component easily.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import React from &apos;react&apos;
import { Machine } from &apos;xstate&apos;
import { useMachine } from &apos;@xstate/react&apos;
//...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now that we&apos;ve imported the &lt;code&gt;Machine&lt;/code&gt; factory function, let&apos;s pass our state &lt;code&gt;chart&lt;/code&gt; to it.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const donutFormMachine = Machine(chart)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, let&apos;s bring that machine into our component with the &lt;code&gt;useMachine&lt;/code&gt; hook.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export default function DonutForm() {
  const [value, setValue] = React.useState(&apos;&apos;)
  const [current, send] = useMachine(donutFormMachine)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We no longer need the &lt;code&gt;transition&lt;/code&gt; function. It still exists, since it is a method on every &lt;code&gt;XState.Machine&lt;/code&gt;, but the &lt;code&gt;useMachine&lt;/code&gt; hook manages it for us. We also can get rid of our &lt;code&gt;send&lt;/code&gt; function and replace it directly with the &lt;code&gt;send&lt;/code&gt; function given to us by the custom hook.&lt;/p&gt;
&lt;p&gt;We only have one update left to make. &lt;code&gt;current&lt;/code&gt; now points to a state &lt;em&gt;object&lt;/em&gt;, not simply a string. We need to replace all of our uses of &lt;code&gt;current === &apos;some value&apos;&lt;/code&gt; with &lt;code&gt;current.matches(&apos;some value&apos;)&lt;/code&gt;. &lt;code&gt;matches&lt;/code&gt; is a method on state objects that takes a string or object that represents a state in the machine, and returns true or false if it matches. Our component ends up looking like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;return (
  &amp;lt;div className=&quot;donut_form-wrap&quot;&amp;gt;
    {current.matches(&apos;success&apos;) ? (
      &amp;lt;&amp;gt;
        &amp;lt;div&amp;gt;Donuts are on their way!&amp;lt;/div&amp;gt;
        &amp;lt;button type=&quot;button&quot; onClick={reset}&amp;gt;
          Reset
        &amp;lt;/button&amp;gt;
      &amp;lt;/&amp;gt;
    ) : (
      &amp;lt;form onSubmit={handleSubmit}&amp;gt;
        &amp;lt;h4&amp;gt;Get Yummy Donuts!&amp;lt;/h4&amp;gt;

        {current.matches(&apos;failure&apos;) ? (
          &amp;lt;div className=&quot;error_wrap&quot;&amp;gt;Failed to order donuts&amp;lt;/div&amp;gt;
        ) : null}

        &amp;lt;div&amp;gt;
          &amp;lt;label htmlFor=&quot;donutFormQuantity&quot;&amp;gt;Quantity&amp;lt;/label&amp;gt;
          &amp;lt;input
            id=&quot;donutFormQuantity&quot;
            min={0}
            name=&quot;donutFormQuantity&quot;
            onChange={handleChange}
            step={1}
            type=&quot;number&quot;
            value={quantity}
          /&amp;gt;
        &amp;lt;/div&amp;gt;

        &amp;lt;button disabled={current.matches(&apos;submitting&apos;)} type=&quot;submit&quot;&amp;gt;
          Order
        &amp;lt;/button&amp;gt;
      &amp;lt;/form&amp;gt;
    )}
  &amp;lt;/div&amp;gt;
)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can see a running example of this code at: &lt;a href=&quot;https://codesandbox.io/s/quirky-shtern-ef40n&quot;&gt;https://codesandbox.io/s/quirky-shtern-ef40n&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Now, this is a form I&apos;d be happy to come back to six months later and work on. Need to add some inputs? No problem. Need to add some states? No problem.&lt;/p&gt;
&lt;p&gt;By enumerating instead of booleanating, we were able to create a program that grows in complexity linearly, not exponentially. Each additional state only adds the complexity of one more state, rather than the boolean explosion of 2^n states. This alone, is enough to reduce vast amounts of complexity in our applications today.&lt;/p&gt;
&lt;p&gt;My hope is that you&apos;ll start to think differently about booleans. Really evaluate if they are the right tool for the job you are trying to accomplish. You might find creating a simple object enum is a better tool for the task at hand. Learn to reach for it more often. I&apos;m sure you&apos;ll find many uses of it. I know I have.&lt;/p&gt;
</content:encoded><category>React</category><category>State Machines</category></item><item><title>The Future of Second Career Devs</title><link>https://kyleshevlin.com/the-future-of-second-career-devs/</link><guid isPermaLink="true">https://kyleshevlin.com/the-future-of-second-career-devs/</guid><description>I started the Second Career Devs podcast in 2017 with a lot of excitement and hope. Let me tell you where my head is at now on the project</description><pubDate>Sat, 04 Jan 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;/p&gt;
&lt;p&gt;At the time of this post, it has been roughly seven and a half months since I released an episode of &lt;a href=&quot;https://secondcareerdevs.com&quot;&gt;Second Career Devs&lt;/a&gt;. I thought it was time to try and write down my thoughts regarding the future of SCD. I warn you, this is mostly a brain dump. It won&apos;t be very orderly. I&apos;m not going to spend a lot of time editing this post. I&apos;m just gonna spew words at my text editor and see what comes out.&lt;/p&gt;
&lt;p&gt;Before I started SCD, I knew I wanted to do &lt;em&gt;something&lt;/em&gt; that both got me some recognition and was useful to others. Vain, I know, but my father never said he was proud of me or that he loved me so I constantly seek the approval of others, yada yada yada. I don&apos;t have a lot of great app or OSS ideas that accomplish that need/goal, but I knew I could talk to people well and knew I had an angle to share with others. So I started SCD with no real plan, kind of like most of the things I do.&lt;/p&gt;
&lt;p&gt;In the beginning, running a podcast was new and interesting. I like new and shiny things (as I imagine many with ADHD do). It was so new and interesting that I wasn&apos;t really aware of what it was costing me in time, money and energy. As time went on, this would become painfully obvious.&lt;/p&gt;
&lt;p&gt;I think the first time it dawned on me that a podcast was more than I bargained for was when people asked for swag. I had no budget for swag.&lt;/p&gt;
&lt;p&gt;The next time was when people complained I didn&apos;t have an episode out when I said I would. I couldn&apos;t tell them that a guest flaked on me not once, not twice, not even thrice, but four times. That was really shitty.&lt;/p&gt;
&lt;p&gt;The next time was when someone more or less yelled at me publicly demanding to know when they would be a guest on the podcast. There was no sense of &quot;guests are invited&quot;, it was total entitlement, &quot;I added myself to your guestlist, so I demand to be on your podcast&quot;. Felt pretty shitty on that one, too.&lt;/p&gt;
&lt;p&gt;Then another time was when it dawned on me just how much time goes into making a &lt;em&gt;single&lt;/em&gt; episode. The act of finding a guest, scheduling the guest, recording the episode, editing, doing the admin to load the episode, update the website, etc, it amounts from 4-8 hours per episode, depending on how inefficient the process went. You can&apos;t shrink the time of recording, it takes what it takes. Editing takes at minimum the time it took to record. Scheduling is a nightmare. Everyone&apos;s always busy (including myself). If I were to try and put out an episode every week, we&apos;re talking between 200-400 hours of work in a year. That&apos;s 10-20% more work in my week. For what? Nothing. I make absolutely nothing from making a podcast.&lt;/p&gt;
&lt;p&gt;Ok, so I can remedy that with ads and sponsors, right? Except they&apos;re just as flaky as guests. Now I have to get real contracts together, come up with rates and invoices and budgets and on and on and on. And if I do that I might want to start an LLC and all of a sudden I&apos;m running a business I never planned on and that&apos;s more time and more energy being taken from me.&lt;/p&gt;
&lt;p&gt;But the money is good, right? Kind of. It was nice to ask for some money and get it, but I used most of the sponsor money I made to pay for transcripts. Every episode with a transcript costs $1/minute to get transcribed by the most affordable service I can find. I was very happy with their work, but now each episode costs me $45-$60. I&apos;m not complaining that accessibility costs money. I believe that making the podcast available to people is a good thing. It&apos;s simply a cost I never considered and didn&apos;t have a strategy to afford.&lt;/p&gt;
&lt;p&gt;&quot;What about Patreon, Kyle? What about donations to keep this going?&quot; Still more work, plus I&apos;m now begging for help &lt;em&gt;and&lt;/em&gt; now I&apos;m obligated to other people in a way I wasn&apos;t before. If someone makes a donation and I can&apos;t come up with a guest or the time or energy to finish a new episode, I&apos;ve now let them down, too.&lt;/p&gt;
&lt;p&gt;All of this, all of the crap &lt;em&gt;around&lt;/em&gt; just trying to have a conversation with someone with an interesting story, the part of the whole project I was &lt;em&gt;actually&lt;/em&gt; interested in, was a huge drain to me.&lt;/p&gt;
&lt;p&gt;You can ask my wife, I&apos;ve had very little energy for the last few years. I don&apos;t really want to hash out why my energy is low here, that&apos;s for another blog, but when you don&apos;t have a lot of excess energy and something isn&apos;t &lt;em&gt;giving&lt;/em&gt; you any back, you&apos;re just not inclined to work on it. And so, here we are, me not working on SCD.&lt;/p&gt;
&lt;p&gt;There was a time where I considered expanding SCD. I still think this is a good idea, but an SCD themed job board could be a real revenue maker. I even started the project once, but I found myself realizing that I don&apos;t want to beholden myself to this. I don&apos;t want it to be my job and that&apos;s what all this was becoming. I&apos;m not sure &lt;em&gt;what&lt;/em&gt; I want to be my job in the long run of my career, but I saw a future where I was trying to scrape a living out of running a podcast and a job board and I was not convinced that is what I wanted to do.&lt;/p&gt;
&lt;p&gt;So this is where my head is at. SCD is loved by a bunch of people. It&apos;s useful and is a good thing for the world. Awesome. All the work around it. Completely not awesome. People want more. I&apos;d love to give it to them, but the only part that interests me is the interviews and making the music for the ad spots and intro (yes, I made those all from scratch). I&apos;m also interested in making the job board, but only if I knew it wouldn&apos;t &lt;em&gt;have&lt;/em&gt; to be a full-time job. It could sustain itself after an initial effort. But I would rather not waste a second of my life on the other stuff at this rate.&lt;/p&gt;
&lt;p&gt;I can&apos;t afford to hire someone to do all the scheduling, do all the editing, and do all the administrative work around SCD and I don&apos;t have the plans to remedy this situation. I&apos;m not looking to add a part-time job to my life, and I&apos;m not looking to put in the work to secure ads, sponsors, and/or donations to get to a place to afford to hire the other help I need to keep SCD going forward.&lt;/p&gt;
&lt;p&gt;Which kind of leads me to an empasse. I would love for more stories to be out there, but I&apos;m not willing to make the time, energy and monetary commitment to make it happen (especially when other uses of those commitments reap much better financial rewards, like my egghead courses). I just don&apos;t really know what to do at this empasse. I don&apos;t want to let it just die, but it kind of already has. I&apos;ve honestly started to wonder what&apos;s the cheapest way I can keep the podcast hosted so at least the episodes remain available to everyone.&lt;/p&gt;
&lt;p&gt;I&apos;m going to stop spewing there. I know I&apos;m not being very linear, and possibly incoherent, but I needed to share what was on my heart. I still love what I was trying to do, I wish it could stay simple and cost nothing to do. It&apos;s hard to do something that costs you when you don&apos;t feel like you have ample resources to be generous in that way. I&apos;m sorry if I&apos;ve let you down, but at least now you might know where I am.&lt;/p&gt;
&lt;p&gt;If you want to respond to this post, feel free to send a tweet to &lt;a href=&quot;https://twitter.com/2ndCareerDevs&quot;&gt;@2ndCareerDevs&lt;/a&gt;. I would love to hear your responses. I do read them all, even if I&apos;m a bit slow to respond to them.&lt;/p&gt;
</content:encoded></item><item><title>How to Render an Object in React</title><link>https://kyleshevlin.com/how-to-render-an-object-in-react/</link><guid isPermaLink="true">https://kyleshevlin.com/how-to-render-an-object-in-react/</guid><description>Learn how to render an object in React by using JSON.stringify</description><pubDate>Fri, 27 Dec 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import Log from &apos;./_Log&apos;&lt;/p&gt;
&lt;p&gt;&amp;lt;EggheadEmbed
src=&quot;https://egghead.io/lessons/react-render-an-object-with-json-stringify-in-react/embed&quot;
title=&quot;Render an Object with JSON.stringify in React&quot;
/&amp;gt;&lt;/p&gt;
&lt;p&gt;The trick I&apos;m about to show you I learned so early on in my days of learning React that it didn&apos;t dawn on me that others still don&apos;t know it. My apologies, let&apos;s fix that right now.&lt;/p&gt;
&lt;p&gt;Have you ever made the mistake of trying to display an object in a React component?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const Component = ({ obj }) =&amp;gt; &amp;lt;div&amp;gt;{obj}&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And been met with this?&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Classic mistake. Don&apos;t worry, we&apos;ve all made it a time or two. We can&apos;t render an object, but we can render strings. What if we turn the object into a string and render it then?&lt;/p&gt;
&lt;p&gt;We can do that with &lt;code&gt;JSON.stringify&lt;/code&gt; (&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify&quot;&gt;docs&lt;/a&gt;). &lt;code&gt;JSON.stringify&lt;/code&gt; takes an object and turns it into a JSON string. We can make a component that does this for us.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// I encourage you to look at the JSON.stringify docs to understand the
// `replacer` and `space` arguments
const Log = ({ value, replacer = null, space = 2 }) =&amp;gt; (
  &amp;lt;pre&amp;gt;
    &amp;lt;code&amp;gt;{JSON.stringify(value, replacer, space)}&amp;lt;/code&amp;gt;
  &amp;lt;/pre&amp;gt;
)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can now use this component anywhere we would like to display an object in our app. This is very useful for debugging apps.&lt;/p&gt;
&lt;p&gt;&amp;lt;Log value={{ name: &apos;Kyle Shevlin&apos;, age: 34, location: &apos;Portland, OR&apos; }} /&amp;gt;&lt;/p&gt;
&lt;p&gt;Use this whenever you&apos;d like to display your object in the browser instead of looking at the object value in the console or the devtools.&lt;/p&gt;
</content:encoded><category>React</category></item><item><title>How to Add Algolia Search to a Gatsby Site</title><link>https://kyleshevlin.com/how-to-add-algolia-search-to-a-gatsby-site/</link><guid isPermaLink="true">https://kyleshevlin.com/how-to-add-algolia-search-to-a-gatsby-site/</guid><description>Learn how I added Algolia Search to my Gatsby site or blog. It was pretty easy and a lot of fun.</description><pubDate>Sun, 22 Sep 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;: In the time since writing this post, I have removed the search feature for my blog. Simply put, it was difficult to keep the number of searches below the free tier threshold every month. Instead, I now have a page with all posts that I&apos;m working on developing filtering and search for. Thanks.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;This weekend I shipped a new feature for my blog--search! Just have a look up and to the right. You should see it up there.&lt;/p&gt;
&lt;p&gt;Adding search was easier than I expected. I had almost no understanding of the work involved in making this happen, but between the Algolia service, their &lt;code&gt;react-instantsearch&lt;/code&gt; library, and a little help from Twitter, this was pretty simple to do. This post will walk you through all the steps it took to make that happen.&lt;/p&gt;
&lt;p&gt;Before I do, quick shout out to &lt;a href=&quot;https://twitter.com/ScottEnock&quot;&gt;Scott Enock&lt;/a&gt; for sending me an email requesting this feature. &amp;lt;Marker content=&quot;He said some nice things, too!&quot; /&amp;gt; I legit didn&apos;t know enough people were reading this blog to make it worth adding this feature. Thanks!&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Step One - Algolia Setup&lt;/h3&gt;
&lt;p&gt;First things first, you need to create an Algolia account to use their service. Head over to &lt;a href=&quot;https://www.algolia.com/users/sign_up&quot;&gt;https://www.algolia.com/users/sign_up&lt;/a&gt; and sign up. There are a few forms to fill out. Here&apos;s the break down of what you need to do for each form step.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Fill out your information&lt;/li&gt;
&lt;li&gt;Pick the data center closest to you geographically&lt;/li&gt;
&lt;li&gt;You probably want to choose &quot;Media - Content&quot; and &quot;As soon as possible&quot;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;After signing up, you get a 14 day free trial, but don&apos;t worry about that running out. You can upgrade your plan to their &quot;Community&quot; level, and it&apos;ll stay free (with some restrictions I&apos;ll talk about later).&lt;/p&gt;
&lt;p&gt;You&apos;ll be taken to a screen with a few options, but head to the &quot;Dashboard&quot; first. Once you do, you&apos;ll be prompted to &quot;Create an Index&quot;. Click that button and give it a good name. &amp;lt;Marker content=&quot;This form will inform you how to name indices for particular environments if that is something you require.&quot; /&amp;gt; You&apos;ll be prompted to &quot;Upload Records&quot;, but we are actually going to let Gatsby create those records for us in a later step. At this point, you need to grab 4 pieces of information to take to the next step.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The name you just gave your index&lt;/li&gt;
&lt;li&gt;Click &quot;API Keys&quot; in the left menu and get the following strings
&lt;ul&gt;
&lt;li&gt;Your App ID&lt;/li&gt;
&lt;li&gt;Your Search-Only API Key&lt;/li&gt;
&lt;li&gt;Your Admin API Key&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;Step Two - &lt;code&gt;gatsby-plugin-algolia&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;The next step in adding search to the blog is setting up the Algolia plugin for Gatsby. You can check out the repository &lt;a href=&quot;https://github.com/algolia/gatsby-plugin-algolia&quot;&gt;here&lt;/a&gt;. Get started by installing the package.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npm install gatsby-plugin-algolia
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Once installed, we need to do a few things to get the plugin fully configured. To start, we need to add some keys to our &lt;code&gt;.env&lt;/code&gt; files. It is likely that you have both an &lt;code&gt;.env.development&lt;/code&gt; and an &lt;code&gt;.env.production&lt;/code&gt; file in your Gatsby application. For the sake of this tutorial, I will have you copy your keys &lt;em&gt;identically into both files&lt;/em&gt;, but for your particular situation, it might make sense to setup separate Algolia indices for your &lt;code&gt;development&lt;/code&gt; and &lt;code&gt;production&lt;/code&gt; environments.&lt;/p&gt;
&lt;p&gt;Take the four strings I had you save from the previous step, and add them to both &lt;code&gt;.env.*&lt;/code&gt; files like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// .env.*

GATSBY_ALGOLIA_APP_ID=YOUR_ALGOLIA_APP_ID
GATSBY_ALGOLIA_INDEX_NAME=YOUR_INDEX_NAME
GATSBY_ALGOLIA_SEARCH_KEY=YOUR_ALGOLIA_SEARCH_KEY
GATSBY_ALGOLIA_ADMIN_KEY=YOUR_ALGOLIA_ADMIN_KEY
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now that we have our environment variables setup, we are going to need to be able to access them in &lt;code&gt;gatsby-config.js&lt;/code&gt;. Gatsby has a few special rules around how it injects various environment variables into your Gatsby builds. One of the rules requires that we inject our own variables into the &lt;code&gt;gatsby-config.js&lt;/code&gt; file, and this will require using the &lt;code&gt;dotenv&lt;/code&gt; package. Install this package.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npm install dotenv
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, we&apos;re going to require &lt;code&gt;dotenv&lt;/code&gt; in our &lt;code&gt;gatsby-config.js&lt;/code&gt; file to have access to our environment variables. Put the following code above your plugin setup in &lt;code&gt;gatsby-config.js&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// gatsby-config.js

require(&apos;dotenv&apos;).config({
  path: `.env.${process.env.NODE_ENV}`,
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now that we have access to our environment variables, let&apos;s setup the plugin. In your &lt;code&gt;plugins&lt;/code&gt; array, add a config object for &lt;code&gt;gatsby-plugin-algolia&lt;/code&gt;, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// We will define and import `queries` in the next step
// replacing this empty array.
const queries = []

module.exports = {
  plugins: [
    // You likely have other plugins here
    {
      resolve: &apos;gatsby-plugin-algolia&apos;,
      options: {
        appId: process.env.GATSBY_ALGOLIA_APP_ID,
        apiKey: process.env.GATSBY_ALGOLIA_ADMIN_KEY,
        indexName: process.env.GATSBY_ALGOLIA_INDEX_NAME,
        queries,
        chunkSize: 10000,
      },
    },
  ],
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At this point, our plugin is configured. However, we still need to create some &lt;code&gt;queries&lt;/code&gt; to be used by the plugin to create the Algolia index records (and UI to follow after that). So let&apos;s work on our &lt;code&gt;queries&lt;/code&gt; next.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Step Three - Creating our Record Queries&lt;/h3&gt;
&lt;p&gt;An Algolia index is made up of &lt;em&gt;records&lt;/em&gt;. In Gatsby, we create query objects that utilize GraphQL to get the data we send to Algolia to create these records. At this time, my blog only requires one query object, so I&apos;ll show you how I wrote that. Your specific needs might vary at this step in the process.&lt;/p&gt;
&lt;p&gt;I want to create a record for each one of my posts. To do this, I need to write a GraphQL query that returns an object of data for each post. I&apos;m going to do this in a separate file I&apos;ve named &lt;code&gt;algolia.js&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This file will export the &lt;code&gt;queries&lt;/code&gt; array to be used by our configuration in &lt;code&gt;gatsby-config.js&lt;/code&gt;, so I like to start my file with that, and then go back and fill in the rest of the logic.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// algolia.js
const queries = []

module.exports = queries
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And in &lt;code&gt;gatsby-config.js&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// gatsby-config.js

// replace the line `const queries = []` with the following,
// Make sure the path matches where you&apos;ve put your file
const queries = require(&apos;./src/utils/algolia&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now that our files are wired up, we need to provide at least one query object to our &lt;code&gt;queries&lt;/code&gt; array. This object will likely take at minimum two properties (though, you should read the documentation for your own specific needs). Those properties are the &lt;code&gt;query&lt;/code&gt; and &lt;code&gt;transformer&lt;/code&gt;. The value provided for the &lt;code&gt;query&lt;/code&gt; property is a GraphQL query string. The &lt;code&gt;transformer&lt;/code&gt; is a function that takes the data retrieved by the query and transforms it into the array of objects that will become your Algolia index records.&lt;/p&gt;
&lt;p&gt;My particular needs here are likely a bit different than yours. My blog explicitly uses Markdown and MDX files, but I can get all of the necessary files with one query to the &lt;code&gt;allMdx&lt;/code&gt; property in my GraphQL schema. Let me show you the pieces I wrote for my initial query:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// algolia.js

const mdxQuery = `
  allMdx(filter: {fileAbsolutePath: {regex: &quot;/posts/&quot;}}) {
    edges {
      node {
        excerpt
        frontmatter {
          description
          slug
          subtitle
          tags
          title
          keywords
        }
        rawBody
      }
    }
  }
}
`

const unnestFrontmatter = node =&amp;gt; {
  const { frontmatter, ...rest } = node

  return {
    ...frontmatter,
    ...rest,
  }
}

const queries = [
  {
    query: mdxQuery,
    transformer: ({ data }) =&amp;gt;
      data.allMdx.edges.map(edge =&amp;gt; edge.node).map(unnestFrontmatter),
  },
]

module.exports = queries
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;My &lt;code&gt;mdxQuery&lt;/code&gt; retrieves all the published posts. &amp;lt;Marker content=&quot;I may add queries for my courses in the future.&quot; /&amp;gt; Then my &lt;code&gt;transformer&lt;/code&gt; method takes the data received and massages it into a shape I can use for my Algolia records by lifting the keys of the &lt;code&gt;frontmatter&lt;/code&gt; object up to the same level as the rest of the &lt;code&gt;node&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Again, your exact query will probably look different than mine. You can tweak your query using the Graphiql explorer that Gatsby has integrated.&lt;/p&gt;
&lt;p&gt;As of right now, we are at a place where we can get some records into your Algolia index. The way I managed to do this was to run a production build of my Gatsby site, which triggered the plugin to generate the records.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npm run build
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If everything worked, you should see in the build output evidence indicating that records were added to your Algolia index. You can now head to your Algolia dashboard, click the &quot;Indices&quot; link in the menu, and see that your index now has records.&lt;/p&gt;
&lt;p&gt;We&apos;re going to revisit this file later on in the tutorial to improve our query.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Step Four - Create a Search UI&lt;/h3&gt;
&lt;p&gt;To create the UI for our search, we&apos;re going to make use of two more packages from Algolia: the &lt;code&gt;algoliasearch&lt;/code&gt; SDK and the &lt;code&gt;react-instantsearch-dom&lt;/code&gt; set of components that go with it. As you might expect by now, let&apos;s install them both:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npm install algoliasearch react-instantsearch-dom
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, before we dive into the UI, please note that you might make very different decisions than I did when making your UI. I chose to put my search in a modal that takes up the full screen. I did this because it allowed the user to always have access to search regardless of what page they were on, without needing to navigate else where. It is possible that in the future, my UI might change. Since our UIs might be very different, I want to first show you the minimum example that you need, and then explain what I did with my UI.&lt;/p&gt;
&lt;p&gt;I have made a new component file, &lt;code&gt;Search.js&lt;/code&gt;, and the minimal example would look like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Search.js

import React from &apos;react&apos;
import algoliasearch from &apos;algoliasearch/lite&apos;
import { InstantSearch, SearchBox, Hits } from &apos;react-instantsearch-dom&apos;

const searchClient = algoliasearch(
  process.env.GATSBY_ALGOLIA_APP_ID,
  process.env.GATSBY_ALGOLIA_SEARCH_KEY
)

export default function Search() {
  return (
    &amp;lt;InstantSearch
      indexName={process.env.GATSBY_ALGOLIA_INDEX_NAME}
      searchClient={searchClient}
    &amp;gt;
      &amp;lt;SearchBox /&amp;gt;
      &amp;lt;Hits /&amp;gt;
    &amp;lt;/InstantSearch&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This minimal example follows the documentation of the package, but also makes use of our &lt;code&gt;env&lt;/code&gt; variables to wire things up correctly. If you import this somewhere in your app, you should be able to do searches on your Algolia index now.&lt;/p&gt;
&lt;p&gt;All the components in &lt;code&gt;react-instantsearch&lt;/code&gt; work together as &quot;compound components&quot;. That is, used in the right way, each component receives the data it needs to render properly &lt;em&gt;under the hood&lt;/em&gt;. You don&apos;t have to do any wiring yourself. However, you might not be completely satisfied with the UI this gives you. I wasn&apos;t. That&apos;s ok, there are options.&lt;/p&gt;
&lt;p&gt;If you are using traditional CSS, you might be able to make all the customizations you need just by updating a stylesheet. Use the inspector (or look at the docs) to find the class names Algolia provides each of these components, and then write styles accordingly.&lt;/p&gt;
&lt;p&gt;In my case, I&apos;m using &lt;a href=&quot;https://github.com/emotion-js/emotion&quot;&gt;&lt;code&gt;emotion&lt;/code&gt;&lt;/a&gt; for my styles, specifically the wonderful &lt;code&gt;css&lt;/code&gt; prop (which I should totally blog about sometime). Lucky for me &lt;code&gt;react-instantsearch&lt;/code&gt; also provides higher order components that allow you to create your own UI, which means combining it with &lt;code&gt;emotion&lt;/code&gt; is no big deal.&lt;/p&gt;
&lt;p&gt;In my case, I specifically customized the &lt;code&gt;Searchbox&lt;/code&gt;, &lt;code&gt;Hits&lt;/code&gt; and &lt;code&gt;Pagination&lt;/code&gt; components of my UI. I&apos;m going to focus on the customized &lt;code&gt;Hits&lt;/code&gt; in this article, you can view the other customizations at &lt;a href=&quot;https://github.com/kyleshevlin/blog/blob/master/src/components/Search.js&quot;&gt;https://github.com/kyleshevlin/blog/blob/master/src/components/Search.js&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;Hits&lt;/code&gt; are the individual results of your query. In my case, I just want a simple list of results running down the page, but with my styles. To do this, I&apos;ll use the &lt;code&gt;connectHits&lt;/code&gt; higher order component provided, and then provide it a component that makes use of the &lt;code&gt;hits&lt;/code&gt; prop it provides.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Search.js

import React from &apos;react&apos;
import algoliasearch from &apos;algoliasearch/lite&apos;
import { connectHits, InstantSearch, SearchBox } from &apos;react-instantsearch-dom&apos;
import { FONTS } from &apos;../constants&apos; // an object of the font family strings in my app
import { bs } from &apos;../shevy&apos; // a helper function for spacing from my vertical rhythm library

const searchClient = algoliasearch(
  process.env.GATSBY_ALGOLIA_APP_ID,
  process.env.GATSBY_ALGOLIA_SEARCH_KEY
)

// Please note, that to get the `css` prop to work, you&apos;ll either
// need to add a jsx pragma or use a babel plugin. Consult the
// Emotion documentation for setting that up for your project.
const Hits = connectHits(({ hits }) =&amp;gt; (
  &amp;lt;div css={{ display: &apos;flex&apos;, flexWrap: &apos;wrap&apos; }}&amp;gt;
    {/* Always use a ternary when coercing an array length */}
    {/* otherwise you might print out &quot;0&quot; to your UI */}
    {hits.length ? (
      &amp;lt;&amp;gt;
        {/* I wanted to give a little explanation of the search here */}
        &amp;lt;div
          css={{
            fontFamily: FONTS.catamaran,
            fontSize: &apos;.85rem&apos;,
            fontStyle: &apos;italic&apos;,
            marginBottom: bs(1),
            maxWidth: &apos;30rem&apos;,
          }}
        &amp;gt;
          These are the results of your search. The title and excerpt are
          displayed, though your search may have been found in the content of
          the post as well.
        &amp;lt;/div&amp;gt;

        {/* Here is the crux of the component */}
        {hits.map(hit =&amp;gt; {
          return (
            &amp;lt;div css={{ marginBottom: bs(1) }} key={hit.objectID}&amp;gt;
              &amp;lt;Link
                css={{ display: &apos;block&apos;, marginBottom: bs(0.5) }}
                to={hit.slug}
              &amp;gt;
                &amp;lt;h4 css={{ marginBottom: 0 }}&amp;gt;
                  &amp;lt;Highlight attribute=&quot;title&quot; hit={hit} tagName=&quot;strong&quot; /&amp;gt;
                &amp;lt;/h4&amp;gt;
                {hit.subtitle ? (
                  &amp;lt;h5 css={{ marginBottom: 0 }}&amp;gt;
                    &amp;lt;Highlight
                      attribute=&quot;subtitle&quot;
                      hit={hit}
                      tagName=&quot;strong&quot;
                    /&amp;gt;
                  &amp;lt;/h5&amp;gt;
                ) : null}
              &amp;lt;/Link&amp;gt;
              &amp;lt;div&amp;gt;
                &amp;lt;Highlight attribute=&quot;excerpt&quot; hit={hit} tagName=&quot;strong&quot; /&amp;gt;
              &amp;lt;/div&amp;gt;
            &amp;lt;/div&amp;gt;
          )
        })}
      &amp;lt;/&amp;gt;
    ) : (
      &amp;lt;p&amp;gt;There were no results for your query. Please try again.&amp;lt;/p&amp;gt;
    )}
  &amp;lt;/div&amp;gt;
))

export default function Search() {
  return (
    &amp;lt;InstantSearch
      indexName={process.env.GATSBY_ALGOLIA_INDEX_NAME}
      searchClient={searchClient}
    &amp;gt;
      &amp;lt;SearchBox /&amp;gt;
      &amp;lt;Hits /&amp;gt;
    &amp;lt;/InstantSearch&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With the higher order component, I&apos;ve been able to use the markup I prefer and style it in a way that fits my blog. Explore the docs and the other higher order components to get the results you&apos;re looking for.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Optional Step Five - Optimize Your Record Size&lt;/h3&gt;
&lt;p&gt;At this point, you should have fully functioning search working on your Gatsby site. Congratulations!&lt;/p&gt;
&lt;p&gt;That said, if you&apos;re like me and adding search to a blog with many long posts, you may have run into an issue while creating your index--some of your records are &lt;strong&gt;too big&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;I have a few lengthy posts that were breaking the allowable size limit for Algolia&apos;s &quot;Community&quot; plan. Luckily, the people over at Algolia have already thought about this and have written this handy post about handling long documents: &lt;a href=&quot;https://www.algolia.com/doc/guides/sending-and-managing-data/prepare-your-data/how-to/indexing-long-documents/&quot;&gt;https://www.algolia.com/doc/guides/sending-and-managing-data/prepare-your-data/how-to/indexing-long-documents/&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Here&apos;s the TL;DR; If your records are too big, we need to divide the content of those records into smaller pieces and index those instead. How you do this is up to you and your specific data, but for a blog, a good place to start might be every paragraph (seriously). We aren&apos;t concerned with how big the index is, just the size of the records. At the start of this process I only had 77 records. By the end, I had over 1.7K records! Let me show you how I did it.&lt;/p&gt;
&lt;p&gt;Reopen the &lt;code&gt;algolia.js&lt;/code&gt; file from before, we&apos;re going to make some modifications to it. The culprit of my large records is the &lt;code&gt;rawBody&lt;/code&gt; data I&apos;m getting from my query. This contains all the text in the body of my blog post. Thus, a long post means a big record. We need to manipulate this data in a way to reduce its size.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// algolia.js

// `mdxQuery` and `unnestfrontmatter` are the same as before
// so scroll up to take a look at them

// I&apos;m defining a function that will map over our data nodes
// We&apos;re going to return an array of record objects
const handleRawBody = node =&amp;gt; {
  // We want to split `rawBody` from the node
  const { rawBody, ...rest } = node

  // To improve search with smaller record sizes, we will divide all
  // blog posts into sections (essentially by paragraph).

  // Since the body of my posts is markdown, we will split
  // whereever there are two adjacent new lines, this is a
  // reasonable proxy for paragraphs
  const sections = rawBody.split(&apos;\n\n&apos;)

  // Now, we&apos;re goint to map over each section, returning
  // an object that contains all the frontmatter and excerpt,
  // but only has the specific content on that key.
  // This way the results are still associated with the
  // correct post.
  const records = sections.map(section =&amp;gt; ({
    ...rest,
    content: section,
  }))

  return records
}

const queries = [
  {
    query: mdxQuery,
    transformer: ({ data }) =&amp;gt;
      data.allMdx.edges
        .map(edge =&amp;gt; edge.node)
        .map(unnestFrontmatter)
        // Now we take rawBody and manipulate it into many more records
        .map(handleRawBody)
        // And we flatten those records into a single array
        // alternatively, flatMap is available wherever ES2019 is implemented
        .reduce((acc, cur) =&amp;gt; [...acc, ...cur], []),
  },
]

module.exports = queries
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, our index has lots of tiny records which is exactly what Algolia wants. Also, each record still contains all the necessary data for our search UI to render. There is one final problem though.&lt;/p&gt;
&lt;p&gt;If I were to do a search at this moment, say for the word &apos;React&apos;, I&apos;ll get results that show the same article over and over again because I use the &lt;code&gt;tag&lt;/code&gt; React for my record objects. This isn&apos;t good. We need a way to dedupe the records. Luckily again, Algolia has thought of this.&lt;/p&gt;
&lt;p&gt;We just need to update two places in our app to make this happen. First, we&apos;ll make a small update to the query object in &lt;code&gt;algolia.js&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// algolia.js

// mdxQuery, unnestFrontmatter and handleRawBody are all the same as before

const queries = [
  {
    query: mdxQuery,
    // Here&apos;s the change
    settings: {
      attributeForDistinct: &apos;slug&apos;,
      distinct: true,
    },
    transformer: ({ data }) =&amp;gt;
      data.allMdx.edges
        .map(edge =&amp;gt; edge.node)
        .map(unnestFrontmatter)
        .map(handleRawBody)
        .reduce((acc, cur) =&amp;gt; [...acc, ...cur], []),
  },
]

module.exports = queries
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the &lt;code&gt;settings&lt;/code&gt; object of our query, we are telling Algolia that we want distinct results and that they should be recognized as distinct by their &lt;code&gt;slug&lt;/code&gt; property (which is unique to each post).&lt;/p&gt;
&lt;p&gt;Now, we need to inform our UI that we only want distinct results. In our &lt;code&gt;Search&lt;/code&gt; component, we need to add the &lt;code&gt;Configure&lt;/code&gt; component. Since I don&apos;t want to show &lt;em&gt;all&lt;/em&gt; my customizations (the code block would be quite long), I&apos;ll take the minimal version and add the &lt;code&gt;Configure&lt;/code&gt; component to that. Make adjustments as you need to for your situation.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Search.js

import React from &apos;react&apos;
import algoliasearch from &apos;algoliasearch/lite&apos;
import {
  Configure,
  InstantSearch,
  SearchBox,
  Hits,
} from &apos;react-instantsearch-dom&apos;

const searchClient = algoliasearch(
  process.env.GATSBY_ALGOLIA_APP_ID,
  process.env.GATSBY_ALGOLIA_SEARCH_KEY
)

export default function Search() {
  return (
    &amp;lt;InstantSearch
      indexName={process.env.GATSBY_ALGOLIA_INDEX_NAME}
      searchClient={searchClient}
    &amp;gt;
      {/* Here&apos;s the change */}
      &amp;lt;Configure distinct /&amp;gt;
      &amp;lt;SearchBox /&amp;gt;
      &amp;lt;Hits /&amp;gt;
    &amp;lt;/InstantSearch&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Seriously, that is all it took. Adding the &lt;code&gt;distinct&lt;/code&gt; prop to our &lt;code&gt;Configure&lt;/code&gt; component, and now my results return only one &lt;code&gt;hit&lt;/code&gt; instead of many duplicates. I owe some props to &lt;a href=&quot;https://twitter.com/haroenv&quot;&gt;Haroen&lt;/a&gt; who helped me out over the weekend to figure this last bit out.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;And that&apos;s it! We&apos;re done. We got search working on a Gatsby blog (and you can apply this to any Gatsby site). To recap, the steps are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Setup Algolia&lt;/li&gt;
&lt;li&gt;Configure &lt;code&gt;gatsby-plugin-algolia&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Create queries to get and set your records&lt;/li&gt;
&lt;li&gt;Create a UI with &lt;code&gt;react-instantsearch-dom&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;And optionally, optimize your records&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I hope you find this process as relatively painless as I did. If you&apos;re confused, be sure to check the documentation. If you&apos;re looking for additional resources, I recommend checking out this video from my friend &lt;a href=&quot;https://twitter.com/jlengstorf&quot;&gt;Jason Lengstorf&lt;/a&gt; on his YouTube channel about this very same topic: &lt;a href=&quot;https://www.youtube.com/watch?v=VSkXyuXzwlc&quot;&gt;Add Algolia search to your Gatsby site (with Bram Adams) — Learn With Jason&lt;/a&gt;. I know I found parts of the video helpful in this process.&lt;/p&gt;
&lt;p&gt;This tutorial is still not &lt;em&gt;exhaustive&lt;/em&gt;, but I hope it&apos;s a big help to what you&apos;re trying to accomplish. Hit me up on Twitter if you have any questions I can help with regarding the post!&lt;/p&gt;
</content:encoded><category>Gatsby</category><category>React</category></item><item><title>Graphs Are Everywhere</title><link>https://kyleshevlin.com/graphs-are-everywhere/</link><guid isPermaLink="true">https://kyleshevlin.com/graphs-are-everywhere/</guid><description>A graph data structure is a useful way to model many things in the real world. Take a look at data visualizations that show this.</description><pubDate>Fri, 06 Sep 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import DirectedGraph from &apos;./_DirectedGraph&apos;&lt;/p&gt;
&lt;p&gt;A few years ago, I was interviewing for a new job and it was the first time I was asked to whiteboard algorithms. It did not go well. In fact, &lt;strong&gt;I got my ass handed to me&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;I was not prepared. With no formal education in computer science, and just a couple years of writing mostly HTML templating and CSS, I didn&apos;t have the skills to pass those tests. Motivated by that failure, I began learning some some basic computer science knowledge in the forms of data structures and algorithms. That education lead to my &lt;a href=&quot;https://egghead.io/courses/data-structures-and-algorithms-in-javascript/?af=8u8eik&quot;&gt;Intro to Data Structures and Algorithms course&lt;/a&gt; on &lt;a href=&quot;https://egghead.io/?af=8u8eik&quot;&gt;egghead.io&lt;/a&gt;. Gaining this knowledge, it changed the way I see things in the world.&lt;/p&gt;
&lt;p&gt;One of the data structures I find most interesting is the &lt;a href=&quot;https://en.wikipedia.org/wiki/Graph_(abstract_data_type)&quot;&gt;graph&lt;/a&gt;. A graph is a collection of nodes (also known as vertices) and edges (also known as links or lines) that connect those nodes. One specific type of graph is the directed graph. The edges of a directed graph convey &lt;em&gt;direction&lt;/em&gt;; that is, it is not enough to show nodes are connected, but (and not to personify nodes too much) &lt;em&gt;from&lt;/em&gt; who &lt;em&gt;to&lt;/em&gt; whom. Each connection has a &lt;em&gt;source&lt;/em&gt; and a &lt;em&gt;target&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;When I gained an understanding of directed graphs, I began to realize that &lt;strong&gt;graphs are everywhere&lt;/strong&gt;. The world is full of them. I experience real life graphs the most when observing the relationships of people. I want to share some of those observations with you. Consider this an incomplete, haphazard online art exhibition of directed graphs in the real world.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;The first graph in this gallery I title &lt;em&gt;Mutuality&lt;/em&gt;. It is the graph that forms when two nodes are connected to each other in a reciprocating fashion. A cycle formed back and forth between the two. I want to point out that the graph implies no connotation of positive or negative relationship. A mutual relationship can be one of respect, love, or attraction, but it can easily be one of resentment, disdain, and hatred as well.&lt;/p&gt;
&lt;p&gt;&amp;lt;DirectedGraph
client:only=&quot;react&quot;
caption=&quot;Mutuality&quot;
data={{
nodes: [{ id: 1 }, { id: 2 }],
links: [
{ source: 1, target: 2 },
{ source: 2, target: 1 },
],
}}
/&amp;gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;The next graph in this gallery I title &lt;em&gt;Admiration&lt;/em&gt;. I find that I typically admire others for something I find lacking in myself. For example, I admire people with the courage to start their own businesses, as I find that I&apos;m more risk-averse than I would like to be. But the ones I admire &lt;em&gt;also&lt;/em&gt; admire others for traits they are lacking in, and so on and so forth. A cycle of admiration forms where everyone is looking at someone else for something they don&apos;t currently have.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Admiration&lt;/em&gt; is an admittedly positive take on this graph. It could just as easily devolve into &lt;em&gt;Envy&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&amp;lt;DirectedGraph
client:only=&quot;react&quot;
caption=&quot;Admiration&quot;
data={{
nodes: [{ id: 1 }, { id: 2 }, { id: 3 }],
links: [
{ source: 1, target: 2 },
{ source: 2, target: 3 },
{ source: 3, target: 1 },
],
}}
/&amp;gt;&lt;/p&gt;
&lt;p&gt;It should also be noted that there can exist mutual admiration, and there can be cycles much greater than three people, but I hope the concept has been conveyed effectively.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;The third piece in the gallery is something I&apos;ve always struggled with, &lt;em&gt;Loneliness&lt;/em&gt;. Without going into too many details here, I was always on the outside growing up. Even as a pretty successful adult, who&apos;s on the &lt;em&gt;in&lt;/em&gt; for many circles, I still often feel lonely. I&apos;ve come to learn more about myself over the years, to understand the reasons why I feel this way, but knowing why doesn&apos;t eliminate experiencing the feeling. If you&apos;ve ever felt lonely, you&apos;ve experienced this graph first hand.&lt;/p&gt;
&lt;p&gt;&amp;lt;DirectedGraph
client:only=&quot;react&quot;
caption=&quot;Loneliness&quot;
data={{
nodes: [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 5 }],
links: [
{ source: 2, target: 3 },
{ source: 2, target: 4 },
{ source: 2, target: 5 },
{ source: 3, target: 2 },
{ source: 3, target: 4 },
{ source: 3, target: 5 },
{ source: 4, target: 2 },
{ source: 4, target: 3 },
{ source: 4, target: 5 },
{ source: 5, target: 2 },
{ source: 5, target: 3 },
{ source: 5, target: 4 },
],
}}
/&amp;gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;The fourth installment in the graph gallery I have titled &lt;em&gt;Interest&lt;/em&gt;. This one is also something I&apos;ve experienced personally and continue to do as I gain new friends and grow my network. I imagine others have experienced it as well.&lt;/p&gt;
&lt;p&gt;My specific depiction of &quot;interest&quot; is one of imbalance. There is a central node whose interest is directed at several other nodes, but all the other nodes are directed at them. There is no reciprocity.&lt;/p&gt;
&lt;p&gt;As I mentioned, I&apos;ve experienced this imbalance personally. What strikes me most about this graph is the wasted energy. Energy flows in one direction, no one ends up replenished or satiated.&lt;/p&gt;
&lt;p&gt;To really get a picture of this, try dragging the nodes around the screen to organize them. Try making all the arrows point in roughly the same direction.&lt;/p&gt;
&lt;p&gt;&amp;lt;DirectedGraph
client:only=&quot;react&quot;
caption=&quot;Interest&quot;
data={{
nodes: [
{ id: 1 },
{ id: 2 },
{ id: 3 },
{ id: 4 },
{ id: 5 },
{ id: 6 },
{ id: 7 },
],
links: [
{ source: 1, target: 2 },
{ source: 1, target: 3 },
{ source: 1, target: 4 },
{ source: 5, target: 1 },
{ source: 6, target: 1 },
{ source: 7, target: 1 },
],
}}
/&amp;gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;This one just sprang to me this morning as I was finishing this post, but I call it &lt;em&gt;The Modern Coffee Shop&lt;/em&gt;. A few years ago, my wife and I binged through the show Friends, and what struck me as anachronistic was that the characters would hit on strangers in the coffee shop every few episodes. Cell phones had not proliferated, WiFi didn&apos;t exist, smart phones weren&apos;t even a figment of the imagination yet. People had fewer &quot;personal technological barriers&quot; that they could put between themselves and others.&lt;/p&gt;
&lt;p&gt;I&apos;m not saying this is a good thing or a bad thing. I&apos;m not trying to place a judgment on it. I think we&apos;ve made a trade off. There are fewer chances for spontaneous interactions and meeting new people, but for some people there is an increased sense of safety from the ability to put up these &quot;barriers&quot;.&lt;/p&gt;
&lt;p&gt;I know I could be romanticizing something that didn&apos;t really exist, but as an extrovert who loves talking to new people, the modern coffee shop where no one interacts, save for a few people, bums me out.&lt;/p&gt;
&lt;p&gt;&amp;lt;DirectedGraph
client:only=&quot;react&quot;
caption=&quot;The Modern Coffee Shop&quot;
data={{
nodes: [
{ id: 1 },
{ id: 2 },
{ id: 3 },
{ id: 4 },
{ id: 5 },
{ id: 6 },
{ id: 7 },
{ id: 8 },
{ id: 9 },
{ id: 10 },
],
links: [
{ source: 1, target: 2 },
{ source: 2, target: 1 },
{ source: 7, target: 9 },
{ source: 9, target: 7 },
],
}}
options={{
chargeStrength: -25,
linkDistance: 60,
}}
/&amp;gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;I could come up with many, many more directed graphs I find in the world, but I&apos;m going to stop there. My only desire with this post was to share an interesting way of looking at the world through the lens of computer science.&lt;/p&gt;
&lt;p&gt;You can find the component I used for this post on my blog&apos;s Github page at &lt;a href=&quot;https://github.com/kyleshevlin/blog/blob/master/src/posts/published/graphs-are-everywhere/DirectedGraph.js&quot;&gt;https://github.com/kyleshevlin/blog/blob/master/src/posts/published/graphs-are-everywhere/DirectedGraph.js&lt;/a&gt; and play around with it. Put it in a sandbox and have some fun.&lt;/p&gt;
&lt;p&gt;Also, 1000 internet points to the people who figure out how I managed to get these &lt;code&gt;svg&lt;/code&gt; graphs to stay centered despite the width of the screen and tweets at me. It&apos;s hacky AF.&lt;/p&gt;
</content:encoded><category>Computer Science</category><category>Data Structures and Algorithms</category></item><item><title>When `else`s Make Your Code Worse</title><link>https://kyleshevlin.com/when-elses-make-your-code-worse/</link><guid isPermaLink="true">https://kyleshevlin.com/when-elses-make-your-code-worse/</guid><description>In this article, Kyle Shevlin teaches us how we can simplify the conditional logic of our code by refactoring it without `else` blocks.</description><pubDate>Wed, 17 Jul 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import SocialPost from &apos;../../../components/SocialPost.astro&apos;&lt;/p&gt;
&lt;p&gt;Prefer a video lesson? Watch it instead.&lt;/p&gt;
&lt;p&gt;&amp;lt;EggheadEmbed
src=&quot;https://egghead.io/lessons/javascript-remove-unnecessary-else-blocks-with-guards-and-early-returns/embed&quot;
title=&quot;Remove Unnecessary Else Blocks with Guards and Early Returns&quot;
/&amp;gt;&lt;/p&gt;
&lt;p&gt;Recently, I wrote a tweet that got some attention about not needing &lt;code&gt;else&lt;/code&gt;s in your code. Some people got a bit upset about that. Here&apos;s that tweet.&lt;/p&gt;
&lt;p&gt;&amp;lt;SocialPost
authorName=&quot;Kyle Shevlin&quot;
authorProfile=&quot;https://bsky.app/profile/kyleshevl.in&quot;
authorHandle=&quot;@kyleshevl.in&quot;
avatarUrl=&quot;/images/kyle-headshot.jpg&quot;
date=&quot;2019-05-23&quot;
content=&quot;Random, lukewarm (as opposed to hot) take: You really don&apos;t need the &lt;code&gt;else&lt;/code&gt; keyword in JavaScript. Any scenarion you&apos;d think to use it, I might argue there&apos;s a better, and possibly simpler, way. &lt;em&gt;searches for the smoking embers of a former fire emoji&lt;/em&gt;&quot;
/&amp;gt;&lt;/p&gt;
&lt;p&gt;I still stand by what I said, and I recently came across some code that was a good example of what I was talking about. The code looked like this (more or less):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function unimportantName(options) {
  const { value, value2, value3, type } = options

  if (type === &apos;Date&apos;) {
    if (value !== 0) {
      return {
        lte: [String(value), value2, &apos;from now&apos;, &apos;starting end of today&apos;].join(
          &apos; &apos;,
        ),
        gte: !value3 ? &apos;today&apos; : &apos;tomorrow&apos;,
      }
    } else {
      return { gte: &apos;today&apos;, lte: &apos;end of today&apos; }
    }
  } else {
    return { lte: value }
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We have an &lt;code&gt;if/else&lt;/code&gt; nested in the &lt;code&gt;if&lt;/code&gt; block of an outer &lt;code&gt;if/else&lt;/code&gt;. I can only guess, but I&apos;d say most people can reason about this level of complexity fairly easily. But just because people can, doesn&apos;t mean they should have to. This code is needlessly more complex than necessary, and I want to show you how just making a few small changes can really simplify this block of code.&lt;/p&gt;
&lt;p&gt;The primary thing I&apos;m going to change is the order of the conditionals. This will make the code much simpler and here&apos;s how I would (actually, did) do it.&lt;/p&gt;
&lt;p&gt;The first thing I notice is the outer &lt;code&gt;if/else&lt;/code&gt;. The condition is &lt;code&gt;if (type === &apos;Date&apos;)&lt;/code&gt;. Thus, I can conclude the &lt;code&gt;else&lt;/code&gt; block is the negation of this condition, which means it is &lt;code&gt;if (type !== &apos;Date&apos;)&lt;/code&gt;. By using the negation, we can refactor the &lt;code&gt;else&lt;/code&gt; away and create a guard statement that early returns with the object we have in the final return currently. Let&apos;s start with this refactor.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function unimportantName(options) {
  const { value, value2, value3, type } = options

  if (type !== &apos;Date&apos;) {
    return { lte: value }
  }

  if (value !== 0) {
    return {
      lte: [String(value), value2, &apos;from now&apos;, &apos;starting end of today&apos;].join(
        &apos; &apos;,
      ),
      gte: !value3 ? &apos;today&apos; : &apos;tomorrow&apos;,
    }
  } else {
    return { gte: &apos;today&apos;, lte: &apos;end of today&apos; }
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;By doing this, we&apos;ve unnested one level of &lt;code&gt;if/else&lt;/code&gt; blocks. We&apos;ve removed the &lt;code&gt;else&lt;/code&gt; statement, early returned, and because we now know that if we have passed that first &lt;code&gt;if&lt;/code&gt; guard, we are in the territory where logically &lt;code&gt;type === &apos;Date&apos;&lt;/code&gt;, we no longer need to check for it.&lt;/p&gt;
&lt;p&gt;Now, we have one &lt;code&gt;if/else&lt;/code&gt; remaining, is anything gained from refactoring this? I believe so. Our conditional is &lt;code&gt;if (value !== 0)&lt;/code&gt;, followed by a somewhat interesting object literal being created. Our &lt;code&gt;else&lt;/code&gt; block, on the other hand, returns a very simple object. I&apos;d prefer to switch the condition with the negation again, and move this part up as another guard statement and early return as well. Like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function unimportantName(options) {
  const { value, value2, value3, type } = options

  if (type !== &apos;Date&apos;) {
    return { lte: value }
  }

  if (value === 0) {
    return { gte: &apos;today&apos;, lte: &apos;end of today&apos; }
  }

  return {
    lte: [String(value), value2, &apos;from now&apos;, &apos;starting end of today&apos;].join(&apos; &apos;),
    gte: !value3 ? &apos;today&apos; : &apos;tomorrow&apos;,
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Great, we&apos;ve now gotten rid of any &lt;code&gt;else&lt;/code&gt;s in our code, made it very clear which scenarios lead to early returns and have a final return if none of those conditions are met. Is there anything left to refactor? Yes!&lt;/p&gt;
&lt;p&gt;I think using an array and calling &lt;code&gt;join&lt;/code&gt; when we can use a template string doesn&apos;t make sense. I&apos;ll refactor this as a template string.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function unimportantName(options) {
  const { value, value2, value3, type } = options

  if (type !== &apos;Date&apos;) {
    return { lte: value }
  }

  if (value === 0) {
    return { gte: &apos;today&apos;, lte: &apos;end of today&apos; }
  }

  return {
    lte: `${String(value)} ${value2} from now starting end of today`,
    gte: !value3 ? &apos;today&apos; : &apos;tomorrow&apos;,
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And there it is, the final code. With just a handful of simple refactors, we have simpler code that is easier to reason about (and, frankly, maintain). I hope you can see some of the value in this kind of refactor, and that it helps you when writing your own code.&lt;/p&gt;
</content:encoded><category>Refactoring</category><category>Software Engineering</category></item><item><title>A Plea for Imagination</title><link>https://kyleshevlin.com/a-plea-for-imagination/</link><guid isPermaLink="true">https://kyleshevlin.com/a-plea-for-imagination/</guid><description>You have an imagination. I am asking that you use it.</description><pubDate>Wed, 29 May 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Some of you reading this know that I occasionally dust off the old microphone, fire up a text editor and make some educational material that I put on the interwebs. Mostly on &lt;a href=&quot;https:///?af=8u8eik&quot;&gt;egghead&lt;/a&gt;. You might even be aware of this very blog post as a direct result of watching one of my lessons. If so, that&apos;s awesome and I thank you. But fair warning, not all students are the same, and I might be speaking directly to you in the next few paragraphs.&lt;/p&gt;
&lt;p&gt;For the most part, I&apos;ve received overwhelming praise for my courses. I&apos;m not bragging. Y&apos;all are just incredibly grateful students and I really appreciate it. Receiving praise is a nice side effect of making the educational material.&lt;/p&gt;
&lt;p&gt;That doesn&apos;t mean my courses aren&apos;t without their flaws or shortcomings, though. I am only human after all. &amp;lt;Marker content=&quot;And not always the brightest one at that!&quot; /&amp;gt; The number one complaint I get about my lessons can be boiled down to, &quot;How does this concept apply to &lt;em&gt;real&lt;/em&gt; software?&quot; &amp;lt;Marker content=&quot;Or better still, how does this apply to &amp;lt;em&amp;gt;my&amp;lt;/em&amp;gt; particular situation?&quot; /&amp;gt; Allow me to address this.&lt;/p&gt;
&lt;p&gt;First, if you&apos;ve never made educational material, than you might not realize that coming up with a good example is some of the hardest shit to do. It&apos;s one thing to have a problem you&apos;re trying to solve in the real world. The constraints reveal themselves and it doesn&apos;t matter how easy or complex it is, you just have to do the work you have to do.&lt;/p&gt;
&lt;p&gt;It&apos;s another thing entirely to try and come up with an example that&apos;s simple enough for any student to approach while being similar enough to their work that they can imagine how to use it. Pay attention to that line, we&apos;ll come back to it.&lt;/p&gt;
&lt;p&gt;You have to understand something, and it&apos;s something I think is lost on a lot of people who watch egghead videos. One thing people fail to really grasp about egghead is that there is a &lt;em&gt;style&lt;/em&gt; to an egghead lesson. There&apos;s no fluff, nothing frivolous or extraneous at all. It is direct and to the point. &amp;lt;Marker content=&quot;Unlike my writing.&quot; /&amp;gt; Demonstration in favor of explanation. Thus, for all of you who have asked me to go further and explain &lt;em&gt;when&lt;/em&gt; or &lt;em&gt;why&lt;/em&gt; you would use a technique and have been disappointed that I didn&apos;t, can you understand why there simply isn&apos;t room for that within that context?&lt;/p&gt;
&lt;p&gt;An egghead lesson is not the time to philosophize or enumerate all the possibilities for a technique. No, it is the time to get to the meat and potatoes of what you&apos;re teaching in the most succinct way possible. To that end, my examples are often contrived and lacking in depth or nuance. It&apos;s not that I&apos;m not capable, it&apos;s that it doesn&apos;t suit the goals we&apos;re going for.&lt;/p&gt;
&lt;p&gt;I don&apos;t actually see a problem with this mode of teaching, because, and here&apos;s the crux of my thesis, &lt;em&gt;it is the responsibility of the developer or engineer&lt;/em&gt; &amp;lt;Marker content=&quot;or any human being for that matter.&quot; /&amp;gt; &lt;em&gt;to be able to take the materials they are given and cultivate their imagination such that they can use the information in new ways, applied to new contexts.&lt;/em&gt; In other words, it&apos;s your job to learn how to remix what you learn into something more. Key words: &lt;strong&gt;your job&lt;/strong&gt;. Not my job. &lt;strong&gt;Your job&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;It is not my job as an educator to try and figure out a way to teach you all the ways in which you can use a technique or API. That would be insane! Almost everything has an infinite number of applications, it would be terribly difficult to cover even a moderate number of use cases. However, if I teach you concepts and give you the skills to &lt;em&gt;apply&lt;/em&gt; that knowledge to other situations, then we can actually achieve something useful.&lt;/p&gt;
&lt;p&gt;Think of it like this, to a small degree, a math teacher forces you to brute force memorize some maths. Like multiplication and division tables. This is done to simplify some of the more abstract work you&apos;ll have to handle soon enough. In web development, you can liken this to memorizing certain fundamental APIs, like certain HTML tags and how to nest elements. But after that, they teach you the &lt;em&gt;concept&lt;/em&gt; of multiplication or division. Literally, they teach you an &lt;em&gt;algorithm&lt;/em&gt; for solving those kinds of problems generally. They then ask you to imagine how to apply those algorithms in all sorts of ways. A math instructor provides you with tools and enough intuition to use them, but ultimately it is your responsibility to learn how to &lt;em&gt;apply&lt;/em&gt; them in whatever situation you&apos;re in.&lt;/p&gt;
&lt;p&gt;The same goes for when I teach a lesson. It doesn&apos;t matter if the example is contrived or all encompassing, it&apos;s your job to figure out how to take the concept and apply it elsewhere.&lt;/p&gt;
&lt;p&gt;The reason this irks me so much is that when I hear those criticisms, they are aimed at me, but in reality, they aren&apos;t &lt;em&gt;about&lt;/em&gt; me. No, those criticisms, they say more about the student than about me. Occasionally, they tell me I need to do a better job. Point taken if that&apos;s the case. But more often, they tell me that this person hasn&apos;t learned how to use their imagination. Haven&apos;t learned how to remix shit yet. Or even worse, and this is the one that really gets me, it tells me that person is &lt;em&gt;lazy&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;I want to give y&apos;all the benefit of the doubt. Software is hard. Sometimes really fucking hard. I have time and patience for people who try hard and struggle much. I&apos;ve been there, we all have. Shit, I&apos;ve just spent six weeks on the struggle bus on a project and the ride ain&apos;t over yet. It happens to everyone I know at some point. We all need patience and understanding in those situations.&lt;/p&gt;
&lt;p&gt;That being said, I have no patience for someone who is acting &lt;em&gt;lazy&lt;/em&gt;. I ain&apos;t got time to hold someone&apos;s hand who doesn&apos;t want to work hard with me. I don&apos;t have the energy to carry you all the way to your epiphany or realization. You gotta work with me! Failing to exercise that gift of a brain you have, failing to even try to imagine other uses and scenarios for a lesson or technique, that&apos;s &lt;em&gt;lazy&lt;/em&gt;, and it&apos;s not cool.&lt;/p&gt;
&lt;p&gt;Look, I fundamentally believe we all have laziness in us. For hundreds of thousands of years, our hunter-gatherer ancestors worked far fewer hours than we do and socialized and leisured a whole lot more. &amp;lt;Marker content=&quot;I&apos;ve read that some anthropologists hypothesize that the average person only needed to work 10 hours in a week to supply all their needs. Can you imagine only working 10 hours? I mean you&apos;d also have to imagine wild animals possibly attacking you, but it might be worth it for only working 10 hours. Just saying.&quot; /&amp;gt; I think it&apos;s in our DNA to take things easy from time to time. But learning something new probably isn&apos;t the time to do that. This is the time to be active, to be alert, to be imaginative.&lt;/p&gt;
&lt;p&gt;You need to cultivate your imagination. You need to improve your ability to think &lt;em&gt;divergently&lt;/em&gt;. That skill, more so than any engineering/dev technique itself, is what will unlock potential in your career, and maybe in your life. So I&apos;m pleading with you, before you criticize me, or another person with something like the complaint above, be sure to take a minute and try to use your imagination. Try and remix that shit.&lt;/p&gt;
&lt;h3&gt;Epilogue&lt;/h3&gt;
&lt;p&gt;I&apos;d be remiss if I made a post on imagination and remixing shit and didn&apos;t mention this awesome documentary I watched a few years ago called &lt;a href=&quot;https://www.everythingisaremix.info/watch-the-series&quot;&gt;Everything is a Remix&lt;/a&gt;. It&apos;s a short 4 part documentary that is well worth your time. Check it out, tell me what you think about it by tweeting me. Peace! ☮&lt;/p&gt;
</content:encoded><category>Thoughts</category></item><item><title>Just Enough FP: Composition</title><link>https://kyleshevlin.com/just-enough-fp-composition/</link><guid isPermaLink="true">https://kyleshevlin.com/just-enough-fp-composition/</guid><description>Functional composition is the act of taking the output of one function and passing it directly as the input to the next function.</description><pubDate>Fri, 17 May 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Composition is the culmination of all the previous &quot;Just Enough FP&quot; blog posts. &amp;lt;Marker content=&quot;Don&apos;t worry, there are still more posts to come.&quot; /&amp;gt; It&apos;s where we combine our knowledge of &lt;a href=&quot;/just-enough-fp-higher-order-functions&quot;&gt;higher order functions&lt;/a&gt;, &lt;a href=&quot;/just-enough-fp-currying&quot;&gt;currying&lt;/a&gt;, &lt;a href=&quot;/just-enough-fp-partial-application&quot;&gt;partial application&lt;/a&gt;, and &lt;a href=&quot;/just-enough-fp-pointfree&quot;&gt;pointfree programming&lt;/a&gt; into a new concept that can really unlock our functional potential.&lt;/p&gt;
&lt;p&gt;Before I get into explaining this concept, I want you to think back to your high school math classes. &amp;lt;Marker content=&quot;I hope this isn&apos;t &amp;lt;em&amp;gt;too&amp;lt;/em&amp;gt; traumatic a thought for you.&quot; /&amp;gt; You might recall somewhere around the time of Algebra 1 or 2 learning about mathematical functions, like this simple one: &lt;code&gt;f(x) = x + 1&lt;/code&gt;. This function takes any &lt;code&gt;x&lt;/code&gt; and always returns &lt;code&gt;x + 1&lt;/code&gt;. You might recognize this as a pure function (all mathematical functions are pure functions).&lt;/p&gt;
&lt;p&gt;Now, let&apos;s add a second function: &lt;code&gt;g(x) = x * 3&lt;/code&gt;. This is also a pure function. What if I wanted to take the output of one function and feed it as the input of another function? It would look like this: &lt;code&gt;f(g(x))&lt;/code&gt;. Now, &lt;code&gt;x&lt;/code&gt; will first be mulitplied by &lt;code&gt;3&lt;/code&gt;, and then &lt;code&gt;1&lt;/code&gt; will be added to it. If I provide an argument of &lt;code&gt;4&lt;/code&gt; for &lt;code&gt;x&lt;/code&gt;, the result will be &lt;code&gt;13&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This is &lt;strong&gt;functional composition&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;It is the act of taking the output of one function and passing it directly as the input to the next function. In its most primitive form, it occurs through nesting functions like you see above. Let&apos;s make a practical-&lt;em&gt;ish&lt;/em&gt; example of this.&lt;/p&gt;
&lt;p&gt;An example I like to use involves manipulating a string through a series of functions. Let&apos;s start by defining those functions.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const scream = str =&amp;gt; str.toUpperCase()
const exclaim = str =&amp;gt; `${str}!`
const repeat = str =&amp;gt; `${str} ${str}`
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;scream&lt;/code&gt; function uppercases a string, &lt;code&gt;exclaim&lt;/code&gt; adds an exclamation point, and &lt;code&gt;repeat&lt;/code&gt;, well repeats the string (with a space inbetween). You&apos;ll notice that each function has the same &lt;em&gt;arity&lt;/em&gt;. If you&apos;ve forgotten what arity is, check out the &lt;a href=&quot;/just-enough-fp-currying&quot;&gt;currying&lt;/a&gt; post before going further. Each one is a curried, unary function. Also, notice that the argument type for each function is the same. They all expect a &lt;code&gt;string&lt;/code&gt;. Our composition wouldn&apos;t work properly if we were mixing types, but I&apos;ll save that discussion for another time. Because all of our functions expect only one more argument and have the same type signature, we can nest them together, passing the output of one as the input of the next without any worries.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;repeat(exclaim(scream(&apos;Just Enough FP is great&apos;)))
// JUST ENOUGH FP IS GREAT! JUST ENOUGH FP IS GREAT!
repeat(exclaim(scream(&apos;i luv learning&apos;)))
// I LUV LEARNING! I LUV LEARNING!
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That&apos;s pretty cool! But imagine you had even more things you wanted to nest, or that your function names were longer than one word. That nesting would get very verbose and difficult to read. Is there a way we can tidy this up? Of course there is.&lt;/p&gt;
&lt;p&gt;If you recall from the &lt;a href=&quot;/just-enough-fp-currying&quot;&gt;currying&lt;/a&gt; and &lt;a href=&quot;/just-enough-fp-partial-application&quot;&gt;partial application&lt;/a&gt; posts, curried functions do not evaluate completely until they receive their final argument. You&apos;ll also recall that they hold their previously partially applied arguments in closure awaiting that final argument. If we were able to programmatically combine all our functions into one new higher order function that awaited its final argument, we&apos;d have ourselves a cool way of generating compositions.&lt;/p&gt;
&lt;p&gt;Well, here&apos;s that cool way. The &lt;code&gt;compose&lt;/code&gt; function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const compose =
  (...fns) =&amp;gt;
  x =&amp;gt;
    fns.reduceRight((acc, fn) =&amp;gt; fn(acc), x)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;compose&lt;/code&gt; function accepts any number of functions as arguments and returns a new function that awaits any value &lt;code&gt;x&lt;/code&gt;. When &lt;code&gt;x&lt;/code&gt; is received, we take our array of functions and call &lt;code&gt;reduceRight&lt;/code&gt; (the same as &lt;code&gt;Array.prototype.reduce&lt;/code&gt;, but we start from the end and work towards the beginning of the array), passing in the accumulated result as the input to the next function, starting with our value &lt;code&gt;x&lt;/code&gt;. &lt;code&gt;compose&lt;/code&gt; can be used like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const withExuberance = compose(repeat, exclaim, scream)

withExuberance(&apos;this is a-maz-ing&apos;)
// THIS IS A-MAZ-ING! THIS IS A-MAZ-ING!
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You see, we were able to generate a composition by passing in the functions from before as arguments to the &lt;code&gt;compose&lt;/code&gt; function, which gave us a brand new function awaiting our string. This string was passed first to &lt;code&gt;scream&lt;/code&gt;, then to &lt;code&gt;exclaim&lt;/code&gt;, and then to &lt;code&gt;repeat&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&quot;Wait! What?!&quot; No, I can&apos;t read your mind, it&apos;s just the response I get every time I teach this.&lt;/p&gt;
&lt;p&gt;In our mathematical compositions, the innermost function is always called first. When we nested our functions, they read from right-to-left: &lt;code&gt;repeat(exclaim(scream(x)))&lt;/code&gt;. So &lt;code&gt;compose&lt;/code&gt; is designed to order its functions the same way, from right-to-left (or bottom-to-top if you have so many they don&apos;t fit on one line). This takes some time to get used to, but with a little practice, becomes fairly easy to read. &amp;lt;Marker content=&quot;&amp;lt;strong&amp;gt;Remember&amp;lt;/strong&amp;gt;: reading top-to-bottom, left-to-right is not &amp;lt;em&amp;gt;natural&amp;lt;/em&amp;gt;, it&apos;s &amp;lt;em&amp;gt;cultural&amp;lt;/em&amp;gt;.&quot; /&amp;gt;&lt;/p&gt;
&lt;p&gt;We can actually break our composition down into smaller compositions and compose them together. Since we only have three functions, I&apos;ll only compose &lt;code&gt;scream&lt;/code&gt; and &lt;code&gt;exclaim&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const withExcitement = compose(exclaim, scream)
const withExuberance = compose(repeat, withExcitement)

withExuberance(&apos;composition is blowing my mind&apos;)
// COMPOSITION IS BLOWING MY MIND! COMPOSITION IS BLOWING MY MIND!
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can start to imagine how the ability to make small compositions and use them in larger ones can add some useful functionality to a program or application. So long as the arity and types match up, you should be able to compose at will without fear.&lt;/p&gt;
&lt;h3&gt;Bonus: &lt;code&gt;pipe&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;If you ever work in a purely functional language, you&apos;ll likely become very accustomed to using &lt;code&gt;compose&lt;/code&gt; and its right-to-left signature. However, to ease you into functional programming. There is an alternative: the &lt;code&gt;pipe&lt;/code&gt; function.&lt;/p&gt;
&lt;p&gt;It&apos;s exactly the same as &lt;code&gt;compose&lt;/code&gt;, but instead of &lt;code&gt;reduceRight&lt;/code&gt;, we use &lt;code&gt;reduce&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const pipe =
  (...fns) =&amp;gt;
  x =&amp;gt;
    fns.reduce((acc, fn) =&amp;gt; fn(acc), x)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Our compositions now read left-to-right, top-to-bottom. &amp;lt;Marker content=&quot;This is also how the pipeline operator &amp;lt;code&amp;gt;|&amp;gt;&amp;lt;/code&amp;gt; works in other languages&quot; /&amp;gt; Forgive me, I had to teach you composition the mathematical way first. Our &lt;code&gt;pipe&lt;/code&gt; compositions now would look like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const withExcitement = pipe(scream, exclaim)
const withExuberance = pipe(withExcitement, repeat)

withExuberance(&quot;I can&apos;t think of an interesting string&quot;)
// I CAN&apos;T THINK OF AN INTERESTING STRING! I CAN&apos;T THINK OF AN INTERESTING STRING!
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Composition is the act of passing the result of one function directly as the input of another function. With our knowledge of higher order functions, we are able to generate useful compositions with a &lt;code&gt;compose&lt;/code&gt; or &lt;code&gt;pipe&lt;/code&gt; function that await any data to operate on. It provides a mechanism for building up complex functionality through combining simpler and smaller functions.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;em&gt;In this series, I&apos;m going over material from my &lt;a href=&quot;https://egghead.io/courses/just-enough-functional-programming-in-javascript/?af=8u8eik&quot;&gt;Just Enough Functional Programming in JavaScript&lt;/a&gt; course on egghead. This post is based on the lesson &lt;a href=&quot;https://egghead.io/lessons/javascript-build-up-complex-functionality-by-composing-simple-functions-in-javascript/?af=8u8eik&quot;&gt;Build Up Complex Functionality by Composing Simple Functions in JavaScript&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;EggheadEmbed
src=&quot;https://egghead.io/lessons/javascript-build-up-complex-functionality-by-composing-simple-functions-in-javascript/embed&quot;
title=&quot;Composition&quot;
/&amp;gt;&lt;/p&gt;
</content:encoded><category>Functional Programming</category><category>JavaScript</category></item><item><title>Just Enough FP: Pointfree</title><link>https://kyleshevlin.com/just-enough-fp-pointfree/</link><guid isPermaLink="true">https://kyleshevlin.com/just-enough-fp-pointfree/</guid><description>Pointfree programming is a style of programming that favors passing the function itself as an argument rather than using lambda functions to operate on data. It focuses on the composition of functions rather than micro-managing your data.</description><pubDate>Wed, 01 May 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Pointfree programming is a style of programming free of points. Great, you got it. Blog post over.&lt;/p&gt;
&lt;p&gt;Just kidding!&lt;/p&gt;
&lt;p&gt;While my first sentence is true, it&apos;s pretty unhelpful, so let me explain what pointfree programming is a little bit better.&lt;/p&gt;
&lt;p&gt;In order to explain pointfree, we first need to understand what a &quot;point&quot; is. I&apos;m going to teach you by showing you, and I&apos;ll use the &lt;code&gt;Array.prototype.map&lt;/code&gt; method to demonstrate that.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;map&lt;/code&gt; method is a &lt;a href=&quot;/just-enough-fp-higher-order-functions&quot;&gt;higher order function&lt;/a&gt; (because it takes a function as an argument). You can read the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map&quot;&gt;docs here&lt;/a&gt;. Let&apos;s create a simple example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const arr = [1, 2, 3, 4, 5]

const doubles = arr.map(x =&amp;gt; x * 2)

console.log(doubles) // [2, 4, 6, 8, 10]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Alright, really simple example. We pass a function to the &lt;code&gt;map&lt;/code&gt; method that multiplies the number by &lt;code&gt;2&lt;/code&gt; and we get a new array with doubled numbers.&lt;/p&gt;
&lt;p&gt;I&apos;d like to draw your attention to the function passed to &lt;code&gt;map&lt;/code&gt;, &lt;code&gt;x =&amp;gt; x * 2&lt;/code&gt;. What is &lt;code&gt;x&lt;/code&gt;? Maybe a better question, why &lt;code&gt;x&lt;/code&gt;? Why not &lt;code&gt;foo&lt;/code&gt;, or &lt;code&gt;num&lt;/code&gt;, or &lt;code&gt;potato&lt;/code&gt;? Each would work equally well. What is it that &lt;code&gt;x&lt;/code&gt; signifies?&lt;/p&gt;
&lt;p&gt;Another way of putting that is, what does &lt;code&gt;x&lt;/code&gt; &lt;em&gt;point&lt;/em&gt; to?&lt;/p&gt;
&lt;p&gt;The function we passed to &lt;code&gt;map&lt;/code&gt; is called a lambda, a single-use anonymous function. We use an arbitrary, interim variable to &lt;em&gt;point&lt;/em&gt; to a value abstractly. Sure, we could follow &quot;clean code&quot; principles and name our interim variable better, but that would make it dependent upon the array, not the operation we&apos;re doing to the array.&lt;/p&gt;
&lt;p&gt;Another way to put this is that using lambdas in this way puts more focus on the data, and less on the functions transforming the data. We want to flip this, and as we&apos;ll see when we get into &lt;em&gt;composition&lt;/em&gt;, it&apos;s necessary that we make this change.&lt;/p&gt;
&lt;p&gt;There&apos;s a way to use higher order functions that avoids lambdas, and increase legibility and reusability in our programs in the process. Let&apos;s walk through that process.&lt;/p&gt;
&lt;p&gt;The first thing we need to understand is that we can pass in the name of a function to &lt;code&gt;map&lt;/code&gt;, we don&apos;t need to use a lambda. Our code can look like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const arr = [1, 2, 3, 4, 5]
const double = x =&amp;gt; x * 2

const doubles = arr.map(double)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We have pulled our lambda out of the &lt;code&gt;map&lt;/code&gt; call and saved it in a variable as a function expression. We can now pass this variable directly to &lt;code&gt;map&lt;/code&gt;. This &lt;em&gt;is&lt;/em&gt; pointfree programming. We no longer concern ourselves with the point in our higher order functions. Instead we make a simple, easily unit-tested (though you probably don&apos;t need to) function, and pass that in by name.&lt;/p&gt;
&lt;p&gt;Now, let&apos;s take it a step further. Let&apos;s combine &lt;a href=&quot;/just-enough-fp-currying&quot;&gt;currying&lt;/a&gt; and &lt;a href=&quot;/just-enough-fp-partial-application&quot;&gt;partial application&lt;/a&gt; to make this a little more functional.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const arr = [1, 2, 3, 4, 5]
const multiply = x =&amp;gt; y =&amp;gt; x * y
const multiplyBy2 = multiply(2)

const doubles = arr.map(multiplyBy2)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This time, we made a generic curried &lt;code&gt;multiply&lt;/code&gt; function. We apply the first argument to &lt;code&gt;multiply&lt;/code&gt; to create our &lt;code&gt;multiplyBy2&lt;/code&gt; function which is identical to our &lt;code&gt;double&lt;/code&gt; function from before. But this time, I can pass &lt;code&gt;multiplyBy2&lt;/code&gt; around my application for reusability.&lt;/p&gt;
&lt;p&gt;&quot;But Kyle, multiplying by 2 is really easy. Give me something with some more &lt;em&gt;substance&lt;/em&gt;.&quot;&lt;/p&gt;
&lt;p&gt;I hear you. Let&apos;s take a more complicated example and show why pulling the function out might be helpful. What if I want to slug-ify a list of strings? We can do that &lt;em&gt;kinda&lt;/em&gt; functionally and using pointfree programming.&lt;/p&gt;
&lt;p&gt;The steps in this algorithm are pretty simple: lower case the string and replace spaces with hyphens. Let&apos;s create a bunch of random strings and give it a try.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const strings = [
  &apos;Portland summers are amazing&apos;,
  &apos;I like big beards and I cannot lie&apos;,
  &apos;I am out of ideas for strings&apos;, // ha
]

const slugs = strings.map(str =&amp;gt; str.toLowerCase().split(&apos; &apos;).join(&apos;-&apos;))

console.log(slugs)
// [
//  &quot;portland-summers-are-amazing&quot;,
//  &quot;i-like-big-beards-and-i-cannot-lie&quot;,
//  &quot;i-am-out-of-ideas-for-strings&quot;
// ]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&apos;s make this pointfree and break up the steps of our algorithm.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Same strings as before

const lowerCase = str =&amp;gt; str.toLowerCase()
const split = separator =&amp;gt; str =&amp;gt; str.split(separator)
const join = separator =&amp;gt; arr =&amp;gt; arr.join(separator)

const splitAtSpace = split(&apos; &apos;)
const joinWithHyphen = join(&apos;-&apos;)

// Bit of a crazy way to do it, but should still make sense
const slugs = strings.map(lowerCase).map(splitAtSpace).map(joinWithHyphen)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, I can read in plain English what&apos;s going on in the final part of my program. Admittedly, it&apos;s pretty verbose this way, so let me give you a sneak peek to the next blog post and do this magically with composition:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const slugify = compose(joinWithHyphen, splitAtSpace, lowerCase)
const slugs = strings.map(slugify)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Boom! 💥 We&apos;re using pointfree all over the place and creating a brand new &lt;code&gt;slugify&lt;/code&gt; function in the process. I&apos;ll explain this in greater detail in the next post, so stay tuned.&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Pointfree programming gives us a few advantages. It encourages us to write small, easily tested, reusable functions to use throughout our applications. It encourages us to create well named functions so our programs become legible combinations of functions. And lastly, it reduces the surface area of bugs by eliminating lambdas and interim variables.&lt;/p&gt;
&lt;p&gt;It will take some time to get used to, but with practice, reading pointfree programming will become as natural as reading the imperative &lt;em&gt;pointful&lt;/em&gt; programming you&apos;re probably doing today. Give it a try in practice, see if there are places you find it useful!&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;em&gt;In this series, I&apos;m going over material from my &lt;a href=&quot;https://egghead.io/courses/just-enough-functional-programming-in-javascript/?af=8u8eik&quot;&gt;Just Enough Functional Programming in JavaScript&lt;/a&gt; course on egghead. This post is based on the lesson &lt;a href=&quot;https://egghead.io/lessons/javascript-eliminate-anonymous-javascript-functions-with-pointfree-programming/?af=8u8eik&quot;&gt;Eliminate Anonymous JavaScript Functions with Pointfree Programming&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;EggheadEmbed
src=&quot;https://egghead.io/lessons/javascript-eliminate-anonymous-javascript-functions-with-pointfree-programming/embed&quot;
title=&quot;Pointfree Programming&quot;
/&amp;gt;&lt;/p&gt;
</content:encoded><category>Functional Programming</category><category>JavaScript</category></item><item><title>Just Enough FP: Argument Order</title><link>https://kyleshevlin.com/just-enough-fp-argument-order/</link><guid isPermaLink="true">https://kyleshevlin.com/just-enough-fp-argument-order/</guid><description>Learn about how argument order impacts the composability of higher order functions.</description><pubDate>Mon, 29 Apr 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In a previous post on &lt;a href=&quot;/just-enough-fp-currying&quot;&gt;currying&lt;/a&gt;, I used a &lt;code&gt;filter&lt;/code&gt; function in a way that may have left you scratching your head. Not because you were still learning currying, but for other reasons. Let me quickly write that function again for reference in this post:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const filter = predicate =&amp;gt; array =&amp;gt; array.filter(predicate)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Our curried filter function receives a &lt;code&gt;predicate&lt;/code&gt; argument (a &lt;code&gt;predicate&lt;/code&gt; is a function that returns a boolean) first, partially applies that to the new function returned, and then awaits an &lt;code&gt;array&lt;/code&gt; to operate upon. What might of had you scratching your head is the order of these arguments. Why did the &lt;code&gt;predicate&lt;/code&gt; come before the &lt;code&gt;array&lt;/code&gt;?&lt;/p&gt;
&lt;p&gt;That&apos;s a good question and the easiest way to find the answer is just to try it. Let&apos;s write a &lt;code&gt;badFilter&lt;/code&gt; function with the argument order swapped:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const badFilter = array =&amp;gt; predicate =&amp;gt; array.filter(predicate)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, the &lt;code&gt;array&lt;/code&gt; is the first argument. This might seem more natural to many of you (and looks exactly like Lodash&apos;s &lt;code&gt;_.filter&lt;/code&gt; method). With this order, your brain models it as, &quot;I have an array, this is what I want to do to it.&quot; But what&apos;s the more reusable piece of that mental model? It&apos;s not the data. The data can change at any time. It&apos;s ephemeral, but &lt;em&gt;what we want to do with our data&lt;/em&gt;, that is worth storing and reusing.&lt;/p&gt;
&lt;p&gt;With the data argument first, we gain no advantage in partially applying it. We&apos;d be better off just using the built in methods for that data type. And with the data first, we&apos;ll never be able to pipe the result of another function into this one. As we&apos;ll see in a future post on &lt;em&gt;composition&lt;/em&gt;, having our data as the final argument is the key to being able to build up functional complexity with composition.&lt;/p&gt;
&lt;p&gt;Let&apos;s just let the bad example play out a bit:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const arr1 = [1, 2, 3, 4, 5]

const badFilterWithArr1 = badFilter(arr1) // returns a function awaiting a predicate

badFilterWithArr1(n =&amp;gt; n % 2 === 0) // [2, 4]
badFilterWithArr1(n =&amp;gt; n % 2 !== 0) // [1, 3, 5]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That&apos;s no more useful than just calling the predicate functions on the the &lt;code&gt;filter&lt;/code&gt; method of the array.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;arr1.filter(n =&amp;gt; n % 2 === 0) // [2, 4]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The wrong argument order immediately negates any benefit we gained through currying and partial application, so it&apos;s important that we have our data as our final argument in our functions.&lt;/p&gt;
&lt;h3&gt;Rules of Thumb for Argument Order&lt;/h3&gt;
&lt;p&gt;Here are my general rules for determining argument order. The first &quot;rule&quot;, as I just stated, is data comes last. You can bake in a lot of reusable functionality with partial application and pass new data into it over and over with this order.&lt;/p&gt;
&lt;p&gt;But what if I have a function that doesn&apos;t operate on data, but benefits from partial application and proper argument order?&lt;/p&gt;
&lt;p&gt;In that case, the second &quot;rule&quot;, and this is really &lt;em&gt;my way&lt;/em&gt; of thinking about it, is to order arguments from &lt;em&gt;most stable&lt;/em&gt; to &lt;em&gt;least stable&lt;/em&gt; argument. What does that mean?&lt;/p&gt;
&lt;p&gt;In my previous post on &lt;a href=&quot;/just-enough-fp-partial-application&quot;&gt;partial application&lt;/a&gt;, I used the example of building up a function to fetch data from an API. That function looked like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const getFromAPI = baseURL =&amp;gt; endpoint =&amp;gt; callback =&amp;gt;
  fetch(`${baseURL}${endpoint}`)
    .then(res =&amp;gt; res.json())
    .then(data =&amp;gt; callback(data))
    .catch(err =&amp;gt; {
      console.log(err)
    })
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If we examine a REST APIs URLs (so many acronyms, sorry), the part of the URL that changes the least (and in a good API, &lt;em&gt;never&lt;/em&gt;) is the &lt;code&gt;baseURL&lt;/code&gt;. If I want to fetch data from Github, I can make a partially applied function like this one:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const getFromGithub = getFromAPI(&apos;https://api.github.com&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This function is really useful! I can build up many endpoints from this one function.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const getUsersFromGithub = getFromGithub(&apos;/users&apos;)
const getReposFromGithub = getFromGithub(&apos;/repositories&apos;)
const getPublicGistsFromGithub = getFromGithub(&apos;/gists/public&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;endpoint&lt;/code&gt; is less stable than the &lt;code&gt;baseURL&lt;/code&gt;, it changes frequently, but still less frequently than what we want to do with the data once we fetch it. We can do any number of things once we have our users. Thus, the &lt;code&gt;callback&lt;/code&gt; argument is last because it is the least stable of our arguments.&lt;/p&gt;
&lt;p&gt;I&apos;d give you a few examples, but literally you can do almost anything you want with the data once you have it. Use your imagination.&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Argument order in curried functions makes a big difference in how useful and reusable a function is. It&apos;s also paramount for enabling composition, as we will see in a future post.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;em&gt;In this series, I&apos;m going over material from my &lt;a href=&quot;https://egghead.io/courses/just-enough-functional-programming-in-javascript/?af=8u8eik&quot;&gt;Just Enough Functional Programming in JavaScript&lt;/a&gt; course on egghead. This post is based on the lesson &lt;a href=&quot;https://egghead.io/lessons/javascript-improve-javascript-function-usability-with-proper-argument-order-in-functional-programming/?af=8u8eik&quot;&gt;Improve JavaScript Function Usability with Proper Argument Order in Functional Programming&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;EggheadEmbed
src=&quot;https://egghead.io/lessons/javascript-improve-javascript-function-usability-with-proper-argument-order-in-functional-programming/embed&quot;
title=&quot;Argument Order&quot;
/&amp;gt;&lt;/p&gt;
</content:encoded><category>Functional Programming</category><category>JavaScript</category></item><item><title>Just Enough FP: Partial Application</title><link>https://kyleshevlin.com/just-enough-fp-partial-application/</link><guid isPermaLink="true">https://kyleshevlin.com/just-enough-fp-partial-application/</guid><description>Learn what &quot;partial application&quot; is and why it matters in functional programming.</description><pubDate>Sat, 27 Apr 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I mentioned partial application several times in my previous post on &lt;a href=&quot;/just-enough-fp-currying&quot;&gt;currying&lt;/a&gt; with the promise of going in more detail about it in the future. I&apos;m fulfilling that promise now. Or resolving. There&apos;s an easy pun or two there if you look for them.&lt;/p&gt;
&lt;p&gt;Partial application is the act of applying some, but not all, of the arguments to a function and returning a new function awaiting the rest of the arguments. These applied arguments are stored in closure and remain available to any of the partially applied returned functions in the future. For those of you who are unfamiliar with closures, let me break that down for you.&lt;/p&gt;
&lt;p&gt;In JavaScript, we can use scopes in a way that allow us to supply state to a function or object, without exposing that state directly to the outside world. This process is called a closure. Let me give you an example.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function withCallCount(fn) {
  let count = 0

  return (...args) =&amp;gt; {
    console.log(`This function has been called ${count++} times`)
    fn(...args)
  }
}

const add = (x, y) =&amp;gt; x + y
const addWithCount = withCallCount(add)

addWithCount(2, 4) // This function has been called 1 times
addWithCount(7, 5) // This function has been called 2 times
addWithCount(2, 4) // This function has been called 3 times
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So what&apos;s going on here? The &lt;code&gt;withCallCount&lt;/code&gt; function creates a variable &lt;code&gt;count&lt;/code&gt; that is restricted to the scope of that function body. I cannot access it from outside that function. However, the anonymous function I return makes use of &lt;code&gt;count&lt;/code&gt;, so that value will remain available to the returned function for as long as it exists. Thus, the new function &lt;code&gt;addWithCount&lt;/code&gt; is able to log out the state of the &lt;code&gt;count&lt;/code&gt; with each call.&lt;/p&gt;
&lt;p&gt;Closures can get much more complex than this, but essentially it boils down to creating state within one scope and not exposing it, but using it, in another.&lt;/p&gt;
&lt;p&gt;With this in mind, partial application should start to click. Let&apos;s take our curried &lt;code&gt;add&lt;/code&gt; function from the previous lesson and point out the closure over the &lt;code&gt;x&lt;/code&gt; argument. I find it easier to point out the closure using the &lt;code&gt;function&lt;/code&gt; keyword, so I&apos;ll do that here, but know that the same thing occurs when using arrow functions.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function add(x) {
  // `x` is held in closure here, it remains available to the returned function
  // because it is used in the final return of `x + y`
  return function (y) {
    return x + y
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, if I take this function and only give it one argument, we can see how that value is stored in the new function and able to be reused over and over&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const add6 = add(6)

console.log(add6(4)) // 10
console.log(add6(20)) // 26
console.log(add6(-14)) // -8
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The same &lt;code&gt;x&lt;/code&gt; value, in this case &lt;code&gt;6&lt;/code&gt;, is held in closure for each call we make of the &lt;code&gt;add6&lt;/code&gt; function. If we use our imaginations a bit, we can find a lot of great examples where this is useful.&lt;/p&gt;
&lt;p&gt;For example, let&apos;s imagine I need to fetch different resources from the same API. I can generate different endpoints quickly with partial application. Let&apos;s create an example with the Github API&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const getFromAPI = baseURL =&amp;gt; endpoint =&amp;gt; cb =&amp;gt;
  fetch(`${baseURL}${endpoint}`)
    .then(res =&amp;gt; res.json())
    .then(data =&amp;gt; cb(data))
    .catch(err =&amp;gt; {
      console.log(err)
    })

const getFromGithub = getFromAPI(&apos;https://api.github.com&apos;)

// Now we have a partially applied getFromGithub function we can apply
// different endpoints to
const getUsersFromGithub = getFromGithub(&apos;/users&apos;)
const getReposFromGithub = getFromGithub(&apos;/repositories&apos;)

// Now I have two new partially applied functions. I can use
// different callbacks with each, and do something with the data

// Log out their logins
getUsersFromGithub(data =&amp;gt; {
  data.map(user =&amp;gt; {
    console.log(user.login)
  })
})
// [&quot;mojombo&quot;, &quot;defunkt&quot;, &quot;pjhyett&quot;, &quot;wycatz&quot;, ...]

// Log out their avatar urls
getUsersFromGithub(data =&amp;gt; {
  data.map(user =&amp;gt; {
    console.log(user.avatar_url)
  })
})
// [
//  &quot;https://avatars0.githubusercontent.com/u/1?v=4&quot;,
//  &quot;https://avatars0.githubusercontent.com/u/2?v=4&quot;,
//  &quot;https://avatars0.githubusercontent.com/u/3?v=4&quot;,
//  &quot;https://avatars0.githubusercontent.com/u/4?v=4&quot;,
// ]

// Or I can get some repos and logout their names
getReposFromGithub(data =&amp;gt; {
  data.map(repo =&amp;gt; {
    console.log(repo.name)
  })
})
// [&apos;grit&apos;, &apos;merb-core&apos;, &apos;rubinius&apos;, &apos;god&apos;, &apos;jsawesome&apos;]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can see how partial application gives us a lot of useful, reusable functions we can pass around our app and reduces how much code we need to write in later uses.&lt;/p&gt;
&lt;h3&gt;Bonus&lt;/h3&gt;
&lt;p&gt;Partial application can be done without currying (though I&apos;ve never had a reason to do so). The &lt;code&gt;bind&lt;/code&gt; method on functions allows you to supply arguments to the function that are applied to the new returned function (&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind&quot;&gt;docs here&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;The first argument of &lt;code&gt;bind&lt;/code&gt; is the &lt;code&gt;thisArg&lt;/code&gt;. This argument will be bound to &lt;code&gt;this&lt;/code&gt; for the new function. We&apos;re going to pass in &lt;code&gt;null&lt;/code&gt;, because we don&apos;t want anything bound to &lt;code&gt;this&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Any argument passed to &lt;code&gt;bind&lt;/code&gt; after the the &lt;code&gt;thisArg&lt;/code&gt; is partially applied as an argument to the function. We can pass any number of arguments, and if we pass in fewer than the function expects, we&apos;ll get a partially applied function.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const multiply = (x, y) =&amp;gt; x * y

const multiply7 = multiply.bind(null, 7)

console.log(multiply7(3)) // 21
console.log(multiply7(4)) // 28
console.log(multiply7(5)) // 35
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So if writing curried functions isn&apos;t available to you for some reason (breaking change to API, frightened coworkers, etc) and you still want to create partially applied functions, here&apos;s an option for you.&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Partial application is just the natural combination of curried functions and closures. Arguments previously applied are stored and available to the new functions returned. This process could lead to easier to write and understand code, though you&apos;ll have to decide what&apos;s useful for you (and your team).&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;em&gt;In this series, I&apos;m going over material from my &lt;a href=&quot;https://egghead.io/courses/just-enough-functional-programming-in-javascript/?af=8u8eik&quot;&gt;Just Enough Functional Programming in JavaScript&lt;/a&gt; course on egghead. This post is based on the lesson &lt;a href=&quot;https://egghead.io/lessons/javascript-create-reusable-functions-with-partial-application-in-javascript/?af=8u8eik&quot;&gt;Create Reusable Functions with Partial Application in JavaScript&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;EggheadEmbed
src=&quot;https://egghead.io/lessons/javascript-create-reusable-functions-with-partial-application-in-javascript/embed&quot;
title=&quot;Partial Application&quot;
/&amp;gt;&lt;/p&gt;
</content:encoded><category>Functional Programming</category><category>JavaScript</category></item><item><title>Just Enough FP: Currying</title><link>https://kyleshevlin.com/just-enough-fp-currying/</link><guid isPermaLink="true">https://kyleshevlin.com/just-enough-fp-currying/</guid><description>Learn what currying is, how to make curried functions, and what the pattern is useful for.</description><pubDate>Fri, 26 Apr 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Currying is, by far, one of the coolest things I&apos;ve learned in the last few years. When it clicked in my brain, it was such an intense epiphany that I literally ran to the other room and begged my wife to join me in the office so I could explain it to her on the whiteboard. She doesn&apos;t know a thing about programming, but she listened to me. &quot;Yeah, Kyle, that &lt;em&gt;kinda&lt;/em&gt; makes sense.&quot; Ha. I just had to share it with the first person I could find. Bless her for putting up with me.&lt;/p&gt;
&lt;p&gt;Anecdote over, on with the blog post!&lt;/p&gt;
&lt;h3&gt;What is Currying?&lt;/h3&gt;
&lt;p&gt;My least jargon filled way of answering that question is this: Currying is the act of refactoring a function that normally receives all its arguments at once into a series of functions that only take one argument at a time.&lt;/p&gt;
&lt;p&gt;In JavaScript, functions can receive any number of arguments. The number of arguments a function expects to receive is known as its &lt;em&gt;arity&lt;/em&gt;. Normally, we do not worry too much about how many arguments a function receives. If it needs more than one argument, we write it so that it receives all its arguments at one time. I believe this makes a lot of intuitive sense and maps to how our brains model and understand functions. Give the function all the arguments, do something with them, give me back the result. Easy peasy. But it&apos;s not the only way.&lt;/p&gt;
&lt;p&gt;In functional programming, all functions only receive one argument at a time. A function with an arity of one is known as a unary function. All curried functions are unary functions. A curried function that requires more than one argument to fulfill its operation, returns a new unary function with each argument until it has all the arguments it needs to finally evaluate.&lt;/p&gt;
&lt;p&gt;Let me demonstrate the currying process with the canonical example, an &lt;code&gt;add&lt;/code&gt; function.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// A common add function
function add(x, y) {
  return x + y
}

add(2, 3) // 5
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This function has an arity of two, aka a &lt;em&gt;binary function&lt;/em&gt;. It expects both arguments at the same time, adds them together, and gives the result back to you. To make this a curried function, we are going to refactor it so it receives the &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; arguments one at a time.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// A curried add function
function add(x) {
  return function (y) {
    return x + y
  }
}

// Or its arrow function equivalent
const add = x =&amp;gt; y =&amp;gt; x + y

// If we only have our `x` argument, we can apply it and return a
// function awaiting the `y` argument with the `x` in closure
const add2 = add(2)

// We can then supply the &apos;y&apos; argument
add2(3) // 5

// For good measure, if you had both arguments at the same time,
// You can supply both by immediately invoking the returned function
add(4)(6) // 10
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Our curried function receives the &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; arguments one at a time. When we receive the &lt;code&gt;x&lt;/code&gt; argument, we return a new function awaiting the &lt;code&gt;y&lt;/code&gt;. This new function has our &lt;code&gt;x&lt;/code&gt; value stored in closure. This is known as &lt;a href=&quot;/just-enough-fp-partial-application&quot;&gt;&lt;em&gt;partial application&lt;/em&gt;&lt;/a&gt;. Partial application is a very powerful feature of currying that I&apos;ll explore in more detail in the &lt;a href=&quot;/just-enough-fp-partial-application&quot;&gt;next post&lt;/a&gt;, but for now just keep following along and try to grok it through context. It&apos;ll be ok.&lt;/p&gt;
&lt;p&gt;If you&apos;re following with me, you now understand what currying is, but are probably still confused as to why this is an important technique. I&apos;m going to give you an example that admittedly will skip ahead a bit, but should show you some of what gets unlocked when functions are curried.&lt;/p&gt;
&lt;p&gt;Let&apos;s consider the array method &lt;code&gt;filter&lt;/code&gt;. &lt;code&gt;filter&lt;/code&gt; receives a predicate function (a function that returns a boolean) that operates on each item in an array and returns a new array with only the items that return true. You can check out the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter&quot;&gt;docs here&lt;/a&gt;. What if we could use the same filter on multiple arrays more easily? Let&apos;s create our own &lt;code&gt;filter&lt;/code&gt; function that&apos;s curried.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const filter = predicate =&amp;gt; array =&amp;gt; array.filter(predicate)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Our function receives the &lt;code&gt;predicate&lt;/code&gt; argument first, returns a new function that awaits the &lt;code&gt;array&lt;/code&gt; and then evaluates and returns the result. Let&apos;s create a predicate and pass it to filter.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const filter = predicate =&amp;gt; array =&amp;gt; array.filter(predicate)
const filterForEvens = filter(x =&amp;gt; x % 2 === 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We have now created a new function, &lt;code&gt;filterForEvens&lt;/code&gt; which has the predicate partially applied. This predicate returns true if dividing by two returns a remainder of 0. The &lt;code&gt;filterForEvens&lt;/code&gt; function awaits an an &lt;code&gt;array&lt;/code&gt; argument. So let&apos;s give it some arrays.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const filter = predicate =&amp;gt; array =&amp;gt; array.filter(predicate)
const filterForEvens = filter(x =&amp;gt; x % 2 === 0)

const arr1 = [1, 2, 3, 4, 5, 6, 7]
const arr2 = [1, 4, 9, 16, 25, 36, 49]
const arr3 = [1, 8, 27, 64, 125, 216, 343]

filterForEvens(arr1) // [2, 4, 6]
filterForEvens(arr2) // [4, 16, 36]
filterForEvens(arr3) // [8, 64, 216]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;By currying our &lt;code&gt;filter&lt;/code&gt; function, we&apos;ve given ourselves the opportunity to delay supplying the &lt;code&gt;array&lt;/code&gt; argument. This allows us to supply as many different arrays to our &lt;code&gt;filterForEvens&lt;/code&gt; function as we want and we never have to resupply the &lt;code&gt;predicate&lt;/code&gt; argument.&lt;/p&gt;
&lt;p&gt;As we&apos;ll see in the next post, currying and partial application is a powerful combination. We can DRY up code in our application through it&apos;s use. We&apos;ll also explore two other topics related to currying: &lt;em&gt;argument order&lt;/em&gt; and &lt;em&gt;function composition&lt;/em&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;em&gt;In this series, I&apos;m going over material from my &lt;a href=&quot;https://egghead.io/courses/just-enough-functional-programming-in-javascript/?af=8u8eik&quot;&gt;Just Enough Functional Programming in JavaScript&lt;/a&gt; course on egghead. This post is based on the lesson &lt;a href=&quot;https://egghead.io/lessons/javascript-refactor-a-function-to-use-currying-in-javascript/?af=8u8eik&quot;&gt;Refactor a Function to Use Currying in JavaScript&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;EggheadEmbed
src=&quot;https://egghead.io/lessons/javascript-refactor-a-function-to-use-currying-in-javascript/embed&quot;
title=&quot;Currying&quot;
/&amp;gt;&lt;/p&gt;
</content:encoded><category>Functional Programming</category><category>JavaScript</category></item><item><title>Just Enough FP: Immutability</title><link>https://kyleshevlin.com/just-enough-fp-immutability/</link><guid isPermaLink="true">https://kyleshevlin.com/just-enough-fp-immutability/</guid><description>Learn what &quot;immutability&quot; is and why it matters in functional programming</description><pubDate>Sun, 21 Apr 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Alright, I know that the title of this post already contains some technical jargon that&apos;s potentially intimidating. But if you&apos;ve made it this far, I assure you, you can understand this concept.&lt;/p&gt;
&lt;p&gt;Let&apos;s define &quot;immutability&quot;. The fastest way to do that is to start with its antonym--&quot;mutability&quot;. Mutability comes from &quot;mutable&quot;. Something that is mutable &lt;strong&gt;can be changed&lt;/strong&gt;. Thus, something that is immutable &lt;strong&gt;cannot be changed&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Mutable data structures can be changed after creation, aka mutated. Immutable data structures cannot.&lt;/p&gt;
&lt;p&gt;You might be asking yourself, how do you make changes to data that can&apos;t be changed? Good question.&lt;/p&gt;
&lt;p&gt;In functional programming, instead of mutating the data directly, we make changes to our data by returning a new data structure with the correct values to reflect that change. Let me give you some examples involving an object. In this first example, I&apos;ll mutate the data.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const me = { name: &apos;Kyle&apos;, age: 33 }

// I recently had a birthday, let&apos;s increase my age mutably
me.age++
console.log(me) // { name: &apos;Kyle&apos;, age: 34 }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We have directly modified the value at &lt;code&gt;me.age&lt;/code&gt; with a mutation. While we still have the same object (the reference hasn&apos;t changed), we have permanently changed the contents of the object. This is sometimes referred to as a &lt;em&gt;destructive operation&lt;/em&gt;, because it does not leave the original object intact during the operation. In this second example, I&apos;ll modify the age immutably now:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const me = { name: &apos;Kyle&apos;, age: 33 }

// I recently had a birthday, let&apos;s increase my age immutably
const olderMe = Object.assign({}, me, { age: 34 })

console.log(olderMe) // { name: &apos;Kyle&apos;, age: 34 }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this case, I create a brand new object and merge the old properties with the new ones to get the correct data structure. I still have access to the &lt;code&gt;me&lt;/code&gt; object and now the &lt;code&gt;olderMe&lt;/code&gt; object. &lt;code&gt;olderMe&lt;/code&gt; reflects the changes we wanted to make to the data.&lt;/p&gt;
&lt;h3&gt;A Case Study: Array.prototype.sort()&lt;/h3&gt;
&lt;p&gt;A lot of our work involves manipulating arrays of data. You might find that after getting very accustomed to using declarative immutable methods like &lt;code&gt;map&lt;/code&gt; and &lt;code&gt;filter&lt;/code&gt;, you find yourself reaching for &lt;code&gt;sort&lt;/code&gt; and &lt;strong&gt;BOOM&lt;/strong&gt; 💥 you&apos;ve mutated your underlying data permanently without intending to.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Array.prototype.sort&lt;/code&gt; is a destructive array method, performing the sort &quot;in place&quot; on the original array itself. I&apos;ll get into why this is the case in a little bit. First, let&apos;s observe what I mean.&lt;/p&gt;
&lt;p&gt;If I have an array of numbers and call sort on it, the reference to that array doesn&apos;t change.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const arr = [5, 3, 2, 4, 1]
const arr2 = arr.sort()

console.log(arr) // [1, 2, 3, 4, 5]
console.log(arr2) // [1, 2, 3, 4, 5]
console.log(arr === arr2) // true, each variable references the same array
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Sorting mutably might be exactly what you want if you never need to use the array to derive any other data from it. However, often you&apos;ll want to keep the original array intact for other purposes. Perhaps you have a table of data derived from a collection of objects, rather than mutate the array each time you need to sort it in a different way, it might be best to create a brand new array with the sort applied. Let&apos;s create a &lt;code&gt;safeSort&lt;/code&gt; function to do this. I&apos;m going to use a &lt;em&gt;curried function&lt;/em&gt; to do so, which I will cover in a future blog post.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const arr = [5, 3, 2, 4, 1]

/* If you are unfamiliar with currying, this will look confusing, but break
 * it down into steps and it&apos;s pretty easy to understand.
 *
 * 1. The first argument is the optional comparator function the `sort`
 * method receives. This returns a new function.
 *
 * 2. The second argument (the first of the second function) is our array
 * to operate on. This implicitly returns the value to the right of the =&amp;gt;
 *
 * 3. We create a new array and spread the items of the original array into it
 * so as not to make any mutations to the original array.
 *
 * 4. We now perform the sort operation on the _new array_, leaving the old
 * one intact
 */
const safeSort = comparator =&amp;gt; array =&amp;gt; [...array].sort(comparator)

const arr2 = safeSort()(arr)

console.log(arr) // [5, 3, 2, 4, 1]
console.log(arr2) // [1, 2, 3, 4, 5]
console.log(arr === arr2) // false
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now our &lt;code&gt;safeSort&lt;/code&gt; sorts the contents of our array without making any changes to the original, returning to us a brand new array reflecting our changes. Thus, we have made an immutable change to our data.&lt;/p&gt;
&lt;h3&gt;Implications&lt;/h3&gt;
&lt;p&gt;I wanted to take a moment to point out the tradeoffs being made between mutable and immutable data structures. Now, I am no expert in computer science, so I will give you the best information I have, but I want it to be clear there might be some cases where the generalizations I make here are wrong.&lt;/p&gt;
&lt;p&gt;Mutations, and thus mutable data structures, have some great benefits. Mutating data models how we understand the world. When we make changes to something, we change &lt;em&gt;that thing&lt;/em&gt;, we don&apos;t return a new copy with the changes applied. One of my favorite metaphors is drinking a glass of water. When we take a sip, we mutate the amount of water in the glass, and we mutate the amount of water in ourselves.&lt;/p&gt;
&lt;p&gt;Mutations also tend to be great for performance, as the operations happen in place. They do not require new structures to be created in memory, or old structures to be garbage collected. For example, in video games, often game developers will create a &quot;pool&quot; of enemies, a set number of enemy objects, and then mutate the objects in that pool to reflect which enemies are alive and dead. Under the hood, you might kill an enemy and the program collects that dead object, mutates new life onto it and sends it back at you as a &quot;new&quot; enemy. You think you&apos;re being attacked by a new enemy, but in reality, that reference is the same reference as the old enemy.&lt;/p&gt;
&lt;p&gt;There are downsides to mutations. First, the destructive nature of the operations can lead to complications, especially regarding situations where we might need to undo operations. Also, mutations can lead to difficulties with state management. What if two operations attempt to change the same data concurrently? Which one takes precedent? What data will we get back in return? Bugs from mutations can often be some of the hardest to track down and fix.&lt;/p&gt;
&lt;p&gt;Immutability, and thus immutable data structures, also have some great benefits. Making changes to immutable data structures often leads to very prescriptive, easy to understand (albeit often verbose) changes to data. This methodology allows us to gain levels of certainty about our programs that mutations don&apos;t inherently give us. The popular state management library Redux is based on immutability, because this gives us the ability to serialize our state and use it for things like time-travel debugging and very simple undo/redo abilities.&lt;/p&gt;
&lt;p&gt;The biggest downside to immutability has to do with memory consumption. Creating new data structures for each change &lt;em&gt;can&lt;/em&gt; have an effect on performance, though be certain to benchmark your performance and verify before worrying about this too much. Most modern systems have ample memory for many of the operations you and I are doing in our web applications.&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Understanding the difference between mutable and immutable data structures is very useful information. Being able to look at code and recognize mutations will really help you understand what transformations your data is going through and may even help you spot a bug or two.&lt;/p&gt;
&lt;p&gt;In functional programming, we require immutable changes because of the purity of our functions. Mutations cannot make the guarantees immutable data can. Mutations can lead to inconsistent results and/or side effects, and we can&apos;t have that if we&apos;re really going to unlock the power of functions in coming posts.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;em&gt;In this series, I&apos;m going over material from my &lt;a href=&quot;https://egghead.io/courses/just-enough-functional-programming-in-javascript/?af=8u8eik&quot;&gt;Just Enough Functional Programming in JavaScript&lt;/a&gt; course on egghead. This post is based on the lesson &lt;a href=&quot;https://egghead.io/lessons/javascript-avoiding-mutations-in-javascript-with-immutable-data-structures/?af=8u8eik&quot;&gt;Avoiding Mutations in JavaScript with Immutable Data Structures&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;EggheadEmbed
src=&quot;https://egghead.io/lessons/javascript-avoiding-mutations-in-javascript-with-immutable-data-structures/embed&quot;
title=&quot;Immutability&quot;
/&amp;gt;&lt;/p&gt;
</content:encoded><category>Functional Programming</category><category>JavaScript</category></item><item><title>Just Enough FP: Pure Functions</title><link>https://kyleshevlin.com/just-enough-fp-pure-functions/</link><guid isPermaLink="true">https://kyleshevlin.com/just-enough-fp-pure-functions/</guid><description>Learn what a &quot;pure function&quot; is, why they are important for functional programming, and how they can improve the quality of your code.</description><pubDate>Sun, 14 Apr 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Another fundamental of functional programming is a solid understanding of pure functions. A pure function is one in which its output is derived solely from its inputs, with no side effects. I know that might still seem like gibberish to some of you, so I&apos;ll break this down and hopefully make it simple and clear.&lt;/p&gt;
&lt;h3&gt;The First Part&lt;/h3&gt;
&lt;p&gt;The first phrase to break down and clarify is &quot;its output is derived solely from its inputs&quot;. Another way to say that is this: given the same arguments, the function always returns the same value. Let&apos;s look at a basic example.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// A pure add function
function add(x, y) {
  return x + y
}

// or with an ES6 arrow function
const add = (x, y) =&amp;gt; x + y
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;add&lt;/code&gt; function will always return the same output given the same arguments. In fact, all functions in math are pure functions, so there&apos;s a good chance you&apos;re already familiar with the concept.&lt;/p&gt;
&lt;p&gt;Now, what if the output doesn&apos;t depend on the inputs? Is it still a pure function?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function subtractFromMaxSafeInteger(number) {
  return Number.MAX_SAFE_INTEGER - number
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the &lt;code&gt;subtractFromMaxSafeInteger&lt;/code&gt; function, given the same input, we always get the same output, right? Sure looks pure.&lt;/p&gt;
&lt;p&gt;But it isn&apos;t.&lt;/p&gt;
&lt;p&gt;Our output depends on a global constant &lt;code&gt;Number.MAX_SAFE_INTEGER&lt;/code&gt;. This makes it impure, as our output should &lt;em&gt;derive solely from the inputs&lt;/em&gt;. If our function was dropped into another program that redefined &lt;code&gt;Number.MAX_SAFE_INTEGER&lt;/code&gt;, we&apos;d end up with different outputs, which would break our function&apos;s purity.&lt;/p&gt;
&lt;p&gt;In other words, the &quot;outside world&quot;, that is the scope outside of our function, should have no affect on the output of our function.&lt;/p&gt;
&lt;p&gt;We also need to be aware of any impure functions within the function we are evaluating as they will impurify an otherwise pure function. Let me show you an example of what I mean. I&apos;ll create a factory function that makes &quot;friend&quot; objects for a program. I&apos;ll want unique IDs for each &quot;friend&quot;, so I&apos;ll create a &lt;code&gt;generateID&lt;/code&gt; function as well.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// DISCLAIMER: Do not use this to create IDs. There are much better ways. Go find them.
const generateID = () =&amp;gt; Math.floor(Math.random() * 10000)

const friendFactory = (name, age) =&amp;gt; ({
  id: generateID(),
  name,
  age,
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I could pass the same name and age to the friend factory, but I&apos;ll get different results each time because &lt;code&gt;generateID&lt;/code&gt; is an impure function.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;friendFactory(&apos;Anna&apos;, 31) // {id: 6777, name: &quot;Anna&quot;, age: 31}
friendFactory(&apos;Anna&apos;, 31) // {id: 6233, name: &quot;Anna&quot;, age: 31}
friendFactory(&apos;Anna&apos;, 31) // {id: 7223, name: &quot;Anna&quot;, age: 31}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice, that the &lt;code&gt;id&lt;/code&gt; property is different in each object returned from our &lt;code&gt;friendFactory&lt;/code&gt; function. We could make our &lt;code&gt;friendFactory&lt;/code&gt; a pure function again by generating the ID outside of the function&apos;s scope and passing it in as an argument instead.&lt;/p&gt;
&lt;h3&gt;The Second Part&lt;/h3&gt;
&lt;p&gt;Now, the second part of my description, &quot;with no side effects&quot;, is a little trickier to understand. The way I like to describe it is that a side effect is a change outside the scope of our function. Let me demonstrate with an example.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let count = 0

const addWithIncrement = (x, y) =&amp;gt; {
  count++
  return x + y
}

addWithIncrement(1, 2)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This &lt;code&gt;addWithIncrement&lt;/code&gt; function will always return the same value given the same inputs, and its output depends solely upon those inputs. However, every time we call this function, we change the value of &lt;code&gt;count&lt;/code&gt;, which is outside the scope of our function.&lt;/p&gt;
&lt;p&gt;Another surprising impure function that falls under this category is a function that has an effect on the world outside of our application. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const log = x =&amp;gt; {
  console.log(x)
}

log(&apos;This is an impure function. Wha???&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;log&lt;/code&gt; function doesn&apos;t make a change inside of our program or application, but it affects the outside world, triggering the console to log out the value passed in. This is a side effect, and thus &lt;code&gt;log&lt;/code&gt; is impure.&lt;/p&gt;
&lt;h3&gt;What Does This Mean?&lt;/h3&gt;
&lt;p&gt;It means that we need to be aware of which functions in our programs are pure and impure. We need impure functions for our applications to do anything meaningful. Strictly speaking, a program entirely made of pure functions (with no side effects) is equivalent to doing nothing at all.&lt;/p&gt;
&lt;p&gt;But, using pure functions throughout our application &lt;em&gt;until we need the side effect to do something meaningful&lt;/em&gt; will make our applications easier to test and reason about.&lt;/p&gt;
&lt;p&gt;As we will see in future posts, pure functions create the foundation for some very cool functional programming techniques, especially &lt;em&gt;composition&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;In my opinion, your goal should be to use more pure functions in your application. Functions that do too much, or have random side effects, can result in buggy applications. Side effect bugs can be some of the most difficult to find and remove.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;em&gt;In this series, I&apos;m going over material from my &lt;a href=&quot;https://egghead.io/courses/just-enough-functional-programming-in-javascript/?af=8u8eik&quot;&gt;Just Enough Functional Programming in JavaScript&lt;/a&gt; course on egghead. This post is based on the lesson &lt;a href=&quot;https://egghead.io/lessons/javascript-identify-side-effects-by-comparing-pure-and-impure-javascript-functions-342b2167/?af=8u8eik&quot;&gt;Identify Side Effects by Comparing Pure and Impure Functions&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;EggheadEmbed
src=&quot;https://egghead.io/lessons/javascript-identify-side-effects-by-comparing-pure-and-impure-javascript-functions-342b2167/embed&quot;
title=&quot;Pure Functions&quot;
/&amp;gt;&lt;/p&gt;
</content:encoded><category>Functional Programming</category><category>JavaScript</category></item><item><title>Just Enough FP: Higher Order Functions</title><link>https://kyleshevlin.com/just-enough-fp-higher-order-functions/</link><guid isPermaLink="true">https://kyleshevlin.com/just-enough-fp-higher-order-functions/</guid><description>Learn what a &quot;higher order&quot; function is and why they are important.</description><pubDate>Mon, 08 Apr 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Making sense of functional programming requires a solid understanding of a few fundamental concepts. In my opinion, the first one you need to learn is the concept of &quot;higher order functions&quot;.&lt;/p&gt;
&lt;p&gt;A higher order function is a function that meets at least one of the following requirements:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It accepts a function as an argument&lt;/li&gt;
&lt;li&gt;It returns a new function&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Functions (and methods) that receive a callback argument are good examples of higher order functions that fulfill the first criterion, such as &lt;code&gt;map&lt;/code&gt; or &lt;code&gt;filter&lt;/code&gt; on an array.&lt;/p&gt;
&lt;p&gt;A good example fulfilling the second criterion is the &lt;code&gt;bind&lt;/code&gt; method for functions, which returns a new function (&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind&quot;&gt;Here&apos;s a link to the docs&lt;/a&gt; if you&apos;re unfamiliar with &lt;code&gt;bind&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;Often, a higher order function will fulfill both criteria.&lt;/p&gt;
&lt;h3&gt;Why Are Higher Order Functions Useful?&lt;/h3&gt;
&lt;p&gt;There are several reasons higher order functions useful, including some that I will cover in future blog posts about &lt;a href=&quot;/just-enough-fp-currying&quot;&gt;&lt;em&gt;currying&lt;/em&gt;&lt;/a&gt;, &lt;a href=&quot;/just-enough-fp-partial-application&quot;&gt;&lt;em&gt;partial application&lt;/em&gt;&lt;/a&gt;, and &lt;em&gt;composition&lt;/em&gt;. For now, I&apos;ll talk about more general uses of higher order functions.&lt;/p&gt;
&lt;h4&gt;Hiding Implementation Details&lt;/h4&gt;
&lt;p&gt;The first reason, in my opinion, that higher order functions are useful is that they are a great mechanism for &quot;hiding&quot; and abstracting away implementation details. This is the benefit gained from using higher order functions that receive a function as an argument.&lt;/p&gt;
&lt;p&gt;For example, the &lt;code&gt;map&lt;/code&gt; method mentioned before could be written any number of ways. Do we use a &lt;code&gt;for&lt;/code&gt; or a &lt;code&gt;while&lt;/code&gt; loop? How do we manage creating a new array and putting our new values into it? The higher order &lt;code&gt;map&lt;/code&gt; method means that you, the consumer of the function, don&apos;t need to worry about those details. Even better, by using the higher order function, you are automatically opted into any upgrades and improvements that are made to the method.&lt;/p&gt;
&lt;h4&gt;Adding Functionality to an Existing Function&lt;/h4&gt;
&lt;p&gt;The second reason is to add functionality to already existing functions. The best way to understand this is through an example.&lt;/p&gt;
&lt;p&gt;Often when debugging code, I want a fast way to log out to the console the result of a function while still allowing it to return that result, not breaking the call stack.&lt;/p&gt;
&lt;p&gt;You could use a &lt;code&gt;debugger&lt;/code&gt; statement. That might be the best strategy in some situations, but if the function is called a lot, it can be frustrating to have to &quot;step over&quot; so many functions.&lt;/p&gt;
&lt;p&gt;You could also manually add the &lt;code&gt;console.log&lt;/code&gt;, but sometimes that can be very tedious. You gotta save the result to a variable, log it out, &lt;em&gt;then&lt;/em&gt; return it. Since higher order functions can receive functions as arguments, what if we make a higher order function that handles these implementation details for us.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function logResult(fn) {
  return (...args) =&amp;gt; {
    const result = fn(...args)

    console.log(result)

    return result
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Our higher order &lt;code&gt;logResult&lt;/code&gt; function receives a function as an argument, returns a new function that receives any number of arguments, calls the original function with those arguments, and logs out the result before returning it. Now, if I&apos;m working in some code and want to see the result of a function call without having to store it, I can wrap the function in &lt;code&gt;logResult&lt;/code&gt; and pass the args to that instead.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;transformData(data) // Uhh, what does this do?

// We can wrap it with logResult to find out
logResult(transformData)(data) // Oh! That&apos;s what it does.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we can see the result of our &lt;code&gt;transformData&lt;/code&gt; function every time it is called. Saves us a few steps of saving the result to a variable and logging it out manually every time.&lt;/p&gt;
&lt;p&gt;Another example of higher order functions that you might be familiar with are Higher Order Components. Since React components boil down to simple functions, we can enhance them by passing them as arguments to higher order functions.&lt;/p&gt;
&lt;p&gt;There are many articles out there on creating Higher Order Components (a style that has fallen out of favor, first with the rise of render props, and now with the advent of Hooks), so I don&apos;t feel a need to cover it here.&lt;/p&gt;
&lt;h3&gt;Some Additional Thoughts on Higher Order Functions&lt;/h3&gt;
&lt;p&gt;In JavaScript, a language where functions are first class citizens that can be treated like any other value, higher order functions are really no different than normal functions. The descriptor &quot;higher order&quot; comes from mathematics and it shouldn&apos;t concern us very much. Our concern should be understanding how to wield them to improve our programs.&lt;/p&gt;
&lt;p&gt;As you grow more comfortable with higher order functions, I&apos;m certain you will find a number of use cases for them. Use your imagination, who knows what you&apos;ll come up with.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;em&gt;In this series, I&apos;m going over material from my &lt;a href=&quot;https://egghead.io/courses/just-enough-functional-programming-in-javascript/?af=8u8eik&quot;&gt;Just Enough Functional Programming in JavaScript&lt;/a&gt; course on egghead. This post is based on the lesson &lt;a href=&quot;https://egghead.io/lessons/javascript-modify-functions-with-higher-order-functions-in-javascript/?af=8u8eik&quot;&gt;Modify Functions with Higher Order Functions in JavaScript&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;EggheadEmbed
src=&quot;https://egghead.io/lessons/javascript-modify-functions-with-higher-order-functions-in-javascript/embed&quot;
title=&quot;Higher Order Functions&quot;
/&amp;gt;&lt;/p&gt;
</content:encoded><category>Functional Programming</category><category>JavaScript</category></item><item><title>Just Enough Functional Programming Course Launch</title><link>https://kyleshevlin.com/just-enough-functional-programming-course-launch/</link><guid isPermaLink="true">https://kyleshevlin.com/just-enough-functional-programming-course-launch/</guid><description>I released a course on Egghead about functional programming. Check it out.</description><pubDate>Fri, 22 Mar 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import SocialPost from &apos;../../../components/SocialPost.astro&apos;&lt;/p&gt;
&lt;p&gt;In 2017, I came across &lt;a href=&quot;https://github.com/MostlyAdequate/mostly-adequate-guide&quot;&gt;The Mostly Adequate Guide to Functional Programming&lt;/a&gt; by &lt;a href=&quot;https://twitter.com/drboolean&quot;&gt;Brian Lonsdorf&lt;/a&gt;. It&apos;s an incredible resource and introduction to functional programming in JavaScript. It inspired me to start giving talks about functional programming in 2018. After giving the talk several times, I decided to make a course to go along with it. That course is available to you now on &lt;a href=&quot;https://egghead.io/course/just-enough-functional-programming-in-javascript/?af=8u8eik&quot;&gt;egghead.io&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The course is called &lt;a href=&quot;https://egghead.io/course/just-enough-functional-programming-in-javascript/?af=8u8eik&quot;&gt;Just Enough Functional Programming in JavaScript&lt;/a&gt; and I think you&apos;ll like it.&lt;/p&gt;
&lt;p&gt;It&apos;s a concise, to-the-point introduction to functional programming designed to help you get started and start applying these concepts to your work right away.&lt;/p&gt;
&lt;p&gt;Here&apos;s what you&apos;ll learn in the course:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Higher order functions&lt;/li&gt;
&lt;li&gt;Pure functions&lt;/li&gt;
&lt;li&gt;Immutability&lt;/li&gt;
&lt;li&gt;Currying&lt;/li&gt;
&lt;li&gt;Partial application&lt;/li&gt;
&lt;li&gt;Pointfree programming&lt;/li&gt;
&lt;li&gt;Functional composition&lt;/li&gt;
&lt;li&gt;Debugging&lt;/li&gt;
&lt;li&gt;And more...&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In just 30 minutes, you&apos;ll learn more than &quot;just enough&quot;.&lt;/p&gt;
&lt;p&gt;&amp;lt;SocialPost
authorName=&quot;Kyle Shevlin&quot;
authorHandle=&quot;@kyleshevl.in&quot;
authorProfile=&quot;https://bsky.app/profile/kyleshevl.in&quot;
avatarUrl=&quot;/images/kyle-headshot.jpg&quot;
date=&quot;2019-03-22&quot;
content={&lt;code&gt;Alright, who of you is excited to learn &quot;just enough&quot; functional programming this weekend? I teach you an almost jargon-less introduction to FP to whet your appetite.&lt;/code&gt;}
/&amp;gt;&lt;/p&gt;
&lt;p&gt;Here&apos;s the course intro video. Give it a watch!&lt;/p&gt;
&lt;p&gt;&amp;lt;EggheadEmbed
src=&quot;https://egghead.io/lessons/javascript-course-introduction-to-just-enough-functional-programming-in-javascript/embed&quot;
title=&quot;Course Launch&quot;
/&amp;gt;&lt;/p&gt;
</content:encoded><category>Functional Programming</category><category>JavaScript</category></item><item><title>Your Own Gathering</title><link>https://kyleshevlin.com/your-own-gathering/</link><guid isPermaLink="true">https://kyleshevlin.com/your-own-gathering/</guid><description>People express FOMO regarding our regular gatherings for drinks and conversation here in Portland. I think you can start your own gathering and here&apos;s why.</description><pubDate>Sat, 02 Feb 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A few months back, &lt;a href=&quot;https://twitter.com/jlengstorf&quot;&gt;Jason Lengstorf&lt;/a&gt; and I started a gathering for people in Portland to get together, relax, and get to know one another. Our biggest night so far had over 30 people crowding this cozy little backroom of a local bar. It was great.&lt;/p&gt;
&lt;p&gt;A lot of people have expressed experiencing considerable FOMO since they can&apos;t make it or the desire to have something like this in their own city. I&apos;m here to tell you that you &lt;em&gt;can&lt;/em&gt;! It&apos;s simpler than it sounds. I want to let you in on all the planning Jason and I did for this gathering.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;One of us, cause I don&apos;t remember who initiated&lt;/strong&gt;: We should get some beers soon.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The other&lt;/strong&gt;: That sounds great! What if we invited a few others?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The first&lt;/strong&gt;: Awesome, let&apos;s share it on Twitter.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That&apos;s it. That&apos;s really all there was to us starting our gathering. It wasn&apos;t a lot of planning, and frankly, it hasn&apos;t been a lot of work either. Hardest part has been mentioning everyone on Twitter (a problem somewhat alleviated by our &lt;a href=&quot;https://tinyletter.com/beersatbeer-pdx&quot;&gt;newsletter&lt;/a&gt;). We wanted to get together to hangout, we wanted our friends to join us, and the opportunity to meet new people from our community. No agenda other than that.&lt;/p&gt;
&lt;h3&gt;But Kyle, You Don&apos;t Understand My Very Specific Situation!&lt;/h3&gt;
&lt;p&gt;You&apos;re right. I don&apos;t. This might not work for everyone, but I think the idea of gathering people regularly around food and drink is universal and a good starting point for community building. In most cases, all it takes is some initiative, someone to get the ball rolling.&lt;/p&gt;
&lt;p&gt;Now, I won&apos;t lie, Jason and I have a lot of initiative between us. We&apos;re both the kind of people to come up with an idea and execute it. We&apos;re also pretty decent networkers, too. Having the reach we have is helpful, but it doesn&apos;t mean you have to be us to make this work for you. I think you can create a gathering of your own with all the skills and talents you have &lt;em&gt;right now&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The reason I am so confident that you can do this is that I believe that there is nothing fundamentally special or unique about our group. Since there&apos;s nothing unique, there&apos;s essentially no part of the gathering you can&apos;t replicate (or even improve). Here are some of the mundane features that I think make our gathering successful.&lt;/p&gt;
&lt;h4&gt;No Speakers&lt;/h4&gt;
&lt;p&gt;Our agenda has never been to have a traditional meetup with speakers and food. That&apos;s not what we wanted. Because meetups are organized around speaking, any networking and relationship building ends up happening as a byproduct of proximity, that is, it happens because you&apos;re unintentionally next to each other. It does not happen through the intentional activity of community.&lt;/p&gt;
&lt;p&gt;Intention is the key difference. Having a gathering where the focus &lt;em&gt;is&lt;/em&gt; community generates opportunities for genuine networking. For example, I&apos;ve helped a couple people I didn&apos;t know before our gathering find new career opportunities already. Why? Because there was more space and room for understanding each other (and our needs) when the time allotted isn&apos;t taken up by a speaker(s) slot.&lt;/p&gt;
&lt;h4&gt;No Topic, Theme, or Agenda&lt;/h4&gt;
&lt;p&gt;Meetups tend to organize around a shared interest and attendees come to listen to someone talk about that shared interest (at least in tech meetups). This creates a fundamental problem. The shared interest increases the likelihood for redundant information transfer. That&apos;s a really boring way to say, you&apos;ve probably heard what the speaker has to say before because you&apos;re interested in the same topic and have read and watched the same things.&lt;/p&gt;
&lt;p&gt;Conferences tend to be the exception because often the talks are bit further ahead of the curve than at meetups. A new library was invented, a new technique (re)discovered. There is occasionally an incredible meetup talk (not suggesting any of mine have ever been that incredible), but on the whole, if you&apos;re staying up to date in your field, there&apos;s not a lot of new stuff being said.&lt;/p&gt;
&lt;p&gt;But here&apos;s the thing we all share: we&apos;re all humans. Getting people together with no agenda means that they can talk about whatever they want. And I do mean talk. Without speakers, everyone &lt;em&gt;participates&lt;/em&gt; to the level they want to in the gathering. Dialogues are preferable to monologues.&lt;/p&gt;
&lt;p&gt;In our gatherings, we&apos;ve talked about a wide swath of topics. We, of course, talk about tech. One time, we spent 20 minutes trying to figure out the algorithm for set of flashing lights on a jukebox because they caught our attention. We&apos;ve talked about bad managers, religion, sex, politics, marital challenges, parental challenges, what we love and hate about our city, how shitty the weather is, and how good the beer is, etc. There is no shortage of things for people in a group to talk about because we all are sharing the common experience of being alive.&lt;/p&gt;
&lt;p&gt;It sounds absurdly philosophical to put it that way, but I do think it makes a difference. I think when you don&apos;t have an agenda in the conversation, you&apos;re able to let people engage how they are most comfortable. When they are comfortable, you get to know who they really are. It creates a space of vulnerability, and vulnerability is a key ingredient in developing friendships.&lt;/p&gt;
&lt;h4&gt;Anyone Is Welcome&lt;/h4&gt;
&lt;p&gt;Yes, our group has a lot of devs. Those are the people Jason and I know. But you don&apos;t have to be a dev to join. At the moment, we have a number of designers, product managers, and significant others who aren&apos;t in tech that attend. Just recently, a young woman studying for the bar exam heard our conversation and joined us. She&apos;s now joined us twice and I hope she keeps coming. It doesn&apos;t matter who you are and what you do because of the prior principle of &quot;No agenda&quot;. There&apos;s always something we can find in common to talk about.&lt;/p&gt;
&lt;p&gt;The &quot;in group&quot; of our gathering is just anyone who decides to show up on a given day. There&apos;s no one left out because of what they do or where they are in their career. This is really important. In fact, when a person enters the room and there&apos;s no obvious spot to join in, we try and break the group up in a way that gets a new small group formed around the newcomer so no one has to deal with awkwardly standing or sitting around. Everyone who comes gets to participate.&lt;/p&gt;
&lt;h4&gt;Conclusion&lt;/h4&gt;
&lt;p&gt;I know I haven&apos;t given you precise steps on &lt;em&gt;how&lt;/em&gt; to do this, but the truth is, I think just &lt;em&gt;trying&lt;/em&gt; to start it with a few friends is enough to get the momentum going. Pick a spot, gather regularly, invite friends. Then, if you really want, follow the principles I&apos;ve laid out above. There&apos;s a good chance it won&apos;t be long until your gathering is doing well.&lt;/p&gt;
&lt;p&gt;Oh, and one last note, don&apos;t worry about &lt;em&gt;metrics&lt;/em&gt; like other meetups. A gathering like this isn&apos;t successful because of how &lt;em&gt;many&lt;/em&gt; people come, it&apos;s successful because a few people got to connect and have a good beverage and conversation. That&apos;s the only metric that matters.&lt;/p&gt;
&lt;p&gt;Alright, with that, I hope to see you at one of our gatherings if you&apos;re ever in Portland. We&apos;ll get to add your shining face to a photo like this one.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
</content:encoded><category>Thoughts</category></item><item><title>Firebase and Gatsby, Together At Last</title><link>https://kyleshevlin.com/firebase-and-gatsby-together-at-last/</link><guid isPermaLink="true">https://kyleshevlin.com/firebase-and-gatsby-together-at-last/</guid><description>Kyle Shevlin breaks down the steps it took to get Firebase, Gatsby, and Netlify to work for the new &quot;beard stroke&quot; post-liking feature of his blog</description><pubDate>Sun, 27 Jan 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;If you look just above the title of this post, you should see a beard icon and the phrase &lt;code&gt;${strokes} bestowed&lt;/code&gt;. It&apos;s a fun little indicator of how many likes this post has received to date. I built this using a &lt;a href=&quot;https://firebase.google.com/&quot;&gt;Firebase Realtime Database&lt;/a&gt;. For those of you unfamiliar with Firebase, it&apos;s a cool, JSON-based DBaaS (database-as-a-service) product from Google that I&apos;ve used in a few other projects.&lt;/p&gt;
&lt;p&gt;Firebase comes with a JavaScript SDK that&apos;s normally a cinch to hook up to a client side code. In fact, I had zero complications with combining &lt;a href=&quot;https://www.gatsbyjs.org/&quot;&gt;Gatsby&lt;/a&gt; and Firebase until I tried to deploy my new feature. That&apos;s when things started hitting the fan.&lt;/p&gt;
&lt;h3&gt;A Missing &lt;code&gt;Window&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;The first issue I ran into was when I tried to run a build. Gatsby ran into some issues with Firebase. I was really confused at first because Firebase was working just fine in Gatsby&apos;s development environment. I wasn&apos;t expecting it to crash and burn so badly when it was built.&lt;/p&gt;
&lt;p&gt;Turns out that Firebase&apos;s initialization code makes a reference to the &lt;code&gt;window&lt;/code&gt; object. This isn&apos;t a problem in development, because we&apos;re using Webpack&apos;s dev server. But running &lt;code&gt;gatsby build&lt;/code&gt; is a bit different. &lt;code&gt;window&lt;/code&gt; does not exist in the build environment and you have to be careful where and when you try to access the object. Firebase was crashing every build because it was trying to access a property on this non-existent object.&lt;/p&gt;
&lt;p&gt;Ok, how do we solve this?&lt;/p&gt;
&lt;p&gt;After going down a few wrong paths (and reading some Github issues), I landed on a solution I&apos;m pretty happy with. I ended up changing how, more precisely &lt;em&gt;when&lt;/em&gt;, Firebase was initialized in the application. At first, I followed a tried and true method for initializing the app that looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import firebase from &apos;firebase/app&apos;
import &apos;firebase/database&apos;

const config = {
  apiKey: process.env.FIREBASE_API_KEY,
  authDomain: process.env.FIREBASE_AUTH_DOMAIN,
  databaseURL: process.env.FIREBASE_DATABASE_URL,
  projectId: process.env.FIREBASE_PROJECT_ID,
  storageBucket: process.env.FIREBASE_STORAGE_BUCKET,
  messagingSenderId: process.env.FIREBASE_MESSAGING_SENDER_ID,
}

firebase.initializeApp(config)

export default firebase

export const database = firebase.database()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With this strategy, I have a file, &lt;code&gt;firebase.js&lt;/code&gt;, that initializes the app right away and exports the initialized &lt;code&gt;firebase&lt;/code&gt; instance around the application. More importantly, it exports my &lt;code&gt;database&lt;/code&gt; around the application to be used in whatever components need to hook up to it.&lt;/p&gt;
&lt;p&gt;The problem with this strategy, as mentioned before, is that the &lt;code&gt;window&lt;/code&gt; object is not available to the &lt;code&gt;initializeApp&lt;/code&gt; method during the build process (not to mention, those environment variables aren&apos;t correct either, but I&apos;ll address that later in the post).&lt;/p&gt;
&lt;p&gt;To solve this, I need Firebase to delay initializing until we&apos;re in the client side environment. But, I still want to have a single instance in the app and a way to export the database. This calls for a refactor that makes use of &lt;strong&gt;dynamic imports&lt;/strong&gt; and a &lt;strong&gt;singleton pattern&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Let&apos;s make it happen.&lt;/p&gt;
&lt;h3&gt;Simple Functions to the Rescue&lt;/h3&gt;
&lt;p&gt;Often, I often find a simple function ends up being the best solution to a problem. First, I started by changing the code in &lt;code&gt;firebase.js&lt;/code&gt; to look like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const config = {
  apiKey: process.env.FIREBASE_API_KEY,
  authDomain: process.env.FIREBASE_AUTH_DOMAIN,
  databaseURL: process.env.FIREBASE_DATABASE_URL,
  projectId: process.env.FIREBASE_PROJECT_ID,
  storageBucket: process.env.FIREBASE_STORAGE_BUCKET,
  messagingSenderId: process.env.FIREBASE_MESSAGING_SENDER_ID,
}

let firebaseInstance
export const getFirebase = firebase =&amp;gt; {
  if (firebaseInstance) {
    return firebaseInstance
  }

  firebase.initializeApp(config)
  firebaseInstance = firebase

  return firebase
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We don&apos;t import any of the &lt;code&gt;firebase&lt;/code&gt; packages into the module. Instead, we export a function that receives the &lt;code&gt;firebase&lt;/code&gt; package as an argument. Inside this function, we check that an instance of &lt;code&gt;firebase&lt;/code&gt; does not previously exist (held in closure by the module). If it does exist, return the initialized instance, otherwise proceed with initializing &lt;code&gt;firebase&lt;/code&gt; and return it. This is the singleton pattern I mentioned before.&lt;/p&gt;
&lt;p&gt;Now, in the components that need &lt;code&gt;firebase&lt;/code&gt;, I can wait until the &lt;code&gt;componentDidMount&lt;/code&gt; lifecycle method has been called, which guarantees that the &lt;code&gt;window&lt;/code&gt; object exists. Once I can make this guarantee, I can then &lt;em&gt;dynamically import&lt;/em&gt; the &lt;code&gt;firebase&lt;/code&gt; modules I need and pass them into my function. The &lt;code&gt;firebase&lt;/code&gt; instance is returned from the function, which I can then get the database from. That code looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;componentDidMount() {
  const lazyApp = import(&apos;firebase/app&apos;)
  const lazyDatabase = import(&apos;firebase/database&apos;)

  Promise.all([lazyApp, lazyDatabase]).then(([firebase]) =&amp;gt; {
    const database = getFirebase(firebase).database()
    // do something with `database` here,
    // or store it as an instance variable or in state
    // to do stuff with it later
  })
}

// I might update this with hooks once they&apos;re released officially.
// You&apos;ll have to come back and find out.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With this code in place, I can make reads and writes to the Firebase database from a component. I &lt;em&gt;thought&lt;/em&gt; this would be the end of my problems. I was wrong.&lt;/p&gt;
&lt;h3&gt;Gatsby, Netlify, and Environment Variables&lt;/h3&gt;
&lt;p&gt;Now, before I go into this I want to make it clear, I read the documentation for all of these things: Gatsby&apos;s environment variables, Netlify&apos;s environment variables. I thought I had it all set up correctly. I did not. I ended up reading (and reading) the docs a few more times before I finally understood what I needed to do.&lt;/p&gt;
&lt;p&gt;For those of you who might not be familiar with &lt;strong&gt;environment variables&lt;/strong&gt;, let me give you a brief explanation. As the name suggests, these are variables that are exposed to a particular environment, such as &lt;code&gt;development&lt;/code&gt;, &lt;code&gt;test&lt;/code&gt;, or &lt;code&gt;production&lt;/code&gt;. For example, you might want to have an &lt;code&gt;API_ENDPOINT&lt;/code&gt; variable in your code that is different depending on whether you&apos;re in &lt;code&gt;development&lt;/code&gt; or &lt;code&gt;production&lt;/code&gt;. Thus, you inject these different values into the environment when it is instantiated, and they&apos;re made available to your code via the &lt;code&gt;process.env&lt;/code&gt; object.&lt;/p&gt;
&lt;p&gt;Environment variables are a great way to keep private code private (yes, I know it&apos;s not perfect, but bear with me. You can read up about the challenges of environment variables elsewhere). Gatsby and Netlify both have a way to inject these variables into your build. But there&apos;s a bit of a catch with Gatsby.&lt;/p&gt;
&lt;p&gt;Gatsby makes a distinction between two kinds of environment variables. They call them &quot;Project env vars&quot; and &quot;OS env vars&quot;. In my original implementation, I did not prefix my env vars with &lt;code&gt;GATSBY_&lt;/code&gt;, thinking I understood how these variables worked. My code was working locally, my environment variables were correctly injected and Firebase was initializing, but I soon realized that none of my variables were getting injected properly in the production build.&lt;/p&gt;
&lt;p&gt;I was baffled, I had also set up my variables correctly with Netlify. I double and triple checked them. Then, I read the docs again and realized that Gatsby will only make available &quot;OS env vars&quot; to Netlify&apos;s build. Thus I needed to prefix all my env vars in my project, in my local &lt;code&gt;.env.*&lt;/code&gt; files, and on Netlify with &lt;code&gt;GATSBY_&lt;/code&gt;. As soon as I did that, the build passed and my blog was back to working.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// adding `GATSBY_` made it all better
const config = {
  apiKey: process.env.GATSBY_FIREBASE_API_KEY,
  authDomain: process.env.GATSBY_FIREBASE_AUTH_DOMAIN,
  databaseURL: process.env.GATSBY_FIREBASE_DATABASE_URL,
  projectId: process.env.GATSBY_FIREBASE_PROJECT_ID,
  storageBucket: process.env.GATSBY_FIREBASE_STORAGE_BUCKET,
  messagingSenderId: process.env.GATSBY_FIREBASE_MESSAGING_SENDER_ID,
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Gatsby and Firebase will work great together, but you&apos;ll have to ensure that Firebase isn&apos;t initialized until the &lt;code&gt;window&lt;/code&gt; object is available. And double check your environment variables setup if you&apos;re struggling to get them defined during Netlify&apos;s build of your app.&lt;/p&gt;
&lt;p&gt;Best of luck if you run into similar problems. Let me know what you think of my solution on Twitter!&lt;/p&gt;
</content:encoded><category>Firebase</category><category>Gatsby</category><category>React</category></item><item><title>State Machines: The XState Visualizer</title><link>https://kyleshevlin.com/xstate-visualizer/</link><guid isPermaLink="true">https://kyleshevlin.com/xstate-visualizer/</guid><description>Sometimes seeing is understanding. XState provides a visualizer tool that allows us to see our state machine as a graphical interface, and not just code.</description><pubDate>Thu, 24 Jan 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I made mention in my &lt;a href=&quot;/what-are-state-machines&quot;&gt;&quot;What Are State Machines?&quot; post&lt;/a&gt; of the fact that a state machine is a graph data structure. Each state a node. Each transition an edge triggered by an event. You remember, right? No worries if you don&apos;t, now you know.&lt;/p&gt;
&lt;p&gt;I also mentioned you can do cool things like create a graphical representation of your state machine &lt;em&gt;because&lt;/em&gt; of this data structure. Well, I have good news. XState has a &lt;a href=&quot;https://statecharts.github.io/xstate-viz/&quot;&gt;state machine visualizer tool&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The XState Visualizer allows you to &lt;em&gt;see&lt;/em&gt; your state machine in action, which might be really handy for those of you who grok things visually. Let&apos;s take a look at it.&lt;/p&gt;
&lt;p&gt;Open up the XState Visualizer in another tab with this link: &lt;a href=&quot;https://statecharts.github.io/xstate-viz/&quot;&gt;https://statecharts.github.io/xstate-viz/&lt;/a&gt;. You&apos;ll see an example of a stop light in the visualizer by default. On the left, is the graphical representation, and on the right is the code to produce that representation.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;On the left, each &quot;box&quot; represents one of our states. The initial state is indicated by the &quot;dot and arrow&quot; you see pointing to the &quot;green&quot; state. The highlighted state (indicated by the blue color), is the state the machine is currently in. The buttons inside each box will trigger the event with that name, and move it into the state it points to with the arrow. Give it a try.&lt;/p&gt;
&lt;p&gt;Clicking the &quot;TIMER&quot; button will move the state to &quot;yellow&quot;. Notice that the state and buttons that are not enabled become gray. You can continue to click event buttons to move the state along.&lt;/p&gt;
&lt;p&gt;Another way to trigger events in the visualizer is manually in the &quot;State&quot; tab in the panel on the right. Click into the State tab, and you should see several items: Value, Context, Actions. At the bottom of the tab is an area for Events, where you can write your own and trigger them with the &quot;Send Event&quot; button. Since the light machine only has one event, try sending the &lt;code&gt;TIMER&lt;/code&gt; event and watch the state update.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Just like clicking the event buttons inside our state boxes, sending events manually also updates the state. I&apos;ll discuss the extra parts of this tab, &lt;strong&gt;context&lt;/strong&gt; and &lt;strong&gt;actions&lt;/strong&gt;, soon.&lt;/p&gt;
&lt;p&gt;Now that you know the basics of using the visualizer, try it out and get a feel for it. If you don&apos;t know where to start, why not start by copy/pasting the code from the elevator example in my &lt;a href=&quot;/our-first-xstate-machine&quot;&gt;&quot;Our First XState Machine&quot; post&lt;/a&gt;. Update the elevator as you go. Can you figure out a way to add an &lt;code&gt;open&lt;/code&gt; and &lt;code&gt;closed&lt;/code&gt; state to the elevator doors? Better yet, figure out how restrict the elevator to only moving up and down while the doors are closed. Send me your answers on Twitter when you do!&lt;/p&gt;
</content:encoded><category>State Machines</category></item><item><title>State Machines: Our First XState Machine</title><link>https://kyleshevlin.com/our-first-xstate-machine/</link><guid isPermaLink="true">https://kyleshevlin.com/our-first-xstate-machine/</guid><description>How do we create a state machine using the XState library. In this article, we will create our first state machine using XState.</description><pubDate>Tue, 22 Jan 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import { Elevator } from &apos;./_Elevator&apos;&lt;/p&gt;
&lt;p&gt;In a &lt;a href=&quot;/what-are-state-machines&quot;&gt;previous post&lt;/a&gt;, I explained what a state machine is and how to build one from scratch. In this post, we&apos;re going to learn how to make our first state machine using the &lt;a href=&quot;https://xstate.js.org&quot;&gt;XState library&lt;/a&gt;. First step? You guessed it. Install the library into your project.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npm install --save xstate
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, we&apos;re going to get the &lt;code&gt;Machine&lt;/code&gt; function and the &lt;code&gt;interpret&lt;/code&gt; function from the library. These functions are very similar to the ones I made in the other post, so these might seem familiar.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { Machine } from &apos;xstate&apos;
import { interpret } from &apos;xstate/lib/interpreter&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, let&apos;s create an example. I&apos;m going to use the same example that I used in an &lt;a href=&quot;https://egghead.io/lessons/javascript-handle-state-transitions-through-events-in-a-finite-state-machine-with-xstate/?af=8u8eik&quot;&gt;egghead lesson I made to introduce this topic&lt;/a&gt;, an elevator. Specifically, a single elevator box.&lt;/p&gt;
&lt;p&gt;The box of an elevator can have three possible states: stopped, moving up, or moving down. Let&apos;s start configuring our &lt;code&gt;elevatorMachine&lt;/code&gt; with these states.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { Machine } from &apos;xstate&apos;
import { interpret } from &apos;xstate/lib/interpreter&apos;

const elevatorMachine = Machine({
  states: {
    stop: {},
    up: {},
    down: {},
  },
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&apos;s give our machine an initial state of &lt;code&gt;stop&lt;/code&gt; next.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { Machine } from &apos;xstate&apos;
import { interpret } from &apos;xstate/lib/interpreter&apos;

const elevatorMachine = Machine({
  initial: &apos;stop&apos;,
  states: {
    stop: {},
    up: {},
    down: {},
  },
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, we need to define the transitions for each state. For each state of our elevator machine, we can transition to the other two possible states. With XState, we define these using a state&apos;s &lt;code&gt;on&lt;/code&gt; property, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { Machine } from &apos;xstate&apos;
import { interpret } from &apos;xstate/lib/interpreter&apos;

const elevatorMachine = Machine({
  initial: &apos;stop&apos;
  states: {
    stop: {
      on: {
        UP: &apos;up&apos;,
        DOWN: &apos;down&apos;
      }
    },
    up: {
      on: {
        STOP: &apos;stop&apos;,
        DOWN: &apos;down&apos;
      }
    },
    down: {
      on: {
        STOP: &apos;stop&apos;,
        UP: &apos;up&apos;
      }
    }
  }
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now that we&apos;ve enumerated our states and event transitions, we can use the &lt;code&gt;interpret&lt;/code&gt; function to make our machine useful. This function will allow us to define an action to occur for each transition, as well as start the machine itself.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { Machine } from &apos;xstate&apos;
import { interpret } from &apos;xstate/lib/interpreter&apos;

// ...previous code for our machine

const elevatorService = interpret(elevatorMachine)
  .onTransition(state =&amp;gt; {
    console.log(state.value)
  })
  .start() // &apos;stop&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we can use the &lt;code&gt;send&lt;/code&gt; method on our &lt;code&gt;elevatorService&lt;/code&gt; to send events and update the state.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;elevatorService.send(&apos;UP&apos;) // &apos;up&apos;
elevatorService.send(&apos;DOWN&apos;) // &apos;down&apos;
elevatorService.send(&apos;STOP&apos;) // &apos;stop&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, what happens if we send an event that&apos;s &lt;em&gt;not&lt;/em&gt; one of the enumerated possibilities?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;elevatorService.send(&apos;FOO&apos;) // &apos;stop&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Absolutely nothing! Which is exactly what we want to happen. Only defined events should have an effect on our machine. That being said, you might be the sort of person who wants to throw up a red flag, so to speak, when something like this might occur. In that case, XState machines can be put into &lt;em&gt;strict mode&lt;/em&gt;. In strict mode, a machine will throw an error when a non-enumerated event is sent.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const elevatorMachine = Machine({
  strict: true,
  // ...the rest of the machine configuration from before
})

// ...and all the interpreter code from before as well
elevatorService.send(&apos;FOO&apos;)
// Error: Machine &apos;(machine)&apos; does not accept event &apos;FOO&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Whoops! XState didn&apos;t like that. An error was thrown indicating an unaccounted event was attempted, but the error message leaves something wanting. Wouldn&apos;t it be nice to be able to identify &lt;em&gt;what machine&lt;/em&gt; broke in the message? This is where giving a state machine an &lt;code&gt;id&lt;/code&gt; can be really handy.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const elevatorMachine = Machine({
  id: &apos;elevator-1&apos;,
  // ... the rest of the machine configuration from before
})

// ...and all the interpreter code from before as well
elevatorService.send(&apos;FOO&apos;)
// Error: Machine &apos;elevator-1&apos; does not accept event &apos;FOO&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And with that, we&apos;ve finished making our first state machine with XState. I hope that you find this helpful as you get started using the library. I&apos;ll cover all the important parts with more depth soon.&lt;/p&gt;
&lt;p&gt;If you&apos;d like to see some of this code in action, you can check out this quick CodeSandbox I made below. Using only plain JavaScript, I added some buttons and a little &quot;elevator&quot; that the state machine controls. Try it out. I recommend hitting the &quot;DOWN&quot; button first, the elevator &lt;em&gt;will&lt;/em&gt; go through the roof if you don&apos;t!&lt;/p&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;Elevator client:load /&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
</content:encoded><category>State Machines</category></item><item><title>State Machines: What Are They?</title><link>https://kyleshevlin.com/what-are-state-machines/</link><guid isPermaLink="true">https://kyleshevlin.com/what-are-state-machines/</guid><description>What is a state machine? A state machine is a way to represent all the enumerated possible states and events of a given system. In this article, we will create a rudimentary state machine and interpreter in JavaScript.</description><pubDate>Mon, 21 Jan 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Defining and managing state in software is a difficult challenge. Even simple systems can often be more complicated than they first seem. State machines provide a reliable interface for handling these systems and are capable of handling problems from the simple to the highly complex.&lt;/p&gt;
&lt;p&gt;A state machine, more specifically a &lt;em&gt;finite&lt;/em&gt; state machine, is an API that enumerates all the possible (and thus finite) states of a system. For each of these states, a set of &lt;code&gt;events&lt;/code&gt; is enumerated which defines the possible transitions between states. A state machine can &lt;em&gt;only&lt;/em&gt; ever be in a single state at a time and is only transitioned to a new state by an event.&lt;/p&gt;
&lt;p&gt;By defining all the finite possibilities of our machine&apos;s states and events, we create a graph data structure describing our system. Each node represents a state, each edge a possible event from that state. There are a lot of cool things we can do with state machines because of this (like auto-generating visualizations of our system) that will be covered in future blog posts.&lt;/p&gt;
&lt;h3&gt;A Simple Example&lt;/h3&gt;
&lt;p&gt;Let&apos;s consider a very simple example, a light switch. A light switch has two finite states, an &lt;code&gt;on&lt;/code&gt; state and an &lt;code&gt;off&lt;/code&gt; state. Let&apos;s write a rudimentary form of a state machine representing a light switch in JavaScript as we go. You can follow along in an online editor such as &lt;a href=&quot;https://codesandbox.io/s/vanilla&quot;&gt;CodeSandbox&lt;/a&gt; or &lt;a href=&quot;https://jsbin.com/?js,console&quot;&gt;JSBin&lt;/a&gt; if you&apos;d like. I&apos;m going to use whatever data structure comes naturally to me and make changes as necessary. Since we&apos;re listing out states, let&apos;s start with an array.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const lightSwitch = {
  states: [&apos;on&apos;, &apos;off&apos;],
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A state machine also requires an initial state, so let&apos;s add that as well. We&apos;ll set our switch to &lt;code&gt;&apos;off&apos;&lt;/code&gt;. We should be energy conscious with our example, of course.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const lightSwitch = {
  initial: &apos;off&apos;,
  states: [&apos;on&apos;, &apos;off&apos;],
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, for each of these states, we need to define possible &lt;code&gt;events&lt;/code&gt;. That is, when a transition is attempted with a given event, what state should we derive next depending on the event? In the case of a light switch, there really is only one event, &lt;code&gt;SWITCH&lt;/code&gt;. This &lt;code&gt;SWITCH&lt;/code&gt; event transitions our machine to the opposite state.&lt;/p&gt;
&lt;p&gt;Since these events correspond with each state, an array no longer serves our purposes well, so we will use an object instead. Each key in the first level of our &lt;code&gt;states&lt;/code&gt; object will correspond with a possible state of our machine. Each state will then have an &lt;code&gt;events&lt;/code&gt; object enumerating the possible events for that state. Each key in the &lt;code&gt;events&lt;/code&gt; object will be the name of our event, in this case &lt;code&gt;SWITCH&lt;/code&gt;, and the corresponding value will be the name of the next state.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const lightSwitch = {
  initial: &apos;off&apos;,
  states: {
    on: {
      events: {
        SWITCH: &apos;off&apos;,
      },
    },
    off: {
      events: {
        SWITCH: &apos;on&apos;,
      },
    },
  },
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now that we&apos;ve enumerated the possibilities of our light switch, we need a function that can take a machine, interpret it, and give us back the correct state. Thus, let&apos;s implement a state machine &lt;code&gt;interpreter&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Our &lt;code&gt;interpreter&lt;/code&gt; will take a &lt;code&gt;machine&lt;/code&gt; as an argument, and expose a set of methods that can be used to get the current state of the machine or attempt a transition on the machine.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const interpreter = machine =&amp;gt; {
  // We store the current state in closure
  // keeping the value in memory
  let currentState = machine.initial

  return {
    currentState() {
      return currentState
    },
    transition(event) {
      // Since we enumerated all possible events
      // for each state, our next state is either
      // the defined state for that event,
      // or it is undefined, and thus we can
      // return the currentState
      const nextState =
        machine.states[currentState].events[event] || currentState
      currentState = nextState
      return nextState
    },
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we can use the &lt;code&gt;interpreter&lt;/code&gt; on our &lt;code&gt;lightSwitch&lt;/code&gt; machine and see it in action.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// ...code from before
const mySwitch = interpreter(lightSwitch)

// Try the current state
console.log(mySwitch.currentState()) // &apos;off&apos;

// Try a defined transition
console.log(mySwitch.transition(&apos;SWITCH&apos;)) // &apos;on&apos;

// Try an undefined transition
console.log(mySwitch.transition(&apos;FOO&apos;)) // &apos;on&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As you can see, our rudimentary machine and interpreter creates a pretty solid interface for managing the state of the light switch. Our light switch can never get into a &quot;bad state&quot;, and it&apos;s completely inert to events that we have not defined. This should give us a lot of confidence in our application.&lt;/p&gt;
&lt;p&gt;We can easily add methods and properties to this interface to enhance its functionality, too. For example, we could add a method to the &lt;code&gt;interpreter&lt;/code&gt; to return all the possible events for a given state.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// ...inside the object returned from `interpreter`
allEvents() {
  const { events = {} } = machine.states[currentState]
  return Object.keys(events)
}

// ...further down
console.log(mySwitch.allEvents()) // [&apos;SWITCH&apos;]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are a lot more possibilities to enhance this rudimentary state machine, but I&apos;d rather focus on a &lt;em&gt;real&lt;/em&gt; state machine library in future blog posts. As I continue to write and explore this topic, I&apos;ll start using the &lt;a href=&quot;https://xstate.js.org&quot;&gt;XState library&lt;/a&gt; by &lt;a href=&quot;https://twitter.com/davidkpiano&quot;&gt;David Khourshid&lt;/a&gt;. I encourage you to check it out and read up on it in the meantime. &lt;a href=&quot;https://www.youtube.com/watch?v=VU1NKX6Qkxc&quot;&gt;David&apos;s talk at React Rally&lt;/a&gt; is what initially inspired my interest in state machines and is something you should definitely watch. Alright, see you in the next blog post!&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Let&apos;s not leave the light on
console.log(mySwitch.transition(&apos;SWITCH&apos;)) // &apos;off&apos;
&lt;/code&gt;&lt;/pre&gt;
</content:encoded><category>State Machines</category></item><item><title>Why I Rewrote My Blog With Gatsby</title><link>https://kyleshevlin.com/why-i-rewrote-my-blog-with-gatsby/</link><guid isPermaLink="true">https://kyleshevlin.com/why-i-rewrote-my-blog-with-gatsby/</guid><description>Learn why I recently had to abandon my WordPress setup and opted for Gatsby instead.</description><pubDate>Wed, 09 Jan 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import SocialPost from &apos;../../../components/SocialPost.astro&apos;&lt;/p&gt;
&lt;p&gt;A couple weeks back now, I was starting to write a blog post to recap my 2018. I thought it would be a good idea to reference my goals for 2018 and started to review that post when I discovered something interesting. As I was reading a paragraph, I noticed some words that didn&apos;t sound like my voice. As I read further, there was a link to an air compressor. I assure you, I don&apos;t own an air compressor (yet) and I certainly would never put it in my article about my 2018 goals.&lt;/p&gt;
&lt;p&gt;That&apos;s when I realized that I had been hacked. Fuck.&lt;/p&gt;
&lt;p&gt;Here&apos;s a tweet thread regaling my woes that evening as I discovered the hacker had been changing my posts for &lt;em&gt;four whole months&lt;/em&gt;!&lt;/p&gt;
&lt;p&gt;&amp;lt;SocialPost
authorName=&quot;Kyle Shevlin&quot;
authorHandle=&quot;@kyleshevl.in&quot;
authorProfile=&quot;https://bsky.app/profile/kyleshevl.in&quot;
avatarUrl=&quot;/images/kyle-headshot.jpg&quot;
date=&quot;2018-12-29&quot;
content=&quot;This really makes me feel good. I&apos;m working on a blog post and
referencing an old post of mine when I noticed that there was copy I
DEFINITELY did not put in the post. Turns out the post was updated 4 weeks
ago. FUCK.&quot;
/&amp;gt;&lt;/p&gt;
&lt;p&gt;I never did find the exact point of weakness that the hacker used to get in and mess with my stuff, but I suspect it comes from my inattentiveness to updating plugins and WordPress itself. It would be nice to be able to trust something like that to be secure, but it seems weaknesses are found and exploited regularly.&lt;/p&gt;
&lt;p&gt;I took the steps of changing all my database users and their passwords (including the root user), repaired all the damage that was done and then some. But after doing all this, there&apos;s still no guarantee that 1) the intruder had been locked out of the system and 2) that this wouldn&apos;t happen again when I forgot to update a plugin a month from now. This put me in a tough spot.&lt;/p&gt;
&lt;p&gt;On the one hand, I &lt;em&gt;really&lt;/em&gt; don&apos;t like rewriting my blog, or even putting that much work into it. I like it functional and simple and that way I don&apos;t waste time rewriting it every year. I think devs everywhere waste a lot of time in this fashion, when they could put that time and energy to much better uses.&lt;/p&gt;
&lt;p&gt;On the other hand, I now have a blog that&apos;s weak and vulnerable. It&apos;s irresponsible of me not to try and remove attack vectors if I can.&lt;/p&gt;
&lt;p&gt;So I bit the bullet, and decided to rebuild my blog on &lt;a href=&quot;https://www.gatsbyjs.org/&quot;&gt;Gatsby&lt;/a&gt;, and let me tell you, it was a blast!&lt;/p&gt;
&lt;p&gt;Overall, my experience rewriting the blog (and streaming it while I did it) was really positive. I hit a few snags, but for the most part, there was always someone or some good documentation that was available to help me get through it. I think I was able to complete the rewrite in under 30 hours, which is pretty good.&lt;/p&gt;
&lt;p&gt;What&apos;s great about having done this is that now I have a much more comfortable framework to make updates to the blog. You may notice a few improvements around here. My face is now at the bottom of each post, my latest &lt;a href=&quot;https://egghead.io/courses/data-structures-and-algorithms-in-javascript/?af=8u8eik&quot;&gt;egghead course&lt;/a&gt; is now present at the bottom of each page. I already have plans to add features such as pages to sell courses and workshops and more. I think Gatsby and it&apos;s vast ecosystem of plugins gives me a ton of power and flexibility, all while being really safe. No more updating plugins. I just build the site and host the static pages. It&apos;s quite amazing.&lt;/p&gt;
&lt;p&gt;On top of that, I moved my hosting to &lt;a href=&quot;https://netlify.com&quot;&gt;Netlify&lt;/a&gt; which means I don&apos;t even have to pay for a server anymore. I am going to save $60 bucks a year by making this change. That&apos;s pretty cool if you ask me.&lt;/p&gt;
&lt;p&gt;In the near future, I&apos;ll write more in depth about my process of converting the blog and make a few posts about Gatsby and Netlify. Should be a lot of fun.&lt;/p&gt;
&lt;p&gt;Let me know if you have any questions about Gatsby on &lt;a href=&quot;https://twitter.com/kyleshevlin&quot;&gt;Twitter&lt;/a&gt;. Happy to help if I can!&lt;/p&gt;
</content:encoded><category>Gatsby</category><category>React</category></item><item><title>The Importance of Competing Thoughts</title><link>https://kyleshevlin.com/the-importance-of-competing-thoughts/</link><guid isPermaLink="true">https://kyleshevlin.com/the-importance-of-competing-thoughts/</guid><description>Sometimes it&apos;s important to hold two or more competing thoughts at the same time.</description><pubDate>Sat, 10 Nov 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Before I dive into this idea of mine, I want to tell you, I&apos;ve been scared to write it out. It&apos;s been in my head for a few months, but I&apos;m genuinely nervous to share it with others. I don&apos;t know how you&apos;re going to receive it. Hopefully well, because I&apos;m going for it.&lt;/p&gt;
&lt;p&gt;Some of you might know, I was a pretty good college golfer. For about 8 years of my life, my only real goal was to be a professional golfer. That didn&apos;t end up working out (I&apos;m honestly kind of glad it didn&apos;t now, but it really hurt at the time.), but it did provide me with a lot of lessons to draw from that are useful in everyday life.&lt;/p&gt;
&lt;p&gt;One of those lessons is this: in golf, and sports in general, in order to perform your very best, you have to be able to hold pairs of competing thoughts in your head. You have to completely and sincerely believe both, potentially paradoxical, concepts simultaneously. Here&apos;s an example:&lt;/p&gt;
&lt;p&gt;When you are competing and performing, you have to believe fully that if you are on a &quot;hot streak&quot;, that that streak will never end. You also have to believe that when you are having a &quot;cold streak&quot;, that you can turn it completely around on the very next shot.&lt;/p&gt;
&lt;p&gt;All hot streaks come to an end. All cold streaks come to an end. Averages exist because, over time, we perform... average. But, if you want to max out a hot streak, get everything you can out of it, the only way to do it is to block out the absolutely logical thing to think, &quot;This could end at any moment.&quot; You must commit yourself to the &lt;em&gt;fact&lt;/em&gt; that you cannot miss, that you have the hottest hand, and there is no end in sight. The moment you think about the streak or doubt yourself, it&apos;s likely over.&lt;/p&gt;
&lt;p&gt;The same goes for when you&apos;re playing really poorly. If you&apos;re playing badly, it&apos;s likely there are errors upon errors compounding, some mental, some physical, and many of which you don&apos;t even fully understand. But, in order to get out of it, you have to think as positively as humanly possible. You have to block out any thought that says you&apos;re going to continue to screw up as you have. You have to fully believe the &lt;em&gt;fact&lt;/em&gt; that you&apos;ll snap out of it, even though there is no evidence at the moment that you will.&lt;/p&gt;
&lt;p&gt;I think learning to hold competing concepts in your brain has a lot to do with how you can be successful at any venture, including being a good software engineer.&lt;/p&gt;
&lt;p&gt;I have had one of these competing thoughts on repeat in my brain for several months that is helping me keep &lt;em&gt;myself&lt;/em&gt; in check. It&apos;s been helping me get refocused and progressing towards my goals. Those thoughts are these:&lt;/p&gt;
&lt;p&gt;There are almost 7.8 billion people on the planet, &lt;strong&gt;I am completely unique&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;There are almost 7.8 billion people on the planet, &lt;strong&gt;I am not special&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;I am unique. I am the only combination of &lt;em&gt;these&lt;/em&gt; genes that exists or will exist in the known universe. I find joy in the qualities and personal philosophies that make me &lt;em&gt;me&lt;/em&gt;. Why shouldn&apos;t I? I believe that the value I offer to the world stems from, at least in part, the unique person I am. I bring something to the table no one else. Not sure what that is, but it&apos;s something. That being said, I can&apos;t let my uniqueness lead to a false belief of superiority or entitlement.&lt;/p&gt;
&lt;p&gt;With so many people on the planet, it is highly unlikely that I am &lt;em&gt;actually&lt;/em&gt; all that unique. Practically, every combination of person and personality exists. I might work hard, but guess what, there are many who also work hard, many who work harder. I might be smart, but guess what, there are many who are smart, and many who are smarter. If I want to achieve some goal in life, I have to be willing to believe that I am &lt;em&gt;not&lt;/em&gt; special, that I don&apos;t deserve to achieve those things by merit of simply being who I am, or believing the things I do. This is the nature of entitlement. That we have earned things we haven&apos;t. Deserve things we don&apos;t. No, I have to be willing to put in the work to achieve those things. If I don&apos;t work hard, at least one of the other 7.8 billion people on the planet &lt;em&gt;will&lt;/em&gt; work that hard. Probably even harder.&lt;/p&gt;
&lt;p&gt;Now, I&apos;m not suggesting that we all become workaholics, that would contradict the opening of this newsletter. I stand behind what I said. We all deserve breaks. But the work that you need to do won&apos;t magically get done either.&lt;/p&gt;
&lt;p&gt;You need to hold two competing thoughts. You are special. You have value. You bring something to the table that others don&apos;t. This will help you find that job, get that promotion, foster a new opportunity.&lt;/p&gt;
&lt;p&gt;You aren&apos;t special at all. You&apos;re just another human being, trying to make the most out of their time on this planet. If you want something, you have to do the work to get it. You don&apos;t deserve it just because of who you are.&lt;/p&gt;
&lt;p&gt;I have been saying these things to myself a lot lately. I have something to offer companies, people, the industry, the community. I have a unique voice to share and it is worth something.&lt;/p&gt;
&lt;p&gt;But I&apos;m also just a person. A person who needs to stay focused and decide what I want in life and go after it because a great life isn&apos;t just going to &lt;em&gt;appear&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;You might need to tell yourself the same. You are special. You are like everyone else. You&apos;re awesome. You&apos;re ordinary.&lt;/p&gt;
&lt;p&gt;There&apos;s nothing wrong with holding two, or even three or more, competing beliefs. The key is knowing what belief applies to what. If I say that I&apos;m special and thus deserve a raise without doing the work, then I&apos;m entitled and just an ass. If I devalue who I am as a person because I don&apos;t believe I have anything special about me, then I hurt myself.&lt;/p&gt;
&lt;p&gt;I&apos;m guessing that some of you do the same to yourself, too. Remember, I&apos;m not that special. I&apos;m probably not the only one.&lt;/p&gt;
</content:encoded><category>Thoughts</category></item><item><title>The Role of Timing In a Job Hunt</title><link>https://kyleshevlin.com/the-role-of-timing-in-a-job-hunt/</link><guid isPermaLink="true">https://kyleshevlin.com/the-role-of-timing-in-a-job-hunt/</guid><description>A discussion on the role of timing in your job hunt.</description><pubDate>Wed, 10 Oct 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In my &lt;a href=&quot;https://kyleshevlin.com/how-to-be-more-successful-on-your-next-web-developer-job-hunt/&quot;&gt;last blog post&lt;/a&gt;, I shared with you several tips on how to make that hunt go better for you. We talked about how shifting our mindset to &quot;seeking offers&quot; instead of &quot;getting a job&quot; puts us in a position to &quot;explore&quot; rather than &quot;judge&quot;. We need to explore many paths and options when trying to find the next step in our career. This week, I&apos;m going to continue to discuss the job hunt by sharing an anecdote from this week and how that might relate to you.&lt;/p&gt;
&lt;p&gt;When I initially put the word out that I was looking for a job, a friend I made at React Rally 2017 reached out with a great opportunity. The position was for a company whose product I really respect. I could see myself &lt;em&gt;actually&lt;/em&gt; caring about it and even evangelizing for. I don&apos;t say that about a lot of products. Their technology stack fits perfectly with my skill set. It was a Bay Area company (good salary!) but I could work remotely (no relocation!) which is, in my opinion, the best combination. Not to mention I&apos;d be working with a friend.&lt;/p&gt;
&lt;p&gt;We schedule a time to hash out the details of the position. The day comes, we chat, and we feel really aligned. This could be a great fit. He starts working it up the chain to his manager. Gets the go ahead to proceed from them. Works it up one more level. Gets the go ahead from them.&lt;/p&gt;
&lt;p&gt;But it had to go up one more level.&lt;/p&gt;
&lt;p&gt;And it didn&apos;t get the go ahead from them.&lt;/p&gt;
&lt;p&gt;My buddy gets back to me with the bad news. So and so doesn&apos;t want to hire any remotes at this time. They also don&apos;t want to revisit the idea &lt;strong&gt;until Q2 of next year&lt;/strong&gt;. Obviously longer than I can wait.&lt;/p&gt;
&lt;p&gt;Shit.&lt;/p&gt;
&lt;p&gt;Now, I&apos;m not going to dwell on this much longer than it takes me to write this post to you all, but it demonstrates an important part of a job hunt—&lt;em&gt;timing&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;I believe that we give our industry a tad too much credit for being &lt;em&gt;meritocratic&lt;/em&gt;, that is, advancement is based upon what you have done and accomplished. There&apos;s certainly &lt;em&gt;some&lt;/em&gt; element of meritocracy, it&apos;s not often that someone completely inept lands a coveted position for very long, but there are plenty of other variables at play in who gets which job in our industry.&lt;/p&gt;
&lt;p&gt;One of those variables (and there are many) is timing. This could be your timing, their timing, or even someone else&apos;s timing. And if you don&apos;t learn to roll with it, it can really wreck you.&lt;/p&gt;
&lt;h3&gt;Your Timing&lt;/h3&gt;
&lt;p&gt;Are you ready for a dream opportunity if it landed at your feet tomorrow? Do you have the skills you need? The experience you need? The network, the clout, the authority you need to seize it?&lt;/p&gt;
&lt;p&gt;Maybe you do. Maybe you don&apos;t. Whether or not isn&apos;t my point. My point is that if you aren&apos;t prepared for a job when it&apos;s available, then that job isn&apos;t available to you. Even if you&apos;d be great at it in 6 months, a year, or more.&lt;/p&gt;
&lt;h3&gt;Their Timing&lt;/h3&gt;
&lt;p&gt;As my anecdote explains, even if you&apos;d be a great candidate for a job, doesn&apos;t mean that they are ready for you to be a candidate. If you&apos;re new to these job hunts, and I suspect some of you are, you might hear the term &quot;head count&quot; thrown around. This is a way of describing how many people a team can hire at a particular time. As in, &quot;We really like you, but we just don&apos;t have head count. I might be able to add a few heads in 4-6 months. You should try again then.&quot;&lt;/p&gt;
&lt;p&gt;Sucks, but it&apos;s out of your control.&lt;/p&gt;
&lt;h3&gt;Someone Else&apos;s Timing&lt;/h3&gt;
&lt;p&gt;When you&apos;re seeking offers, it&apos;s easy to forget that you&apos;re &lt;em&gt;actually&lt;/em&gt; competing for a limited resource against unknown third parties. Your timing could be perfect. The company&apos;s timing could be perfect. But if someone with a superior skill set, better cultural fit, or cheaper salary requirements (and a host of other possibilities) comes along at the right time, then your timing isn&apos;t really so perfect.&lt;/p&gt;
&lt;p&gt;Shit. Again.&lt;/p&gt;
&lt;p&gt;This happens, too. The difference between this and the &quot;your timing&quot; category is where the locus of control is. You control how ready you are for opportunities by working on your skill set and network. This is an internal locus of control. Everything to prepare yourself comes from within you.&lt;/p&gt;
&lt;p&gt;You can&apos;t shape who does or does not apply for a job. Well, perhaps you could by nefarious means, but don&apos;t do that. Not cool. This is an external locus of control, it&apos;s outside of you and not one you can change.&lt;/p&gt;
&lt;h3&gt;How Do We Respond?&lt;/h3&gt;
&lt;p&gt;When bad timing occurs, there&apos;s very little you can do to change the immediate situation. It sucks, but it&apos;s a fact. However, we can be prepared for it. Something like this will likely happen to most of you at some point in your career, so here&apos;s my tips for being prepared.&lt;/p&gt;
&lt;h4&gt;Respond Professionally&lt;/h4&gt;
&lt;p&gt;This is an absolute must. Don&apos;t whine to them. Don&apos;t complain to them. If this happens to you and you respond poorly, it only &lt;em&gt;hurts you&lt;/em&gt;, it does not help you.&lt;/p&gt;
&lt;p&gt;By responding well, you may impress them. You might be remembered for a future opportunity. Plus, in the scenario where someone else beats you for the job, they might not accept the offer, and they may come back to you. Keep this in mind.&lt;/p&gt;
&lt;h4&gt;Don&apos;t Worry About It&lt;/h4&gt;
&lt;p&gt;The variable of timing in a job hunt means that there is a significant amount of luck involved in finding the right job. That being said, &lt;strong&gt;this pendulum swings both ways&lt;/strong&gt;. Assuming that you are a qualified candidate, skilled at your job and hard working, then you will likely benefit from timing as often as you will suffer from it. Keep your head up when the pendulum swings away from you. Figure out how to move forward. You&apos;re seeking offers and there are more out there.&lt;/p&gt;
&lt;h3&gt;Coda&lt;/h3&gt;
&lt;p&gt;Random segue, but if you know what a coda is in music, you might get how this applies here. A coda signifies we&apos;ve reached the end, &lt;em&gt;but&lt;/em&gt; we&apos;re going to cycle back to another point. The job hunt is often cyclical. You&apos;ll probably be in this boat again. You might be on the hiring end of this equation at some point. Try to keep this in mind next time you find yourself in a job hunt.&lt;/p&gt;
</content:encoded><category>Career</category></item><item><title>How to be More Successful on Your Next Web Developer Job Hunt</title><link>https://kyleshevlin.com/how-to-be-more-successful-on-your-next-web-developer-job-hunt/</link><guid isPermaLink="true">https://kyleshevlin.com/how-to-be-more-successful-on-your-next-web-developer-job-hunt/</guid><description>Here are some of the best tips I have on making your next web developer job hunt more successful.</description><pubDate>Fri, 28 Sep 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;If you follow me on Twitter, you may have seen this &lt;a href=&quot;https://twitter.com/kyleshevlin/status/1041735370478542851&quot;&gt;tweet&lt;/a&gt; go out into the universe. I&apos;m in the process of exploring the next part of my career and asking you all to help me do that by spreading the word. Don&apos;t think spreading the word can make a difference? It totally can.&lt;/p&gt;
&lt;p&gt;Just this past week, a junior dev I&apos;ve been helping in his job hunt landed his first dev job! I used my network and made a tweet promoting his background, skillset, and hard work and it paid off. A company reached out to him, he nailed the technical interview, and now he starts in a few weeks. All because a tweet connected some people! Trust me, spreading the word can help, and I&apos;d appreciate whatever support you could show me (if you haven&apos;t already. Much love to all of you who have!).&lt;/p&gt;
&lt;p&gt;Putting oneself out there, into the job market, can be one of the most nerve wracking parts of one&apos;s career. Whether it&apos;s your first job, your second, or your tenth, being in the hot seat and under scrutiny can be really uncomfortable. No matter how many times you&apos;ve done it, I don&apos;t think you can get rid of the nerves &lt;em&gt;entirely&lt;/em&gt;. However, I think there are a few changes you can make alter your mindset and get more offers. So here are my tips to help you be more successful at job hunts.&lt;/p&gt;
&lt;h3&gt;Stop Trying to Win the Resume Lottery&lt;/h3&gt;
&lt;p&gt;There&apos;s this game that so many people play that I like to call the &quot;resume lottery&quot;. People throw their resume and cover letter into a giant pile of other resumes and cover letters and hope and pray that somehow they stand out. It&apos;s nearly impossible to win this game. I mean that literally. According to &lt;a href=&quot;https://amzn.to/2xvdrPs&quot;&gt;Designing Your Life&lt;/a&gt;, a book I&apos;ve been loving lately, their research suggests that playing the &quot;resume lottery&quot; has a success rate of about 5%. That&apos;s horrible!&lt;/p&gt;
&lt;p&gt;Why is that percentage so low? Because as much as 80% of job openings never make it to a job board. When they do, they aren&apos;t always &lt;em&gt;really&lt;/em&gt; open. Often, they have a candidate in mind that they&apos;ve customized the opening for in order to appease HR. On top of this, according to a &lt;a href=&quot;http://careerbuildercommunications.com/candidatebehavior/&quot;&gt;2015 report&lt;/a&gt;, 52% of managers admitted to responding to fewer than half of people who applied for a position. What chance do you have of winning the &quot;resume lottery&quot; up against those odds?!&lt;/p&gt;
&lt;p&gt;You can keep playing the game. You can submit hundreds of resumes. Sure, you&apos;ll get a few bites, but you&apos;ll learn almost nothing from your failures. There&apos;s no feedback mechanism, no incentive for those companies to help you improve. All the while, you&apos;re not building up a network, you&apos;re not gathering new information to act upon, and all you&apos;re left with is an empty inbox. What on earth are you supposed to do?&lt;/p&gt;
&lt;p&gt;Try smarter, not harder.&lt;/p&gt;
&lt;p&gt;Playing the &quot;resume lottery&quot; is insane. You need to lean upon your &quot;weak ties&quot;, people whom you know, but aren&apos;t in your innermost circle (&quot;strong ties&quot;), to help you create &quot;warm introductions&quot;. Most job placements come through referrals, and that&apos;s precisely what a warm introduction can do for you. Learning how to build up connections and get these referrals helps tremendously. So how do you do that?&lt;/p&gt;
&lt;p&gt;You need to start doing &quot;informational interviews&quot;. These aren&apos;t really interviews, they&apos;re conversations. You reach out to people who are doing a job you&apos;re interested in and you ask them to tell you about it (of course, with kindness, politeness and a little bit of charm if you can muster it). It&apos;s really that simple. People &lt;em&gt;like&lt;/em&gt; talking about what they do! They&apos;ll tell you all about it, and you&apos;ll gain information. As you listen and respond, you&apos;ll be able to figure out 1) whether or not what they do is something you&apos;re interested in, 2) be able to share some of your own passions as you respond to them, which will help them unconsciously begin to see where you might fit, whether on their team or someone else&apos;s team they know, and 3) you&apos;ll begin to access their weak ties, thus expanding your own.&lt;/p&gt;
&lt;p&gt;These weak ties, these connections, they&apos;re your way to more opportunities.&lt;/p&gt;
&lt;h3&gt;You&apos;re Not Looking For a Job, You&apos;re Seeking Offers&lt;/h3&gt;
&lt;p&gt;I&apos;m going to be honest, I&apos;m ripping this straight from Designing Your Life, so give them all the credit. That being said, this tip is really helping me have the right mindset in my search.&lt;/p&gt;
&lt;p&gt;You need to reframe your thinking from looking for a job to seeking offers. It&apos;s going to change your approach entirely. When you&apos;re looking for a job, you&apos;re fixated more on doing what it takes to get a job, instead of exploring whether or not the job is any good for you. Exploration is the key.&lt;/p&gt;
&lt;p&gt;There isn&apos;t a perfect job out there, not one just waiting for you at least. There are probably a number of jobs you&apos;ll do great at. Knowing this, knowing you don&apos;t have to get &lt;em&gt;this&lt;/em&gt; job, but rather you&apos;re trying to give yourself options with many offers, means you can be your authentic self in an interview. You aren&apos;t trying to conform to them, instead you&apos;re on a path of discovery, you&apos;re learning things about them, you&apos;re focused on whether or not this fits with your goals, your personality, your aspirations.&lt;/p&gt;
&lt;p&gt;When you&apos;re seeking offers, everything becomes an opportunity. Every conversation and interview, at the worst, still provides you with information and probably connections. And here&apos;s the thing, when you&apos;re relaxed and not focused on getting just &lt;em&gt;this&lt;/em&gt; job, you&apos;ll do better at the interview in general, which will lead to more offers.&lt;/p&gt;
&lt;p&gt;Even if you&apos;re just starting out in the field, you need to believe this, because it&apos;s absolutely true: &lt;strong&gt;You are capable of doing a good job at many places.&lt;/strong&gt; There is no &lt;em&gt;one&lt;/em&gt; job that will be perfect, no &lt;em&gt;one&lt;/em&gt; interview that will make or break your career. If that was the case, then the only successful people would all have had the same path to their success, right? So dismiss that rubbish (sorry, I&apos;ve been watching a lot of the Great British Baking Show and all my swears are somewhat Anglicized at the moment) and realize that your best chance at landing a great job is having a bunch of offers.&lt;/p&gt;
&lt;p&gt;The other great thing about seeking offers is it immediately triggers your creativity and curiosity. You&apos;ll be amazed at how some of your informational interviews might lead to offers because of your creativity and curiosity.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Hope these tips help! Tell me some of your best tips in a comment down below!&lt;/strong&gt;&lt;/p&gt;
</content:encoded><category>Career</category></item><item><title>3 Tips for Changing Your Career to Coding</title><link>https://kyleshevlin.com/3-tips-for-changing-your-career-to-coding/</link><guid isPermaLink="true">https://kyleshevlin.com/3-tips-for-changing-your-career-to-coding/</guid><description>In this post, Kyle Shevlin shares several tips on how to make a career change into web development and software engineering</description><pubDate>Sat, 15 Sep 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Friday night, after &lt;a href=&quot;https://www.reactrally.com/&quot;&gt;React Rally 2018&lt;/a&gt;, I led a group of intrepid devs to Beer Bar in downtown Salt Lake City for what I like to call &quot;the unofficial after after party&quot;. Our group was quite large, so we ended up divided amongst two large tables. Our particular table only had a handful of our group. It was &lt;a href=&quot;https://twitter.com/cball_&quot;&gt;Chris Ball&lt;/a&gt;, &lt;a href=&quot;https://twitter.com/GabeRicard&quot;&gt;Gabe Ricard&lt;/a&gt;, and myself. The other half of our table was eventually filled with total strangers.&lt;/p&gt;
&lt;p&gt;The strangers were legitimately nice. Asked if they could sit there, which of course they could, and then each of them introduced themselves and shook our hands. Very pleasant introductions all around. We settled down and they start talking in their group and we go back to talking shop amongst ourselves.&lt;/p&gt;
&lt;p&gt;A little ways into our conversation, one of the strangers, Kevin was his name, hears us talking about coding and politely interrupts us, &quot;Wait a minute, are you all programmers?!&quot;&lt;/p&gt;
&lt;p&gt;&quot;Yup. We&apos;re here for a conference,&quot; we reply with a calmness that belies how excited we are that someone outside of tech is excited about what we do.&lt;/p&gt;
&lt;p&gt;&quot;Woah! That&apos;s crazy! I&apos;m considering getting into web development and learning JavaScript. What&apos;s your best advice for someone like me?&quot;&lt;/p&gt;
&lt;p&gt;This is where Gabe gets all excited for me, &quot;You have no idea how lucky you are to be sitting here,&quot; as he points at me. &quot;This guy has a whole podcast about people who have made the change to web development!&quot;&lt;/p&gt;
&lt;p&gt;So I told Kevin my best tips, none of them coding specific, and now I&apos;m going to share them with you.&lt;/p&gt;
&lt;h3&gt;1. Be Ready to Bang Your Head Against a Wall&lt;/h3&gt;
&lt;p&gt;Learning to code requires a lot of persistence. The only way you&apos;ll gain the skills to make the career change is to have the gumption and stubbornness to push through those times where you feel completely and utterly stuck. Sticking with it and overcoming the challenge before you is the only way to achieve your goals.&lt;/p&gt;
&lt;p&gt;A guitar player is not ashamed to play the same chords over and over again in order to learn a new song or skill. Don&apos;t be afraid to write the same code over and over again until you completely get it. Don&apos;t be afraid to read that tutorial two, three, four, five or more times to understand it fully. That&apos;s how you make breakthroughs and start heading for your next wall.&lt;/p&gt;
&lt;h3&gt;2. Be Ready to Constantly Cycle Through Feeling Like a Genius and Feeling Like a Dumb Ass&lt;/h3&gt;
&lt;p&gt;Every programmer out there is familiar with feeling like a genius one moment and a complete dumb ass the next. This cycle repeats continually throughout one&apos;s career. The difference between the newb and the seasoned veteran is that the vet has done the cycle so often that they no longer fear it, and in fact embrace it.&lt;/p&gt;
&lt;p&gt;Being a developer means going through waves of competency and struggle. As painful as the downswings might be, it&apos;s a clear indicator of previous growth. Being aware of this phenomenon, and being mentally prepared to handle it, will keep the bad parts of the cycle from crushing you. Awareness has the added benefit of keeping you humble while on your next upswing.&lt;/p&gt;
&lt;h3&gt;3. It&apos;s Probably Going to Take Longer Than You Thought&lt;/h3&gt;
&lt;p&gt;We&apos;ve all heard the story of so-and-so who was able to change their life entirely in just three months. That spunky person who went from minimum wage to six-figure salaries overnight, all by learning to code.&lt;/p&gt;
&lt;p&gt;This is the exception, not the rule.&lt;/p&gt;
&lt;p&gt;The rule is you will in all likelihood, &lt;em&gt;eventually&lt;/em&gt; make a pretty good salary. The rule is you will likely get benefits you enjoy and find some decent challenges to overcome. But it often doesn&apos;t happen overnight.&lt;/p&gt;
&lt;p&gt;I think you should expect to put in about a year and a half of solid coding, that is doing some amount of coding, deliberate practice, most days for that time. It&apos;s not that you&apos;re not smart enough or capable enough sooner, but that a year and a half is about the amount of time it often takes to be comfortable enough with your new skills to pass an interview, build up enough projects to prove your new skills, and probably build up a network enough to even have places to apply. Be patient with yourself. You can do this.&lt;/p&gt;
&lt;h2&gt;Bonus Tip: Start Networking Right Away&lt;/h2&gt;
&lt;p&gt;Speaking of networks, you should be doing this from day one. Networking isn&apos;t a sleazy thing to do. It&apos;s not just about helping yourself, it&apos;s about recognizing that everyone needs someone sometime. You may need help now, but soon enough someone will need your help instead.&lt;/p&gt;
&lt;p&gt;I recently read a great analogy for networking in the book &lt;a href=&quot;https://amzn.to/2NhPd4R&quot;&gt;Designing Your Life&lt;/a&gt;. Networking is more like asking for directions than asking for handouts. Almost everyone is more than willing to help someone else find their way and feels good about doing it. Have some faith this.&lt;/p&gt;
&lt;p&gt;You can start networking by participating, not just lurking, in conversations. You can reach out for informational interviews, aka conversations where you ask someone to tell you about what they do. You get the benefit of learning details you can&apos;t learn otherwise while building up professional relationships. That&apos;s a win-win situation.&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Making a career change is challenging. It&apos;s going to require persistence, patience, and probably some outside help. Don&apos;t be afraid to ask for it. Start developing relationships as soon as possible with people in the industry, it might lead to your next opportunity.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;I don&apos;t normally do self-promotion in my material, but if you want to listen to a podcast devoted to this topic, check out my podcast &lt;a href=&quot;https://secondcareerdevs.com&quot;&gt;Second Career Devs&lt;/a&gt;, where I interview people who have made the career change to software engineering or web development and share the lessons they learned along the way. Thanks.&lt;/p&gt;
</content:encoded><category>Career</category></item><item><title>Let Me Tell You About This Cat</title><link>https://kyleshevlin.com/let-me-tell-you-about-this-cat/</link><guid isPermaLink="true">https://kyleshevlin.com/let-me-tell-you-about-this-cat/</guid><description>Allow me to share a deeply touching moment I shared with a local cat recently, and how I will never forget the encounter.</description><pubDate>Tue, 21 Aug 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The events of this story took place several months ago, but let me tell you, they are as vivid to me now as they were then. It&apos;s going to sound a bit ridiculous, but I had a chance encounter with a cat that I don&apos;t think I&apos;ll forget for the rest of my life. I&apos;m hoping you&apos;ll find the story quite impactful as well.&lt;/p&gt;
&lt;p&gt;One day in the late spring, I was coming home after having run an errand. I live in a two bedroom apartment on the second floor of a small complex. Our apartments are all connected by a wooden deck that meanders between two buildings. Our apartment, in particular, is around a bit of a corner with our entrance being the only one on that side of the building. It awards us a degree of privacy that the other apartments don&apos;t have. It&apos;s quite nice. It also means I very rarely run into unexpected people or things as I come around the corner to my front door.&lt;/p&gt;
&lt;p&gt;So I&apos;m coming home from my errand, walking briskly as I do, when I turn the corner and, to my surprise, see our neighbor&apos;s cat, Bullet, lying next to our front door.&lt;/p&gt;
&lt;p&gt;I wasn&apos;t &lt;em&gt;totally&lt;/em&gt; surprised. Bullet was an outdoor cat and over the last few years, he and I had enjoyed a few minor pet sessions together. Bullet was the old-timer of our apartments. He was 18 years old, pretty skinny at this point. His eyes were a bit occluded and often seeped of some form of fluid. He wasn&apos;t a sight to behold, but he was a good cat who often wanted nothing more than to be let inside his home (something I could never do).&lt;/p&gt;
&lt;p&gt;I say to him, &quot;Hi, Bullet!&quot; and he immediately meows back at me. I walk up to my door, expecting him to leave, but he doesn&apos;t. He continues to meow and starts to rub against my legs as cats do. I set my grocery bag down and bend down to pet him. On this particular day, though, he&apos;s quite insistent. He keeps meowing at me. Again and again.&lt;/p&gt;
&lt;p&gt;I eventually get the idea and I sit down on the deck, cross-legged. I&apos;m barely to the ground when he climbs into my lap starts to curl up. Bullet has never done this before, never shown this level of affection, but I&apos;m not one to refuse him this.&lt;/p&gt;
&lt;p&gt;As he nestles in and I start to pet him, I notice that the sun is shining on us, creating a nice spot of light on top of him, warming up his thinning, gray fur. I can feel the heat upon him as I pet his side.&lt;/p&gt;
&lt;p&gt;Perhaps a minute or so into this, Bullet begins to purr. This isn&apos;t a soft purr, one that can be barely heard like my own cats. This is &lt;em&gt;loud&lt;/em&gt;. Loud enough to guarantee others heard it. I could feel the vibrations of his chest upon my legs as he did so. It&apos;s about this point that it dawns on me what is going on.&lt;/p&gt;
&lt;p&gt;I start bawling.&lt;/p&gt;
&lt;p&gt;As I said, Bullet is a much older cat. He&apos;s not in the greatest of health. Under-nourished. Tired. Alone. And now, out of nowhere, he is curled up in my lap, enjoying some pets to the fullest.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;All he is trying to do is get a little bit of joy and pleasure out of the last few moments or days of his life&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;He knows that the end is near, and he just wants a few minutes of sunshine and good pets before it&apos;s over. He&apos;s just trying his damndest to get something good out of this one and precious life.&lt;/p&gt;
&lt;p&gt;I&apos;m bawling as I write this.&lt;/p&gt;
&lt;p&gt;We stay like this for about ten minutes. Him on my lap, me crying, sitting in the sunshine. As I stroke his rough fur again and again, I think about how much I understand him. I, too, want to have a little more joy and pleasure in this life. I, too, want to sit in the sun and feel the affection of another (or some similarly equivalent pleasure). I want to have more happiness in this life. To live the best I can with what I have.&lt;/p&gt;
&lt;p&gt;That&apos;s really all most of us are trying to do. Almost every creature in the entire universe is trying to do the best they can.&lt;/p&gt;
&lt;p&gt;Even the shitty ones.&lt;/p&gt;
&lt;p&gt;The universe consists of limited creatures with their limited knowledge and their limited resources and their limited lives, striving to make something &quot;good&quot; for themselves.&lt;/p&gt;
&lt;p&gt;I have to put &quot;good&quot; in quotes, because this is not some objective goodness. It&apos;s entirely subjective. I don&apos;t mean to imply that every creature is pursuing an ultimate good, the &lt;em&gt;summum bonum&lt;/em&gt;. Rather, that most are pursuing a &quot;good&quot;, even if that &quot;good&quot; is quite awful.&lt;/p&gt;
&lt;p&gt;In those ten minutes, I was overwhelmed with compassion, with empathy for others. I understood others better on a fundamental level. Even people I vehemently disagree with, perhaps even hate, I understood now more than ever.&lt;/p&gt;
&lt;p&gt;All because a cat sat in my lap for some pets in the sunshine.&lt;/p&gt;
&lt;p&gt;Eventually, a cloud passed in front of the sun. Bullet took this opportunity to get up, perhaps to pursue another patch of light elsewhere. As he departs, I say, &quot;Goodbye.&quot;&lt;/p&gt;
&lt;p&gt;Bullet died two days later.&lt;/p&gt;
</content:encoded><category>Thoughts</category></item><item><title>From Pastor to Programmer</title><link>https://kyleshevlin.com/from-pastor-to-programmer/</link><guid isPermaLink="true">https://kyleshevlin.com/from-pastor-to-programmer/</guid><description>In this article, Kyle Shevlin explains how he made the career change from being a pastor to a programmer.</description><pubDate>Mon, 05 Feb 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I am often asked to share the story of how I went from being a Christian pastor to a software engineer. Now that I&apos;ve started &lt;a href=&quot;https://secondcareerdevs.com&quot;&gt;Second Career Devs&lt;/a&gt;, I am being asked this question so often that I thought it wise to write it down and answer it once and for all.&lt;/p&gt;
&lt;h3&gt;Where I Believe the Story Begins&lt;/h3&gt;
&lt;p&gt;Unlike many people who eventually find their way to programming, I never did any programming as a kid. I had a computer, a Commodore 64, but I mostly used it to play games and write stories. In other words, I don&apos;t think anyone suspected that I would wind up where I have.&lt;/p&gt;
&lt;p&gt;I was an excellent student, albeit, an easily bored one (really, I am just an easily bored person). I slept through most of high school while still getting straight A&apos;s. I didn&apos;t really care about the grades, though. I was mostly concerned with athletics at that time in my life. That is a story for another time.&lt;/p&gt;
&lt;p&gt;Because I was solid in all my classes, there was no particularly clear path for me to choose after high school. The irony of being good at many things is that it can sometimes make choices more difficult. You have more options than you know what to do with and a fear of choosing wrongly can be overwhelming. A bunch of my friends were going to pursue engineering, and I thought that would work for me, so I headed to college with a vague plan of becoming an engineer.&lt;/p&gt;
&lt;p&gt;College mathematics continued to go well, but the work became incredibly tedious. I abhor tedium. It is something for which I have no patience. I began to grow increasingly tired of math homework that would only be a couple of problems, but would take multiple hours to complete by sheer volume of steps required. My instincts would tell me, &quot;Computers will solve all these problems for me on the job. Why do I need to do this by hand?&quot; Thus, I started to drift away from mathematics.&lt;/p&gt;
&lt;p&gt;At the same time, I took my first philosophy course. I was immediately hooked. I had always been a thoughtful person (more in quantity than quality), frequently scolded by my peers and for &quot;thinking too much&quot;. Suddenly, I found an area of study that matched my overly cognitive demeanor. This led me to make what I consider to be one of the worst decisions of my life, but I switched directions to become a philosophy major.&lt;/p&gt;
&lt;h3&gt;How Philosophy Lead to Theology&lt;/h3&gt;
&lt;p&gt;I earned athletic and academic scholarships to attend Lenoir-Rhyne University in Hickory, North Carolina and transferred there my junior year. The Southeast was quite the culture shock for me. I had never visited before my transfer and didn&apos;t know what to expect. One of the biggest culture shocks was moving right into the heart of the Bible Belt. I had never seen such overt religiosity in my life. While I was raised in a Lutheran church and considered myself a Christian, I did not share the same passion for Jesus as many of peers and elders did. It was eye-opening and life changing.&lt;/p&gt;
&lt;p&gt;One night, late my junior year, I had an epiphany of sorts where I felt overwhelmingly compelled to devote myself to Jesus and his teachings. I became highly involved in a local church and various campus ministries. This was really the beginning of my ministry career.&lt;/p&gt;
&lt;p&gt;Studying philosophy trained me to be excellent at critical thinking. I was also a pretty naturally gifted public speaker (I like talking a lot). Thus, I enjoyed the challenge of reading and deducing interesting insights from the Bible and sharing them with others. With these gifts and talents, I was both drawn to and encouraged to pursue a career in ministry.&lt;/p&gt;
&lt;p&gt;I can&apos;t emphasize the &quot;encouragement&quot; enough. Looking back at that time from my current vantage point enables me to recognize just how much peer pressure shaped the next eight years of my life. There was an incredible amount of pressure put on me by others, and my own sense of guilt, to use these skills &quot;for the Lord.&quot; As in, if I didn&apos;t use these skills in the church, that I would be squandering them, or even worse, committing sin. I, of course, didn&apos;t want to be a sinner and so it seemed like I was destined to be a pastor.&lt;/p&gt;
&lt;p&gt;After college, I spent a year in a volunteer organization where I practically lived in a van with five other people, driving around the United States doing youth and worship ministry. We covered ~60,000 miles that year. It was a challenging time for my team. We started as a group of six, but only three of us, including me, stayed with the program for the entire year of service. After this time of volunteering, I continued following the natural path of ministry and became a pastor of youth and worship ministries for a small church in rural Illinois.&lt;/p&gt;
&lt;p&gt;I took this job at the same time that our country entered the Great Recession. As you might imagine, this wasn&apos;t a good time to work for an organization that depends upon donations to survive. My time at the church was quite short, just over a year, and finances played a big part in just how brief my tenure was.&lt;/p&gt;
&lt;p&gt;Because of the recession, the congregation had less discretionary money to tithe to the church. Less tithing means coming up short on budget. But it wasn&apos;t just the recession that was preventing people from giving. They also were less encouraged to donate because there was a general displeasure with the new pastor the diocese had assigned to the church.&lt;/p&gt;
&lt;p&gt;This was the first time I really understood how money is power and how the intended target of an attack is not always the one who gets hurt. My church was unhappy with the head pastor. To hurt the pastor, they withheld their money. However, I being the lowest person on the totem pole, was the one who lost their job. With very little notice, I was told I was being let go. My final day at that church was Easter Sunday of 2010.&lt;/p&gt;
&lt;p&gt;By then, I had become convinced that I needed to attend seminary so that I could finally be a lead pastor. Because, of course, when you&apos;re in charge, everything will be better (I know that this isn&apos;t true now, but a younger me had no clue). However, &lt;em&gt;when&lt;/em&gt; I was let go presented a pretty serious problem. I was let go in the spring, &lt;em&gt;after&lt;/em&gt; the admissions deadlines for virtually every seminary in the country had passed. I would have to wait a full year before I could get into school, and I didn&apos;t have a job, any savings, or any real skills at the time. To put it politely, I was pretty screwed.&lt;/p&gt;
&lt;p&gt;There were only a handful of seminaries in the country with open enrollment. One of them was Fuller Theological Seminary in Pasadena, California. I applied and was accepted. In August of 2010, with no idea how I was going to afford Los Angeles or grad school, I packed up my entire life in my car and moved out to Southern California to earn a Masters of Theology.&lt;/p&gt;
&lt;h3&gt;How Theology Leads to Technology&lt;/h3&gt;
&lt;p&gt;This part of the story is challenging to tell in a linear fashion. In truth, there are three simultaneous storylines taking place, like three cords wound together to form a single rope. In this section, I will be weaving in and out of these storylines to try and tell the whole story.&lt;/p&gt;
&lt;p&gt;In order to understand these three parts, you must understand something about me. I have many diverse and seemingly random passions, often pursuing three or four of them simultaneously. It&apos;s just who I am. Some last for a short season of my life, maybe a couple months or years, others last for much longer.&lt;/p&gt;
&lt;h4&gt;Storyline #1 - Music&lt;/h4&gt;
&lt;p&gt;I taught myself how to play guitar and write music in college. This is what eventually led to me being a worship leader and a music producer. While in grad school, I pursued a secular music career as a singer/songwriter doing folk/Americana music. I produced an album at the time. If you&apos;d like to listen to it, you can &lt;a href=&quot;https://open.spotify.com/album/2EgNgF6ugGzxQO03xkPx1F&quot;&gt;hear it here&lt;/a&gt;.&lt;/p&gt;
&lt;h4&gt;Storyline #2 - A Serendipitous Mentor&lt;/h4&gt;
&lt;p&gt;My main means of staying physically fit in my life has been through playing sports. During grad school (and still today), my main sport was ultimate frisbee. I played in many regular pick-up games around Los Angeles and eventually made good friends with some of the people in the community. One of those people, Dave, became not only a good friend, but a mentor as well.&lt;/p&gt;
&lt;p&gt;Dave and I shared something in common, we were both pastors. He was a few years older than I am and had finished his Masters before I met him. What was interesting about Dave&apos;s story was that he didn&apos;t work full time as a pastor. He had made the choice to go into real estate.&lt;/p&gt;
&lt;p&gt;He understood that his gifts could be used in a much more efficient way that would still allow him to do some ministry. In fact, he could earn more money for his family and donate more to his ministry by not working as a full time pastor. Dave is very successful at what he does, and he was the first person to start to push me to think outside the box of traditional ministry. He helped me eventually understand that I didn&apos;t have to be stuck on the path I was on if I didn&apos;t want to be.&lt;/p&gt;
&lt;h4&gt;Storyline #3 - Learning to Code&lt;/h4&gt;
&lt;p&gt;One day, an acquaintance posted a link on Facebook about a course he developed for &lt;a href=&quot;https://www.codecademy.com/&quot;&gt;Codecademy&lt;/a&gt;. For those of you who might know, Codecademy is a free learning resource for coding. Remember that insatiable curiosity of mine? Well, it compelled me to click the link and give the course a try. Honestly, I don&apos;t remember what I learned that day (probably some HTML), but I enjoyed the course enough that I worked all the way through it. And then I found another course and worked through that, and then another and another.&lt;/p&gt;
&lt;h4&gt;Back to Music&lt;/h4&gt;
&lt;p&gt;My music &quot;career&quot; (if you can call it that) was going a bit better than I expected. I was playing shows on the Sunset Strip in Hollywood and getting a little PR here and there. So, of course, I needed a good website, but couldn&apos;t afford to pay anyone to make it for me.&lt;/p&gt;
&lt;h4&gt;Back to Coding&lt;/h4&gt;
&lt;p&gt;But I was learning how to code so I could build the website myself, right? Kind of. I had learned some HTML, CSS, and jQuery, but I was a little over my head in terms of understanding how the Internet worked. Servers, clients, etc. It was all new stuff to me. I&apos;d get an idea and then bang my head against a wall in my free time trying to figure it out. Lucky for me, I had two things going for me. First, I had a few friends willing to help me get started. They helped my buy some server space and a domain name and connect the two. Second, I had spent my life teaching myself how to do things and knew how to persevere through times where it seemed like I would never be good at it. I had done it with golf. I had done it with music. I knew I could do it again with coding.&lt;/p&gt;
&lt;h4&gt;Back to Dave&lt;/h4&gt;
&lt;p&gt;Dave and I talked a lot about my future. I think he recognized some writing on the wall that I didn&apos;t and he knew I&apos;d need to think outside of the box to find work (and to pay off my massive student loans).&lt;/p&gt;
&lt;p&gt;During my time at Fuller, my theology moved much further left than what would be considered orthodox evangelicalism. I was partially heading that way to begin with, but the education I received gave me a whole new set of tools to more accurately consider the implications of Biblical texts. I began to realize there was a great chasm between academic theology and the theology taught from the pulpit on Sunday. Academic theology is interesting and nuanced. Pulpit theology lacks so much of this. Academic theology isn&apos;t afraid of suggesting a radical idea if it can be supported. Say something similar from the pulpit and you&apos;ll lose your job and be told, &quot;You&apos;re going to burn in hell!&quot; I&apos;ve never been comfortable with knowing one thing and saying another, and this was making pastoral ministry more and more challenging.&lt;/p&gt;
&lt;p&gt;Those theological stances are not terribly important for this story. What is important is that it meant I struggled to find work. Conservative churches have more money to hire pastors than progressive churches. Also, typically, churches require that you sign a &quot;statement of faith,&quot; a document that defines their beliefs and your agreement with those beliefs. In a lot of cases, I just couldn&apos;t do this in good conscience.&lt;/p&gt;
&lt;p&gt;Throughout all of this, Dave would remind me that I might have skills that could be used elsewhere. He didn&apos;t really know I had been coding on a regular basis, but he knew that I was smart and talented.&lt;/p&gt;
&lt;h4&gt;Back to Coding&lt;/h4&gt;
&lt;p&gt;I graduated seminary in December of 2012. I was engaged, about to marry Anna in a few months. She was still in school and wouldn&apos;t graduate until June. I was actively looking for pastoral jobs with almost no luck. I was often selected as a candidate, I&apos;d get to the final interviews with the churches, and come in second place every single time. I know for a fact that I lost out on three jobs solely based on my support of the LGBTQ community. It hurt to come so close and fail again and again. I&apos;m sure many people can relate to that in their own field.&lt;/p&gt;
&lt;p&gt;In the meantime, I was working a smattering of part time jobs to make some ends meet. I was a private tutor, a janitor, an intramural sports coordinator, and a freelance blogger (I got paid to write articles about audio production). Anna was working a few random jobs, too. We were scraping by.&lt;/p&gt;
&lt;p&gt;During this time, I developed possibly the best habit I ever established in my life. Every morning, I would wake up, make myself a full French press of coffee, and I would sit down and try and learn something new with code for a few hours each day. Coffee and code. That was it. I didn&apos;t have any particular path. I would just find tutorials that interested me or a simple project I could view the source and rebuild. I did this every day for about a year.&lt;/p&gt;
&lt;p&gt;Anna and I got married in March of 2013, she graduated in June, and then we were faced with a decision. Neither of us were finding jobs, and neither of us wanted to live in Los Angeles long term. The cost of living was too high, traffic was horrible, we would never own a home, etc. We knew it just wasn&apos;t the right place for us.&lt;/p&gt;
&lt;p&gt;Through a lot of prayer and discussion, we eventually landed on moving to Portland. We realized that our savings would last longer by moving to a lower cost of living city. We thought that it would be a good place for my music (it would have been, but Anna made me so happy I kind of stopped writing), we knew we&apos;d have a few friends moving back there in a few years so we&apos;d be able to have &lt;em&gt;some&lt;/em&gt; community, and we thought Anna would be able to find work pretty quickly. I was still looking for pastoral jobs, but was losing hope.&lt;/p&gt;
&lt;p&gt;We moved to Portland in September of 2013. It was really challenging. A new town without much money, no community, and no jobs. I don&apos;t recommend that many challenges in your first year of marriage. But we tried to dive right in.&lt;/p&gt;
&lt;h4&gt;Now the Part Where All These Random Things Come Together&lt;/h4&gt;
&lt;p&gt;One Sunday, my wife and I attended a church here in Portland and I met a guy named Mike. Mike is very well connected in Portland because he works for the city. I explained our situation and he asked me what my interests were. When I said coding, he arranged for me to meet two developers he knew.&lt;/p&gt;
&lt;p&gt;These two devs were kind enough to look at the portfolio of little projects I had built up over my year of coding. To my surprise, both of them thought I knew enough to go get a junior developer job. This was really the first time I had ever considered it as a potential career.&lt;/p&gt;
&lt;p&gt;I had tried for almost a year to become a pastor, had sunk about $90K into my education and was getting no where. This is when I remembered Dave&apos;s wisdom to think outside of the box. To pursue alternative avenues to success. So I decided to go for it. I was going to find a job as a web developer.&lt;/p&gt;
&lt;p&gt;I applied to basically anything I could find. Seriously. Every job website. Every Craigslist ad. Luckily, the market here was booming and it wasn&apos;t flooded with junior devs. Within two months, I had a few offers. I chose to start my career with &lt;a href=&quot;https://wearefine.com&quot;&gt;FINE&lt;/a&gt; and the rest is history.&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;You can piece together my career so far by looking at my &lt;a href=&quot;https://kyleshevlin.github.io&quot;&gt;resume&lt;/a&gt; and reading my other post--&lt;a href=&quot;https://medium.com/@kyleshevlin/four-years-in-cbf12e92ac58&quot;&gt;Four Years In&lt;/a&gt;. I have had some ups and downs, but mostly, my career has been overwhelmingly positive. When I got started, I had no idea where it would take me. And I am thankful for every part of it so far.&lt;/p&gt;
&lt;p&gt;Thank you for reading my story. I hope it gives you some context to understand how I got to where I am. Please let me know if there are more details I should try and add to the story. I can update this as time goes on.&lt;/p&gt;
</content:encoded><category>Thoughts</category></item><item><title>Not All &amp;ldquo;Just JavaScript&amp;rdquo; is the Same</title><link>https://kyleshevlin.com/not-all-just-javascript-is-the-same/</link><guid isPermaLink="true">https://kyleshevlin.com/not-all-just-javascript-is-the-same/</guid><description>A not-so-small rant about why two JavaScript frameworks can feel so vastly different.</description><pubDate>Thu, 07 Sep 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I&apos;m going to start this post with what will appear to be a tangent. I assure you, it&apos;s not.&lt;/p&gt;
&lt;p&gt;My wife, wonderful as she is, is &lt;em&gt;not&lt;/em&gt; a very technical person. She is very caring, though, and will often listen to me talk about the technical things I am working on. This often means I need to use metaphors and similes to get my point across. I want to take a recent one I shared with her and share it with you.&lt;/p&gt;
&lt;p&gt;Imagine two similar, but slightly different, worlds that both required you to use two languages to communicate. In both of these worlds, one of the two languages is your common tongue, your &lt;em&gt;lengua franca&lt;/em&gt;. You know it very well. Have studied it for years. You&apos;ll never forget it. Sure, this language can seem, at times, primitive and without polish, but you know how to use it well, be expressive with it.&lt;/p&gt;
&lt;p&gt;In both of these worlds, the second language, while based, in part, on the other language, is much more foreign to you. You haven&apos;t used it as long. Fewer people speak it conversationally, it&apos;s specialized and, to an outsider, might even sound like gibberish.&lt;/p&gt;
&lt;p&gt;Now, in both worlds, in order to start any conversation, you &lt;em&gt;must&lt;/em&gt; use the second, more specific language &lt;em&gt;before&lt;/em&gt; you can use the first language. In these worlds, the first language lacks almost all context for understanding with out the second language. There is one catch, though, one major difference between these two worlds. In one world, only &lt;strong&gt;one word&lt;/strong&gt; from the more difficult language is needed to start your conversations. In the other, you might need to use &lt;strong&gt;hundreds&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;What On Earth Are You Talking About, Kyle?&lt;/h3&gt;
&lt;p&gt;I&apos;m talking about APIs and JavaScript obviously! If you think about it, every API is built upon a language you know. Some of these APIs are wonderful and allow you to express things easily without repeating yourself often. Some APIs aren&apos;t so great. Maybe they don&apos;t have the greatest architecture, or maybe it has some quirks and oddities that are difficult to grasp. Maybe they are so big as to be difficult to learn thoroughly. Maybe there&apos;s no documentation. I think we can all appreciate that one.&lt;/p&gt;
&lt;p&gt;APIs are the second language in the metaphor. By starting a dialogue, or rather a program or algorithm with them, we gain access to whatever methods have been expressed within the API. Once we are in the domain of these methods, we often can revert back to our native tongue, but not always.&lt;/p&gt;
&lt;h3&gt;The Two Worlds&lt;/h3&gt;
&lt;p&gt;Currently, I have myself in two worlds at the same time. For my day job, I work with Ember, and for all my side projects and talks, I work with React. To me, React is the first world. I only have to use a few words and some idioms from the language to get it to work. Ember, on the other hand, is the second world, where there are hundreds of words you need to know.&lt;/p&gt;
&lt;h3&gt;The First World&lt;/h3&gt;
&lt;p&gt;With React, the only word you &lt;em&gt;must&lt;/em&gt; know is &quot;Component&quot;. If you&apos;re using ES6 classes and JSX, then the &lt;code&gt;React.Component&lt;/code&gt; method is the only &quot;word&quot; you need to know to get started. Sure, there are idioms like &lt;code&gt;props&lt;/code&gt;, &lt;code&gt;setState&lt;/code&gt;, and &lt;code&gt;componentDidMount&lt;/code&gt;, but the overall technical, specific language is quite small. Aside from that, you exclusively use &quot;Just JavaScript&quot;, that is you use the primitives and data structures given to you by the language, &lt;em&gt;not the React API&lt;/em&gt;.&lt;/p&gt;
&lt;h3&gt;The Second World&lt;/h3&gt;
&lt;p&gt;With Ember, there are many words to know. For starters, there are 40+ classes off the &lt;code&gt;Ember&lt;/code&gt; module (according to the docs). There are methods upon methods to learn. Many having the same name as native data structures. Do I need &lt;code&gt;Ember.Array&lt;/code&gt; or &lt;code&gt;Array&lt;/code&gt;? When I use &lt;code&gt;Function&lt;/code&gt; which &lt;code&gt;Function&lt;/code&gt; am I getting? If an &lt;code&gt;Ember.Object&lt;/code&gt; is an &lt;code&gt;Object&lt;/code&gt;, why do I need special getters and setters to get properties (two-way data binding, of course, I&apos;m being rhetorical). Some of these methods are &lt;em&gt;really&lt;/em&gt; important to the overall ecosystem, like &lt;code&gt;computed&lt;/code&gt;. And &lt;code&gt;computed&lt;/code&gt; isn&apos;t enough to know, as there are methods on that method, such as &lt;code&gt;alias&lt;/code&gt; and &lt;code&gt;reads&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;While Ember is written in &quot;Just JavaScript,&quot; you spend a lot less time writing native JavaScript than in React. You end up writing a lot of &lt;code&gt;Ember&lt;/code&gt; (literally, you have to write &lt;code&gt;Ember&lt;/code&gt; a lot).&lt;/p&gt;
&lt;h3&gt;Which Is Why...&lt;/h3&gt;
&lt;p&gt;...I contend that not all &quot;Just JavaScript&quot; is the same, and &lt;em&gt;this&lt;/em&gt; is specifically what I think people mean when they claim that React is &quot;Just JavaScript™&quot; (see what I did there?). Sure, with Ember (and other similar JS frameworks) you&apos;re writing &lt;em&gt;with&lt;/em&gt; JavaScript, but you&apos;re spending more of your time using the API than using the language.&lt;/p&gt;
&lt;p&gt;I think this is why React devs speak with such passion about the library and why they feel so productive. Once you get started, you virtually never need to consult the documentation again because there are significantly fewer &quot;words&quot; to know. There are also fewer quirks to know (setState is async, that&apos;s really the biggest one). You want to try something crazy? Just go for it with the language you already know. It&apos;s how we&apos;ve gotten great patterns like HOCs and render callbacks.&lt;/p&gt;
&lt;p&gt;With Ember, I find myself trying to do things with JavaScript, only to learn that what I really need is an Ember method. Ember has worked so hard to give me a &quot;right way&quot; to do things, but sometimes it feels like the &quot;right way&quot; is really difficult to discover. I&apos;d rather be given the freedom to express the task at hand using the language I know best.&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;I&apos;m not here just to bash on Ember. Ember was my first introduction to JavaScript frameworks and I&apos;ll always feel some positive sentiment towards the project. People have built some amazing things in Ember. I&apos;m hoping my team and I can build a great thing with Ember. But I feel like we, the JavaScript community, is really learning that less is more.&lt;/p&gt;
&lt;p&gt;Less API. More &quot;Just JavaScript&quot;.&lt;/p&gt;
</content:encoded><category>Thoughts</category></item><item><title>How to Write Your Own JavaScript DOM Element Factory</title><link>https://kyleshevlin.com/how-to-write-your-own-javascript-dom-element-factory/</link><guid isPermaLink="true">https://kyleshevlin.com/how-to-write-your-own-javascript-dom-element-factory/</guid><description>Learn how to write a JavaScript DOM element factory function from scratch.</description><pubDate>Wed, 12 Jul 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Recently at an interview I was asked to write a custom component from scratch with vanilla JavaScript. I thought I&apos;d take a few minutes to write part of that code for you. It&apos;s not as scary as it might seem at first.&lt;/p&gt;
&lt;p&gt;There are three basic parts to any DOM element: the type of element it is, any attributes we need the element to have, and any children of the element. Knowing this, we can start to write our factory function.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const elFactory = (type, attributes, children) =&amp;gt; {}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The first thing we need to do is create the DOM element we will eventually return. We do this with the &lt;code&gt;createElement()&lt;/code&gt; method.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const elFactory = (type, attributes, children) =&amp;gt; {
  const el = document.createElement(type)

  return el
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The next thing we need to do is apply each key/value pair found in the attributes object we pass in.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const elFactory = (type, attributes, children) =&amp;gt; {
  const el = document.createElement(type)

  for (key in attributes) {
    el.setAttribute(key, attributes[key])
  }

  return el
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The last thing we need to do is handle children. There are two basic types of children we might run into: strings and other elements. So our function will need to handle both cases. Also, implied by the variable name &lt;code&gt;children&lt;/code&gt; is that we might receive any number of extra arguments, so we&apos;ll need to use the rest operator to gather up our remaining parameters into an array. That code looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const elFactory = (type, attributes, ...children) =&amp;gt; {
  const el = document.createElement(type)

  for (key in attributes) {
    el.setAttribute(key, attributes[key])
  }

  children.forEach(child =&amp;gt; {
    if (typeof child === &apos;string&apos;) {
      el.appendChild(document.createTextNode(child))
    } else {
      el.appendChild(child)
    }
  })

  return el
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And now we have a factory function that will create DOM elements for us. We can use it like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const markup = elFactory(
  &apos;div&apos;,
  { class: &apos;my-component&apos; },
  elFactory(&apos;span&apos;, {}, &apos;Hello World!&apos;),
  &apos; Thanks for reading my blog!&apos;,
)

document.body.appendChild(markup)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Which will output the following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;div class=&quot;my-component&quot;&amp;gt;
  &amp;lt;span&amp;gt;Hello World!&amp;lt;/span&amp;gt; Thanks for reading my blog!
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the future, I&apos;ll discuss how we might be able to handle updates and have state available to our components. For now, this should help you if you&apos;re ever in a similar situation.&lt;/p&gt;
</content:encoded><category>JavaScript</category></item><item><title>My Mock Interview Experience with Rick Altherr from Google</title><link>https://kyleshevlin.com/my-mock-interview-experience-with-rick-altherr-from-google/</link><guid isPermaLink="true">https://kyleshevlin.com/my-mock-interview-experience-with-rick-altherr-from-google/</guid><description>A recap of my mock interview experience with a Googler.</description><pubDate>Mon, 03 Jul 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import SocialPost from &apos;../../../components/SocialPost.astro&apos;&lt;/p&gt;
&lt;p&gt;A few days ago, I came across a tweet by Stephanie Hurlbut, a software engineer and entrepreneur who uses her influence to help other engineers out. Allow me to share that tweet with you:&lt;/p&gt;
&lt;p&gt;&amp;lt;SocialPost
authorName=&quot;Stephanie Hurlburt&quot;
authorHandle=&quot;@sehurlburt&quot;
authorProfile=&quot;https://stephaniehurlburt.com/&quot;
avatarUrl=&quot;https://media.licdn.com/dms/image/v2/C4E03AQEvHhki38rs2Q/profile-displayphoto-shrink_200_200/profile-displayphoto-shrink_200_200/0/1516475818410?e=1743638400&amp;amp;v=beta&amp;amp;t=8n68LxwGx0OdA9KzD9S4pxJ6zo2q_DrmLxDM4l2TRyo&quot;
date=&quot;2017-06-08&quot;
content={&lt;code&gt;If you would be up for giving someone a mock typical whiteboard interview to help them pass those (Skype or in person), reply to this tweet.&lt;/code&gt;}
/&amp;gt;&lt;/p&gt;
&lt;p&gt;I was really intrigued by this idea and was hoping someone would rise to the occasion. As it so happens, a few awesome people offered to give mock interviews. In particular, I came across Senior Software Engineer at Google Rick Altherr&apos;s offer.&lt;/p&gt;
&lt;p&gt;&amp;lt;SocialPost
authorName=&quot;Rick Altherr&quot;
authorHandle=&quot;@kc8apf&quot;
authorProfile=&quot;https://www.linkedin.com/in/mxshift/&quot;
avatarUrl=&quot;https://media.licdn.com/dms/image/v2/D5603AQHoT5Epk6zXoA/profile-displayphoto-shrink_200_200/profile-displayphoto-shrink_200_200/0/1723008952944?e=1743638400&amp;amp;v=beta&amp;amp;t=x3zAZj5JQuBNMpllSmbqw5cgdCbB9_XRgAAOXTqxQk8&quot;
date=&quot;2017-06-27&quot;
content=&quot;I&apos;m waiting for my first taker&quot;
/&amp;gt;&lt;/p&gt;
&lt;p&gt;Well, as you can guess, I took Rick up on his offer and setup an interview with him.&lt;/p&gt;
&lt;h3&gt;Some Context&lt;/h3&gt;
&lt;p&gt;I think it&apos;s appropriate to provide some context to why I was so interested in this opportunity. I reveal this with some apprehension. It&apos;s not really culturally acceptable to admit that one is interviewing with companies (even though, realistically, we know it&apos;s happening all the time and we might be better off if we could all be a bit more open about it), but I hope my honesty is appreciated by those who are interested in what the mock interview process was like.&lt;/p&gt;
&lt;p&gt;For the last four to five months, I have been interviewing with companies for senior front-end JavaScript developer/engineer positions. I&apos;m looking for the next challenge in my career and hoping to join a solid engineering team for a company with a great product. This season of interviewing has been challenging and, at times, even disheartening.&lt;/p&gt;
&lt;p&gt;I&apos;ve had a lot of interest, more than I expected and from bigger companies than I had even thought were available to me before. Companies like Stripe, New Relic, Amazon and others. I must be doing something right with my career for this to happen.&lt;/p&gt;
&lt;p&gt;I have gotten to a final interview with every company I started the candidate process with, used quite a bit of PTO to get to these onsite interviews, but thus far, haven&apos;t been able to get over that hurdle of getting an offer.&lt;/p&gt;
&lt;p&gt;Companies have a legal incentive not to provide feedback. As a developer, I find this frustrating. We&apos;re used to our code telling us why it isn&apos;t working and making changes. Interviews don&apos;t work like that. The feedback is often non-existent, and when it is provided, it is so vague as to be practically useless. So the opportunity to participate in a technical interview with no real pressure and guaranteed feedback was a perfect opportunity for me to learn if there&apos;s anything I can adjust moving forward in my search.&lt;/p&gt;
&lt;h3&gt;The Interview&lt;/h3&gt;
&lt;p&gt;After responding to Rick&apos;s tweet and getting the affirmative, we messaged each other a few times to set up a time for the interview. I handled this as I would any normal interview. We discussed times that would be a good fit for both of us and then hammered out a few of the details we wanted to cover in the interview. When the time came, we used a Google hangout and a Google doc to share the code. I&apos;ve not used a Google doc in this way before (and I certainly missed some nice features of a code editor while coding), but it worked just fine. As Rick said, it had the added benefit of him highlighting some of my code if necessary. After some brief introductions, we dove right into Rick&apos;s problem.&lt;/p&gt;
&lt;p&gt;Now, I won&apos;t share any details of the problem because, to some degree, the problem itself is irrelevant, and I wouldn&apos;t want to burn one of his questions. He told me later that he has used this question for four and a half years. I wouldn&apos;t want to be the reason he had to stop.&lt;/p&gt;
&lt;p&gt;He described the problem. I made some quick notes of details I thought were important to finding solutions. I like to do this for two reasons. First, I don&apos;t like working through a solution only to realize I forgot a key part of it. Second, I think it&apos;s my first opportunity to show my thought process and what it would be like working with me on a problem. I think it indicates I can pay attention to details and summarize problems into their most salient parts. I asked some questions about what assumptions I could make and then focused on writing the code for the two main parts of the problem.&lt;/p&gt;
&lt;p&gt;I solved one part of the problem relatively quickly, but it was the smaller of the two parts. The second, bigger part involved recognizing a key element of the problem (which I did). However, I wavered on what was the best strategy to solve it. This wavering slowed me down a bit and became a focal point of our discussion afterwards. After deciding a path ahead, I spent a little more time coding, about 15 minutes in total, before Rick cut me off. He cut me off so we would have more time to chat and that it was apparent I would solve the problem eventually.&lt;/p&gt;
&lt;h3&gt;The Feedback&lt;/h3&gt;
&lt;p&gt;Right away, Rick asked me a question I wasn&apos;t quite expecting, &quot;How do &lt;em&gt;you&lt;/em&gt; feel you are doing?&quot;&lt;/p&gt;
&lt;p&gt;I answered with some moderate confidence, but also with a hint of apprehension. I was confident I was on a good path to a solution, but I was uncertain that I was heading towards an optimum answer. I took some time to explain that this has been a common feeling in the interviews I have had. I don&apos;t have a background in computer science, so the more technical aspects of data structures, Big O, and algorithms is fairly new to me. I&apos;ve only been studying these things for a short while (6-9 months). I can find solutions, I&apos;ve yet to be completely stumped by a problem given to me in a technical interview. But I often get the sense, or know, that there is a more optimal solution that I am not coming up with.&lt;/p&gt;
&lt;p&gt;His response was that he has seen hundreds of engineers attempt this problem. Of those many engineers, including those who work at Google, I was doing &quot;average to above average&quot; on solving the problem. I&apos;ll take that. That&apos;s a big win in my book.&lt;/p&gt;
&lt;p&gt;He said it was clear I understood my language and that I did a good job describing my thought process as I worked. His main concern was my speed, that I needed to go faster.&lt;/p&gt;
&lt;p&gt;I tend to be a methodical, slower coder. I get things done on time, but I get them done by thinking through my problem and then coding. Maybe you&apos;d call me a &quot;measure twice, cut once&quot; kind of coder. This isn&apos;t normally a problem because I &lt;em&gt;do&lt;/em&gt; think of solutions relatively quickly, but when I hit a place of uncertainty, I slow down and think through options. I question myself. I waver.&lt;/p&gt;
&lt;p&gt;This wavering isn&apos;t serving me well. First, it makes me slow. I had never considered just how important speed might be to the culture of a company. Rick said that my speed might be acceptable at &lt;em&gt;this&lt;/em&gt; company, but &quot;it would never fly&quot; at &lt;em&gt;that&lt;/em&gt; company.&lt;/p&gt;
&lt;p&gt;Second, I am a verbal processor (and an honest one), so while it serves me well in describing my thought process, it also means that I describe those moments when I&apos;m uncertain and unconfident as well. This isn&apos;t likely to help me in an interview. An interviewer might think I&apos;m trying to fish for an answer, or look for some kind of visual cue to indicate I am on the right track.&lt;/p&gt;
&lt;p&gt;I took from this that I may have to push myself to code with a bit more speed. I think I also need to make decisions confidently, or at the very least, act like my solution is solid. If I discover there is a better way, I can simply state that fact, and refactor my code. It does happen. I have to signal less that I am unsure, or that I want affirmation I am on the right path. I have to have more belief that I &lt;em&gt;am&lt;/em&gt; on the right path already.&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Having done quite a few of these interviews now, I can say that this experience was very similar to the real one. It was so helpful to be able to talk immediately with my interviewer about how I did instead of trying to infer the feedback based on subtle social cues like speech, tone, and body language.&lt;/p&gt;
&lt;p&gt;I really enjoyed this process. I think it should be a more common practice among aspiring and ambitious developers. It can be a great benefit to interview, even with friends, frequently. Practice will make the real thing much easier.&lt;/p&gt;
&lt;p&gt;Personally, I thought it was great to get some feedback, and frankly, some affirmation that I am doing well with my chosen focus and that I am on the right path. Going through these really challenging interview processes has occasionally left me wondering if I&apos;m not ready yet, or I&apos;m not good enough. I don&apos;t think that&apos;s the case. I think I am really close to getting to my next goal.&lt;/p&gt;
&lt;p&gt;So that was my experience doing a mock interview with Rick. I want to publicly thank him for taking the time to help out engineers this way. I also want to thank Stephanie for her part, creating an opportunity for people to connect. Thanks to both of you.&lt;/p&gt;
&lt;p&gt;I know that this was a very personal post, but I hope there was something you could take from it. Feel free to ask me more questions in the comments if you have one. Having done this experience, I think I may have to offer some mock interviews for the junior developers I meet. If you&apos;re a mid-to-senior level developer, consider offering mock interviews, too. Or maybe trade them with a good friend. Either way, we&apos;re all bound to learn a little something more about being better at interviews.&lt;/p&gt;
&lt;p&gt;&amp;lt;script async src=&quot;//platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;/p&gt;
</content:encoded><category>Career</category></item><item><title>Make Your Own Charts in React Without a Charting Library</title><link>https://kyleshevlin.com/make-your-own-charts-in-react-without-a-charting-library/</link><guid isPermaLink="true">https://kyleshevlin.com/make-your-own-charts-in-react-without-a-charting-library/</guid><description>Learn how to make your own data chart with React and SVG without using a data visualization library.</description><pubDate>Sat, 24 Jun 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import { ExampleBarChart } from &apos;./_BarChart&apos;&lt;/p&gt;
&lt;p&gt;Occasionally I see someone ask, &quot;What&apos;s the best way to make bar charts with React? Are there any great libraries?&quot; I often respond with, &quot;Why not build it with React yourself?&quot;&lt;/p&gt;
&lt;p&gt;React&apos;s one-way data binding model is perfect for creating simple data visualizations from scratch and I want to show you how.&lt;/p&gt;
&lt;h3&gt;Why shouldn&apos;t I use a charting library?&lt;/h3&gt;
&lt;p&gt;Charting libraries are great! I&apos;m not going to stop you. But bringing in a whole library for a simple data viz might be a bit of overkill in some situations. If you go the route of adding a charting library to your application, you now have to understand two APIs versus one. React&apos;s API is well suited to creating these visualizations, so I&apos;m encouraging you to use what you already know.&lt;/p&gt;
&lt;h3&gt;A Simple Bar Chart&lt;/h3&gt;
&lt;p&gt;&amp;lt;EggheadEmbed
src=&quot;https://egghead.io/lessons/javascript-build-a-bar-chart-with-svg-from-scratch-with-react/embed&quot;
title=&quot;Bar Chart from Scratch&quot;
/&amp;gt;&lt;/p&gt;
&lt;p&gt;We are going to build is a bar chart. These are really easy to build with React. Once you understand the concepts, I&apos;m sure you&apos;ll be jumping ahead and making even more complex visualizations in no time. Let&apos;s get started.&lt;/p&gt;
&lt;p&gt;To make our bar chart, we&apos;re going to first need some data. Because I lack creativity, I&apos;m going to create a data set based on the number of repos a few of my favorite Github users own (and mine for good measure):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const data = [
  {
    name: &apos;kentcdodds&apos;,
    repos: 371,
  },
  {
    name: &apos;sindresorhus&apos;,
    repos: 909,
  },
  {
    name: &apos;developit&apos;,
    repos: 222,
  },
  {
    name: &apos;getify&apos;,
    repos: 43,
  },
  {
    name: &apos;btholt&apos;,
    repos: 56,
  },
  {
    name: &apos;kyleshevlin&apos;,
    repos: 82,
  },
]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, we need to build a few basic components to represent this data. We&apos;ll start with a &lt;code&gt;Chart&lt;/code&gt; component and a &lt;code&gt;Bar&lt;/code&gt; component.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const Chart = ({ children, width, height }) =&amp;gt; (
  &amp;lt;svg viewBox={`0 0 ${width} ${height}`} width={width} height={height}&amp;gt;
    {children}
  &amp;lt;/svg&amp;gt;
)

const Bar = ({ x, y, width, height }) =&amp;gt; (
  &amp;lt;rect x={x} y={y} width={width} height={height} /&amp;gt;
)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These are really simple components. Our &lt;code&gt;Chart&lt;/code&gt; component creates an &lt;code&gt;svg&lt;/code&gt; based upon the width and height we pass in as props. Then, the &lt;code&gt;Bar&lt;/code&gt; component creates a &lt;code&gt;rect&lt;/code&gt; element that we will pass as a child of the &lt;code&gt;Chart&lt;/code&gt; component.&lt;/p&gt;
&lt;p&gt;Putting this together (with some math to handle the discrepancy in repo totals), we can make our bar chart like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const BarChart = ({ data }) =&amp;gt; {
  // Width of each bar
  const itemWidth = 20

  // Distance between each bar
  const itemMargin = 5

  const dataLength = data.length

  // Normalize data, we&apos;ll reduce all sizes to 25% of their original value
  const massagedData = data.map(datum =&amp;gt;
    Object.assign({}, datum, { repos: datum.repos * 0.25 }),
  )

  const mostRepos = massagedData.reduce((acc, cur) =&amp;gt; {
    const { repos } = cur
    return repos &amp;gt; acc ? repos : acc
  }, 0)

  const chartHeight = mostRepos

  return (
    &amp;lt;Chart width={dataLength * (itemWidth + itemMargin)} height={chartHeight}&amp;gt;
      {massagedData.map((datum, index) =&amp;gt; (
        &amp;lt;Bar
          key={datum.name}
          x={index * (itemWidth + itemMargin)}
          y={0}
          width={itemWidth}
          height={datum.repos}
        /&amp;gt;
      ))}
    &amp;lt;/Chart&amp;gt;
  )
}

ReactDOM.render(&amp;lt;BarChart data={data} /&amp;gt;, document.getElementById(&apos;barchart&apos;))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you&apos;ve followed along, you should now have a bar chart of 6 bars. Their heights should correspond with how many repos the user has. There is one small problem, though. The bars are upside down.&lt;/p&gt;
&lt;p&gt;This is a typical problem with bar charts and is easily solved. I just wanted to show you how.&lt;/p&gt;
&lt;p&gt;In our &lt;code&gt;BarChart&lt;/code&gt; component, we need to change the &lt;code&gt;y&lt;/code&gt; prop to place the &lt;code&gt;rect&lt;/code&gt; such that they all line up on the bottom. To do this, we can set &lt;code&gt;y&lt;/code&gt; equal to &lt;code&gt;chartHeight&lt;/code&gt; minus that &lt;code&gt;rect&lt;/code&gt;&apos;s height. Let&apos;s make some small changes to the component:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const BarChart = ({ data }) =&amp;gt; {
  // all the same ...

  return (
    &amp;lt;Chart width={dataLength * (itemWidth + itemMargin)} height={chartHeight}&amp;gt;
      {massagedData.map((datum, index) =&amp;gt; {
        const itemHeight = datum.repos

        return (
          &amp;lt;Bar
            x={index * (itemWidth + itemMargin)}
            y={chartHeight - itemHeight}
            width={itemWidth}
            height={itemHeight}
          /&amp;gt;
        )
      })}
    &amp;lt;/Chart&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And there you have it, a very simple to make bar chart. Check out a rendering of our bar chart below:&lt;/p&gt;
&lt;p&gt;&amp;lt;OffsetWrap&amp;gt;
&amp;lt;div class=&quot;flex justify-center&quot;&amp;gt;
&amp;lt;ExampleBarChart client:load /&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/OffsetWrap&amp;gt;&lt;/p&gt;
</content:encoded><category>React</category><category>Data Visualization</category><category>SVG</category></item><item><title>How I Stumbled Upon Normalizing Redux State</title><link>https://kyleshevlin.com/how-i-stumbled-upon-normalizing-redux-state/</link><guid isPermaLink="true">https://kyleshevlin.com/how-i-stumbled-upon-normalizing-redux-state/</guid><description>Learn how I stumbled my way into discovering normalizing Redux state.</description><pubDate>Thu, 18 May 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;My most recent work project was an interesting challenge. I built an app (actually 2 Electron apps supporting 3 React apps communicating through WebSockets) that allowed a user (actually 4 simultaneous users) to look at an array of stories related to sea ports, select one, have a detail component pop up with more information about the story, and then move to the next or previous story from within the detail window.&lt;/p&gt;
&lt;p&gt;For each of these actions, a particular story had to be retrieved from the Redux store. In my naive, initial implementation, stories were kept as an array and a simple &lt;code&gt;.find()&lt;/code&gt; was used to loop through the array and match ids. For those of you who know where I&apos;m going with this, this was a slow solution. For those of you who don&apos;t know where I&apos;m going with this, let me explain.&lt;/p&gt;
&lt;p&gt;Up until about a year ago, I knew very little of how data structures worked. I just used whatever structure seemed to make the most sense. Like in this example, I have a collection of stories, it seems most obvious to use an array. However, data structures all have pros and cons. One of the cons of an array is how slow a lookup is if you don&apos;t know the index of the item. Let me explain why.&lt;/p&gt;
&lt;p&gt;Say I have an array with &lt;em&gt;a lot&lt;/em&gt; of items (think thousands, for this example). Now imagine that I have to find an item in this array, but the only way I can find it is by checking, one by one, if the current item matches what I&apos;m looking for. It would be like having to search through a filing cabinet, file by file, to find something. It&apos;s really slow. In CS terms, this search has a time complexity of O(n), meaning it takes the time of &lt;em&gt;n&lt;/em&gt; items to find the right one. So how can we speed this up?&lt;/p&gt;
&lt;p&gt;I mentioned that finding an item in an array is faster if you know the index of the item. You go directly to the correct spot and retrieve the item stored there. Does this remind you of another data structure? That&apos;s right. An object.&lt;/p&gt;
&lt;p&gt;An object stores key/value pairs. If you know the key, you can get the value. This has a time complexity of O(1). Regardless of how many key/value pairs are stored in the object, the lookup is the same speed. So how do we take an array and create an object out of it?&lt;/p&gt;
&lt;p&gt;In my situation, this is (roughly) what I did:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const array = [
  {
    id: 1,
    title: &apos;Awesome Story&apos;,
    content: &apos;This is a very awesome story&apos;,
  },
  {
    id: 2,
    title: &apos;Happy Story&apos;,
    content: &apos;This is a happy story :)&apos;,
  },
  {
    id: 3,
    title: &apos;Sad Story&apos;,
    content: &apos;This is a sad story :(&apos;,
  },
]

// Turn into an object with .reduce()
const objFromArray = array.reduce((accumulator, current) =&amp;gt; {
  accumulator[current.id] = current
  return accumulator
}, {})

console.log(objFromArray)
// Logs out
// {
//   1: {
//     id: 1,
//     title: &apos;Awesome Story&apos;,
//     content: &apos;This is a very awesome story&apos;
//   },
//   2: {
//     id: 2,
//     title: &apos;Happy Story&apos;,
//     content: &apos;This is a happy story :)&apos;
//   },
//   3: {
//     id: 3,
//     title: &apos;Sad Story&apos;,
//     content: &apos;This is a sad story :(&apos;
//   }
// }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, to find an item, we do a lookup with the item&apos;s &lt;code&gt;id&lt;/code&gt; property. This is much faster. To do this normalization in Redux, use this logic in your reducer when you receive the array. It is often helpful to maintain an array of the &lt;code&gt;id&lt;/code&gt;s so you have a list of all the keys, in the correct order, to your new object. In the same reducer logic, &lt;code&gt;map()&lt;/code&gt; out your keys into an array and define it as a property in your state object. Your state tree will come out looking something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const state = {
  stories: {
    // an object that looks like the one logged out from above
  },
  allStoryIds: [
    // an array of each id to use as keys for lookup
  ],
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After I had done all this, my app performed much faster. I don&apos;t have statistical breakdown of the data, but it was obvious to everyone. My team did a bunch of &quot;oohs&quot; and &quot;ahhs&quot; when they saw how much faster everything was performing.&lt;/p&gt;
&lt;h3&gt;Guess What? I Didn&apos;t Make This Up. It&apos;s Recommended by Redux&lt;/h3&gt;
&lt;p&gt;A few weeks later, I came across this: &lt;a href=&quot;http://redux.js.org/docs/recipes/reducers/NormalizingStateShape.html&quot;&gt;http://redux.js.org/docs/recipes/reducers/NormalizingStateShape.html&lt;/a&gt;. This just goes to show you should really read the Redux documentation, doesn&apos;t it? If you&apos;re looking to normalize your state shape even more, please give that a thorough read and see how it improves the performance of your Redux application.&lt;/p&gt;
&lt;p&gt;If you have any questions or comments, leave them below, and let me know of any other ways you have stumbled upon to optimize your Redux state objects.&lt;/p&gt;
</content:encoded><category>JavaScript</category><category>Redux</category></item><item><title>ShevyJS</title><link>https://kyleshevlin.com/shevyjs/</link><guid isPermaLink="true">https://kyleshevlin.com/shevyjs/</guid><description>Announcing a new library, ShevyJS, a vertical-rhythm library for CSS-in-JS.</description><pubDate>Wed, 17 May 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This morning I released &lt;a href=&quot;https://github.com/kyleshevlin/shevyjs&quot;&gt;ShevyJS&lt;/a&gt; into the wild. ShevyJS is a remake of &lt;a href=&quot;https://github.com/kyleshevlin/shevy&quot;&gt;Shevy&lt;/a&gt; for CSS-in-JS styling.&lt;/p&gt;
&lt;p&gt;If you&apos;re new to the concept of CSS-in-JS, you can find some great resources on the topic including &lt;a href=&quot;https://github.com/MicheleBertoli/css-in-js&quot;&gt;this massive repo&lt;/a&gt;. In a nutshell, CSS-in-JS is the task of adding styles either inline or otherwise directly with JavaScript. You may have seen a &lt;code&gt;style&lt;/code&gt; tag used in a React component. This was a form of CSS-in-JS.&lt;/p&gt;
&lt;p&gt;Now, you can have the mathematics of Shevy&apos;s Sass version in your JavaScript client-side framework.&lt;/p&gt;
&lt;p&gt;ShevyJS is a class that exposes a set of properties and methods for you to consume throughout your application. Because it is a constructor, you can define as many Shevy configurations you need and pass them around your app with &lt;code&gt;imports&lt;/code&gt; and &lt;code&gt;exports&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;It is available on npmjs.org, and be sure to check out the repo at &lt;a href=&quot;https://github.com/kyleshevlin/shevyjs&quot;&gt;https://github.com/kyleshevlin/shevyjs&lt;/a&gt;. If you like the library, please star it.&lt;/p&gt;
&lt;p&gt;If you have any questions, feel free to ask them here, or create an issue on the repository. And share examples of using ShevyJS in the wild.&lt;/p&gt;
</content:encoded><category>JavaScript</category></item><item><title>What I Love About React #1</title><link>https://kyleshevlin.com/what-i-love-about-react-1/</link><guid isPermaLink="true">https://kyleshevlin.com/what-i-love-about-react-1/</guid><description>Learn how to use ternaries for conditional rendering in React.</description><pubDate>Sat, 22 Apr 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This won&apos;t be a very long, nor deep, post. As I was working on some code this afternoon, a thought occurred to me. I love React. I really do. I find it so pleasant to work in React, and I can&apos;t always describe why. However, I have at least one reason I can describe, and I thought I&apos;d share that with you right now. I&apos;ll share more as I think of others.&lt;/p&gt;
&lt;p&gt;One reason I love React is the simple fact that the same component can render different markup depending upon &lt;code&gt;props&lt;/code&gt; and/or &lt;code&gt;state&lt;/code&gt;. I think many of us have grown so accustom to this that we have forgotten how novel and amazing this is.&lt;/p&gt;
&lt;p&gt;Let&apos;s take a very simple component for an example.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class MyComponent extends React.Component {
  constructor() {
    super()
    this.state = { isReady: false }
  }

  componentDidMount() {
    setTimeout(() =&amp;gt; {
      this.setState({ isReady: true })
    }, 3000)
  }

  render() {
    return this.state.isReady ? (
      &amp;lt;div&amp;gt;I&apos;m ready!&amp;lt;/div&amp;gt;
    ) : (
      &amp;lt;div&amp;gt;One moment. I&apos;m still getting ready.&amp;lt;/div&amp;gt;
    )
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this simple component, I am using a ternary to render one &lt;code&gt;div&lt;/code&gt; when the component &lt;code&gt;isReady&lt;/code&gt; and an entirely different one when we are not. There are a number of other ways to handle this situation that return the same result, but at it&apos;s core, any one of them will use a ternary or an &lt;code&gt;if...else&lt;/code&gt; statement to return different DOM for different state.&lt;/p&gt;
&lt;p&gt;This is absolutely brilliant. Could you imagine trying to accomplish this with a server side application? You could probably do it with vanilla JavaScript or jQuery simply enough, but would it be as elegant? Our component is as pure as the driven snow. It renders solely based on its inputs, is really easy to test, and pretty easy to reason about.&lt;/p&gt;
&lt;p&gt;Just last year, I was working as a Rails developer. There&apos;s nothing in that ecosystem that even comes close to this. Often in this scenario, I would actually render both &lt;code&gt;div&lt;/code&gt;s and hide the correct one with CSS. It was hacky, but made transitioning simple and nice.&lt;/p&gt;
&lt;p&gt;React eliminates these hacks and instead provides us with a very elegant way of creating really responsive UIs (not responsive in design, but responsive to our data). It&apos;s just hard to beat how simple, yet powerful this mechanism is.&lt;/p&gt;
</content:encoded><category>React</category></item><item><title>What is Most Important to a Web Developer?</title><link>https://kyleshevlin.com/what-is-most-important-to-a-web-developer/</link><guid isPermaLink="true">https://kyleshevlin.com/what-is-most-important-to-a-web-developer/</guid><description>I recently asked developers what was most important to them. The results were a bit surprising.</description><pubDate>Sun, 26 Feb 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import SocialPost from &apos;../../../components/SocialPost.astro&apos;&lt;/p&gt;
&lt;p&gt;Recently, I ran a poll on Twitter asking web developers what was most important to them. Here&apos;s a look at the results.&lt;/p&gt;
&lt;p&gt;&amp;lt;SocialPost
authorName=&quot;Kyle Shevlin&quot;
authorHandle=&quot;@kyleshevl.in&quot;
authorProfile=&quot;https://bsky.app/profile/kyleshevl.in&quot;
avatarUrl=&quot;/images/kyle-headshot.jpg&quot;
date=&quot;2017-02-22&quot;
content=&quot;What&apos;s more important to you as a web developer?&quot;
/&amp;gt;&lt;/p&gt;
&lt;p&gt;Over 50% of the voters said the people they work with is most important to them, followed by the product they work on, and lastly, followed by the tech they use at work. No one replied with an &quot;other&quot;, even though a couple people voted for it.&lt;/p&gt;
&lt;p&gt;I wanted to take some time and write about what I found surprising and not surprising about these results. If you&apos;re not a fan of think pieces and only like technical articles, turn away now.&lt;/p&gt;
&lt;h3&gt;Not Surprising&lt;/h3&gt;
&lt;p&gt;I want to start with what is &lt;em&gt;not&lt;/em&gt; surprising about the results. I don&apos;t find it surprising that developers said the people they work with matter so much to them, but I also don&apos;t think this is something exclusive to developers. Human beings are social creatures. It&apos;s in our nature to want to interact with the people around us, especially those we must spend so much time with. And since no one wants to put up with a difficult person for long, it makes sense that having people you enjoy to work with would be important.&lt;/p&gt;
&lt;p&gt;Another way to put this is as a business develops a culture and a tribe, you recruit more people who fit and enhance that tribe. In doing so, you have a better chance of a newcomer fitting in (because you only select newcomers that already likely fit in) and reduce potential disruption. This might have some negative effects, but you are likely to find a group of people who like being around each other.&lt;/p&gt;
&lt;p&gt;It also didn&apos;t surprise me that a third of voters said the product they work on mattered most to them. Again, I don&apos;t think this is exclusive to developers. People want to believe that the work they do is meaningful and has an impact. Working on a product that you don&apos;t care about, that you have no emotional investment in can be some of the most draining, boring and soul-sucking work. When people work on products that they &lt;em&gt;actually&lt;/em&gt; care about, they give you their best work and feel satisfied and accomplished with what they do.&lt;/p&gt;
&lt;h3&gt;Surprising&lt;/h3&gt;
&lt;p&gt;On the other hand, I &lt;em&gt;do&lt;/em&gt; find it surprising that developers say that the people they work with matter so much to them. If you were to take a broad slice of blog posts, tweets, and other articles written by developers, you&apos;d get the picture that the tech stack would be the most important to them. We&apos;re quite fond of writing articles bashing this technology and praising that technology. We are opinionated about our field, and it would make sense that we would have strong opinions about what technology we use day in and day out. But technology was the least important of the three.&lt;/p&gt;
&lt;p&gt;What I found most interesting about the results of this poll, is that they have a perfect inverse correlation to how much knowledge you can have about each one before taking a job. Let me explain.&lt;/p&gt;
&lt;p&gt;When you&apos;re looking for jobs, web developer job descriptions are littered with acronyms to describe the tech stack used at a particular company. We obsess over these acronyms, because they represent hours and years of effort learning and programming. Developers fall in a couple camps, but when considering a job, they want to know what stack they will use. Will it be one I&apos;m really comfortable with and love? Will it be a new language and new challenges? These matter to developers. And it&apos;s the &lt;em&gt;easiest&lt;/em&gt; thing to learn about a new job. You ask a question, and you get a perfect, corresponding answer. There is no ambiguity, other than what might be used in the future.&lt;/p&gt;
&lt;p&gt;Next, you might ask about the product you are working on. How often have you asked a developer what kind of product they work on, and you receive a semi-ambiguous response? &quot;Well, it kind of does this. It kind of does that. Somehow it makes money.&quot; Products, can be challenging to describe, but generally you can describe the shape of it. You might not be able to express all the fine details of a product in an elevator pitch, but you can get a sense of what you will be working on. Thus, you&apos;ll likely be less clear on the product than you were on the tech stack, but you&apos;ll have a reasonable understanding.&lt;/p&gt;
&lt;p&gt;But the people you will work with is a mystery prior to starting a job and continues to be for some time after starting. Unless you happen to previously know the people you are working with, you most likely know &lt;em&gt;nothing&lt;/em&gt; about your future coworkers. Unless it is a very small company, you will likely only meet a handful of people in the hiring process and virtually everyone is on their very best behavior, each party trying to woo the other. At best, you&apos;ll get a small glimpse into the culture of the company, but will not have enough information to make an accurate assessment of the overall culture of your future team and the company as a whole. The only way to gather this data is to be a part of it and hope it works out for the best.&lt;/p&gt;
&lt;h3&gt;Final Thoughts&lt;/h3&gt;
&lt;p&gt;To summarize, it&apos;s not surprising that people care about the people they work with and the product they work on. I think people want to enjoy work and want to work on something that matters, that is important to them and to the world. I think developers are willing to sacrifice working on the newest technology stack for the opportunity to work with great people or on a product they can get behind.&lt;/p&gt;
&lt;p&gt;What is surprising is that these very things might be the most difficult to ascertain before joining a team or taking a job. I wonder if there are ways that we can flip this correlation and make the things most important to developers (and people in general) easier to learn about.&lt;/p&gt;
</content:encoded><category>Career</category></item><item><title>Renderless Components</title><link>https://kyleshevlin.com/renderless-components/</link><guid isPermaLink="true">https://kyleshevlin.com/renderless-components/</guid><description>Renderless components are a way to use React&apos;s component model for side effects and logic that isn&apos;t mapped directly to your UI</description><pubDate>Thu, 23 Feb 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;If you&apos;re using Redux with React, you are probably familiar with the concept of container and presentational components. If you are, you can skip ahead to the section &lt;a href=&quot;#renderless-components&quot;&gt;&lt;strong&gt;Renderless Components&lt;/strong&gt;&lt;/a&gt;. If you&apos;re not, let me give you a very brief description of each.&lt;/p&gt;
&lt;h3&gt;Container Components&lt;/h3&gt;
&lt;p&gt;The purpose of a &quot;container component&quot; is to gather and pass data into a presentational component. Container components are used to connect to stores, fetch data during various lifecycle methods, and otherwise gather and transfer data to child components.&lt;/p&gt;
&lt;h3&gt;Presentational Components&lt;/h3&gt;
&lt;p&gt;The purpose of a &quot;presentational component&quot; is to render UI based solely on the props passed to it. These have also been referred to in the past as &quot;dumb components&quot;. These components have no (or at least very little) logic, and do not use any lifecycle methods other than &lt;code&gt;render()&lt;/code&gt;. In fact, most presentational components are written as stateless functional components. That is, these components are pure functions that receive props as arguments and render appropriate markup. Presentational components are relatively easy to test due to this.&lt;/p&gt;
&lt;h3&gt;Redux and Container Components&lt;/h3&gt;
&lt;p&gt;Those familiar with Redux know that a single store governs your application&apos;s state in a Redux app. The typical way to pass this state to your app is through a &lt;code&gt;Provider&lt;/code&gt; and using the &lt;code&gt;connect()&lt;/code&gt; function to connect components to this &lt;code&gt;Provider&lt;/code&gt;. These can be found in the &lt;code&gt;react-redux&lt;/code&gt; package.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;connect()&lt;/code&gt; function creates a Higher Order Component, that maps state and actions to props and connects the component to the Redux store. Like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import React, { Component } from &apos;react&apos;
import { connect } from &apos;react-redux&apos;

class FooContainer extends Component {
  //...
}

export default connect()(FooContainer)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I won&apos;t go into the &lt;code&gt;connect()&lt;/code&gt; API. The docs are very well written and there are plenty of tutorials and videos on how to use it. I simply wanted to show that we are not exporting &lt;code&gt;FooContainer&lt;/code&gt; itself, but rather the HOC returned by the &lt;code&gt;connect()&lt;/code&gt; function.&lt;/p&gt;
&lt;h3&gt;Redux and Presentational Components&lt;/h3&gt;
&lt;p&gt;Using the example from above, generally speaking, we would use this container component to connect to our store to gather props and pass those props into a presentational component. There are two ways to do this.&lt;/p&gt;
&lt;p&gt;We can pass the props directly to our presentational component if we don&apos;t need to use any lifecycle hooks in a container component, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { connect } from &apos;react-redux&apos;
import FooPresentational from &apos;./FooPresentational&apos;

const mapStateToProps = state =&amp;gt; ({
  someProp: state.someProp,
})

export default connect(mapStateToProps)(FooPresentational)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this situation, &lt;code&gt;someProp&lt;/code&gt; is passed directly into &lt;code&gt;FooPresentational&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;We can also map the props to the container component, and then pass them to the presentational component in the &lt;code&gt;render()&lt;/code&gt; method of our container component, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import React, { Component } from &apos;react&apos;
import FooPresentational from &apos;./FooPresentational&apos;

class FooContainer extends Component {
  render() {
    return &amp;lt;FooPresentational someProp={this.props.someProp} /&amp;gt;
  }
}

const mapStateToProps = state =&amp;gt; ({
  someProp: state.someProp,
})

export default connect(mapStateToProps)(FooContainer)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This way of passing props explicitly might be a bit cumbersome, but can be useful if you need to massage the props for any reason before passing them.&lt;/p&gt;
&lt;h3&gt;Renderless Components&lt;/h3&gt;
&lt;p&gt;When I first came to React, my mental model treated components and the UI as a 1-to-1 mapping. It took me some time to realize not all components will render DOM elements. It took me even longer to realize that not all components need to render &lt;em&gt;anything at all&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;It is a perfectly legitimate use of a component to &lt;code&gt;render () { return null }&lt;/code&gt;. This is particularly helpful when you need logic to exist that updates your store, but has no associated UI. In this case, you&apos;re making a container component that doesn&apos;t return any presentational components. For now, I call this a &lt;em&gt;renderless component&lt;/em&gt;. This is an incredibly useful pattern.&lt;/p&gt;
&lt;p&gt;For a project I am working on, I need to update a value in my store, &lt;code&gt;currentTime&lt;/code&gt;, with the current hours, minutes, and seconds. Since Redux requires reducers to be pure, the logic for updating the time must be in the action itself or passed to the action creator function as parameters. This means, I need a component to set up an interval to dispatch a function that will in turn update my store. Here&apos;s what a component like that might look like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { Component, PropTypes } from &apos;react&apos;
import { connect } from &apos;react-redux&apos;

// This is my action creator function
// It takes three parameters: hours, minutes, seconds
import { updateTime } from &apos;../actions&apos;

class UpdateTimeContainer extends Component {
  constructor() {
    super()

    this.intervalId = null
    this.startClock = this.startClock.bind(this)
    this.stopClock = this.stopClock.bind(this)
    this.getCurrentTime = this.getCurrentTime.bind(this)
  }

  componentDidMount() {
    this.startClock()
  }

  componentWillUnmount() {
    this.stopClock()
  }

  startClock() {
    this.intervalId = setInterval(this.getCurrentTime, 5000)
  }

  stopClock() {
    clearInterval(this.intervalId)
  }

  getCurrentTime() {
    const now = new Date()
    const hours = now.getHours()
    const minutes = now.getMinutes()
    const seconds = now.getSeconds()

    this.props.updateTime(hours, minutes, seconds)
  }

  render() {
    return null
  }
}

UpdateTimeContainer.propTypes = {
  updateTime: PropTypes.func,
}

const mapDispatchToProps = {
  updateTime,
}

export default connect(null, mapDispatchToProps)(UpdateTimeContainer)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As you can see, this component uses lifecycle methods like any normal component, but doesn&apos;t render any markup. That&apos;s right! A component will &lt;em&gt;mount&lt;/em&gt; even if it doesn&apos;t &lt;em&gt;render&lt;/em&gt; markup.&lt;/p&gt;
&lt;p&gt;If you check your inspector, you&apos;ll see that React adds a nice little comment about this component &lt;code&gt;&amp;lt;!-- react-empty: [id] --&amp;gt;&lt;/code&gt;. Our component exists in the virtual DOM and updates to the store without rendering pointless markup.&lt;/p&gt;
&lt;p&gt;This pattern allows us to write business logic into our applications as React components. I have used this pattern for event handlers, listening to web sockets, and more. It seems every time I make an app, I think of a new use case for this pattern.&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;What I want you to take away from this post is that rendering &lt;code&gt;null&lt;/code&gt; from a React component is a perfectly legitimate use of a component. Using this pattern will allow you to encapsulate necessary logic for updating your store (or however else you are managing state in your app).&lt;/p&gt;
&lt;p&gt;I hope this helps and that you find use cases in your own projects for creating these renderless components. Let me know if you have any questions, ways to improve this technique, or examples using it in the comments.&lt;/p&gt;
</content:encoded><category>React</category><category>Redux</category></item><item><title>Zeno&apos;s Paradox of Infinite Loop Scrolling</title><link>https://kyleshevlin.com/zenos-paradox-of-infinite-loop-scrolling/</link><guid isPermaLink="true">https://kyleshevlin.com/zenos-paradox-of-infinite-loop-scrolling/</guid><description>I recently learned a lesson eerily similar to a Greek paradox.</description><pubDate>Fri, 17 Feb 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;My current project has a strange requirement. Given a collection of items, a user should be able to infinitely loop scroll left and right in a carousel. From strictly a UI perspective, this makes sense, when I move to the left, add items to the right and vice versa. From a developer&apos;s perspective, this is kind of crazy.&lt;/p&gt;
&lt;p&gt;Let&apos;s assume I have a collection, we can use an array of numbers for this example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const collection = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&apos;s assume I can only see five of these items on the screen at once. Thus, when we reach either &quot;edge&quot; of the array, we should get the items on the other &quot;edge&quot; to populate our visible five. For example, if I went past the left edge, I would see this: &lt;code&gt;9,10,1,2,3&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The way this is handled, from a developer&apos;s perspective, is that when you scroll the container you add and remove items simultaneously (or &lt;code&gt;.map()&lt;/code&gt; a new set of items for better performance) so that the number of items is always the same. Because the number of items is a constant, when we &quot;move&quot; our items, we must compensate the scroll position of the container an equal amount. If you move to reveal an item on the left we must:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Remove the item on the right&lt;/li&gt;
&lt;li&gt;Add an item on the left&lt;/li&gt;
&lt;li&gt;Then compensate the scroll position the width of one item&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Doing this results in your scroll position being exactly the same as it was. Assuming a world where the wrapping container never changes width, and the performance of the machine you view this UI on is perfect, you would &lt;em&gt;literally&lt;/em&gt; never move position. Crazy!&lt;/p&gt;
&lt;p&gt;Similar to Zeno&apos;s paradox where the arrow never reaches its target, the user never actually scrolls despite what appears like scrolling.&lt;/p&gt;
</content:encoded><category>JavaScript</category></item><item><title>Head Scratcher #1</title><link>https://kyleshevlin.com/head-scratcher-1-2d-array-from-array-of-objects/</link><guid isPermaLink="true">https://kyleshevlin.com/head-scratcher-1-2d-array-from-array-of-objects/</guid><description>Read along as I solve a tricky problem with Array.reduce()</description><pubDate>Thu, 16 Feb 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I am starting a randomly occurring series called &quot;Head Scratchers.&quot; At least once a week (probably once a day), I run into a problem that makes me scratch my head for while. So I&apos;m going to share the problem and my solution with you. If you think of a better way to solve the problem, I want to see it in the comments below.&lt;/p&gt;
&lt;h3&gt;The Problem&lt;/h3&gt;
&lt;p&gt;Currently I am building an application for an interactive touch table that will be on a boat. This table will retrieve a number of locations associated with particular ports. The shape of the data (for now) is a bit odd. I can retrieve an array of the locations, but then have to gather them by ports for the user interface. This is what a few example items of this data might look like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// My API endpoint returns an array of objects with ids and a foreign key to a port
;[
  { id: 1, port_id: 3 },
  { id: 2, port_id: 1 },
  { id: 3, port_id: 2 },
  { id: 4, port_id: 1 },
  { id: 5, port_id: 3 },
]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If I only had to display these items with their associated port, this would be fine, but the expectation of the user interface is to list them in groups by ports. So, I need to take this array and turn it into a two dimensional array gathered by ports.&lt;/p&gt;
&lt;h3&gt;My Solution&lt;/h3&gt;
&lt;p&gt;I needed to go from a one dimensional array, like &lt;code&gt;[1,2,3,4,5]&lt;/code&gt;, to a two dimensional array, like &lt;code&gt;[[1,2],[3],[4,5]]&lt;/code&gt;. I can&apos;t accomplish this in one step (as far as I know). I can&apos;t use &lt;code&gt;.map()&lt;/code&gt; since it&apos;s not a one-to-one mapping of values. I need a solution that will allow me to create my sub-arrays first, and then push them into a new array.&lt;/p&gt;
&lt;p&gt;To start, I decided to use &lt;code&gt;.reduce()&lt;/code&gt; to turn my array into an object, the keys of which are the &lt;code&gt;port_id&lt;/code&gt;s and the values for each key are an array of the points of interest objects. That looked like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const items = [
  { id: 1, port_id: 3 },
  { id: 2, port_id: 1 },
  { id: 3, port_id: 2 },
  { id: 4, port_id: 1 },
  { id: 5, port_id: 3 },
]

const ports = items.reduce((acc, cur) =&amp;gt; {
  if (!acc[cur.port_id]) {
    acc[cur.port_id] = []
  }

  acc[cur.port_id].push(cur)

  return acc
}, {})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;.reduce()&lt;/code&gt; method takes a callback and starting value. In this case, I want to start with an empty object. This empty object will be supplied as the &lt;code&gt;acc&lt;/code&gt; value in the first pass through the function. &lt;code&gt;acc&lt;/code&gt; stands for &quot;accumulator&quot; as this will be the accumulation of our iterations over each item. &lt;code&gt;cur&lt;/code&gt; is short for &quot;currentValue&quot;, which is the current item being iterated over.&lt;/p&gt;
&lt;p&gt;With each pass, if the accumulated object does not have a key that matches the current &lt;code&gt;port_id&lt;/code&gt;, we create a key of that &lt;code&gt;port_id&lt;/code&gt; and assign it an empty array. Regardless of whether the array needed to be created, we will be pushing the current item into the array associated with the &lt;code&gt;port_id&lt;/code&gt;. We then must return the accumulator to be used in the next iteration of the function. When this runs over our &lt;code&gt;items&lt;/code&gt;, should have an object that looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;console.log(ports)

// {
//   1: [{ id: 2, port_id: 1 }, { id: 4, port_id: 1 }],
//   2: [{ id: 3, port_id: 2 }],
//   3: [{ id: 1, port_id: 3 }, { id: 5, port_id: 3 }]
// }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we have an object whose keys are paired with values that will be the subarrays of our two dimensional arrays. We want those values, and we want them in an array. There happens to be a new method on the JavaScript primitive &lt;code&gt;Object&lt;/code&gt; that will do just that, the &lt;code&gt;.values()&lt;/code&gt; method.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Object.values(obj)&lt;/code&gt; returns an array containing the values of the enumerable properties of your object. Since our values happen to all be arrays, we will end up with an array of arrays. Using this method looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const twoDimItems = Object.values(ports)
console.log(twoDimItems)

// [[{ id: 2, port_id: 1 }, { id: 4, port_id: 1 }], [{ id: 3, port_id: 2 }], [{ id: 1, port_id: 3 }, { id: 5, port_id: 3 }]]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now I have a two dimensional array gathered by ports. Since I mentioned that this is necessary, I might as well explain my needs there.&lt;/p&gt;
&lt;p&gt;Each of these items, individually, will represent a &lt;code&gt;Card&lt;/code&gt; of information. I need a list of these &lt;code&gt;Card&lt;/code&gt;s gathered by their ports, thus I have &lt;code&gt;CardGroup&lt;/code&gt;s. Each &lt;code&gt;CardGroup&lt;/code&gt; displays a list of its &lt;code&gt;Card&lt;/code&gt;s. Lastly, I have a &lt;code&gt;CardGroupsList&lt;/code&gt; that displays all my groups. It&apos;s a cascade of lists, and thus, my UI is a mapping over the outer array, followed by mapping each inner array. With React stateless functional components, that looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const Card = ({ item }) =&amp;gt; &amp;lt;div className=&quot;card&quot;&amp;gt;{item.id}&amp;lt;/div&amp;gt;

const CardGroup = ({ group }) =&amp;gt; (
  &amp;lt;div className=&quot;card_group&quot;&amp;gt;
    {group.map(item =&amp;gt; (
      &amp;lt;Card item={item} /&amp;gt;
    ))}
  &amp;lt;/div&amp;gt;
)

const CardGroupsList = ({ groups }) =&amp;gt; (
  &amp;lt;div className=&quot;card_groups_list&quot;&amp;gt;
    {groups.map(group =&amp;gt; (
      &amp;lt;CardGroup group={group} /&amp;gt;
    ))}
  &amp;lt;/div&amp;gt;
)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;And that&apos;s how I turned one array into a two dimensional array sorted by a foreign key. I&apos;ll leave it to you to figure out how all the pieces fit together with the React components. I hope it&apos;s clear how I came to my solution. If you can think of a better solution, leave it in the comments (or create a Gist and link to it, might be easier). I&apos;d love an opportunity to learn from one of you.&lt;/p&gt;
</content:encoded><category>React</category></item><item><title>How to Dynamically Render React Components</title><link>https://kyleshevlin.com/how-to-dynamically-render-react-components/</link><guid isPermaLink="true">https://kyleshevlin.com/how-to-dynamically-render-react-components/</guid><description>Learn how to dynamically render React components based on a discriminated object property.</description><pubDate>Wed, 08 Feb 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I am currently working on a React/Redux universally rendered application at work. It has some fun parts and I want to share what I&apos;ve learned from building them.&lt;/p&gt;
&lt;p&gt;One of those parts is a component I have called the &lt;code&gt;BlocksLoop&lt;/code&gt;. In the design phase of the project, long before I was ever a part of the project, the designers and back end dev had the foresight to create a system of reusable admin components. They called them &quot;blocks&quot;. Each page of the application was to be architected by utilizing these blocks in different orders and patterns. This was a front-end developer&apos;s dream come true. I considered crying, but then didn&apos;t, mostly because I can&apos;t. Seriously. I have some weird dry eye condition. I don&apos;t create the same amount of tears as you normal, emotionally and physically healthy people. But I digress.&lt;/p&gt;
&lt;p&gt;In the end, the designers came up with 10 reusable blocks for the project. The backend developer implemented an API that returned an array of objects. So, how do we handle rendering components when we have no idea how many, or specifically which ones we&apos;ll need at any given time?&lt;/p&gt;
&lt;p&gt;In my last blog post, I showed you how we can render different components conditionally. We&apos;re going to take that a step further. Actually we&apos;re going to take that to 11.&lt;/p&gt;
&lt;p&gt;Inspired by the architecture of reducers in Redux, I realized a simple way to handle this very dynamic array of objects was to use a &lt;code&gt;switch&lt;/code&gt; statement.&lt;/p&gt;
&lt;p&gt;I knew that each object in the array had a &lt;code&gt;type&lt;/code&gt; property. I needed to make individual components for each type. I could then check this type, and require the proper component with each one. This is significantly easier architecture than attempting to write a giant component to handle all the types. So let&apos;s see how this works.&lt;/p&gt;
&lt;p&gt;For this example, imagine that I have several built out components. Each of these components represents a type of block. We&apos;re going to import these into what will become our &lt;code&gt;BlocksLoop&lt;/code&gt; component. I&apos;ll also setup our component to accept a &lt;code&gt;blocks&lt;/code&gt; prop, but it won&apos;t do anything important yet.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import React, { Component, PropTypes } from &apos;react&apos;
import HeadingBlock from &apos;./HeadingBlock&apos;
import TextBlock from &apos;./TextBlock&apos;
import ImageBlock from &apos;./ImageBlock&apos;
import ListBlock from &apos;./ListBlock&apos;

export default class BlocksLoop extends Component {
  render() {
    return (
      &amp;lt;div className=&quot;blocks_loop&quot;&amp;gt;
        {this.props.blocks.map(block =&amp;gt; (
          &amp;lt;div className=&quot;block&quot; /&amp;gt;
        ))}
      &amp;lt;/div&amp;gt;
    )
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Right now, I&apos;m just returning all the blocks as a simple &lt;code&gt;div&lt;/code&gt; and not utilizing the imported individual blocks. Let&apos;s solve that with a &lt;code&gt;switch&lt;/code&gt; statement. To make it cleaner, we&apos;ll move this logic into a method on the component that&apos;s called each time a block item is mapped over.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// ...

export default class BlocksLoop extends Component {
  constructor() {
    super()
    this.getBlockComponent = this.getBlockComponent.bind(this)
  }

  getBlockComponent(block) {
    switch (block.type) {
      case &apos;heading&apos;:
        return &amp;lt;HeadingBlock key={block.id} {...block} /&amp;gt;

      case &apos;text&apos;:
        return &amp;lt;TextBlock key={block.id} {...block} /&amp;gt;

      case &apos;image&apos;:
        return &amp;lt;ImageBlock key={block.id} {...block} /&amp;gt;

      case &apos;list&apos;:
        return &amp;lt;ListBlock key={block.id} {...block} /&amp;gt;

      default:
        return &amp;lt;div className=&quot;no_block_type&quot; /&amp;gt;
    }
  }

  render() {
    return (
      &amp;lt;div className=&quot;blocks_loop&quot;&amp;gt;
        {this.props.blocks.map(block =&amp;gt; this.getBlockComponent(block))}
      &amp;lt;/div&amp;gt;
    )
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And there you have it! Our &lt;code&gt;blocks&lt;/code&gt; array is mapped over, each item is passed into our method, and the correct component is returned dynamically. If for some reason a type was added in the back end before I could make a new component for it, the method returns an empty &lt;code&gt;div&lt;/code&gt; with a class I can style.&lt;/p&gt;
&lt;p&gt;I think it might be possible to reduce some of the boilerplate in the switch statement by creating a variable, such as &lt;code&gt;let dynamicComponent = null&lt;/code&gt;, and then overriding that assignment in each case with the correct component. Then in one last step in the function, I could add the &lt;code&gt;key&lt;/code&gt; and &lt;code&gt;{...block}&lt;/code&gt; props (via the Object spread operator) to the currently assigned &lt;code&gt;dynamicComponent&lt;/code&gt; variable. I&apos;m ok with being this explicit for now. It&apos;s very legible and understandable.&lt;/p&gt;
&lt;p&gt;If you find this useful, I&apos;d love to hear about it in the comments. Or if you have a way to improve this, I&apos;d love to hear that, too.&lt;/p&gt;
</content:encoded><category>React</category></item><item><title>Loading State Trick for Stateless Functional Components in React</title><link>https://kyleshevlin.com/loading-state-trick-for-stateless-functional-components-in-react/</link><guid isPermaLink="true">https://kyleshevlin.com/loading-state-trick-for-stateless-functional-components-in-react/</guid><description>Learn how to show a loading indicator for function components in React.</description><pubDate>Fri, 20 Jan 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I want to share with you a little trick I&apos;ve been using lately with stateless functional components in React. This is probably really old news to some of you, but I&apos;m hoping there are a few of you who don&apos;t know this one yet.&lt;/p&gt;
&lt;p&gt;If you&apos;re getting started with React, and especially if you&apos;re using Redux, you&apos;ve probably come across the concept of container and presentational components.&lt;/p&gt;
&lt;p&gt;Container components provide data to nested components. These components will generally use lifecycle methods, such as &lt;code&gt;componentDidMount&lt;/code&gt;, to fetch some data and pass it down.&lt;/p&gt;
&lt;p&gt;Presentational components, on the other hand, are used solely for displaying data passed into them and generally do not use any lifecycle methods. Often, if a presentational component does not require any lifecycle method (other than the required &lt;code&gt;render&lt;/code&gt;), then this component is written as a stateless functional component.&lt;/p&gt;
&lt;p&gt;A stateless functional component is simply a function that returns the markup (React functions or JSX). Props are passed as arguments to the function, and then utilized within the markup. Let&apos;s make a simple example of a stateless functional component that expects an array of items, and displays each one of those items.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import React, { PropTypes } from &apos;react&apos;

const DisplayItems = ({ items }) =&amp;gt; (
  &amp;lt;div className=&quot;items&quot;&amp;gt;
    {items.map((item, index) =&amp;gt; (
      &amp;lt;div className=&quot;item&quot; key={index} {...item} /&amp;gt;
    ))}
  &amp;lt;/div&amp;gt;
)

Display.propTypes = {
  items: PropTypes.array,
}

export default DisplayItems
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I hope the ES6 doesn&apos;t scare you. I&apos;ve created a function called &lt;code&gt;DisplayItems&lt;/code&gt;. This function expects a &lt;code&gt;props&lt;/code&gt; object as an argument, and I&apos;m using ES6 destructuring to make it clear that I&apos;m expecting and will use an &lt;code&gt;items&lt;/code&gt; property on the &lt;code&gt;props&lt;/code&gt; object.&lt;/p&gt;
&lt;p&gt;Then, I am using the implicit &lt;code&gt;return&lt;/code&gt; feature of ES6 arrow functions to return the markup (in this case JSX, it&apos;s all I really use) from within the body of the function.&lt;/p&gt;
&lt;p&gt;Then, I &lt;code&gt;map&lt;/code&gt; over each item, returning another &lt;code&gt;div&lt;/code&gt;. React requires that we add a key attribute to items that are dynamically populated, which is often the case with displaying arrays. In this case, it was easy to use the index, but it might be more useful to use a property on the &lt;code&gt;item&lt;/code&gt; itself in your case.&lt;/p&gt;
&lt;p&gt;Lastly, I am using ES6&apos;s Object spread syntax to pass all props from &lt;code&gt;item&lt;/code&gt; into the &lt;code&gt;div&lt;/code&gt;. In your example, it is possible that this inner item &lt;code&gt;div&lt;/code&gt; would be another presentational component that needs access to all the &lt;code&gt;props&lt;/code&gt; on &lt;code&gt;item&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Thus, if we used this in our app, regardless of how many &lt;code&gt;items&lt;/code&gt; we pass to this stateless functional component, React would give us the wrapping &lt;code&gt;div&lt;/code&gt;, and then any &lt;code&gt;div&lt;/code&gt;s generated by the map function.&lt;/p&gt;
&lt;p&gt;But what if you currently don&apos;t have any items &lt;em&gt;and&lt;/em&gt; you don&apos;t want to display the wrapping &lt;code&gt;div&lt;/code&gt; until you have &lt;code&gt;items&lt;/code&gt;?&lt;/p&gt;
&lt;p&gt;It is possible to reconfigure this component to display alternative markup if there are no items to display.&lt;/p&gt;
&lt;p&gt;Imagine that I have built another component called &lt;code&gt;LoadingSpinner&lt;/code&gt; which simply shows the user a loading spinner animation. Perhaps it looks something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import React, { PropTypes } from &apos;react&apos;

const LoadingSpinner = () =&amp;gt; (
  &amp;lt;div className=&quot;loading_spinner-wrap&quot;&amp;gt;
    &amp;lt;svg
      className=&quot;loading_spinner&quot;
      width=&quot;60&quot;
      height=&quot;20&quot;
      viewBox=&quot;0 0 60 20&quot;
      xmlns=&quot;http://www.w3.org/2000/svg&quot;
    &amp;gt;
      &amp;lt;circle cx=&quot;7&quot; cy=&quot;15&quot; r=&quot;4&quot; /&amp;gt;
      &amp;lt;circle cx=&quot;30&quot; cy=&quot;15&quot; r=&quot;4&quot; /&amp;gt;
      &amp;lt;circle cx=&quot;53&quot; cy=&quot;15&quot; r=&quot;4&quot; /&amp;gt;
    &amp;lt;/svg&amp;gt;
  &amp;lt;/div&amp;gt;
)

export default LoadingSpinner
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And maybe I&apos;ve written some basic styles for it to animate the circles:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.loading_spinner-wrap {
  width: 100%;
  padding: 50px 0;
}

.loading_spinner {
  display: block;
  margin: 0 auto;
  fill: #000;

  circle {
    animation-name: upAndDown;
    animation-duration: 2s;
    animation-timing-function: cubic-bezier(0.05, 0.2, 0.35, 1);
    animation-iteration-count: infinite;

    &amp;amp;:nth-child(2) {
      animation-delay: 0.18s;
    }

    &amp;amp;:nth-child(3) {
      animation-delay: 0.36s;
    }
  }
}

@keyframes upAndDown {
  0% {
    opacity: 0;
    transform: translateY(0);
  }
  25% {
    opacity: 1;
    transform: translateY(-10px);
  }
  75% {
    opacity: 1;
    transform: translateY(-10px);
  }
  100% {
    opacity: 0;
    transform: translateY(0);
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, I can set up my &lt;code&gt;DisplayList&lt;/code&gt; component to either render the &lt;code&gt;LoadingSpinner&lt;/code&gt; component, or my list, depending on whether any &lt;code&gt;items&lt;/code&gt; have been passed to it. Like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import React, { PropTypes } from &apos;react&apos;
import LoadingSpinner from &apos;./LoadingSpinner&apos;

const DisplayItems = ({ items }) =&amp;gt; {
  return items.length ? (
    &amp;lt;div className=&quot;items&quot;&amp;gt;
      {items.map((item, index) =&amp;gt; (
        &amp;lt;div className=&quot;item&quot; key={index} {...item} /&amp;gt;
      ))}
    &amp;lt;/div&amp;gt;
  ) : (
    &amp;lt;LoadingSpinner /&amp;gt;
  )
}

Display.propTypes = {
  items: PropTypes.array,
}

export default DisplayItems
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Did you see what I did there? I removed the implicit return from the &lt;code&gt;DisplayItems&lt;/code&gt; function, and then used a ternary operator to determine which component gets rendered.&lt;/p&gt;
&lt;p&gt;If &lt;code&gt;items&lt;/code&gt; has any length other than 0, the ternary will evaluate to &lt;code&gt;true&lt;/code&gt; and thus render our items list. However, if the length of the array is 0, it will evaluate to &lt;code&gt;false&lt;/code&gt; and render our &lt;code&gt;LoadingSpinner&lt;/code&gt; component. You might end up with something similar to this:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;You could, of course, use any other component that you would prefer to render instead. You can determine what&apos;s best for your project, and even what&apos;s best per component. But if you&apos;re looking for a way to indicate to your users that you&apos;re expecting data to eventually make it to your stateless functional component, perhaps this pattern will be useful to you.&lt;/p&gt;
&lt;p&gt;Let me know if this is helpful to you in the comments and link to any examples you have of this trick or similar ones. I&apos;d love to see them.&lt;/p&gt;
</content:encoded><category>React</category></item><item><title>How To Use Client Side Libraries in a Universal JavaScript App</title><link>https://kyleshevlin.com/how-to-use-client-side-libraries-in-a-universal-javascript-app/</link><guid isPermaLink="true">https://kyleshevlin.com/how-to-use-client-side-libraries-in-a-universal-javascript-app/</guid><description>Learn how to use client-only libraries in server-side rendered React apps.</description><pubDate>Thu, 01 Dec 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;At work, I am building a JavaScript application with universal rendering. There are a number of challenges with building a universally rendered application, but one challenge in particular is making sure code that should only run on the client doesn&apos;t cause the server to crash.&lt;/p&gt;
&lt;p&gt;Today, I built a React component that used the &lt;a href=&quot;http://imagesloaded.desandro.com/&quot;&gt;imagesloaded&lt;/a&gt; library to detect if any images nested in the component were loaded. This is very useful for downloading large images. You can set the opacity of the image to 0 until it loads, and then transition to a visible state.&lt;/p&gt;
&lt;p&gt;Sadly, this is not as simple as importing the library and treating it like any other application. The reason: the &lt;code&gt;window&lt;/code&gt; object doesn&apos;t exist in a Node environment. Thus, any code that requires the &lt;code&gt;window&lt;/code&gt; object will fail, and often fail loudly (which are, of course, the best errors, pesky as they may be).&lt;/p&gt;
&lt;p&gt;There are a number of possible solutions to this problem. Some involve setting a fake &lt;code&gt;global.window&lt;/code&gt; object in your Node server. Another solution might be to use &lt;a href=&quot;https://github.com/tmpvar/jsdom&quot;&gt;jsdom&lt;/a&gt; but I think that could be overkill. What we need is a solution that allows the code to harmlessly fail when it runs on the server, and then run as it should on the client. Here&apos;s the trick.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const isBrowser = typeof window !== &apos;undefined&apos;
const imagesLoaded = isBrowser ? require(&apos;imagesloaded&apos;) : () =&amp;gt; {}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It&apos;s really that simple. First we create a check for whether this code is being run on the client or on the server. If it&apos;s on the client, we require the library using CommonJS (not ES6 imports) and it runs as it should. If the code is being run on the server, we return an empty function that is perfectly harmless when called. It&apos;s a simple little trick to keeping your code from crashing your server.&lt;/p&gt;
&lt;h3&gt;Next Steps&lt;/h3&gt;
&lt;p&gt;I have not tested this out, but if you&apos;re trying to use methods from a client side library on the server and throwing errors, I believe you could add methods to an otherwise empty object. Make sure these methods are just empty functions, thus continuing the trend of harmless server side failure. And remember, it&apos;s not really failure. This code wouldn&apos;t do anything in that environment anyways.&lt;/p&gt;
&lt;p&gt;In Webpack 2, I would take this code a step further and split it so it&apos;s not even requested until it is needed on the client, and thus present another potential solution to this problem.&lt;/p&gt;
&lt;p&gt;Best of luck with this trick and building your own universal application. Let me know if you think of any hiccups that this technique might raise, or any other clever tricks you have up your sleeve for this scenario.&lt;/p&gt;
</content:encoded><category>React</category></item><item><title>State Snapshots in Redux</title><link>https://kyleshevlin.com/state-snapshots-in-redux/</link><guid isPermaLink="true">https://kyleshevlin.com/state-snapshots-in-redux/</guid><description>Learn how we can store a previous state as a &quot;snapshot&quot; in Redux.</description><pubDate>Wed, 16 Nov 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://redux.js.org/&quot;&gt;Redux&lt;/a&gt; is a predictable state container for JavaScript apps. I&apos;ve been using it in all of my apps recently and I discovered an elegant and clever use of it that I want to share. The rest of this article assumes you know how to use Redux. If you do not, follow the link above and read up before continuing this one.&lt;/p&gt;
&lt;h3&gt;The Problem I Was Solving&lt;/h3&gt;
&lt;p&gt;In one particular app I am working on, the UI depends upon state to determine the correct layout and color scheme. I have several elements (a logo, heading, and footer) that each are colored based on several booleans kept in state. When certain actions are taken, such as opening the nav, I need to change the state of those items. If the user were to close the nav without selecting a link, I need those elements to return back to the state they were in.&lt;/p&gt;
&lt;p&gt;The first, most obvious solution was too simply fire actions that would change the color of each individual piece of UI like I had when opening the nav. This proved problematic. While I knew with certainty what state the UI should be in when the nav was open, I was not sure what state the UI should return to when the nav was closed. Trying to accommodate for every potential scenario would not only have been tedious, but buggy at best. Any new page in the app would have to be coded for. Then the solution dawned on me.&lt;/p&gt;
&lt;h3&gt;Snapshots&lt;/h3&gt;
&lt;p&gt;I could create a snapshot of any part of my state object, store it within that same state object, and then use its values to replace my current state at any given time. It&apos;s first-level &quot;Inception&quot; for your state.&lt;/p&gt;
&lt;p&gt;This creating and applying a snapshot of state became a significant feature of the app as it was a much better way for returning to a previous state than my other efforts. Let&apos;s walk through the code to accomplish this.&lt;/p&gt;
&lt;h3&gt;The Code&lt;/h3&gt;
&lt;p&gt;Any Redux app requires a few things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;An initial state&lt;/li&gt;
&lt;li&gt;Actions to dispatch and change state&lt;/li&gt;
&lt;li&gt;Reducers to handle actions and return a new state object&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Before I start tackling changing state, I like to consider what my initial state is. Generally, I define my initialState in the reducer file it belongs to, but for the sake of this article, I&apos;m going to be repetitious, showing you what your initial state might look like and then copy/paste this into my reducer where it normally would be. Without further adieu, or initial state:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const initialState = {
  headingIsLight: false,
  logoIsLight: false,
  footerIsLight: true,
  navIsOpen: false,
  uiSnapshot: null,
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We&apos;ve added on particular property of interest to us, the &lt;code&gt;uiSnapshot&lt;/code&gt; property. We&apos;re going to use this key to store pieces of our state. Since this is the initial state, we can set it to &lt;code&gt;null&lt;/code&gt; for the time being (and will later see that this has an added benefit).&lt;/p&gt;
&lt;p&gt;Next, we need actions to dispatch to our reducers. There are a number of strategies for handling action creators and action types out there and I&apos;ll leave it to you to research them. For now, I&apos;ve been using an &lt;code&gt;actionTypes.js&lt;/code&gt; file for all my types, and then creating action creators under an &lt;code&gt;actions&lt;/code&gt; directory.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// actionTypes.js
export const OPEN_NAV = &apos;OPEN_NAV&apos;
export const CLOSE_NAV = &apos;CLOSE_NAV&apos;
export const TAKE_UI_SNAPSHOT = &apos;TAKE_UI_SNAPSHOT&apos;
export const APPLY_UI_SNAPSHOT = &apos;APPLY_UI_SNAPSHOT&apos;

// actions/ui.js
import {
  OPEN_NAV,
  CLOSE_NAV,
  TAKE_UI_SNAPSHOT,
  APPLY_UI_SNAPSHOT,
} from &apos;./actionTypes&apos;

export function openNav() {
  return { type: OPEN_NAV }
}

export function closeNav() {
  return { type: CLOSE_NAV }
}

export function takeUISnapshot() {
  return { type: TAKE_UI_SNAPSHOT }
}

export function applyUISnapshot() {
  return { type: APPLY_UI_SNAPSHOT }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Before we dispatch actions, we need reducers to handle them (and technically we need reducers to create a &lt;code&gt;store&lt;/code&gt; to even &lt;code&gt;dispatch&lt;/code&gt; our actions). So next we create a reducer to define how we handle each of our action types:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import {
  OPEN_NAV,
  CLOSE_NAV,
  TAKE_UI_SNAPSHOT,
  APPLY_UI_SNAPSHOT
} from &apos;./actionTypes&apos;

// Our initial state from before
const initialState = {
  headingIsLight: false,
  logoIsLight: false,
  footerIsLight: true,
  navIsOpen: false,
  uiSnapshot: null
}

const reducer = (state = initialState, action) {
  switch (action.type) {
    case OPEN_NAV:
      return Object.assign({}, state, {
        navIsOpen: true,
        headingIsLight: true,
        logoIsLight: true,
        footerIsLight: false
      })

    case CLOSE_NAV:
      return Object.assign({}, state, { navIsOpen: false })

    case TAKE_UI_SNAPSHOT:
      return Object.assign({}, state, { uiSnapshot: state })

    case APPLY_UI_SNAPSHOT:
      return Object.assign({}, state, state.uiSnapshot)

    default:
      return state
  }
}

export default reducer

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So this part needs some explanation. In a Redux reducer, we handle each &lt;code&gt;action.type&lt;/code&gt; with a different case. Each case is designed to return a new object with our desired state.&lt;/p&gt;
&lt;p&gt;If you&apos;re unfamiliar with &lt;code&gt;Object.assign&lt;/code&gt;, I would suggest reading up about it &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign&quot;&gt;here&lt;/a&gt;. The first argument is our target, in this case, an empty object. Any following argument is deeply merged into our target. So we start by handling (virtually every) case by using &lt;code&gt;Object.assign({}, state)&lt;/code&gt; and then pass another object containing just the state we want to change. In the &lt;code&gt;OPEN_NAV&lt;/code&gt; case, we can see that we want to change 4 properties of our state, and thus pass an object containing those changes as the final source to our &lt;code&gt;Object.assign()&lt;/code&gt; method.&lt;/p&gt;
&lt;p&gt;Understanding how &lt;code&gt;Object.assign()&lt;/code&gt; works is key to understanding how snapshots can be saved and applied. Let&apos;s say that in our store we dispatch an &lt;code&gt;OPEN_NAV&lt;/code&gt; action, preceded by a &lt;code&gt;TAKE_UI_SNAPSHOT&lt;/code&gt; action like so.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import store from &apos;./store&apos;
import { takeUISnapshot, openNav } from &apos;./actions/ui&apos;

store.dispatch(takeUISnapshot())
store.dispatch(openNav())
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When we take our snapshot, the &lt;code&gt;uiSnapshot&lt;/code&gt; property contains our entire previous state, including its own initial state of &lt;code&gt;null&lt;/code&gt;. An example snapshot would look like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  headingIsLight: false,
  logoIsLight: false,
  footerIsLight: true,
  navIsOpen: false,
  uiSnapshot: {
    headingIsLight: false,
    logoIsLight: false,
    footerIsLight: true,
    navIsOpen: false,
    uiSnapshot: null
  }
}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As you can see, our state tree has been duplicated. Now when we apply the snapshot, we merge the value stored under &lt;code&gt;uiSnapshot&lt;/code&gt; at the root level of our tree, which handily resets &lt;code&gt;uiSnapshot&lt;/code&gt; to &lt;code&gt;null&lt;/code&gt;. Thus, if a user closes the nav without choosing a link (and thus choosing a different state), we can close the nav and revert to the previous state just by applying the snapshot.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import store from &apos;./store&apos;
import { closeNav, applyUISnapshot } from &apos;./actions/ui&apos;

store.dispatch(applyUISnapshot())
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Because &lt;code&gt;navOpen: false&lt;/code&gt; is stored in the snapshot, the nav closes when we apply it to state (though, I would likely dispatch &lt;code&gt;closeNav()&lt;/code&gt; to be explicit. There&apos;s no harm when &lt;code&gt;Object.assign()&lt;/code&gt; encounters key/value pairs that are equal).&lt;/p&gt;
&lt;h3&gt;The Sky&apos;s the Limit&lt;/h3&gt;
&lt;p&gt;I think the uses for this technique are many and I wouldn&apos;t be surprised to find that it&apos;s already being used in lots of places. One potential use case I can think of is when an error in your application occurs, you could log out a snapshot of your &lt;em&gt;entire&lt;/em&gt; state tree and use that snapshot for debugging purposes. I could also see it being useful if you just wanted to toggle between states while developing components.&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Hope you find this technique useful. Please feel free to share any other use cases you can think of or any libraries already using this technique. I would love to read through the code and learn any new tricks I can from it.&lt;/p&gt;
</content:encoded><category>Redux</category></item><item><title>Why I Think Opening External Links In New Tabs Is a Bad Idea</title><link>https://kyleshevlin.com/why-i-think-opening-external-links-in-new-tabs-is-a-bad-idea/</link><guid isPermaLink="true">https://kyleshevlin.com/why-i-think-opening-external-links-in-new-tabs-is-a-bad-idea/</guid><description>A short rant on why forcing users to open links in new tabs is silly.</description><pubDate>Sun, 27 Mar 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In previous posts I&apos;ve mentioned my vehement dislike of purposefully opening links in a new tab. Here&apos;s a short list of reasons why it&apos;s a bad idea:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It&apos;s not the default behavior of links.&lt;/li&gt;
&lt;li&gt;It&apos;s extra work, generally because the developer will code it to open normally, someone will see it and say that&apos;s wrong and then the developer needs to reopen the project, add the code and send it back.&lt;/li&gt;
&lt;li&gt;It steals control away from the user. The user should be able to choose whether links open in this tab or a new one.&lt;/li&gt;
&lt;li&gt;Lastly and most honestly, it&apos;s demeaning to the user. Let me explain.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Forcing a user to open a link in a new tab is almost always done to ensure that the user does not leave the website. This isn&apos;t the action of a confident website that knows the value of its content. This is done out of fear. Fear that a user will never come back. Fear that the back button might stop working. Fear that the user doesn&apos;t know how to open links in a new tab on their own. That&apos;s a little ridiculous.&lt;/p&gt;
&lt;p&gt;In my opinion, if you want a user to stay on your site then you better provide them with content compelling enough to keep them there. Because stealing control away from the user displays a lack of faith in two ways. First, a lack of faith in the intelligence and ability of your user and customer. If you don&apos;t believe in your customer enough to trust them to know how to use your site, you should reconsider your relationship to the user. Second, exerting unnecessary control over the user is a lack of faith in your own brand and product. If your brand and product is compelling, users will stick around. Or comeback. People respond to confidence, online and offline. Shouldn&apos;t you have some confidence in yourself? Just some food for thought.&lt;/p&gt;
</content:encoded><category>Thoughts</category></item><item><title>JavaScript: External Links in New Tabs</title><link>https://kyleshevlin.com/javascript-external-links-in-new-tabs/</link><guid isPermaLink="true">https://kyleshevlin.com/javascript-external-links-in-new-tabs/</guid><description>Learn a quick JavaScript tip for opening external links in new tabs.</description><pubDate>Sat, 26 Mar 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I&apos;ve written before about my not so mild hatred for the request to open all external links in new tabs. For those who don&apos;t know, this is done by adding &lt;code&gt;target=&quot;_blank&quot;&lt;/code&gt; to the anchor tag. I don&apos;t like doing this for so many reasons, but I&apos;ll save that rant for another blog post.&lt;/p&gt;
&lt;p&gt;Now, I&apos;ve been asked to do this so often that automating this process was long overdue. I spent a few minutes and wrote some JavaScript that programmatically looks for external links and adds &lt;code&gt;target=&quot;_blank&quot;&lt;/code&gt; to them if necessary.&lt;/p&gt;
&lt;p&gt;Now, the defining characteristic of an externally pointing link is that it has to be an absolute path and thus start with &quot;http&quot;. We can use this to target only those links. Here&apos;s how:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function setTargetBlankOnExternalLinks() {
  const links = document.getElementsByTagName(&apos;a&apos;)

  for (var i = 0; i &amp;lt; links.length; i++) {
    if (/^http/.test(links[i].getAttribute(&apos;href&apos;))) {
      const link = links[i]
      link.setAttribute(&apos;target&apos;, &apos;_blank&apos;)
      link.setAttribute(&apos;rel&apos;, &apos;noopener noreferrer&apos;)
    }
  }
}

setTargetBlankOnExternalLinks() // call this after the DOM is ready
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is pretty straightforward. Find all the links, loop through them and check if they begin with &quot;http&quot; (The use of &lt;code&gt;test()&lt;/code&gt; instead of &lt;code&gt;match()&lt;/code&gt; here is important since &lt;code&gt;test()&lt;/code&gt; returns a boolean while &lt;code&gt;match()&lt;/code&gt; returns an array or &lt;em&gt;null&lt;/em&gt;). This means that relative links are given a pass, and links that happen to have &quot;http&quot; in them elsewhere, such as &quot;/link-to-blog-about-http&quot; don&apos;t get mistakenly modified.&lt;/p&gt;
&lt;p&gt;I hope this helps and saves you some time.&lt;/p&gt;
</content:encoded><category>JavaScript</category></item><item><title>Intro to D3.js and Data Visualization</title><link>https://kyleshevlin.com/intro-to-d3-js-and-data-visualization/</link><guid isPermaLink="true">https://kyleshevlin.com/intro-to-d3-js-and-data-visualization/</guid><description>Learn how to use `d3`, the popular data visualization library.</description><pubDate>Sun, 13 Mar 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Recently, I worked my way through the &lt;a href=&quot;https://frontendmasters.com/courses/interactive-data-visualization-d3-js/&quot;&gt;D3 Intro Course&lt;/a&gt; taught by &lt;a href=&quot;https://twitter.com/enjalot&quot;&gt;Ian Johnson&lt;/a&gt; over at &lt;a href=&quot;https://frontendmaster.com&quot;&gt;Front End Masters&lt;/a&gt; and have been practicing what I&apos;ve learned ever since. I&apos;m not great at it (yet), and I haven&apos;t made anything too amazing, but I am getting a better grasp of this awesome library (big thanks to creator &lt;a href=&quot;https://twitter.com/mbostock&quot;&gt;Mike Bostock&lt;/a&gt; and all his posts/tutorials about it).&lt;/p&gt;
&lt;p&gt;I am currently working on a project at &lt;a href=&quot;https://wearefine.com&quot;&gt;FINE&lt;/a&gt; that utilizes D3.js, so I wanted to code up an example for you. This way, you can see some of the techniques I might use in the project and perhaps inspire you to try out D3.js in a future project of yours.&lt;/p&gt;
&lt;p&gt;First things first, you can&apos;t build a data visualization without first having some data to work with. Lucky for me, there&apos;s data everywhere. I decided for this example, I would create a dataset based on the people I work with everyday.&lt;/p&gt;
&lt;p&gt;To do this, I created a JSON file, turning each one of my fellow devs into a an object in an array. Normally, you shouldn&apos;t objectify people, but I got their permission to so this time (Remember, there are ethics to responsible data visualization). Here&apos;s a small snippet of that JSON file:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;teammates&quot;: [
    {
      &quot;id&quot;: 1,
      &quot;name&quot;: &quot;Charlie&quot;,
      &quot;birthdate&quot;: &quot;1988-10-17&quot;,
      &quot;position&quot;: &quot;DevOps&quot;,
      &quot;startdate&quot;: &quot;2015-07-06&quot;
    },
    {
      &quot;id&quot;: 2,
      &quot;name&quot;: &quot;Eman&quot;,
      &quot;birthdate&quot;: &quot;1986-09-16&quot;,
      &quot;position&quot;: &quot;Front End&quot;,
      &quot;startdate&quot;: &quot;2015-05-12&quot;
    }
    // More teammates here...
  ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;You Can&apos;t Do Data Visualization Without Some Data&lt;/h3&gt;
&lt;p&gt;Now I have some data to work with. I thought it would be interesting to create a bar chart that graphs each dev&apos;s age and how long they&apos;ve been at FINE. This would be represented on the X axis and with a radio button would toggle between the two. Later, I will add some sorting methods to the Y axis. Let&apos;s start coding this up.&lt;/p&gt;
&lt;p&gt;While we could code this visualization as a one-off piece of code, I think it&apos;s a good idea to follow the &quot;Reusable Charts&quot; pattern laid out in &lt;a href=&quot;https://bost.ocks.org/mike/chart/&quot;&gt;this awesome blog post&lt;/a&gt;. In short, a reusable chart turns our visualization into a function that can be called on multiple datasets. This way, when our dataset is updated, we simply re-render the chart with the new data. To do this, we need some basic setup to our code.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if (!d3.chart) {
  d3.chart = {}
}

d3.chart.fine_visual = function () {
  var data, svg

  function chart(container) {
    // Setup static elements of our visualization
    svg = container

    // Call update function to apply our data to our visualization
    update()
  }

  chart.update = update
  function update() {
    // Code the dynamic elements of our visualization
  }

  chart.data = function (value) {
    if (!arguments.length) return data
    data = value
    return chart
  }

  return chart
}

d3.json(&apos;teammates.json&apos;, function (err, teammates) {
  if (err) {
    return d3
      .select(&apos;.js-display&apos;)
      .append(&apos;p&apos;)
      .text(&apos;There was an error retrieving the data&apos;)
  }

  var data = teammates.teammates
  var display = d3.select(&apos;.js-display&apos;)

  var visual = d3.chart.fine_visual().data(data)
  visual(display)
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The code starts by ensuring that the d3.chart object exists so that our custom function can be set as a property on the d3.chart object. This is followed by &lt;code&gt;var&lt;/code&gt; declarations that will be scoped to our function. Next is the chart function which will be returned when this visual function is called. This is followed by setting a property on our chart function of our update function (so that we can call updates on our chart). Lastly, any chart property that can be customized by our end user needs this &lt;code&gt;chart.property&lt;/code&gt; pattern to create getters and setters for the property.&lt;/p&gt;
&lt;p&gt;Once the custom chart function is created, an AJAX call to the data is made. Upon returning the data, the custom function is called with the data supplied to it with the &lt;code&gt;.data()&lt;/code&gt; setter.&lt;/p&gt;
&lt;h3&gt;The Chart() Function&lt;/h3&gt;
&lt;p&gt;The chart function within our custom function is where pieces of our visualization that will remain static should be instantiated. If this code is instead put in the &lt;code&gt;update()&lt;/code&gt;function, it will be re-rendered to the page (meaning multiple axes would pile on top of each other). Thus, it follows that pieces of the visualization that will be updated are moved into the &lt;code&gt;update()&lt;/code&gt; function.&lt;/p&gt;
&lt;p&gt;An example of static content is an axis. A bar chart will have an X and Y axis, representing some scale of our data. In the case of my example, the X axis will represent time measured in months, and the Y axis will be used to identify different developers.&lt;/p&gt;
&lt;p&gt;In order to add an axis to our visual, a decision must be made regarding what scale to use. D3 provides a number of different scale types, saving you from the hassle of coding your own (though you can if you want to). In this case, the &lt;code&gt;linear&lt;/code&gt; scale will suit our purposes, but we could have also considered using the &lt;code&gt;time&lt;/code&gt; scale as well. Be sure to read about &lt;a href=&quot;https://github.com/mbostock/d3/wiki/Scales&quot;&gt;d3 scales&lt;/a&gt; when you have a chance.&lt;/p&gt;
&lt;p&gt;To implement the scale and append an axis based on it, the following code is used:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var xScale = d3.scale
  .linear()
  .domain([
    0,
    d3.max(data, function (d) {
      return age(d.birthdate)
    }),
  ])
  .range([0, width])

var xAxis = d3.svg.axis().scale(xScale).orient(&apos;bottom&apos;)

var xAxisGroup = svg.append(&apos;g&apos;)

xAxis(xAxisGroup)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I have left out some code on purpose here, namely the helper function &lt;code&gt;age()&lt;/code&gt;, in order to focus on the more important pieces. A linear scale is declared, the domain is set from age 0 to the maximum age of our dev team, and the range is from 0 to the full width of our visualization. Then, an axis is declared and called on the &lt;code&gt;svg&lt;/code&gt; var in an appended &lt;code&gt;g&lt;/code&gt; element. The example follows a similar pattern for the Y axis, but uses the ordinal scale instead. I may cover the sorting functionality of the Y axis in depth in another post.&lt;/p&gt;
&lt;h3&gt;The D3 Pattern: Selecting, Entering, Appending, Exiting, Removing&lt;/h3&gt;
&lt;p&gt;Now that the axes are in place, the bars can be added to our chart. D3 has a pretty specific pattern to follow when rendering data driven elements to our visual. It seems downright counterintuitive at first, but begins to make sense the more you understand how d3 is acting upon our objects. This pattern looks similar to this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var bars = svg.selectAll(&apos;.bar&apos;)
  .data(data);
  .enter()
  .append(&apos;rect&apos;).classed(&apos;bar&apos;, true)
  .attr({
    x: 0,
    y: function(d,i) { return i * 35; },
    width: function(d) { return xScale( age(d.birthdate) ); },
    height: 30,
  })
  .exit()
  .remove();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;While this isn&apos;t the exact code used in the example, it&apos;s a good example of showing this d3 pattern at work. Because d3 can update elements already on the page, it&apos;s important that we select those elements. If not, we would end up creating a function that added a whole new set of elements each time the data was updated. This is why all elements are selected, then the data is entered, existing elements are updated, new ones are added and unused ones are destroyed.&lt;/p&gt;
&lt;h3&gt;Customizable Settings&lt;/h3&gt;
&lt;p&gt;The last convention I want to cover is how to add configurable settings on our reusable chart via adding a property to the &lt;code&gt;chart()&lt;/code&gt; function. You may have noticed above, that we had a small bit of code looked like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;chart.data = function (value) {
  if (!arguments.length) return data
  data = value
  return chart
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This bit of code allows our user to get and set the data property for our chart. This is what enables us to reuse this chart in another instance or update our current chart by setting a new dataset. Typically, this is used on &lt;code&gt;width&lt;/code&gt; and &lt;code&gt;height&lt;/code&gt; properties to allow the user to customize the size of their visualization, but there can be many other uses.&lt;/p&gt;
&lt;p&gt;Taking these concepts (and adding a few more I leave you to discover), a quick and interesting data visualization can be created. Play around with it a while and explore the code. Fork it on Codepen or make your own, and best of luck as you explore d3.js in the future.&lt;/p&gt;
&lt;p&gt;&amp;lt;p
class=&quot;codepen&quot;
data-height=&quot;770&quot;
data-theme-id=&quot;0&quot;
data-slug-hash=&quot;YqPNeo&quot;
data-default-tab=&quot;result&quot;
data-user=&quot;kyleshevlin&quot;&lt;/p&gt;
&lt;blockquote&gt;&lt;/blockquote&gt;
&lt;p&gt;See the Pen{&apos; &apos;}
&amp;lt;a href=&quot;http://codepen.io/kyleshevlin/pen/YqPNeo/&quot;&amp;gt;
d3 Intro - Example for Mingle post
&amp;lt;/a&amp;gt;{&apos; &apos;}
by Kyle Shevlin (&amp;lt;a href=&quot;http://codepen.io/kyleshevlin&quot;&amp;gt;@kyleshevlin&amp;lt;/a&amp;gt;) on{&apos; &apos;}
&amp;lt;a href=&quot;http://codepen.io&quot;&amp;gt;CodePen&amp;lt;/a&amp;gt;.
&amp;lt;/p&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;script src=&quot;//assets.codepen.io/assets/embed/ei.js&quot; async&amp;gt;&amp;lt;/script&amp;gt;&lt;/p&gt;
</content:encoded><category>D3</category><category>Data Visualization</category></item><item><title>Using &amp;&amp; and || in Bash Scripts</title><link>https://kyleshevlin.com/using-and-and-or-in-bash-scripts/</link><guid isPermaLink="true">https://kyleshevlin.com/using-and-and-or-in-bash-scripts/</guid><description>Learn how to use logical AND and OR in bash.</description><pubDate>Wed, 09 Mar 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I write about Bash so often you might start to think it&apos;s all I do. It&apos;s not, but considering I spend a good portion of my day in the terminal, I&apos;m always on the look out for ways to make it a more efficient experience.&lt;/p&gt;
&lt;p&gt;Recently, I came upon a simple trick for bash scripts that just has to be shared. It involves the operators &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; (AND) and &lt;code&gt;||&lt;/code&gt; (OR). In most cases, &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; and &lt;code&gt;||&lt;/code&gt; are used for evaluation purposes, resulting in a boolean value (true or false).&lt;/p&gt;
&lt;p&gt;In most languages, this would look something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Using Ruby for this example
foo = true
bar = false

if foo &amp;amp;&amp;amp; bar; end # returns false; &amp;amp;&amp;amp; requires both expressions to evaluate to true
if foo || bar; end # returns true; || requires only one expression to evaluate to true

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;The &amp;amp;&amp;amp; Operator&lt;/h3&gt;
&lt;p&gt;Since we know that an &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; requires both expressions to be true, we can use this knowledge to chain bash commands that we only want to run in succession if the first command was successful. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd foo &amp;amp;&amp;amp; touch bar.html

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If the terminal is able to successfully &lt;code&gt;cd&lt;/code&gt; into the directory &lt;code&gt;foo&lt;/code&gt;, then it will attempt to create the file &lt;code&gt;bar.html&lt;/code&gt;. If it fails, no attempt at file creation will be made.&lt;/p&gt;
&lt;h3&gt;The || Operator&lt;/h3&gt;
&lt;p&gt;In other circumstances, we might want to try one command and then another if the first fails. In this case, the &lt;code&gt;||&lt;/code&gt; operator is our friend. I have specifically used this in a bash alias I&apos;ve made for deploying a site. Depending upon what version of Capistrano is being used in a project, the terminal command syntax is different. Thus, we simply try one, and if it fails we try another.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Literally my alias for deploying to production
alias capp=&quot;cap deploy -S loc=prod || cap prod deploy&quot;

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Putting Them Together&lt;/h3&gt;
&lt;p&gt;So, you can see that you can quickly use these to construct larger scripts that can do a rudimentary form of error handling without a lot of effort. Often, I need to deploy the same feature branch of code to multiple environments. I made a bash function using the &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; and &lt;code&gt;||&lt;/code&gt; operators like I&apos;ve laid out here to do just that with one short command.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Deploy a branch to all branches
function mgdep () {
  # if no argument is passed to the function, get the current branch (the feature branch)
  if [ $# -eq 0 ]; then
      # get_git_branch is a bash function I&apos;ve made that grabs the current branch
      branch=$(get_git_branch)
  else
    branch=$1
  fi

  git checkout master &amp;amp;&amp;amp; git pull --rebase origin master &amp;amp;&amp;amp; echo -e &quot;\033[0;32mMaster checked out and pulled\033[0m&quot;
  git merge $branch &amp;amp;&amp;amp; echo -e &quot;\033[0;32m${branch} merged into master\033[0m&quot;
  git push origin master &amp;amp;&amp;amp; echo -e &quot;\033[0;32m${branch} pushed to master\033[0m&quot;
  # You&apos;ve seen my Capistrano alias above, ones for stage and dev are used further down
  capp &amp;amp;&amp;amp; echo -e &quot;\033[0;32m${branch} deployed to prod via master branch\033[0m&quot;
  git checkout stage &amp;amp;&amp;amp; git pull --rebase origin stage &amp;amp;&amp;amp; echo -e &quot;\033[0;32mStage checked out and pulled\033[0m&quot;
  git merge $branch &amp;amp;&amp;amp; echo -e &quot;\033[0;32m${branch} merged into stage\033[0m&quot;
  git push origin stage &amp;amp;&amp;amp; echo -e &quot;\033[0;32m${branch} pushed to stage\033[0m&quot;
  caps &amp;amp;&amp;amp; echo -e &quot;\033[0;32m${branch} deployed to stage via stage branch\033[0m&quot;
  git checkout dev &amp;amp;&amp;amp; git pull --rebase origin dev &amp;amp;&amp;amp; echo -e &quot;\033[0;32mDev checked out and pulled\033[0m&quot;
  git merge $branch &amp;amp;&amp;amp; echo -e &quot;\033[0;32m${branch} merged into dev\033[0m&quot;
  git push origin dev &amp;amp;&amp;amp; echo -e &quot;\033[0;32m${branch} pushed to dev\033[0m&quot;
  capd &amp;amp;&amp;amp; echo -e &quot;\033[0;32m${branch} deployed to dev via dev branch\033[0m&quot;
  # Terminal-notifier lets me know all the deploys have completed
  git checkout master &amp;amp;&amp;amp; terminal-notifier -message &apos;Deploys completed. Master checked out.&apos; -sound &apos;default&apos;
}

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Hope this inspires you a bit and encourages you to create your own bash scripts for programmatically adding some efficiency into your development process.&lt;/p&gt;
</content:encoded><category>Bash</category></item><item><title>My Favorite Git Aliases</title><link>https://kyleshevlin.com/my-favorite-git-aliases/</link><guid isPermaLink="true">https://kyleshevlin.com/my-favorite-git-aliases/</guid><description>Learn some of my favorite git aliases.</description><pubDate>Thu, 10 Sep 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;If you&apos;re like me, you like to find patterns in your work and turn them into aliases and shortcuts in the terminal. I thought I&apos;d share with you my current Git aliases, explaining a few along the way.&lt;/p&gt;
&lt;p&gt;For starters, you&apos;ll want to add these aliases to your &lt;code&gt;.gitconfig&lt;/code&gt; file.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[alias]
  br = branch
  brm = branch --merged
  brnm = branch --no-merged
  ci = commit
  co = checkout
  copl = &quot;!f() { git checkout $1 &amp;amp;&amp;amp; git pull --rebase origin $1; }; f&quot;
  df = diff
  lg = log --graph --pretty=format:&apos;%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)&amp;lt;%an&amp;gt;%Creset&apos; --abbrev-commit --date=relative
  mg = merge
  st = status
  plo = pull --rebase origin
  pho = push origin
  plod = pull --rebase origin dev
  phod = push origin dev
  plos = pull --rebase origin stage
  phos = push origin stage
  plom = pull --rebase origin master
  phom = push origin master
  reaper-nokill = remote prune --dry-run origin
  reaper = remote prune origin
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Most of these aliases are self explanatory, but let&apos;s go through some of the less common ones.&lt;/p&gt;
&lt;h4&gt;brm&lt;/h4&gt;
&lt;p&gt;Using the &lt;code&gt;branch --merged&lt;/code&gt; command will give you a list of branches merged into the branch you&apos;re currently on. It&apos;s counterpart &lt;code&gt;branch --no-merged&lt;/code&gt; does exactly the opposite. These commands are great for cleaning up merged branches.&lt;/p&gt;
&lt;h4&gt;copl&lt;/h4&gt;
&lt;p&gt;This is a function that takes a branch name for an argument. It first checks out that branch, and then runs a &lt;code&gt;git pull --rebase&lt;/code&gt; on that branch. I found myself constantly checking out a branch and pulling it immediately, so I turned it into one alias.&lt;/p&gt;
&lt;h4&gt;lg&lt;/h4&gt;
&lt;p&gt;This is a prettier log format. It will actually create the branch structure in the terminal.&lt;/p&gt;
&lt;h4&gt;reaper&lt;/h4&gt;
&lt;p&gt;Sometimes you need your local git to forget about remote branches that no longer exist. This is where pruning comes into play. When I first wrote this alias, it was &lt;code&gt;repr&lt;/code&gt; for &quot;remote prune&quot;. Phonetically, that sounded like &quot;reaper&quot; and given that I&apos;m slashing branches from git, it seemed appropriate to rename the alias after our friendly harbinger of death.&lt;/p&gt;
&lt;p&gt;So there you have it. Hope this Git aliases help you out. Leave some of your favorites in the comments below.&lt;/p&gt;
</content:encoded><category>Bash</category></item><item><title>Bash Shortcut: Copy your Present Working Directory to your Clipboard</title><link>https://kyleshevlin.com/bash-shortcut-copy-your-present-working-directory-to-your-clipboard/</link><guid isPermaLink="true">https://kyleshevlin.com/bash-shortcut-copy-your-present-working-directory-to-your-clipboard/</guid><description>Create a bash alias that copies your `pwd` to your clipboard.</description><pubDate>Sat, 25 Jul 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Like most developers, I&apos;m always looking for ways to increase my efficiency. One way I like to do this is through &lt;a href=&quot;https://en.wikipedia.org/wiki/Bash_(Unix_shell)&quot;&gt;Bash&lt;/a&gt; functions.&lt;/p&gt;
&lt;p&gt;Just like other programming languages, Bash functions allow you to combine Bash commands or manipulate user input to output a desired effect. While I have a good number of Bash functions, today we&apos;re going to focus on a simple one: how to copy your present working directory to your clipboard.&lt;/p&gt;
&lt;p&gt;While in your terminal, the present working directory (or pwd) is the directory you are currently in. Using the command &lt;code&gt;pwd&lt;/code&gt; will supply you with an output of your current directory.&lt;/p&gt;
&lt;p&gt;The other Bash command we&apos;re going to use is the &lt;code&gt;pbcopy&lt;/code&gt; command. This command is short for &quot;pasteboard copy&quot; and will take the standard input and paste it on the clipboard. A nice feature of the &lt;code&gt;pbcopy&lt;/code&gt; command is the ability to &quot;pipe&quot; (|) the standard output of one command into the &lt;code&gt;pbcopy&lt;/code&gt; command. We&apos;re going to use that to make our Bash function. Put this in your &lt;code&gt;.bash_profile&lt;/code&gt; or &lt;code&gt;.bashrc&lt;/code&gt; file.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Copy the PWD to the Clipboard
alias cpwd=&quot;pwd | tr -d &apos;\n&apos; | pbcopy &amp;amp;&amp;amp; echo &apos;pwd copied to clipboard&apos;&quot;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we can use the command &lt;code&gt;cpwd&lt;/code&gt; to copy our present working directory to the clipboard. I use this frequently for getting the right file paths for symlinks, but there are other uses as well.&lt;/p&gt;
&lt;p&gt;Hope this helps!&lt;/p&gt;
</content:encoded><category>Bash</category></item><item><title>Bash Shortcut: How to Make Directory and Change Directory in One Command</title><link>https://kyleshevlin.com/bash-shortcut-how-to-make-directory-and-change-directory-in-one-command/</link><guid isPermaLink="true">https://kyleshevlin.com/bash-shortcut-how-to-make-directory-and-change-directory-in-one-command/</guid><description>Make a bash alias to make a new directory and change to it in one command.</description><pubDate>Sat, 25 Jul 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;If you&apos;re like me, you&apos;re constantly using the command line to make a directory and then immediately change to that directory. Here&apos;s a Bash function that will allows you to do that:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Make a directory &amp;amp;&amp;amp; cd into that directory
function mkdircd () { mkdir -p &quot;$@&quot; &amp;amp;&amp;amp; eval cd &quot;\&quot;\$$#\&quot;&quot;; }

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This function takes the user supplied directory name, makes all the directories needed to get there, and then &lt;code&gt;cd&lt;/code&gt;s to that directory.&lt;/p&gt;
&lt;p&gt;Hope you find it useful!&lt;/p&gt;
</content:encoded><category>Bash</category></item><item><title>Small Gripe: Target=&amp;ldquo;_blank&amp;rdquo;</title><link>https://kyleshevlin.com/small-gripe-target_blank/</link><guid isPermaLink="true">https://kyleshevlin.com/small-gripe-target_blank/</guid><description>A tiny rant about `target=&quot;_blank&quot;`.</description><pubDate>Mon, 26 Jan 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I&apos;m often asked to make small, almost trivial changes to our clients&apos; websites. One of these changes that grinds my gears is the frequent request to &quot;Make this hyperlink open in a new tab/window.&quot;&lt;/p&gt;
&lt;p&gt;This bothers me because it changes the default behavior of links and takes away the user&apos;s control over his or her browser. Default behavior of a link is to open in the current window. Now, every browser/system I know of provides the user with an action that can open a link in a new tab (for example, cmd + click on Mac will do this). Adding a &lt;code&gt;target=&quot;_blank&quot;&lt;/code&gt; to a link robs the user of this ability.&lt;/p&gt;
&lt;p&gt;Clients&apos; reason that opening a link in a new tab will prevent a customer from leaving a site prematurely and not converting a sale. Shouldn&apos;t we have faith that our customers will stick around and buy products if &lt;em&gt;they want to&lt;/em&gt;? One might even reason that removing the default behavior might be discomforting enough to turn away users.&lt;/p&gt;
&lt;p&gt;My thoughts, don&apos;t selfishly change default behavior if you don&apos;t have to.&lt;/p&gt;
&lt;p&gt;Here&apos;s a much better written article on the subject: &lt;a href=&quot;http://css-tricks.com/use-target_blank/&quot;&gt;http://css-tricks.com/use-target_blank/&lt;/a&gt;&lt;/p&gt;
</content:encoded><category>Thoughts</category></item></channel></rss>