<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://bridgetownrb.com/" version="2.2.0">Bridgetown</generator><link href="http://blog.boon.gl/feed.xml" rel="self" type="application/atom+xml" /><link href="http://blog.boon.gl/" rel="alternate" type="text/html" /><updated>2026-06-05T15:15:58-07:00</updated><id>http://blog.boon.gl/feed.xml</id><title type="html">Boon Blog</title><subtitle>Boon Blog — writing on technology, React, Elm, and the occasional aside about life in San Francisco.</subtitle><author><name>Robert Fletcher</name></author><entry><title type="html">Test Flake: Chrome Clicks</title><link href="http://blog.boon.gl/2026/06/05/test-flake-chrome-clicks/" rel="alternate" type="text/html" title="Test Flake: Chrome Clicks" /><published>2026-06-05T00:00:00-07:00</published><updated>2026-06-05T00:00:00-07:00</updated><id>repo://posts.collection/_posts/2026-06-05-test-flake-chrome-clicks.md</id><content type="html" xml:base="http://blog.boon.gl/2026/06/05/test-flake-chrome-clicks/">&lt;p&gt;This is the first in what I expect to be an ongoing series of posts on common
sources of test flake. Today: Chrome! Specifically, sometimes clicking a link
in end-to-end tests, even on a static page, doesn’t navigate to the next page.
In the screenshot grabbed from the failing test it might even show the link as
outlined as if it &lt;em&gt;had&lt;/em&gt; been clicked. There was a period where roughly half of
our builds were failing due to this issue, which, as you might imagine, can
make you start questioning the value of end-to-end tests.&lt;/p&gt;

&lt;!--more--&gt;

&lt;h2 id=&quot;the-diagnosis&quot;&gt;The Diagnosis&lt;/h2&gt;

&lt;p&gt;My understanding is that Chromedriver figures out where the element is, then
clicks at those coordinates. If the layout shifts in that window, the click can
land in the wrong spot. My best guess at what we saw: the &lt;code class=&quot;highlighter-rouge&quot;&gt;mousedown&lt;/code&gt; landed on
the link, focusing it, but by the &lt;code class=&quot;highlighter-rouge&quot;&gt;mouseup&lt;/code&gt; the link had moved, so the two
never registered as a real click. Chromedriver has a &lt;a href=&quot;https://developer.chrome.com/docs/chromedriver/help/clicking-issues#chromedriver_cant_click_a_moving_element&quot;&gt;page on click
issues&lt;/a&gt;, but it doesn’t seem to be a priority for them to fix.&lt;/p&gt;

&lt;h2 id=&quot;the-fix&quot;&gt;The Fix&lt;/h2&gt;

&lt;p&gt;Switch to Firefox with Geckodriver. Maybe a bit cheeky, but that was our
solution, and the amount of flake in our end-to-end tests plummeted. You might
also consider checking out &lt;a href=&quot;https://github.com/rubycdp/cuprite&quot;&gt;Cuprite&lt;/a&gt; if you’re in Ruby land, as it doesn’t
use Chromedriver. There are a number of hackier alternatives, such as retrying
the click or doing a JavaScript &lt;code class=&quot;highlighter-rouge&quot;&gt;click()&lt;/code&gt; directly on the element, but I’d be
concerned about those masking other issues.&lt;/p&gt;</content><author><name>Robert Fletcher</name></author><category term="technical" /><category term="flake" /></entry><entry><title type="html">React Lifecycle Edge Cases</title><link href="http://blog.boon.gl/2017/12/13/react-lifecycle-edge-cases/" rel="alternate" type="text/html" title="React Lifecycle Edge Cases" /><published>2017-12-13T00:00:00-08:00</published><updated>2017-12-13T00:00:00-08:00</updated><id>repo://posts.collection/_posts/2017-12-13-react-lifecycle-edge-cases.md</id><content type="html" xml:base="http://blog.boon.gl/2017/12/13/react-lifecycle-edge-cases/">&lt;p&gt;I have a “scratch” wrapper I wrote for React as an alternative to &lt;code class=&quot;highlighter-rouge&quot;&gt;setState&lt;/code&gt;
for controlled components. The idea being that it’s nice to keep all data in
Redux, but it’s kind of a pain in the butt to do so manually for every single
form, since generally you will also want that data to be cleared from the store
when the form is unmounted. My &lt;code class=&quot;highlighter-rouge&quot;&gt;ConnectWithScratch&lt;/code&gt; higher order component adds
lifecycle hooks on component mount and unmount to create and delete scratch
space for the component. As I’ve been using it, though, I’ve been discovering
some interesting edge cases.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;So my current &lt;code class=&quot;highlighter-rouge&quot;&gt;ConnectWithScratch&lt;/code&gt; component calls &lt;code class=&quot;highlighter-rouge&quot;&gt;createScratch&lt;/code&gt; in
&lt;code class=&quot;highlighter-rouge&quot;&gt;constructor&lt;/code&gt; with a user provided &lt;code class=&quot;highlighter-rouge&quot;&gt;scratchKey&lt;/code&gt;. (I’m not going to share the
current implementation with you because it’s a hairball and I’m still finding
edge cases.) It passes an &lt;code class=&quot;highlighter-rouge&quot;&gt;updateScratch&lt;/code&gt; prop down to the component to use.
And it calls &lt;code class=&quot;highlighter-rouge&quot;&gt;deleteScratch&lt;/code&gt; when the component unmounts. In one case I’m using
my scratch component for an edit task form, where the scratch key might be
something like &lt;code class=&quot;highlighter-rouge&quot;&gt;editTask-114&lt;/code&gt;, where &lt;code class=&quot;highlighter-rouge&quot;&gt;114&lt;/code&gt; is the task id. When I introduced
this edit task form on another page, I ran into an interesting issue. The one
on the new page has the same key, but when navigating from one page to the
other, it tries to create the scratch for the new page before the old one has
been removed. Console logging out revealed the following:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ShowView constructor // the new view is being rendered
ConnectWithScratch constructor:  editTask-114 // new view setting up scratch
creating scratch:  editTask-114 // so far so good...
FocusView componentWillUnmount // and the old view is about to unmount
ConnectWithScratch componentWillUnmount:  editTask-114 // old component scratch unmounting
deleting scratch:  editTask-114 // old component deletes the scratch space!!!
ConnectWithScratch componentDidMount:  editTask-114 // show view scratch mounted
ShowView componentDidMount // and the show view mounts, but has no scratch to work with
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;So, in short, React starts constructing the next component before the previous
one is told it will be unmounted. Which maybe makes sense in terms of how React
needs to work to reconcile and see if it can re-use anything. But it creates a
pain point here. A few options that come to mind for me:&lt;/p&gt;

&lt;p&gt;1) I might be able to move the &lt;code class=&quot;highlighter-rouge&quot;&gt;createScratch&lt;/code&gt; call to &lt;code class=&quot;highlighter-rouge&quot;&gt;componentDidMount&lt;/code&gt;.
  This will cause extra renders and maybe performance issues, &lt;a href=&quot;https://reactjs.org/docs/react-component.html#componentdidmount&quot;&gt;per their
  docs&lt;/a&gt;, but the user won’t see any intermediary state. It
  also means we can’t touch the scratch space in the constructor.&lt;/p&gt;

&lt;p&gt;2) I could assign each scratch component a unique id instead and use that as
  the scratch key, or part of it. This loses some of the benefit of the scratch
  space, though, in that we no longer have a readable key for debugging, nor
  can we rehydrate components in a straightforward way.&lt;/p&gt;

&lt;p&gt;3) I could require the parent component to pass down a part of the scratch key
  that would make it unique, such as &lt;code class=&quot;highlighter-rouge&quot;&gt;ShowView-editTask-114&lt;/code&gt;,
  &lt;code class=&quot;highlighter-rouge&quot;&gt;FocusView-editTask-114&lt;/code&gt;. This maintains readability and rehydratability
  (sic), but adds additional complexity to actually using the scratch
  container. Now both the parent and the child need to know about the scratch
  component.&lt;/p&gt;

&lt;p&gt;I don’t love any of these options, though I’m leaning towards option 1 for my
first attempt at a fix. Option 2 is my last resort.&lt;/p&gt;</content><author><name>Robert Fletcher</name></author><category term="technical" /><category term="react" /><category term="redux" /></entry><entry><title type="html">React Elm Wrapper</title><link href="http://blog.boon.gl/2017/11/28/react-elm-wrapper/" rel="alternate" type="text/html" title="React Elm Wrapper" /><published>2017-11-28T00:00:00-08:00</published><updated>2017-11-28T00:00:00-08:00</updated><id>repo://posts.collection/_posts/2017-11-28-react-elm-wrapper.md</id><content type="html" xml:base="http://blog.boon.gl/2017/11/28/react-elm-wrapper/">&lt;p&gt;I’ve recently been spending a lot of time scratching my head regarding
application architecture with React and Redux. It often feels like this tug of
war between class based and functional programming. I’m not super attached to
one paradigm or another, but I am certainly FP-curious. However, whenever I
push to work exclusively in a functional way in JavaScript, I keep running into
situations where the code would be cleaner or more performant if I were doing
it in a mutative or class based way. It feels like I’m trying to awkwardly
shoehorn functional methods into a language that really wasn’t built for it.&lt;/p&gt;

&lt;!--more--&gt;

&lt;h2 id=&quot;enter-elm&quot;&gt;Enter Elm&lt;/h2&gt;

&lt;p&gt;I’ve been hearing more and more about this language &lt;a href=&quot;http://elm-lang.org/&quot;&gt;Elm&lt;/a&gt; and how happy
people are on that side of the fence, so I decided it’s finally time to give it
a shot. It’ll be a good opportunity to really immerse myself in functional
programming, and even if I come away feeling it’s not for me, I should
hopefully come back with some new wisdom and appreciation for the React
ecosystem.&lt;/p&gt;

&lt;h2 id=&quot;in-react&quot;&gt;In React?&lt;/h2&gt;

&lt;p&gt;The first step along that route is figuring out whether and how Elm might
actually integrate with React for an easier transition. It turns out it does,
and the core maintainers of Elm &lt;a href=&quot;https://github.com/evancz/react-elm-components&quot;&gt;built out a simple
harness&lt;/a&gt; to make it easier.  However, sadly, it hasn’t
been updated in a while, so it doesn’t work with React version 16. There’s not
that much code to it, so I’d be hesitant to add it as a dependency, anyway. So
I brought the code up to date and plugged it into my application. Worked like a
charm. Here’s the code:&lt;/p&gt;

&lt;div class=&quot;language-jsx highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;autobind&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;class-autobind&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;PropTypes&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;prop-types&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;React&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;react&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ReactElmWrapper&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;React&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Component&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nf&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;props&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;props&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;autobind&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;nf&quot;&gt;componentDidMount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;app&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;props&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;embed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;props&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;flags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;props&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;props&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;nf&quot;&gt;shouldComponentUpdate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;nf&quot;&gt;storeNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;nf&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;storeNode&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;/&amp;gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;ReactElmWrapper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;propTypes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;flags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;PropTypes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;PropTypes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;PropTypes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;isRequired&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ReactElmWrapper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;and you can use it like:&lt;/p&gt;

&lt;div class=&quot;language-jsx highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;MyReactComponent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ReactElmWrapper&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;SomeImportedElmApp&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;/&amp;gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;See the “ground up” article below for a more in-depth example.&lt;/p&gt;

&lt;h2 id=&quot;links&quot;&gt;Links&lt;/h2&gt;

&lt;p&gt;I’ve found these to be really helpful, or hope to find them helpful in the near
future:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://codeburst.io/using-elm-in-react-from-the-ground-up-e3866bb0369d&quot;&gt;Using Elm in React — from the ground up&lt;/a&gt;: This is a good place to
start for setting up Elm with your application with configuration and a
simple example project. Side note: if you’re running Rails, you can just run
&lt;code class=&quot;highlighter-rouge&quot;&gt;rails webpacker:install:elm&lt;/code&gt; to get things configured.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/rtfeldman/elm-spa-example&quot;&gt;Elm SPA Example&lt;/a&gt;: A fully fleshed out Elm app with lots of
great reference from nuts and bolts all the way up to application
architecture.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://medium.com/javascript-inside/building-a-react-redux-elm-bridge-8f5b875a9b76&quot;&gt;Building A React/Redux/Elm Bridge&lt;/a&gt;:
Haven’t dug into this one, yet, but looks like it’ll provide some solid
insights around passing data back and forth.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/rtfeldman/node-elm-compiler&quot;&gt;Node Elm Compiler&lt;/a&gt;: Haven’t done anything with this, yet,
but my JS tests are written in Jest, and I’d like them to continue working as
I transition, so I think the code here may be useful along with &lt;a href=&quot;https://facebook.github.io/jest/docs/en/configuration.html#transform-object-string-string&quot;&gt;Jest’s
&lt;code class=&quot;highlighter-rouge&quot;&gt;transform&lt;/code&gt; setting&lt;/a&gt;. If all goes well you’ll be seeing another
blog post soon about how I managed with that.&lt;/li&gt;
&lt;/ul&gt;</content><author><name>Robert Fletcher</name></author><category term="technical" /><category term="react" /><category term="elm" /></entry><entry><title type="html">Routes as State in React</title><link href="http://blog.boon.gl/2017/06/29/routes-as-state-in-react/" rel="alternate" type="text/html" title="Routes as State in React" /><published>2017-06-29T00:00:00-07:00</published><updated>2017-06-29T00:00:00-07:00</updated><id>repo://posts.collection/_posts/2017-06-29-routes-as-state-in-react.md</id><content type="html" xml:base="http://blog.boon.gl/2017/06/29/routes-as-state-in-react/">&lt;p&gt;I’ve been using &lt;a href=&quot;https://github.com/ReactTraining/react-router&quot;&gt;React Router&lt;/a&gt; for a while now in a project and
was running up against some frustration getting access to information that
comes through the URL. I’m using &lt;a href=&quot;http://redux.js.org/&quot;&gt;Redux&lt;/a&gt; and &lt;a href=&quot;https://github.com/reactjs/react-redux&quot;&gt;React Redux&lt;/a&gt;
for state management and &lt;a href=&quot;https://github.com/reactjs/reselect&quot;&gt;Reselect&lt;/a&gt; for getting useful bits of
information out of the state. The problem is that when I need to grab some
information from the state based on the current route, it can be really tricky
to get all of the information I need in the right places. After a good deal of
head scratching and soul searching, I realized that for my purposes, the
routing information belongs in the state, not encoded implicitly in the
components that are rendered.&lt;/p&gt;

&lt;!--more--&gt;

&lt;h2 id=&quot;the-lay-of-the-land&quot;&gt;The Lay of the Land&lt;/h2&gt;

&lt;p&gt;So I’m working on yet another todo list application. By default it shows you
the next ordered task from your list, one at a time. When you select a tag, it
should update the URL based on a url friendly “slug” for that tag (e.g.:
&lt;code class=&quot;highlighter-rouge&quot;&gt;/at-home&lt;/code&gt;), as well as showing the next task for that specific tag.  Starting
out, for this workflow, I was using React Router’s &lt;code class=&quot;highlighter-rouge&quot;&gt;Link&lt;/code&gt; component and had a
simple &lt;code class=&quot;highlighter-rouge&quot;&gt;onClick&lt;/code&gt; handler that set the selected tag in the redux store:&lt;/p&gt;

&lt;div class=&quot;language-jsx highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;TagLink&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;props&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;updateTagMeta&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;slug&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;props&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;return &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Link&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;`/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;slug&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;onClick&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;updateTagMeta&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;selectedTagId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Link&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Routes looked something like:&lt;/p&gt;

&lt;div class=&quot;language-jsx highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Provider&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;store&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;appStore&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;BrowserRouter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Switch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Route&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;exact&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;/&apos;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;component&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;TaskContainer&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Route&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;/sessions/new&apos;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;component&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;SessionsNew&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Route&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;/tasks&apos;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;component&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;TaskList&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Route&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;/:slug&apos;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;component&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;TaskContainer&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Switch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;BrowserRouter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Provider&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This all worked well and fine, as long as the user got to a tag by clicking on
it. However, if the user used the URL to navigate to a tag (e.g.: by visiting
&lt;code class=&quot;highlighter-rouge&quot;&gt;/at-home&lt;/code&gt;) things didn’t work. There was no &lt;code class=&quot;highlighter-rouge&quot;&gt;selectedTagId&lt;/code&gt; in the store so it
ended up showing the next task from all of them. I had to find a way to get the
currently selected tag into the state from the get go. When a user clicked the
button, I set the selected tag id and also the slug in the URL, but when they
went directly to that URL, I needed a way to derive the tag id from the slug
already in the URL.&lt;/p&gt;

&lt;p&gt;I considered a few options here. The first was to find a way to make use of the
slug that was being parsed out by the &lt;code class=&quot;highlighter-rouge&quot;&gt;Route&lt;/code&gt; component. It passed the matched
URL elements down to the sub-components, so I could have added some lifecycle
hooks to check for an updated slug and update the store accordingly. This
didn’t feel quite right to me, though. I don’t like my components being too
smart, and in this case it felt weird to have my sub-components doing the work
of compensating for missing state that really ought to already be in the store.
I briefly looked at &lt;a href=&quot;https://github.com/ReactTraining/react-router/blob/master/packages/react-router-redux&quot;&gt;React Router Redux&lt;/a&gt;, but the only
thing it provides you is the entire route path, not the matched elements from
the path, so with or without it, I’m left with the option of parsing the path
myself, duplicating the work that is already being handled by the &lt;code class=&quot;highlighter-rouge&quot;&gt;Route&lt;/code&gt;
component. I could have written my own wrapper component, but when I am
starting to write as much code to work around a library as it would take to
roll my own, I start to think it’s time to build something more specific to my
needs.&lt;/p&gt;

&lt;h2 id=&quot;my-approach&quot;&gt;My Approach&lt;/h2&gt;

&lt;p&gt;In addition to the issue above, I’ve also had another nagging concern. I don’t
like how tightly coupled the logic in my app is tied to the path in the URL.
Much like one would fetch and persist data to a server, but store it locally
in, say, a Redux store, it seems to me like we ought to do an initial “fetch”
of the data from the URL, normalize it in a reasonable format for our client
side, and hold onto it in our store. Likewise, when we update the information,
we “persist” it to the URL, but continue to use our store as the source of data
for our components. With all of this in mind, here’s what I came up with.&lt;/p&gt;

&lt;h4 id=&quot;routes&quot;&gt;Routes&lt;/h4&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;pathToRegexp&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;path-to-regexp&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;compileRoutes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;routes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;routes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;route&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;regexp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;pathToRegexp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;route&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;route&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;

      &lt;span class=&quot;nf&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;regexp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;exec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;params&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{};&lt;/span&gt;

        &lt;span class=&quot;nx&quot;&gt;regexp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;nx&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;

      &lt;span class=&quot;na&quot;&gt;toPath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;pathToRegexp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;compile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;route&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ROUTES&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;compileRoutes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;sessionsNew&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;/sessions/new&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;tasks&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;/tasks&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;tag&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;/:slug&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ROUTES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;reducer&quot;&gt;Reducer&lt;/h4&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ROUTES&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;src/route/routes&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;routeReducer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;previousState&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;route/SET&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;payload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;matchingRoute&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ROUTES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;route&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;route&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;history&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;pushState&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;matchingRoute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;toPath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;route/INIT&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;matchingRoute&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ROUTES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;route&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;params&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;route&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;location&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;pathname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Boolean&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;matchingRoute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;router-container&quot;&gt;Router Container&lt;/h4&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;react-redux&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Router&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;src/route/components/router&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;mapStateToProps&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;route&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;route&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;mapStateToProps&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Router&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;router-component&quot;&gt;Router Component&lt;/h4&gt;

&lt;div class=&quot;language-jsx highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;React&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;react&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;SessionsNew&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;src/session/components/new&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;TaskContainer&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;src/task/containers/item&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;TaskList&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;src/task/containers/list&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ROUTE_NAME_TO_COMPONENT_MAP&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;TaskContainer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;sessionsNew&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;SessionsNew&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;tasks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;TaskList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;tag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;TaskContainer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Router&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;props&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Component&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ROUTE_NAME_TO_COMPONENT_MAP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;props&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;route&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Component&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;/&amp;gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;link-container&quot;&gt;Link Container&lt;/h4&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;react-redux&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Link&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;src/_common/components/link&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;setRoute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;src/route/action_creators&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;setRoute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Link&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;link-component&quot;&gt;Link Component&lt;/h4&gt;

&lt;div class=&quot;language-jsx highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;React&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;react&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ROUTES&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;src/route/routes&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Link&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;React&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Component&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nf&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;props&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;props&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;navigate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;navigate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;nf&quot;&gt;navigate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;preventDefault&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;props&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;setRoute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;props&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;props&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;nf&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;matchingRoute&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ROUTES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;route&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;route&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;props&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;matchingRoute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;toPath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;props&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;nf&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;children&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;props&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;onClick&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;navigate&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;children&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And the Tag Link from before becomes…&lt;/p&gt;

&lt;div class=&quot;language-jsx highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;TagLink&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;props&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;slug&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;props&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;return &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Link&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;tag&apos;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;slug&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Link&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;epilogue&quot;&gt;Epilogue&lt;/h2&gt;

&lt;p&gt;Et voila! The routing state is now in the store and accessible wherever we might
need a bit of info about what is going on. I’ve also made it so that the routes
are named. Some additional considerations:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A careful reader will notice that my reducer is no longer “pure” in that it
has a side effect on the URL. This was again for the sake of readability, but
I’ll probably end up moving that to an action creator.&lt;/li&gt;
  &lt;li&gt;I’m not accounting for the user pressing the back button, but that should be
manageable if we subscribe to history &lt;code class=&quot;highlighter-rouge&quot;&gt;POP&lt;/code&gt; events and simply reset the
routing state from scratch.&lt;/li&gt;
  &lt;li&gt;I left off some additional error checking as an exercise for the reader (and
again for readability), such as catching situations where a route does not
exist and when the wrong parameters are passed for a route.&lt;/li&gt;
  &lt;li&gt;I started writing this article and came across &lt;a href=&quot;https://medium.freecodecamp.org/an-introduction-to-the-redux-first-routing-model-98926ebf53cb&quot;&gt;this recent article from Free
Code Camp&lt;/a&gt; exploring similar ideas, though they take a
middleware approach to updating the browser history. Might be worth a glance
if you’re looking for some alternatives. (And they’ve got more links for you
at the end if you’re still not satiated!)&lt;/li&gt;
&lt;/ul&gt;</content><author><name>Robert Fletcher</name></author><category term="technical" /><category term="react" /><category term="redux" /></entry><entry><title type="html">React DnD Example Simplified</title><link href="http://blog.boon.gl/2015/04/13/react-dnd-example-simplified/" rel="alternate" type="text/html" title="React DnD Example Simplified" /><published>2015-04-13T00:00:00-07:00</published><updated>2015-04-13T00:00:00-07:00</updated><id>repo://posts.collection/_posts/2015-04-13-react-dnd-example-simplified.md</id><content type="html" xml:base="http://blog.boon.gl/2015/04/13/react-dnd-example-simplified/">&lt;p&gt;I recently started playing around with &lt;a href=&quot;https://github.com/gaearon/react-dnd&quot;&gt;React DnD&lt;/a&gt; to implement some
drag and drop sorting on &lt;a href=&quot;https://www.questlog.io&quot;&gt;an app I’m working on&lt;/a&gt;. The &lt;a href=&quot;https://github.com/gaearon/react-dnd/tree/master/examples&quot;&gt;examples
provided&lt;/a&gt; are built using a lot of the new syntax in ES6, as well
as having a good deal of what might be considered more “proper” structuring for
a React app, so it was challenging for me to parse out the critical bits for
React DnD to function. To further my own understanding, I stripped out all of
the ES6 syntax and some of the non-essential code in order to get the most
basic drag and drop implementation up and running. &lt;!--more--&gt; Check it out below,
as well as the &lt;a href=&quot;https://github.com/gaearon/react-dnd/tree/master/examples/_sortable-simple&quot;&gt;original example&lt;/a&gt; for reference. This
was built in the context of a rails app with &lt;a href=&quot;https://github.com/reactjs/react-rails&quot;&gt;react-rails&lt;/a&gt; and
&lt;a href=&quot;https://rails-assets.org/&quot;&gt;rails-assets&lt;/a&gt;-react-dnd, though I think the code should work
readily outside of the rails context.&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/mockdeep/2cb109097a9f9580aeb5.js&quot;&gt;&lt;/script&gt;</content><author><name>Robert Fletcher</name></author><category term="technical" /><category term="react" /></entry><entry><title type="html">Setting up a Middleman Blog</title><link href="http://blog.boon.gl/2014/09/23/setting-up-a-middleman-blog/" rel="alternate" type="text/html" title="Setting up a Middleman Blog" /><published>2014-09-23T00:00:00-07:00</published><updated>2014-09-23T00:00:00-07:00</updated><id>repo://posts.collection/_posts/2014-09-23-setting-up-a-middleman-blog.md</id><content type="html" xml:base="http://blog.boon.gl/2014/09/23/setting-up-a-middleman-blog/">&lt;p&gt;Second blog post seems like a good time to write about my experience setting up
a blog using &lt;a href=&quot;http://middlemanapp.com/&quot;&gt;Middleman&lt;/a&gt; while it’s still fresh in my mind.
Middleman is a static site generator, a la &lt;a href=&quot;http://jekyllrb.com/&quot;&gt;Jekyll&lt;/a&gt;, and I’m using
their &lt;a href=&quot;http://middlemanapp.com/basics/blogging/&quot;&gt;blogging extension&lt;/a&gt;. If you’re starting fresh, then I
would recommend the &lt;a href=&quot;http://robots.thoughtbot.com/middleman-bourbon-walkthrough&quot;&gt;thoughtbot post&lt;/a&gt; on how to get a blog set up
with their &lt;a href=&quot;http://bourbon.io/&quot;&gt;bourbon&lt;/a&gt;, &lt;a href=&quot;http://neat.bourbon.io/&quot;&gt;neat&lt;/a&gt;, and &lt;a href=&quot;http://bitters.bourbon.io/&quot;&gt;bitters&lt;/a&gt; SASS
libraries, as this is somewhat an extension of their post. I’ll talk about
setting up layouts, as well as coping with some minor styling issues I ran
into.&lt;/p&gt;

&lt;!--more--&gt;

&lt;h2 id=&quot;the-issue&quot;&gt;The Issue&lt;/h2&gt;

&lt;p&gt;So coming away from the above thoughtbot blog post, I was pretty happy with the default styling
provided by bitters, but one particular issue was that it removes the bullets and numbers
from ordered and unordered lists. This makes sense in terms of the navigation, but
inside my blog post I actually wanted to see them. Without putting straight up
html in my markdown, my options for customizing the styling were limited. I
spent probably well more time than I ought to have finagling the styling and
structuring in my layout file only to find that the styling would work on the
index page but not in the article view, or vice versa. Thus I went on the hunt
for a saner option and found it in &lt;a href=&quot;http://middlemanapp.com/basics/templates/#nested-layouts&quot;&gt;nested layouts&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;nested-layouts&quot;&gt;Nested Layouts&lt;/h2&gt;

&lt;p&gt;Setting up nested layouts is pretty straightforward. Here’s one of those lovely
bullet point lists:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;create an &lt;code class=&quot;highlighter-rouge&quot;&gt;articles&lt;/code&gt; directory and move your blog posts in there&lt;/li&gt;
  &lt;li&gt;create a &lt;code class=&quot;highlighter-rouge&quot;&gt;layouts&lt;/code&gt; directory for your nested layouts&lt;/li&gt;
  &lt;li&gt;add a layout &lt;code class=&quot;highlighter-rouge&quot;&gt;layouts/article_layout.html.erb&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;add the following configurations to &lt;code class=&quot;highlighter-rouge&quot;&gt;config.rb&lt;/code&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;blog.sources = &apos;articles/{year}-{month}-{day}-{title}.html&apos;&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;page &apos;/articles/*&apos;, layout: :article_layout&lt;/code&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And you should be set. Here’s what my article layout looks like:&lt;/p&gt;

&lt;div class=&quot;language-erb highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wrap_layout&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:layout&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;h3&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;%=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;link_to&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;current_article&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;current_article&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%&amp;gt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;h5&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;%=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;current_article&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;strftime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;%b %d, %Y&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%&amp;gt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;/h5&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;article&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;cp&quot;&gt;&amp;lt;%=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;&amp;lt;%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;and my config.rb, minus the fluff:&lt;/p&gt;

&lt;div class=&quot;language-rb highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;activate&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:blog&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;blog&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;blog&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;sources&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;articles/{year}-{month}-{day}-{title}.html&apos;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;blog&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;tag_template&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;tag.html&apos;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;blog&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;calendar_template&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;calendar.html&apos;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;activate&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:syntax&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;line_numbers: &lt;/span&gt;&lt;span class=&quot;kp&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:markdown_engine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:redcarpet&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:markdown&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;fenced_code_blocks: &lt;/span&gt;&lt;span class=&quot;kp&quot;&gt;true&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;page&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;/feed.xml&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;layout: &lt;/span&gt;&lt;span class=&quot;kp&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;page&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;/articles/*&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;layout: :article_layout&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:css_dir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;stylesheets&apos;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:js_dir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;javascripts&apos;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:images_dir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;images&apos;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:build_dir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;tmp&apos;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;configure&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:build&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;configure&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:development&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;activate&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:livereload&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;styles&quot;&gt;Styles&lt;/h2&gt;

&lt;p&gt;So there were a couple of styling issues I ran into. The first was the
aforementioned missing bullets. I created a new partial
&lt;code class=&quot;highlighter-rouge&quot;&gt;stylesheets/partials/_article.css.scss&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-scss highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;article&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;ul&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;@extend&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;%default-ul&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;nt&quot;&gt;ol&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;li&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nl&quot;&gt;margin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;@extend&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;%default-ol&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;You’ll need to add &lt;code class=&quot;highlighter-rouge&quot;&gt;@import &apos;partials/article&apos;;&lt;/code&gt; to &lt;code class=&quot;highlighter-rouge&quot;&gt;all.css.scss&lt;/code&gt; after the
bourbon includes.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One other issue is that the default bourbon styling on tables makes the line
numbers in fenced code blocks take up half the page, so I also added this to
&lt;code class=&quot;highlighter-rouge&quot;&gt;_article.css.scss&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-scss highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;article&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// ...other stuff you just added&lt;/span&gt;

  &lt;span class=&quot;nc&quot;&gt;.highlight&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;table&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nl&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;auto&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And that just about covers it.&lt;/p&gt;

&lt;h2 id=&quot;errors&quot;&gt;Errors&lt;/h2&gt;

&lt;p&gt;Here are a couple of errors and bugs I ran into, so if you see them, here’s how
you can fix them. If you run into a build error, use &lt;code class=&quot;highlighter-rouge&quot;&gt;middleman build
--verbose&lt;/code&gt; to get the full output.&lt;/p&gt;

&lt;h4 id=&quot;undefined-method-title-for-nilnilclass&quot;&gt;undefined method `title’ for nil:NilClass&lt;/h4&gt;

&lt;p&gt;You probably haven’t put your layout in it’s proper subdirectory. Move
&lt;code class=&quot;highlighter-rouge&quot;&gt;article_layout.html.erb&lt;/code&gt; into the &lt;code class=&quot;highlighter-rouge&quot;&gt;layouts&lt;/code&gt; directory.&lt;/p&gt;

&lt;h4 id=&quot;article-not-showing-up&quot;&gt;article not showing up&lt;/h4&gt;

&lt;p&gt;Make sure your article is in the &lt;code class=&quot;highlighter-rouge&quot;&gt;articles&lt;/code&gt; subdirectory, and make sure you
don’t have&lt;/p&gt;

&lt;div class=&quot;language-yml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;published&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;in your front matter at the beginning of the post.&lt;/p&gt;

&lt;h4 id=&quot;the-selector-default-ul-was-not-found&quot;&gt;The selector “%default-ul” was not found.&lt;/h4&gt;

&lt;p&gt;It’s trying to precompile your &lt;code class=&quot;highlighter-rouge&quot;&gt;scss&lt;/code&gt; partial stand alone. Double check that you
have the &lt;code class=&quot;highlighter-rouge&quot;&gt;_&lt;/code&gt; in &lt;code class=&quot;highlighter-rouge&quot;&gt;_article.css.scss&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;fin&quot;&gt;Fin&lt;/h2&gt;

&lt;p&gt;That’s all. You can check out the full repo &lt;a href=&quot;https://github.com/mockdeep/boon-blog&quot;&gt;here&lt;/a&gt;, and the build
that was referenced in this blog post &lt;a href=&quot;https://github.com/mockdeep/boon-blog/tree/bourbon-blog&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;</content><author><name>Robert Fletcher</name></author><category term="technical" /><category term="blogging" /><category term="middleman" /></entry><entry><title type="html">Finding an Apartment in San Francisco</title><link href="http://blog.boon.gl/2014/09/19/finding-an-apartment-in-sf/" rel="alternate" type="text/html" title="Finding an Apartment in San Francisco" /><published>2014-09-19T00:00:00-07:00</published><updated>2014-09-19T00:00:00-07:00</updated><id>repo://posts.collection/_posts/2014-09-19-finding-an-apartment-in-sf.md</id><content type="html" xml:base="http://blog.boon.gl/2014/09/19/finding-an-apartment-in-sf/">&lt;p&gt;I recently settled into a new apartment after a grueling two month search, so I
thought I’d share some of my experience looking for an apartment during the
&lt;a href=&quot;http://lifehacker.com/5954711/apartment-hunting-heres-the-best-time-of-year-month-and-day-to-search&quot;&gt;worst time of the year for it&lt;/a&gt;. It can be a harrowing time, and to
be honest, if you can put it off until a better time of year, I’d recommend it.
Prices will be lower and the competition for the affordable places will be
considerably less fierce.  Regardless of when you’re on the hunt, though, here
are some tips that might help you get through it a little easier. &lt;!--more--&gt; What
I share here is from the perspective of looking for a place to myself, but
&lt;strong&gt;much of it should still apply if you’re looking for a roommate situation&lt;/strong&gt;.&lt;/p&gt;

&lt;h2 id=&quot;know-what-you-want&quot;&gt;Know What You Want&lt;/h2&gt;

&lt;p&gt;When I started looking for a new place to live, it was easy to start
rationalizing every place I went into and think “I could make this work”. I
would spend my time applying and put in the application fee, and then a couple
hours later realize that I didn’t really want it. Something that helped me to
make a decision on a place before wasting too much time and money was to have a
set of clear criteria that I could go over. My rule of thumb was that it had to
meet all but one criteria, and some were more negotiable than others.&lt;/p&gt;

&lt;p&gt;My criteria:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Bathtub&lt;/li&gt;
  &lt;li&gt;Not on the ground floor&lt;/li&gt;
  &lt;li&gt;Not in a sketchy area where I wouldn’t feel safe myself, or having my
girlfriend walk&lt;/li&gt;
  &lt;li&gt;Room for all of my stuff and space to stretch out in between&lt;/li&gt;
  &lt;li&gt;Wood floors&lt;/li&gt;
  &lt;li&gt;Under $2000 ($2200 max fail)&lt;/li&gt;
  &lt;li&gt;Close to work, and the Mission&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this case I ended up compromising on the wood floors. To state the obvious,
&lt;strong&gt;the higher you go on price, the less competition you’ll have&lt;/strong&gt;, and better
odds of satisfying all of your criteria. $2000 was actually kind of on the low
end for my criteria, though I eventually found a place for a little less than
that.&lt;/p&gt;

&lt;h2 id=&quot;be-on-the-ground&quot;&gt;Be on the Ground&lt;/h2&gt;

&lt;p&gt;Most landlords won’t even consider you unless they can see your face. If you’re
coming in from out of town, you’re going to have a much harder time finding a
place unless you find your way to the city first. Expect to pay higher rent and
get a lot more rejections. Landlords are on the watch for scammers, too, and
for better or worse, one clear warning sign of a scam is that the person is out
of town. Your best bet is to find some temporary accommodations in the city and
look from there.&lt;/p&gt;

&lt;h2 id=&quot;papers-please&quot;&gt;Papers, please!&lt;/h2&gt;

&lt;p&gt;When you go to a showing, typically they will have applications you can fill
out, but it can become really tiring and discouraging to spend fifteen minutes
apiece filling out one application after another. The &lt;a href=&quot;http://www.caanet.org/documents/application-to-rent&quot;&gt;California Apartment
Association&lt;/a&gt; has an application that is pretty generally accepted. You
can fill it out by hand and scan/copy it, or fill it out with a tool like
&lt;a href=&quot;http://www.adobe.com/products/acrobat.html&quot;&gt;Adobe Acrobat&lt;/a&gt; or &lt;a href=&quot;http://xournal.sourceforge.net/&quot;&gt;Xournal&lt;/a&gt;. Aside from the application,
different landlords and leasing agents will expect to see different documents.
Here’s a list of documents I’d recommend keeping with you in a folder:&lt;/p&gt;

&lt;p&gt;&lt;input type=&quot;checkbox&quot; /&gt;
3 filled out copies of an application
&amp;lt;/input&amp;gt;
&lt;br /&gt;
&lt;input type=&quot;checkbox&quot; /&gt;
2 photocopies of your drivers license or other state ID
&amp;lt;/input&amp;gt;
&lt;br /&gt;
&lt;input type=&quot;checkbox&quot; /&gt;
1 copy of your full credit report (yes, there is the occasional landlord who
wants the full 30+ page report)
&amp;lt;/input&amp;gt;
&lt;br /&gt;
&lt;input type=&quot;checkbox&quot; /&gt;
2 copies of your printed credit score (nothing fancy, just your name and a
number from one of the three credit bureaus)
&amp;lt;/input&amp;gt;
&lt;br /&gt;
&lt;input type=&quot;checkbox&quot; /&gt;
checkbook (you’re unlikely to need to put down a deposit, but some require a
rental application fee of around $50)
&amp;lt;/input&amp;gt;
&lt;br /&gt;
&lt;input type=&quot;checkbox&quot; /&gt;
2 copies of a reference letter from your previous landlord (you can find a form
letter online to send to your landlord and ask them to sign)
&amp;lt;/input&amp;gt;
&lt;br /&gt;
&lt;input type=&quot;checkbox&quot; /&gt;
2 copies of your most recent 3 pay stubs
&amp;lt;/input&amp;gt;&lt;/p&gt;

&lt;h2 id=&quot;the-hunt&quot;&gt;The Hunt&lt;/h2&gt;

&lt;p&gt;Here’s where the rubber hits the road. Before we get started, I want to give
you a little personal advice: &lt;strong&gt;don’t get attached&lt;/strong&gt;. We all like to think
we’re that one delicate and unique flower in the field that is somehow more
precious than all the others, but keep in mind that there are probably a lot of
qualified candidates applying for each of the units you’re visiting, some of
whom have better credit scores. Like sales, apartment hunting is a numbers
game. The more places you apply to (that meet your criteria, of course), the
better your chances of getting something you like.&lt;/p&gt;

&lt;h4 id=&quot;padmapper&quot;&gt;Padmapper&lt;/h4&gt;

&lt;p&gt;&lt;a href=&quot;http://www.padmapper.com/&quot;&gt;Padmapper&lt;/a&gt; was my power tool of choice during this hunt. In the
past I always just used craigslist search and RSS feeds, but Padmapper makes it
so much easier to find craigslist results in the areas that I want to live in
and quickly filter them out.  I’d recommend signing up for an account and
setting up an email alert. My workflow went something like this:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;open Padmapper&lt;/li&gt;
  &lt;li&gt;click open a link into a new tab&lt;/li&gt;
  &lt;li&gt;respond to the ad by their preferred means if I’m interested (or take a note
  to do so later)&lt;/li&gt;
  &lt;li&gt;close the tab&lt;/li&gt;
  &lt;li&gt;hide the result in Padmapper&lt;/li&gt;
  &lt;li&gt;repeat&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And come back in another hour or two to start the process again…&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Side note&lt;/em&gt;: I’d occasionally get gateway errors with Padmapper, so if you run
into that you can clear your cookies and log back in. In Chrome you can click
on the icon to the left of the url and click on “Show cookies and site data”,
and remove them from there.&lt;/p&gt;

&lt;h4 id=&quot;responding&quot;&gt;Responding&lt;/h4&gt;

&lt;p&gt;It’s important to respond to ads promptly, because often times the poster ends
up inundated with responses and won’t be as likely to reply after the first few
hours or so. You should still respond if you’re interested regardless, but your
odds are better the earlier you do.&lt;/p&gt;

&lt;p&gt;Some ads will want you to email, others call, and still others just want you to
show up at the open house. If they have something marked as a preferred contact
means under the “reply” menu, make sure to use that.&lt;/p&gt;

&lt;p&gt;You can make responding less painful having a simple canned email that you can
modify for each listing. Gmail has a Labs feature called Canned Responses that
you can enable. In your email you should have:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;the address you’re interested in&lt;/li&gt;
  &lt;li&gt;anything specifically asked for in the posting&lt;/li&gt;
  &lt;li&gt;3-4 sentences about you&lt;/li&gt;
  &lt;li&gt;how to contact you&lt;/li&gt;
  &lt;li&gt;I also like to paste in the craigslist link at the bottom for easy access&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here’s the message that I used:&lt;/p&gt;

&lt;blockquote&gt;
RE: Elegant Studio - With full amenities
&lt;br /&gt;
&lt;br /&gt;
Hi there,
&lt;br /&gt;
&lt;br /&gt;
I saw your ad on Craigslist for a studio at Harrison at Main and the apartment
sounds like a good fit for me. I&apos;d love to come check it out if it&apos;s still
available. When works best for you?
&lt;br /&gt;
&lt;br /&gt;
About me, if you&apos;re interested: I&apos;m 33 years old and I work for a company that
helps schools to minimize administrative costs, in particular by reducing
paperwork. Sounds kind of boring, but it&apos;s having a huge impact. I bike a ton,
climb some, and try to get outside and wander when I get a chance. I&apos;m pretty
quiet and clean, don&apos;t smoke or use drugs, and don&apos;t have any pets.
&lt;br /&gt;
&lt;br /&gt;
Anyway, so please let me know if there&apos;s anything else you&apos;d like to know about
me. If it&apos;s more convenient, you can call me at ^^^-^^^-^^^^.
&lt;br /&gt;
&lt;br /&gt;
Hope to hear from you,
&lt;br /&gt;
&lt;br /&gt;
- Robert
&lt;/blockquote&gt;

&lt;p&gt;This will differ pretty dramatically if you’re looking for a roommate
situation, since then it is much more important to express your personality and
respond to the specifics of their posting. You can still have a canned email,
but you’ll need to customize it a bit more.&lt;/p&gt;

&lt;h4 id=&quot;showing-up&quot;&gt;Showing Up&lt;/h4&gt;

&lt;p&gt;Most people will suggest that you show up early for a listing. This is, in my
experience, only true-ish. It depends on a lot of factors, and I would still
recommend it for the most part, but it can depend on the situation. Some places
go first-come, first-serve, many are looking for a pile of decent applications
to choose from, and some are actually looking for a personality fit. For the
most part I’ve found that showing up 15 minutes or so before the viewing can be
helpful, since the person showing it is often there early, too, and you can
sneak in before anybody else shows up. Other times you’re one of a mass of
people who got the same idea, so your mileage may vary.&lt;/p&gt;

&lt;p&gt;Be aware that &lt;strong&gt;landlords aren’t your friends&lt;/strong&gt;. Schmoozing can be productive,
but their top priorities are going to be looking for someone who is clean,
quiet, and pays their bills on time. Those are the traits that you should focus
on exhibiting, with likeability in a close fourth. Often times the person
showing the apartment isn’t going to be the decision maker anyway, and your
application will have to speak for itself.&lt;/p&gt;

&lt;h4 id=&quot;anatomy-of-a-scam&quot;&gt;Anatomy of a Scam&lt;/h4&gt;
&lt;p&gt;Whenever there are goods and services being exchanged for money, there will be
people trying to scam both sides, and here is no exception. On the property
side, scammers will often pose as potential renters who for one reason or
another can’t come to see the property. Typically, they are after the bank
account info of the landlord with the overt intention of transferring a deposit
into it, and the subvert intention of draining it.&lt;/p&gt;

&lt;p&gt;From the other side of things, scammers will try to get you to pay them without
having any goods to deliver. They will list an apartment that is not on the
market and give you excuses why you can’t see it. Either the tenant is out of
town, or they already have a ton of applications and want you to get your
chance, or it’s under renovation. They might tell you to drive by it and check
it out from the outside. They’ll ask you to pay up front and emphasize that
time is of the essence, and possibly try to tell you they think you’re the
right person for the place, despite knowing nothing about you. A corollary to
the bit above about landlords not being your friend is that if they sound like
you’re friend, they’re almost certainly a scammer. Some even go so far as to
offer you deals if you pay more up front, such as 10% discount for 6-months
rent up front and 15% for a year.&lt;/p&gt;

&lt;p&gt;Bottom line is, &lt;strong&gt;if it sounds too good to be true, it almost certainly is&lt;/strong&gt;.
Scammers will do what they can to try to look legitimate. They will copy images
and descriptions from other postings and websites. They might impersonate a
real person, using “brian.smith@yahoo.com” when there is a real
“brian.smith@somerealtyco.com”. They might even be so bold as to copy
a listing with an open house that is still available. You go to the open house,
like it, and then pay the scammer instead of the real owner. When in doubt,
make sure you see the face of the person you’re in touch with.&lt;/p&gt;

&lt;h2 id=&quot;additional-thoughts&quot;&gt;Additional Thoughts&lt;/h2&gt;

&lt;p&gt;There’s still a lot I could add to this, but I think I’ve shared the most
important parts. A couple of final bits of advice, though.&lt;/p&gt;

&lt;p&gt;First off, iterate. I spent a little time every day looking over my application
and the process I was using, and it was surprising to find there was always
something that could use a bit more tuning, whether it be on my application or
my presentation. I even went so far as to get my shaggy hair trimmed up a bit
to look more presentable.&lt;/p&gt;

&lt;p&gt;A second thought is to ask for feedback. People showing apartments are going to
be pretty busy and overwhelmed, but there might be a window from time to time
where you can ask them what they’re looking for and if there are any red flags
on your application.&lt;/p&gt;

&lt;p&gt;If you’d like a bit more reading, &lt;a href=&quot;http://ohhappyday.com/2013/04/5-tips-for-apartment-hunting-in-san-francisco-our-story/&quot;&gt;here’s another article&lt;/a&gt; I found
useful when I started my search. Best of luck!&lt;/p&gt;</content><author><name>Robert Fletcher</name></author><category term="personal" /><category term="San Francisco" /></entry></feed>