<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: crishanks</title>
    <description>The latest articles on DEV Community by crishanks (@crishanks).</description>
    <link>https://dev.to/crishanks</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F139695%2Ffc278490-3367-4591-8925-54e1f5b48540.jpeg</url>
      <title>DEV Community: crishanks</title>
      <link>https://dev.to/crishanks</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/crishanks"/>
    <language>en</language>
    <item>
      <title>Drag &amp; Drop: Reorder Lists with react-dnd</title>
      <dc:creator>crishanks</dc:creator>
      <pubDate>Wed, 03 Jan 2024 18:44:29 +0000</pubDate>
      <link>https://dev.to/crishanks/transfer-lists-with-react-dnd-3ifo</link>
      <guid>https://dev.to/crishanks/transfer-lists-with-react-dnd-3ifo</guid>
      <description>&lt;h1&gt;
  
  
  Drag &amp;amp; Drop with react-dnd
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://amzn.to/3S1VsKG"&gt;Stay Hydrated&lt;/a&gt; out there&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/ycgw5l"&gt;
&lt;/iframe&gt;
.&lt;/p&gt;
&lt;h2&gt;
  
  
  Diving In
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/JrjNe1zbLYd3y/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/JrjNe1zbLYd3y/giphy.gif" width="400" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At the top level of our component we import 'react-dnd' and 'react-dnd-html5-backend' and hook up the DndProvider. If it's gonna be draggable, it's gotta be wrapped in the provider and passed a backend.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./styles.css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;DndProvider&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-dnd&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;HTML5Backend&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-dnd-html5-backend&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;DropZone&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./drop-zone&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dndCharacterData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;classType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Barbarian&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;race&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Dragonborn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;classType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Barbarian&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;race&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Dwarf&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;classType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Fighter&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;race&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Elf&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;classType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Fighter&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;race&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Gnome&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;classType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Monk&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;race&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Half - elf&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;classType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Monk&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;race&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Half - orc&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;classType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Druid&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;race&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Halfling&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;classType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Druid&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;race&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Tiefling&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;
      &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;App&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flex&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;flexDirection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;column&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;alignItems&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;react&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;dnd&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* The DndProvider component provides React-DnD capabilities to our application. */&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* There are different backend types for different applications like 'touch' for mobile
        but HTML5 is the primary supported backend. Use this unless you have a
        really specific use case*/&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;DndProvider&lt;/span&gt; &lt;span class="nx"&gt;backend&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;HTML5Backend&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;DropZone&lt;/span&gt; &lt;span class="nx"&gt;dndCharacterData&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;dndCharacterData&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/DndProvider&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's create a drop zone that surrounds our draggable items. Typically a drop zone configured component will have its own instance of useDrop, but when your dragabbles are always inside  the drop zone, we don't need it (see the beginner example for contrast). So for this example, the DropZone component really serves as more of a container to extrapolate out some of the business logic associated with reordering our list.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useCallback&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Draggable&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./draggable&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;update&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;immutability-helper&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;DropZone&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;dndCharacterData&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;//grabbing api data and rendering it with `renderDndCharacterCards`&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;dndCharacters&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setDndCharacters&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dndCharacterData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;//a memoized function that uses js `immutability-helper` &amp;amp; `splice` to update the&lt;/span&gt;
  &lt;span class="c1"&gt;//order of our rows&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;moveRow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useCallback&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;dragIndex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;hoverIndex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setDndCharacters&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;prevCharacters&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
      &lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prevCharacters&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;$splice&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;dragIndex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
          &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;hoverIndex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;prevCharacters&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;dragIndex&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;renderDndCharacterCards&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;dndCharacters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;dndCharacter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Draggable&lt;/span&gt;
        &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;dndCharacter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;dndCharacter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;dndCharacter&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;moveRow&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;moveRow&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;));&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;
      &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
        &lt;span class="na"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1px solid blue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;80%&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flex&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;flexDirection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;column&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;alignItems&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;20px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;10px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="p"&gt;}}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h2&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Drop&lt;/span&gt; &lt;span class="nx"&gt;Zone&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h2&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;renderDndCharacterCards&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's get into the nitty gritty.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/10MG0J9z19Sjjq/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/10MG0J9z19Sjjq/giphy.gif" width="500" height="255"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our Draggable component is actually going to take care of almost all of the drag and drop functionality. We use the useDrop provided by react-dnd to establish a droppable area, and the useDrag hook to make something draggable. The two are connected by useDrop's accept property, and useDrag's type property. &lt;em&gt;If those don't match, no draggy droppy.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useRef&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useDrag&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useDrop&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-dnd&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;//High Level 101 -- react-dnd uses drop areas and draggable items&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Draggable&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;dndCharacter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;moveRow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;race&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;classType&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;dndCharacter&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c1"&gt;//react-dnd uses refs as its vehicle to make elements draggable&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRef&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;//we use `useDrop` to designate a drop zone&lt;/span&gt;
  &lt;span class="c1"&gt;//it returns `collectedProps` and a `drop` function&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;collectedProps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;drop&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useDrop&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="c1"&gt;//collectedProps is an object containing collected properties from the collect function&lt;/span&gt;

    &lt;span class="c1"&gt;//`accept` is very important. It determines what items are allowed to be dropped inside it&lt;/span&gt;
    &lt;span class="c1"&gt;//this corresponds with the useDrag `type` value we'll see in a bit.&lt;/span&gt;
    &lt;span class="na"&gt;accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dnd-character&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="c1"&gt;//here's that collect function!&lt;/span&gt;
    &lt;span class="c1"&gt;//Usually the info we want out of `collect()` comes from the `monitor` object&lt;/span&gt;
    &lt;span class="c1"&gt;//react- dnd gives us. We can use `monitor` to know things about the state of dnd,&lt;/span&gt;
    &lt;span class="c1"&gt;//like isDragging, clientOffset, etc.&lt;/span&gt;
    &lt;span class="c1"&gt;//If we we want to expose this data outside of the hook and use in other places, we&lt;/span&gt;
    &lt;span class="c1"&gt;//should return it as a part of the `collect(monitor)` function.&lt;/span&gt;
    &lt;span class="nf"&gt;collect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;monitor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;handlerId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;monitor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getHandlerId&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="c1"&gt;// Example: maybe you want `isOver: monitor.isOver()` for dynamic styles&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;

    &lt;span class="c1"&gt;//`hover` gets called by react-dnd when an `accept`ed draggable item is hovering&lt;/span&gt;
    &lt;span class="c1"&gt;//over the drop zone. There is a decent amount of vanilla js that is required to&lt;/span&gt;
    &lt;span class="c1"&gt;//make the reorder ui work:&lt;/span&gt;
    &lt;span class="nf"&gt;hover&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;monitor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dragIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hoverIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="c1"&gt;// Don't replace items with themselves&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dragIndex&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;hoverIndex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="c1"&gt;// Determine rectangle on screen&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hoverBoundingRect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;getBoundingClientRect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="c1"&gt;// Get vertical middle&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hoverMiddleY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hoverBoundingRect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bottom&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;hoverBoundingRect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;top&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="c1"&gt;// Determine mouse position&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;clientOffset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;monitor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getClientOffset&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="c1"&gt;// Get pixels to the top&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hoverClientY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;clientOffset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;hoverBoundingRect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;top&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="c1"&gt;// Only perform the move when the mouse has crossed half of the items height&lt;/span&gt;
      &lt;span class="c1"&gt;// When dragging downwards, only move when the cursor is below 50%&lt;/span&gt;
      &lt;span class="c1"&gt;// When dragging upwards, only move when the cursor is above 50%&lt;/span&gt;

      &lt;span class="c1"&gt;// Dragging downwards&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dragIndex&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;hoverIndex&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;hoverClientY&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;hoverMiddleY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="c1"&gt;// Dragging upwards&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dragIndex&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;hoverIndex&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;hoverClientY&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;hoverMiddleY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="c1"&gt;// Time to actually perform the action&lt;/span&gt;
      &lt;span class="nf"&gt;moveRow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dragIndex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;hoverIndex&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;hoverIndex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;//useDrag allows us to interact with the drag source&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;collectedDragProps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;drag&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;preview&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useDrag&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="c1"&gt;//here's that `type` that corresponds with `accept`. These two have to align.&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dnd-character&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c1"&gt;//`item` describes the item being dragged. It's called by react-dnd when drag begins.&lt;/span&gt;
    &lt;span class="c1"&gt;//`item` gets passed into hover and we use that data there&lt;/span&gt;
    &lt;span class="na"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;collect&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;monitor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;isDragging&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;monitor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isDragging&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;//Here's an example of how we use `collectedProps`.&lt;/span&gt;
  &lt;span class="c1"&gt;//I'm using bgColor instead of opacity to demonstrate the difference between the item&lt;/span&gt;
  &lt;span class="c1"&gt;//being dragged and the preview, meaning the element in dragging state. isDragging affects&lt;/span&gt;
  &lt;span class="c1"&gt;//the actual dragged element, not the preview.&lt;/span&gt;
  &lt;span class="c1"&gt;//*Note: if we want to change the preview we would want to use a custom drag layer and render a preview component&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bgColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;collectedDragProps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isDragging&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gray&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;//in the return statement, we assign the ref to be the value of the div&lt;/span&gt;

  &lt;span class="c1"&gt;//Join the two refs together. This is a shorthand that allows us to create&lt;/span&gt;
  &lt;span class="c1"&gt;//a drop zone around our draggables in one line.&lt;/span&gt;
  &lt;span class="nf"&gt;drag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;drop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;
      &lt;span class="c1"&gt;//here's that ref&lt;/span&gt;
      &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
        &lt;span class="na"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1px dotted&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;50%&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2px 12px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;bgColor&lt;/span&gt;
      &lt;span class="p"&gt;}}&lt;/span&gt;
      &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;handler&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;collectedProps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handlerId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`Class: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;classType&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`Race: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;race&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A couple of gotchas on the above code that are worth reiterating:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;There is a difference between the preview and the draggable item we've given to the ref. The preview is what shows up when you start dragging. The draggable item is what actually moves when we reorder. If we want to interact with the preview we often do this with a 'Custom Drag Layer'. We aren't going over that in detail here, but we'll cover it in the advanced example.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Remember a few paragraphs ago when we said typically a drop zone's useDrag is separated from the draggable item component? Take a look at line 98, drag(drop(ref)); . Since our draggables are always going to be inside of a corresponding drop zone, react-dnd gives us a shorthand that says 'go ahead and combine the refs' so we just pass the combined ref to the containing draggable element we return in the Draggable.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;There we have it. Our feature now has drag and drop.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://amzn.to/3tHVQVy"&gt;Stay hydrated&lt;/a&gt; out there&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/l0NwKAlZzZ9pyi9fa/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/l0NwKAlZzZ9pyi9fa/giphy.gif" width="238" height="193"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>interviewquestions</category>
      <category>reactdnd</category>
      <category>draganddrop</category>
      <category>react</category>
    </item>
    <item>
      <title>Deploy / Host your React App with cPanel in Under 5 Minutes</title>
      <dc:creator>crishanks</dc:creator>
      <pubDate>Fri, 09 Aug 2019 20:04:22 +0000</pubDate>
      <link>https://dev.to/crishanks/deploy-host-your-react-app-with-cpanel-in-under-5-minutes-4mf6</link>
      <guid>https://dev.to/crishanks/deploy-host-your-react-app-with-cpanel-in-under-5-minutes-4mf6</guid>
      <description>&lt;p&gt;&lt;a href="https://amzn.to/3S26cJa" rel="noopener noreferrer"&gt;Stay hydrated out there&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Diving Right In
&lt;/h1&gt;

&lt;p&gt;While working on a personal project called &lt;a href="http://punchstart.me" rel="noopener noreferrer"&gt;Punchstarter&lt;/a&gt;, a Kickstarter clone app, I struggled to find any good documentation on how to host a custom app on my own domain with cPanel. I hope this will serve useful to many.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Purchase a Domain and Hosting
&lt;/h3&gt;

&lt;p&gt;To host a website, you'll need to purchase a registered domain name and a hosting plan from a hosting provider (both provided through numerous sources like &lt;a href="https://www.namecheap.com/hosting/shared/" rel="noopener noreferrer"&gt;Namecheap&lt;/a&gt; or &lt;a href="https://www.godaddy.com/hosting/web-hosting" rel="noopener noreferrer"&gt;Godaddy&lt;/a&gt;). If you buy them together, these providers will typically point the domain to your hosting server automatically. If not, &lt;a href="https://sitebeginner.com/domains/domaintosite/" rel="noopener noreferrer"&gt;this tutorial&lt;/a&gt; can help you out.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Add the Homepage to your package.json File
&lt;/h3&gt;

&lt;p&gt;Next, open up your React App. Open up your &lt;code&gt;package.json&lt;/code&gt; file and add a &lt;code&gt;"homepage"&lt;/code&gt; attribute like so:&lt;/p&gt;

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

&lt;p&gt;The format should be &lt;code&gt;"homepage": "http://yourdomainname.whatever"&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Create the &lt;code&gt;build&lt;/code&gt; File
&lt;/h3&gt;

&lt;p&gt;In your application's root directory, run &lt;code&gt;yarn install&lt;/code&gt; to install the updated dependencies. Once this has finished, the next command you'll run is &lt;code&gt;yarn build&lt;/code&gt; (&lt;code&gt;npm install&lt;/code&gt; and &lt;code&gt;npm build&lt;/code&gt; work, too).&lt;/p&gt;

&lt;p&gt;You'll notice this creates a new directory in your project called &lt;code&gt;build&lt;/code&gt;. The build folder is essentially a super-compressed version of your program that has everything your browser needs to identify and run your app.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  4. Connect to cPanel
&lt;/h3&gt;

&lt;p&gt;Let's head over to your hosting provider (Namecheap, Godaddy, Bluehost etc.). Once you've logged in, navigate to the cPanel manager for your domain. Typically there is a dropdown menu of some kind that says "Manage" which will direct you to cPanel.&lt;/p&gt;

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

&lt;p&gt;Your cPanel manager should look something like this:&lt;/p&gt;

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

&lt;p&gt;Navigate into the File Manager. There you'll find a dropdown list of directories. The one we're interested in is &lt;code&gt;public_html&lt;/code&gt;. Open that up.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  5. Add the Build File Contents to &lt;code&gt;public_html&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Navigate to the &lt;code&gt;build&lt;/code&gt; file in your app's root directory. Open it up and select all the contents &lt;strong&gt;inside the build file&lt;/strong&gt;. &lt;em&gt;If you upload the entire build file itself, the process will not work&lt;/em&gt;.&lt;/p&gt;

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

&lt;p&gt;Once you've copied all the contents &lt;em&gt;inside the build file&lt;/em&gt;, upload them into &lt;code&gt;public_html&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Create and Upload the &lt;code&gt;.htaccess&lt;/code&gt; File
&lt;/h2&gt;

&lt;p&gt;In order for the routes to work in your React app, you need to add a &lt;code&gt;.htaccess&lt;/code&gt; file. In the &lt;code&gt;public_html&lt;/code&gt; folder, at the same level as the &lt;code&gt;build&lt;/code&gt; file contents, add a new file and name it &lt;code&gt;.htaccess&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Edit the file and insert the following boilerplate information: &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

&amp;lt;IfModule mod_rewrite.c&amp;gt;

  RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_FILENAME} !-l
  RewriteRule . /index.html [L]

&amp;lt;/IfModule&amp;gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

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

&lt;p&gt;Save the file.&lt;/p&gt;

&lt;h2&gt;
  
  
  You're Super Done.
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://amzn.to/3S26cJa" rel="noopener noreferrer"&gt;Stay hydrated out there&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's it! Navigate to your domain address in the browser and you should see your fully functioning web app.&lt;/p&gt;

&lt;p&gt;But you know what else is nice... &lt;a href="https://amzn.to/48GVlcT" rel="noopener noreferrer"&gt;A shiny new mechanical keyboard&lt;/a&gt;. Click that if you're interested in a good one. Or click this for &lt;a href="https://amzn.to/48lQTRe" rel="noopener noreferrer"&gt;another cool option&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Or perhaps you have a good one and you want to &lt;a href="https://amzn.to/3RMztpK" rel="noopener noreferrer"&gt;spruce it up a bit&lt;/a&gt; (you know I did). &lt;/p&gt;

&lt;h1&gt;
  
  
  A Note on FileZilla
&lt;/h1&gt;

&lt;p&gt;I know a lot of folks like to use FileZilla to deploy and host their custom web apps. I found it to be unnecessary for my purposes, but should you choose, you can:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Download and run &lt;a href="https://filezilla-project.org/" rel="noopener noreferrer"&gt;FileZilla&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://ipinfo.info/html/ip_checker.php" rel="noopener noreferrer"&gt;Grab your domain's ip address&lt;/a&gt; -- or ask your hosting provider&lt;/li&gt;
&lt;li&gt;Input the domain ip, cPanel login, cPanel username, and host port (i.e. 21. Your hosting provider should provide that info for you) into the top bar&lt;/li&gt;
&lt;li&gt;Click QuickConnect&lt;/li&gt;
&lt;li&gt;Once connected, navigate to, select, and copy the contents inside the &lt;code&gt;build&lt;/code&gt; file (in the left-side pane showing your computer's directories)&lt;/li&gt;
&lt;li&gt;Navigate to the &lt;code&gt;public_html&lt;/code&gt; directory in the cPanel pane on the right-hand side. Paste the contents of the &lt;code&gt;build&lt;/code&gt; file into &lt;code&gt;public_html&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Create the &lt;code&gt;.htaccess&lt;/code&gt; file with the same information listed above&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>cpanel</category>
      <category>hosting</category>
    </item>
    <item>
      <title>It Isn't Magic, It's Webpack.</title>
      <dc:creator>crishanks</dc:creator>
      <pubDate>Sun, 07 Jul 2019 03:18:58 +0000</pubDate>
      <link>https://dev.to/crishanks/it-isn-t-magic-it-s-webpack-3ca4</link>
      <guid>https://dev.to/crishanks/it-isn-t-magic-it-s-webpack-3ca4</guid>
      <description>&lt;p&gt;&lt;a href="https://amzn.to/3S26cJa" rel="noopener noreferrer"&gt;Stay hydrated out there&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Bundlers
&lt;/h1&gt;

&lt;p&gt;Maybe a better title for this post would have been "It Isn't Magic, It's Webpack (or Browserify, Brunch or Parcel, etc.)." These are known as &lt;em&gt;module bundlers&lt;/em&gt;, which &lt;a href="https://github.com/ronami/minipack/blob/master/src/minipack.js" rel="noopener noreferrer"&gt;have been defined&lt;/a&gt; as packages of code that &lt;em&gt;"compile small pieces of code into something larger and more complex that can run in a web browser."&lt;/em&gt; In essence, this will package all of your stylesheets into one package, your TypeScript into another, all of your JavaScript files into yet another, etc.&lt;/p&gt;

&lt;p&gt;Module bundlers essentially figure out which bits of code depend on other bits of code (in other words, bundlers identify dependencies) and make sure code runs in the order it needs to. Bundlers ultimately create a &lt;strong&gt;dependency graph&lt;/strong&gt;, starting with a root (which has no dependencies) wherein the further down the graph a bundle of code falls, the more dependencies it has. Further-down code waits its turn for its dependencies to load first before it is loaded itself.&lt;/p&gt;

&lt;h1&gt;
  
  
  So, What Is Webpack?
&lt;/h1&gt;

&lt;p&gt;Even in simple applications, we write a lot of code in a lot of separate files. We use syntax like &lt;code&gt;@import&lt;/code&gt; and ES6. We use helpers like TypeScript to which allow us to write clearer code and catch errors sooner. Think of applications built with component-based libraries and frameworks like &lt;a href="https://reactjs.org" rel="noopener noreferrer"&gt;React&lt;/a&gt; where we import components or functions that depend on code written somewhere else in our application. The way our code is parsed, packaged, and executed in a way our browsers can understand can seem like nothing short of magic. But it isn't. &lt;strong&gt;It's a bundler called Webpack.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What makes Webpack stand out, though, is its ability to gather all dependencies including not just code, but assets such as images, stylesheets (including preprocessors like &lt;a href="https://sass-lang.com/guide" rel="noopener noreferrer"&gt;sass&lt;/a&gt;, &lt;a href="https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes.html" rel="noopener noreferrer"&gt;typescript&lt;/a&gt; and more and create the beforementioned dependency graph. And that's the key -- &lt;em&gt;the heart of Webpack is building the dependency graph.&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Building the Dependency Graph
&lt;/h1&gt;

&lt;p&gt;The dependency graph consists of a few key components. Here I'll focus on: Entry, Output, Loaders, and Plugins. One can run &lt;code&gt;yarn add webpack webpack-dev-server --save-dev&lt;/code&gt; and create a &lt;code&gt;webpack.config.js&lt;/code&gt; file to your app's root directory to get started. Don't forget to update your &lt;code&gt;package.json&lt;/code&gt; scripts:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;"start": "webpack-dev-server",&lt;br&gt;
    "build": "webpack"&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Establish an Entry Point
&lt;/h3&gt;

&lt;p&gt;The first thing Webpack does is establish an entry point. This is going to be the root of the dependency graph. We can do this by creating a variable containing an object which points to the source file. This is typically going to be &lt;code&gt;index.js&lt;/code&gt;.   You can create the object with a simple string, but for scalability and the possibility of a need for multiple entry points, let's use an object.&lt;/p&gt;

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

&lt;p&gt;Simple enough.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Establish an Output
&lt;/h3&gt;

&lt;p&gt;Once Webpack has finished bundling code and creating the dependency tree, it needs to be told where to put the finished product; This is our Output. Remember, you can name the filename parameter whatever you'd like. Typically this will be named something like &lt;code&gt;main.js&lt;/code&gt;.&lt;/p&gt;

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

&lt;p&gt;Interestingly enough, this is the base information the application needs to bundle code. With this, you can spin up your local server with &lt;code&gt;yarn start&lt;/code&gt; and Webpack will begin doing its thing.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Loaders: Bundling File Types Beyond JavaScript
&lt;/h3&gt;

&lt;p&gt;This is where Webpack starts getting so cool. &lt;/p&gt;

&lt;p&gt;Here's a screen grab of some imports from the &lt;code&gt;index.js&lt;/code&gt; file of a recent React project of mine called &lt;a href="https://github.com/crishanks/squad-frontend" rel="noopener noreferrer"&gt;Squad&lt;/a&gt;. &lt;/p&gt;

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

&lt;p&gt;It's something we do 100 times a day. But what's really happening behind the scenes? We're telling Webpack about the dependencies &lt;code&gt;index.js&lt;/code&gt; needs. For example, the line &lt;code&gt;import ./index.css&lt;/code&gt; tells Webpack to grab those styles. &lt;/p&gt;

&lt;p&gt;In our &lt;code&gt;webpack.config.js&lt;/code&gt; file, we add a module object like the example below (see &lt;a href="https://webpack.js.org/concepts/" rel="noopener noreferrer"&gt;webpack concepts, loaders&lt;/a&gt;).&lt;/p&gt;

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

&lt;p&gt;This object uses a &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions" rel="noopener noreferrer"&gt;Regular Expression&lt;/a&gt; to identify certain file types and then tells Webpack which loader to use before bundling. We're saying, "Webpack compiler when you find a path that ends with &lt;code&gt;.css&lt;/code&gt; in an import, transform/load them using the &lt;code&gt;css-loader&lt;/code&gt; and &lt;code&gt;style-loader&lt;/code&gt; when you bundle."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important note:&lt;/strong&gt; "Transforming" means parsing files (other than &lt;code&gt;.js&lt;/code&gt; files), and translating it into something else that Webpack and the browser can understand. &lt;/p&gt;

&lt;p&gt;A few examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Have you ever used &lt;code&gt;@import&lt;/code&gt; or syntax like &lt;code&gt;url('./icon.png')&lt;/code&gt; in your CSS files? Webpack's &lt;a href="https://webpack.js.org/loaders/css-loader/" rel="noopener noreferrer"&gt;css-loader&lt;/a&gt; is the reason why! It parses your &lt;code&gt;.css&lt;/code&gt; file and processes it. &lt;em&gt;That is why you can &lt;code&gt;import Icon from ./icon.png;&lt;/code&gt; and later &lt;code&gt;element.appendChild(Icon)&lt;/code&gt;!&lt;/em&gt; As stated in the &lt;a href="https://webpack.js.org/guides/asset-management/" rel="noopener noreferrer"&gt;Webpack Documentation&lt;/a&gt;, "The loader will recognize this is a local file, and replace the &lt;code&gt;./icon.png&lt;/code&gt; path with the final path to the image in your output directory. The html-loader handles &lt;code&gt;&amp;lt;img src="./icon.png" /&amp;gt;&lt;/code&gt; in the same manner." Isn't that so cool?&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.typescriptlang.org/" rel="noopener noreferrer"&gt;TypeScript&lt;/a&gt; is a superset of JavaScript that (among other things) allows JS devs to write more statically-typed code to catch errors while writing code. But Webpack doesn't speak TypeScript. The &lt;a href="https://github.com/TypeStrong/ts-loader" rel="noopener noreferrer"&gt;ts-loader&lt;/a&gt; parses TypeScript files and converts them into JavaScript Webpack can read. &lt;/li&gt;
&lt;li&gt;What about any &lt;a href="https://www.w3schools.com/js/js_es6.asp" rel="noopener noreferrer"&gt;ES6 syntax&lt;/a&gt; like classes, &lt;code&gt;let&lt;/code&gt; or &lt;code&gt;const&lt;/code&gt; variables, arrow functions, default values, destructuring, etc? &lt;a href="https://webpack.js.org/loaders/babel-loader/" rel="noopener noreferrer"&gt;babel-loader&lt;/a&gt; parses the code you wrote, identifies ES6 syntax, and loads and transpiles it to ES5 the browser understands.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can learn more about how loaders work under the hood, and even how to write your own loaders &lt;a href="https://webpack.js.org/contribute/writing-a-loader/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Plugins vs. Loaders
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Loaders&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Work on a file level&lt;/li&gt;
&lt;li&gt;Help create the bundle (during or before bundle generation)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Plugins&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Work on a system level&lt;/li&gt;
&lt;li&gt;Affect the created bundle (bundle or chunk level)&lt;/li&gt;
&lt;li&gt;Focus on optimization (&lt;a href="https://webpack.js.org/plugins/uglifyjs-webpack-plugin/#root" rel="noopener noreferrer"&gt;uglifyJS&lt;/a&gt; takes the &lt;code&gt;bundle.js&lt;/code&gt; and minimizes it to decrease file size)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The code implementation looks something like this:&lt;/p&gt;

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

&lt;p&gt;The following &lt;a href="https://stackoverflow.com/questions/37452402/webpack-loaders-vs-plugins-whats-the-difference" rel="noopener noreferrer"&gt;graphic&lt;/a&gt; may help visualize the difference as well:&lt;/p&gt;

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

&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;Webpack is the culprit behind much of the magical secret sauce that allows us to use syntax and libraries that makes code cleaner, clearer, more scalable. From imports to ES6, developing apps would be difficult without bundlers like Webpack. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://amzn.to/3S26cJa" rel="noopener noreferrer"&gt;Stay hydrated out there&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You know what's nice... &lt;a href="https://amzn.to/48GVlcT" rel="noopener noreferrer"&gt;A shiny new mechanical keyboard&lt;/a&gt;. Click that if you're interested in a good one. Or click this for &lt;a href="https://amzn.to/48lQTRe" rel="noopener noreferrer"&gt;another cool option&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Or perhaps you have a good one and you want to &lt;a href="https://amzn.to/3RMztpK" rel="noopener noreferrer"&gt;spruce it up a bit&lt;/a&gt; (you know I did). &lt;/p&gt;

</description>
      <category>webpack</category>
      <category>react</category>
      <category>interviewquestions</category>
      <category>javascript</category>
    </item>
    <item>
      <title>5 Steps to Use OAuth in Your App</title>
      <dc:creator>crishanks</dc:creator>
      <pubDate>Mon, 22 Apr 2019 16:06:25 +0000</pubDate>
      <link>https://dev.to/crishanks/5-steps-to-use-oauth-in-your-app-10hp</link>
      <guid>https://dev.to/crishanks/5-steps-to-use-oauth-in-your-app-10hp</guid>
      <description>&lt;p&gt;&lt;a href="https://amzn.to/3S26cJa" rel="noopener noreferrer"&gt;Stay hydrated out there&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  What is OAuth?
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fzhpq7exsjpvl8ypm9j29.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fzhpq7exsjpvl8ypm9j29.png" alt="tinder oauth example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;OAuth allows developers to create ultra curated content for specific users. It essentially allows users to grant your application limited permission to access specific, allowed features from another application like Spotify, Facebook Instagram and more. So, developers can work with features and content a user has already curated for his or herself. Searchmicroservices said it, "allows an end user's account information to be used by third-party services, such as Facebook, without exposing the user's password."&lt;/p&gt;

&lt;p&gt;You have seen this before. Dating app X would like to access your Instagram images. Music Streaming App Y would like to access your Facebook profile information. The list goes on.&lt;/p&gt;

&lt;p&gt;What makes OAuth so interesting, in my opinion, is its ability to curate personalized content which is much more likely to be valuable to a user. Why? With OAuth, the user opts in to let our app integrate certain features of another app they're already using, which we can assume is already providing them with a great deal of value.&lt;/p&gt;

&lt;h1&gt;
  
  
  Why Use OAuth?
&lt;/h1&gt;

&lt;p&gt;Imagine an app that helps users create a collage of pictures with friends, and automatically sends those pictures to them on their birthday. Wouldn't it be great if within our app the user had instant access to lists of images with tagged friends without having to open another app? Wouldn't it be cool if they didn't have to leave our app, sort through their posted pictures, manually find those tagged pictures and somehow import them for every friend on every birthday? In this hypothetical example, OAuth would be the portal allowing us to access users' photos and tags (something they already probably care about quite a bit) so we can do all that for them.&lt;/p&gt;

&lt;h1&gt;
  
  
  Using OAuth in Your App
&lt;/h1&gt;

&lt;p&gt;In this example, &lt;a href="https://dev.to/jasonbasuil"&gt;Jason Basuil&lt;/a&gt; and I connected to the Spotify public API to create MetroBeat, an app that gamifies playlist making by guessing the tempo (BPM) of songs served to them.&lt;/p&gt;

&lt;p&gt;There are 3 main players in OAuth: &lt;strong&gt;The User&lt;/strong&gt; (Stacy), &lt;strong&gt;the Consumer&lt;/strong&gt; (MetroBeat), and the &lt;strong&gt;Service Provider&lt;/strong&gt; (Spotify). &lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1 -- Get a Client ID and Client Secret
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fy96e5sie0c4lab4dc31h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fy96e5sie0c4lab4dc31h.png" alt="OAuth rails routes"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developer.spotify.com/dashboard/" rel="noopener noreferrer"&gt;Set up an account&lt;/a&gt; through Spotify Developer. The walkthrough is straightforward. They will give you a client ID and Client Secret. Make sure to never reveal these to anyone! You will need to include these in the initial request to Spotify in order to gain an access token and make requests (I'll explain in a sec). An initial request is made to Spotify with encoded versions of the Client ID and Secret. &lt;a href="https://medium.com/cedarcode/rails-5-2-credentials-9b3324851336" rel="noopener noreferrer"&gt;More details on how you can encode info in Rails&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2 --Verify the Consumer Identity to the Service Provider
&lt;/h3&gt;

&lt;p&gt;We set up MetroBeat to redirect to &lt;code&gt;get '/login', to: "auth#spotify_request"&lt;/code&gt; first thing. &lt;code&gt;#spotify_request&lt;/code&gt; makes that initial request to Spotify with the Client ID and Secret, verifying it's us, we know each other, and suggesting we should get together for brunch sometime. This redirects Stacy to a prompt that asks if she's cool to allow MetroBeat to access her Spotify account.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F9vodi6cakz1elg92jdw2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F9vodi6cakz1elg92jdw2.png" alt="Rails Auth Controller"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This code makes a request to Spotify and contains a redirect to our &lt;code&gt;get '/user', to: "users#create"&lt;/code&gt;. You'll also notice the body of this request specifies which permissions (scope) we need Stacy to agree to. You can add as many or as few as you need. Best practice requires we not to add any that aren't essential. When Stacy says it's all good, she gets created as a User and is assigned an access token.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3 -- Create the User and Assign Her an Access Token
&lt;/h3&gt;

&lt;p&gt;Since we made that initial request, we'll get some params back in Spotify's response. We'll need to grab the &lt;code&gt;params[:code]&lt;/code&gt; from that and include it in our request body, along with the client ID and Secret. We'll make a few more requests to Spotify for a Refresh token and an Access token.&lt;/p&gt;

&lt;p&gt;The Consumer (MetroBeat) needs to remind the Service Provider (Spotify) that it's us every time we make a request to Stacy's Spotify info via the Spotify API. This is done by with an &lt;strong&gt;access token&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fc8ipdbvd56u8nxszjtqd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fc8ipdbvd56u8nxszjtqd.png" alt="Refresh and Access Token"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When Stacy grants MetroBeat permission to access her Spotify account, we'll need to place this access token in every single request to a Spotify API endpoint.&lt;br&gt;
These &lt;code&gt;auth_params&lt;/code&gt; will get us back the access and refresh tokens we need to make those requests. The &lt;code&gt;user_params&lt;/code&gt; contain profile info from Stacy's Spotify account that we can use to authenticate her and get her logged in (like her username and profile image. We can't see her password).&lt;/p&gt;

&lt;p&gt;Then, we can create her as a User and make sure to associate those user and auth params to her in the database so we can use them later.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Ffg3w9y6o62bvup4u731j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Ffg3w9y6o62bvup4u731j.png" alt="rails create user"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Spotify's access tokens expire each hour, so we request a new one if Stacy's been playing for about 55 minutes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4 -- Request User info from Service Provider API
&lt;/h3&gt;

&lt;p&gt;Now we can make some requests and see the data come to life! We can create new playlists and add songs to them, see song analyses including song tempo, top tracks by country and so much more. &lt;/p&gt;

&lt;p&gt;In order to attach these requests to components and event listeners, we'll move to our ReactJS front end.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fh8ymf7ukfhw2js8471bw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fh8ymf7ukfhw2js8471bw.png" alt="React fetch user"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fdty9wiln0at37erlccag.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fdty9wiln0at37erlccag.png" alt="React fetch playlists"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fn56udsoxzahp1dfaueei.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fn56udsoxzahp1dfaueei.png" alt="React create playlist"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h6&gt;
  
  
  &lt;em&gt;users[1] was hard-coded in some areas initially, only for testing purposes&lt;/em&gt;
&lt;/h6&gt;

&lt;p&gt;We made other requests (to get song analysis info, for instance) but the sky's the limit. &lt;strong&gt;You'll need to pay close attention to the Service Provider's request formatting. The headers and body for each request type will need to match their requirements&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5 -- Implement Requests in React Components
&lt;/h3&gt;

&lt;p&gt;All that's left to do now is determine when and where to display the info we get back from our requests. Make sure you keep &lt;a href="https://eloquentjavascript.net/11_async.html" rel="noopener noreferrer"&gt;asynchronous programming&lt;/a&gt; in mind when planning your requests. You'll need that user info and access token back first before you can make other requests.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F4kt6e4sgltbpyaupy4vp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F4kt6e4sgltbpyaupy4vp.png" alt="react login button"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fokst81sfav8w582yv43n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fokst81sfav8w582yv43n.png" alt="react song card"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;OAuth is a super interesting and secure technology that can help you create convenient, curated, tailored content that actually matters to users. The User, Consumer and Service Provider work closely through the entire process, passing access tokens and other vital info back and forth to verify your app and allow you to access a User's info through the Service Provider. Using Rails and React are a great way to make these requests and create a user experience all your own.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://amzn.to/3S26cJa" rel="noopener noreferrer"&gt;Stay hydrated out there&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But you know what else is nice... &lt;a href="https://amzn.to/48GVlcT" rel="noopener noreferrer"&gt;A shiny new mechanical keyboard&lt;/a&gt;. &lt;br&gt;
Click that if you're interested in a good one. &lt;/p&gt;

&lt;p&gt;Or click this for &lt;a href="https://amzn.to/48lQTRe" rel="noopener noreferrer"&gt;another cool option&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Or perhaps you have a good one and you want to &lt;a href="https://amzn.to/3RMztpK" rel="noopener noreferrer"&gt;spruce it up a bit&lt;/a&gt; (you know I did). &lt;/p&gt;

</description>
      <category>oauth</category>
      <category>rails</category>
      <category>react</category>
      <category>spotify</category>
    </item>
    <item>
      <title>How to Write A Programming Language</title>
      <dc:creator>crishanks</dc:creator>
      <pubDate>Mon, 08 Apr 2019 17:01:11 +0000</pubDate>
      <link>https://dev.to/crishanks/how-to-write-a-programming-language-3e6f</link>
      <guid>https://dev.to/crishanks/how-to-write-a-programming-language-3e6f</guid>
      <description>&lt;p&gt;&lt;a href="https://amzn.to/3S26cJa" rel="noopener noreferrer"&gt;Stay hydrated out there&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Under the Hood
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiwg4kw68pc5fkc71l0yh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiwg4kw68pc5fkc71l0yh.png" alt="Lord of the Rings"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Have you ever found yourself writing code and wondering exactly what is going on under the hood? How does programming &lt;em&gt;really&lt;/em&gt; work? In an attempt to peel back at least one of the curtains, &lt;a href="https://dev.to/jessicabetts"&gt;Jessica Betts&lt;/a&gt; and I created our own Esoteric Programming Language based on Lord of the Rings lore called My_Precious. There are many different approaches to creating a programming language.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is an Esoteric Programming Language?
&lt;/h1&gt;

&lt;p&gt;Esolangs.org defines an Esoteric Programming Language as, “A computer programming language designed to experiment with weird ideas, to be hard to program in, or as a joke, rather than for practical use."&lt;/p&gt;

&lt;p&gt;Examples include Kaiser Ruby and $:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4d3uozevdsfr2ucxv2qr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4d3uozevdsfr2ucxv2qr.png" alt="Kaiser Ruby Esoteric Language Example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2ouvrlj8cawor3yghlrf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2ouvrlj8cawor3yghlrf.png" alt="$ Esoteric Language Example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Esoteric programming languages are essentially a new, creative way of writing code that is designed to be interesting rather than intuitive, efficient or especially functional.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;a href="https://rubygems.org/gems/my_precious" rel="noopener noreferrer"&gt;My_Precious&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;My_Precious is a gem that uses the English language and Lord of the Rings keywords written in what we defined as a .precious file which is then translated into actual usable Ruby code.&lt;/p&gt;

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

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

&lt;p&gt;My_Precious is a gem in which users are able to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Generate a .precious file using LOTR lore keywords&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Translate code written in the .precious file and output it to a .rb file&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete files&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

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

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

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

&lt;p&gt;My_Precious essentially works like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The User creates a test file&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The test file is passed into a Run file&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Run file opens the test file and passes it to the Parser&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Parser combes through each line of code and translates it to Ruby&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Parser returns translated code to the Run file&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Run file writes the code to the Output file&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  The Planning Phase
&lt;/h1&gt;

&lt;p&gt;When starting out, it's important to &lt;em&gt;find something you're passionate about&lt;/em&gt;. Why do you want to create an Esoteric Programming Language? Do you want to poke fun at a specific aspect of coding? Do you think there's a better way to do something? Do you want to challenge yourself and create something technical? We wanted to make something fun that would reinforce current Ruby knowledge and expand our understanding of how programming languages really work.&lt;/p&gt;

&lt;p&gt;Next, &lt;em&gt;choose a domain whose size fits your purpose&lt;/em&gt;. My_Precious needed to be large enough to work with English but niche enough to have well-known and memorable keywords. (Some minimalistic language have as few as 8 characters). So, we chose the Lord of the Rings.&lt;/p&gt;

&lt;p&gt;Lastly, &lt;em&gt;decide the scope of your project&lt;/em&gt;. Are you interpreting the language or translating it? We chose to translate to Ruby. It was more familiar and slightly less complex.&lt;/p&gt;

&lt;h1&gt;
  
  
  Creating the Language
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Parser
&lt;/h2&gt;

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

&lt;p&gt;The Parser is the heart of My_Precious; the most important file. In the Parser, we define keywords or characters that will be mapped to programming functionality. For example, &lt;code&gt;Precious&lt;/code&gt; is the keyword for &lt;code&gt;true&lt;/code&gt;.  &lt;code&gt;You shall not pass&lt;/code&gt; is the keyword for &lt;code&gt;end&lt;/code&gt; used in loops, conditionals, function declarations, etc. &lt;/p&gt;

&lt;p&gt;The Parser parses through each line of written code, holds on to established keywords, and outputs them to a .rb file. In essence, it's our translator.&lt;/p&gt;

&lt;h2&gt;
  
  
  Run File
&lt;/h2&gt;

&lt;p&gt;To separate functionality, we created a Run file. Its job is to check for the .precious extension, open a .precious file, pass the file to the Parser, grab the returned translation, and write the translation to a .rb file. The Parser file should only have to worry about parsing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test File
&lt;/h2&gt;

&lt;p&gt;The Test file is a .precious file in which to write My_Precious code. It's used to make sure the Parser is correctly translating your code into Ruby. It tests each keyword defined in the Parser.&lt;/p&gt;

&lt;h2&gt;
  
  
  Output File
&lt;/h2&gt;

&lt;p&gt;This is a .rb file to which the translation will be written. You compare the results here against the inputs in the Test file.&lt;/p&gt;

&lt;h1&gt;
  
  
  Publish Your Language
&lt;/h1&gt;

&lt;p&gt;Ruby Gems are open source and widely used. We chose to make My_Precious a downloadable gem so anyone could contribute to it, and more easily download and use it right away.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Interface
&lt;/h1&gt;

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

&lt;p&gt;How do you want users to interact with your language? We chose to use a Command Line Interface (CLI). CLIs are great tools which allow users to type commands into the terminal. A CLI makes My_Precious more intuitive and user-friendly, allows flexibility (users can name their own input and output files), and made it easy for us to implement clean error handling including output error messages and instructions.&lt;/p&gt;

&lt;h1&gt;
  
  
  Have Fun, &lt;em&gt;Precious&lt;/em&gt;!
&lt;/h1&gt;

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

&lt;p&gt;Creating an Esoteric Programming Language can be daunting at times. Remember to choose a domain that you can sincerely get behind, something you're passionate about. Go one operation at a time and celebrate those wins.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://amzn.to/3S26cJa" rel="noopener noreferrer"&gt;Stay hydrated out there&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Be sure to download &lt;a href="https://rubygems.org/gems/my_precious" rel="noopener noreferrer"&gt;My_Precious&lt;/a&gt; and give it a try.&lt;/p&gt;

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

&lt;p&gt;Check out the &lt;a href="https://github.com/jessicabettsftw/my_precious" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt; as well!&lt;/p&gt;

&lt;h1&gt;
  
  
  Making this was really fun
&lt;/h1&gt;

&lt;p&gt;But you know what else is fun... &lt;a href="https://amzn.to/48GVlcT" rel="noopener noreferrer"&gt;A shiny new mechanical keyboard&lt;/a&gt;. Click that if you're interested in a good one. Or click this for &lt;a href="https://amzn.to/48lQTRe" rel="noopener noreferrer"&gt;another cool option&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Or perhaps you have a good one and you want to &lt;a href="https://amzn.to/3RMztpK" rel="noopener noreferrer"&gt;spruce it up a bit&lt;/a&gt; (you know I did). &lt;/p&gt;

</description>
      <category>ruby</category>
      <category>esoteric</category>
      <category>gem</category>
      <category>createalanguage</category>
    </item>
    <item>
      <title>Classical vs. Prototypal Inheritance</title>
      <dc:creator>crishanks</dc:creator>
      <pubDate>Mon, 25 Mar 2019 20:18:58 +0000</pubDate>
      <link>https://dev.to/crishanks/classical-vs-prototypal-inheritance-2o5a</link>
      <guid>https://dev.to/crishanks/classical-vs-prototypal-inheritance-2o5a</guid>
      <description>&lt;p&gt;&lt;a href="https://amzn.to/3S26cJa" rel="noopener noreferrer"&gt;Stay hydrated out there&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm4lph4sisdm33367w4x0.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm4lph4sisdm33367w4x0.jpg" alt="Shoe Class Example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Object Orientation
&lt;/h1&gt;

&lt;p&gt;Objects are abstractions (or described representations) of physical things with which we interact in the real world. Some real-world things are much more alike than others. A boot, for example, has much more in common with a slipper than it does with a tree. It wouldn't be out of the ordinary to refer to either as a Shoe. Without hardly knowing it, we make these mental organizations all the time.&lt;/p&gt;

&lt;p&gt;The purpose of Object-Oriented Programming is to mimic these real-world categories as closely as possible. As important as it is to recognize the similarities between objects, we must also realize their differences. Let's take our Shoe example a step farther.&lt;/p&gt;

&lt;p&gt;Let's discuss what properties and behaviors shoes have in common: a size, a color, and a material. We can change a shoe's color or a shoe can wear down.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff2jumz28igr6jwk742js.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff2jumz28igr6jwk742js.png" alt="Shoe Class Example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Just as we do in reality we can categorize all Shoes by what they have in common, and create an endless amount of individual Shoe copies that inherit all the characteristics that all shoes have, but with their own unique characteristics as well. &lt;/p&gt;

&lt;p&gt;In this case Shoe is known as a &lt;strong&gt;Generalization&lt;/strong&gt;; in other words the more general, less specific description of a real-world item.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiiyuykzqe6nujo6nz94x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiiyuykzqe6nujo6nz94x.png" alt="Shoe Class Example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Classical Inheritance
&lt;/h1&gt;

&lt;p&gt;In Classical Inheritance, Objects are still abstractions of real world 'things', but we can only refer to Objects through &lt;em&gt;Classes&lt;/em&gt;. Classes are a &lt;em&gt;Generalization of an object&lt;/em&gt;. In other words, Classes are an abstraction of an object of a real world thing. (Classes, then, are an abstraction of an abstraction of a real-world thing). Since a Class is yet another reference to (or abstraction of) its predecessor, each descendant child Class increases the level of abstraction, thus increasing the level of generalization.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3fj3b4sjwb44mbaxaf60.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3fj3b4sjwb44mbaxaf60.png" alt="Shoe Class Example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Prototypal Inheritance
&lt;/h1&gt;

&lt;p&gt;As opposed to Classical Inheritance, Prototypal Inheritance does not deal with increasing layers of abstraction. An Object is either an abstraction of a real-world thing, same as before, &lt;em&gt;or&lt;/em&gt; is a direct copy of another Object (in other words, a &lt;strong&gt;Prototype&lt;/strong&gt;). Objects can be created from thin air, or they can be created from other objects:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuknk79bph6khm1s9834r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuknk79bph6khm1s9834r.png" alt="Shoe Class Example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is important! It means that Generalizations (like the overarching Shoe concept) are just other Objects. With Classical Inheritance, Generalizations are abstractions of abstractions of abstractions... all the way down to the most recent descendant. &lt;/p&gt;

&lt;p&gt;The abstraction level here is never deeper than 1; &lt;em&gt;The only abstraction that occurs with Prototypal Inheritance is the abstraction away from real-world things&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;Prototypal Inheritance includes some &lt;a href="http://aaditmshah.github.io/why-prototypal-inheritance-matters/" rel="noopener noreferrer"&gt;key advantages over Classical Inheritance:&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzat8rb7jrawhq7w785gx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzat8rb7jrawhq7w785gx.png" alt="Shoe Class Example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  The Mechanics of Prototypal Inheritance
&lt;/h1&gt;

&lt;h2&gt;
  
  
  The Constructor
&lt;/h2&gt;

&lt;p&gt;In JavaScript, all Objects have a Constructor. And in JavaScript classes, we use the Constructor function to create and instantiate new Objects within a class. Each class can only have one constructor. In the example above, we instantiate each Shoe Object with characteristics that all Shoe Objects share (all Shoes have a size, color, and material). &lt;/p&gt;

&lt;p&gt;You can take a more in-depth look into Constructors (how to view an Object's class, how to change a class, etc.) on &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor" rel="noopener noreferrer"&gt;MDN&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  New Operator
&lt;/h2&gt;

&lt;p&gt;According to &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new" rel="noopener noreferrer"&gt;MDN docs&lt;/a&gt; the New operator performs the following actions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Creates a blank, plain JavaScript object;&lt;/li&gt;
&lt;li&gt;Links (sets the constructor of) this object to another object;&lt;/li&gt;
&lt;li&gt;Passes the newly created object from Step 1 as the this context;&lt;/li&gt;
&lt;li&gt;Returns this if the function doesn't return its own object.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In order to instantiate a Prototype of a JS class, we use the keyword &lt;code&gt;new&lt;/code&gt;. In the example above, we define the name of the new Object &lt;code&gt;let slipper&lt;/code&gt; and create it with &lt;code&gt;new&lt;/code&gt;. We then pass in the parameters defined in the constructor of the Shoe class. These new Object instantiations are known as &lt;em&gt;types&lt;/em&gt;. You can then access any of the Object properties by calling, for example, &lt;code&gt;slipper.size&lt;/code&gt; or &lt;code&gt;slipper.color&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm2ayxrmhoimj2pkbi6e5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm2ayxrmhoimj2pkbi6e5.png" alt="Shoe Class Example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;The differences between Classical and Prototypical Inheritance can get pretty complex quickly. If you wish to study these concepts on a much deeper level, you might try &lt;a href="http://aaditmshah.github.io/why-prototypal-inheritance-matters/" rel="noopener noreferrer"&gt;"Why Prototypical Inheritance Matters"&lt;/a&gt; by Aadit M Shah.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://amzn.to/3S26cJa" rel="noopener noreferrer"&gt;Stay hydrated out there&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  I hope this was helpful
&lt;/h1&gt;

&lt;p&gt;But you know what else is helpful... &lt;a href="https://amzn.to/48GVlcT" rel="noopener noreferrer"&gt;A shiny new mechanical keyboard&lt;/a&gt;. &lt;br&gt;
Click that if you're interested in a good one. &lt;/p&gt;

&lt;p&gt;Or click this for &lt;a href="https://amzn.to/48lQTRe" rel="noopener noreferrer"&gt;another cool option&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Or perhaps you have a good one and you want to &lt;a href="https://amzn.to/3RMztpK" rel="noopener noreferrer"&gt;spruce it up a bit&lt;/a&gt; (you know I did). &lt;/p&gt;

</description>
      <category>objectorientation</category>
      <category>javascript</category>
      <category>classes</category>
      <category>beginners</category>
    </item>
    <item>
      <title>HTML &amp; CSS - Find Your Inner Dev With Divs</title>
      <dc:creator>crishanks</dc:creator>
      <pubDate>Sun, 10 Mar 2019 03:20:19 +0000</pubDate>
      <link>https://dev.to/crishanks/css---finding-your-inner-dev-with-divs-1bd7</link>
      <guid>https://dev.to/crishanks/css---finding-your-inner-dev-with-divs-1bd7</guid>
      <description>&lt;h1&gt;
  
  
  Channeling Your Inner Dev
&lt;/h1&gt;

&lt;p&gt;"If you like CSS, you're probably a Front End Dev." It's a phrase that's been floating around campus a lot since delving into Full Stack frameworks like Ruby on Rails.&lt;/p&gt;

&lt;p&gt;As I experiment with new technologies, I discover more about the type of Developer I want to be. It's doubtless one of the most exhilarating and daunting aspects of being a student of Tech. As a curious Developer who deeply cares about user experience, I decided to "div" into a little CSS myself.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Project
&lt;/h2&gt;

&lt;p&gt;Turns out, you can whip up a pretty nifty static site with some vanilla HTML and CSS. The following example was made with a single index.html and style.css file. I thought it might be fun to make a shout out to an old site some of you may remember:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/SxMzCLEEe1E"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Set up an &lt;a href="https://www.w3schools.com/hTml/html_basic.asp" rel="noopener noreferrer"&gt;index.html file&lt;/a&gt; like you would with any other project.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a style.css file in the same directory. In order to link the CSS stylesheet, you'll need to link to it via link tag in the header section your index.html file (line 7 below).&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;As with all great amigos, your HTML will now listen and respond to the styles in your CSS file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Organize HTML with Divs
&lt;/h2&gt;

&lt;p&gt;In index.html, you'll be essentially telling your browser what info you want to be displayed. Sometimes web pages display a lot of information, and if we don't keep it organized it will be nearly impossible for your CSS to accurately identify where each HTML element should live, what it should look like and even what it should do.&lt;/p&gt;

&lt;p&gt;Enter the div tag. Divs look like this: &lt;code&gt;&amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;&lt;/code&gt;. They're essentially containers for sections of HTML code you want to live together and behave similarly. We often nest divs, so child divs (divs inside other divs) can inherit qualities from outer parent divs but also be assigned unique qualities.&lt;/p&gt;

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

&lt;p&gt;Check out lines 13-15. I have a lot of unique sidebar content, but I wanted all the elements in the sidebar to be contained in the same area. So, I nested the divs together.&lt;/p&gt;

&lt;h2&gt;
  
  
  Selectors &amp;amp; Specificity
&lt;/h2&gt;

&lt;p&gt;Inside those div tags above, you'll notice I've added &lt;code&gt;class='sidebar'&lt;/code&gt; and &lt;code&gt;id='sidebar_content'&lt;/code&gt;. The style.css file will have corresponding syntax, &lt;code&gt;.sidebar&lt;/code&gt; and &lt;code&gt;#sidebar-content&lt;/code&gt;. These are knows as selectors. They're the way your CSS tells your HTML which pieces of information to style.&lt;/p&gt;

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

&lt;p&gt;Selecters allow us to get nit-picky. If I want to select all the images in the sidebar, I can use &lt;code&gt;.sidebar img&lt;/code&gt;. Pretty cool. But what if I want to select just a specific element (image, paragraph, list item, etc.) in the sidebar section? Selectors follow a rule of Specificity, meaning certain types of tags carry a higher weight than others. Chained together Selectors combine scores and the highest Specificity score wins.&lt;/p&gt;

&lt;p&gt;Specificity is calculated like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Elements (&lt;code&gt;&amp;lt;h1&amp;gt;, &amp;lt;p&amp;gt;, &amp;lt;img&amp;gt;&lt;/code&gt;, etc.):  1 point&lt;/li&gt;
&lt;li&gt;Classes (signified with a &lt;code&gt;.&lt;/code&gt;):  10 points&lt;/li&gt;
&lt;li&gt;IDs (signified with a &lt;code&gt;#&lt;/code&gt;):  100 points&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note that the universal &lt;code&gt;*&lt;/code&gt; selects everything regardless of score. We try to use it rarely.&lt;/p&gt;

&lt;p&gt;Let's take a look at an example:&lt;/p&gt;

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

&lt;p&gt;Can you calculate the Specificities? Since the &lt;code&gt;.hero-text&lt;/code&gt; Class selector is worth 10 points and the &lt;code&gt;h3&lt;/code&gt; Element selector is worth 1, the &lt;code&gt;.hero-text h3&lt;/code&gt; selector (11 points) gets specific styling unique from anything else in the &lt;code&gt;.hero-text&lt;/code&gt; div. For additional practice, &lt;a href="https://www.w3schools.com/css/css_specificity.asp" rel="noopener noreferrer"&gt;W3 Schools&lt;/a&gt; has some great info.&lt;/p&gt;

&lt;h2&gt;
  
  
  And I Don't Even Need JS?
&lt;/h2&gt;

&lt;p&gt;CSS Selectors allow us to get pretty tricky. We can use Selectors called &lt;a href="https://www.w3schools.com/css/css_pseudo_classes.asp" rel="noopener noreferrer"&gt;Pseudo Classes&lt;/a&gt; that tell our HTML when to make an element look a certain way. We can specify actions like &lt;code&gt;:visited&lt;/code&gt;, &lt;code&gt;:hover&lt;/code&gt;, &lt;code&gt;:active&lt;/code&gt;, &lt;code&gt;:lang&lt;/code&gt; and more. Take the hovers and clicks we saw on the buttons and links. By using the following selectors, our CSS is able to tell our HTML to change color or even background on hover and on click.&lt;/p&gt;

&lt;p&gt;Using Pseudo Classes, I'm even able to get the images in the blog content to expand when my mouse hovers over it.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;For anyone wondering whether or not Front End Web Development is their cup of tea, I suggest taking a day to dive into a personal CSS project. &lt;/p&gt;

&lt;p&gt;Web design is creative, artistic and fun. It can also be very tricky and frustrating. After struggling with CSS on my first project, I gained a huge appreciation for great-looking web apps. I feel a sense of responsibility to make the internet look clean and interesting, and operate smoothly. I think it's likely you will too.&lt;/p&gt;

</description>
      <category>css</category>
      <category>html</category>
      <category>webdesign</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Prevent SQL Injections</title>
      <dc:creator>crishanks</dc:creator>
      <pubDate>Wed, 27 Feb 2019 00:13:54 +0000</pubDate>
      <link>https://dev.to/crishanks/prevent-sql-injections-c6o</link>
      <guid>https://dev.to/crishanks/prevent-sql-injections-c6o</guid>
      <description>&lt;p&gt;&lt;a href="https://amzn.to/3S26cJa"&gt;Stay hydrated out there&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Protect Your Data from Malicious User Input&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IS8Q6tP8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://crishanks.files.wordpress.com/2019/02/robotsports-1.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IS8Q6tP8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://crishanks.files.wordpress.com/2019/02/robotsports-1.gif" alt="robotsports.gif" width="500" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's the year 3019 and, naturally, all athletes are robots. You've programmed each robo-player to receive instructions from a coach in order to carry out carefully choreographed plays.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One example might look like this:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Player (&lt;span&gt;coach input&lt;/span&gt;) do (&lt;span&gt;coach input&lt;/span&gt;). Player (&lt;span&gt;coach input&lt;/span&gt;) then do (&lt;span&gt;coach input&lt;/span&gt;).&lt;/p&gt;

&lt;p&gt;For example: Player &lt;strong&gt;&lt;span&gt;12&lt;/span&gt;&lt;/strong&gt;,  &lt;strong&gt;&lt;span&gt;pass &lt;em&gt;&lt;/em&gt;&lt;/span&gt; to Player _&lt;span&gt;6&lt;/span&gt;&lt;/strong&gt;. Player &lt;strong&gt;&lt;span&gt;6&lt;/span&gt;&lt;/strong&gt;, __&lt;span&gt;run &lt;/span&gt;&lt;span&gt;pattern 4 _&lt;/span&gt;.&lt;/p&gt;

&lt;p&gt;But bad news. Coach is upset because his players malfunctioned and didn't pour yellow sports drink all over him after last week's big win! Disgruntled, he inputs the following instructions into your program:&lt;/p&gt;

&lt;p&gt;Player &lt;span&gt;&lt;strong&gt;8&lt;/strong&gt;,&lt;/span&gt; &lt;strong&gt;&lt;span&gt;turn around and dropkick the ball into the rafters&lt;/span&gt;&lt;/strong&gt;. Players &lt;strong&gt;&lt;span&gt;7, 3, 4, and 12&lt;/span&gt;&lt;/strong&gt;, &lt;strong&gt;g&lt;span&gt;o to the locker room and think about what you've done&lt;/span&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Since the robo-players weren't protected against these inputs, they carried them out! Now you and the entire coaching staff have been fired and no one gets covered with any colored sports drink.&lt;/p&gt;

&lt;h3&gt;What is a SQL Injection?&lt;/h3&gt;

&lt;p&gt;SQL (structured query language) is a special programming language used to communicate with a database and tell it what to do. SQL can be used to tell a database to Create, Read, Update and Destroy data (CRUD). When a user enters an SQL command into input fields (such as typical login info like username, password, email, etc.), it will be read by your program and carry out exactly what you've programmed it to do. If left unprotected, your program interacts with that pernicious input and mistakenly allows it to send unintended commands to the database.&lt;/p&gt;

&lt;h3&gt;Those Pesky Hackers&lt;/h3&gt;

&lt;p&gt;Let's look at an example. Coach is not pleased about his recent career status, and depression has made it nearly impossible for him to keep it 100 on his Friends fanblog. Three weeks and 15 pounds later, he looks to the National Robo Sports League (NRSL) for revenge.&lt;/p&gt;

&lt;p&gt;Coach knows the NRSL website login page has a simple input field for a User Id. The code is set up to take in that string and assign it to a variable, which will then be used to run a simple SQL query. It might look something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0ZxvJDb8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://crishanks.files.wordpress.com/2019/02/screen-shot-2019-02-23-at-12.33.14-pm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0ZxvJDb8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://crishanks.files.wordpress.com/2019/02/screen-shot-2019-02-23-at-12.33.14-pm.png" alt="Screen Shot 2019-02-23 at 12.33.14 PM.png" width="800" height="314"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The user input string is 105 OR 1=1, which will always be true. Guess what? Coach just got all data in all columns for every user! That could mean passwords, credit card info, and other private information.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--akMCp1P2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://crishanks.files.wordpress.com/2019/02/rich-2.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--akMCp1P2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://crishanks.files.wordpress.com/2019/02/rich-2.gif" alt="rich.gif" width="500" height="282"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's take a look at another example.&lt;/p&gt;

&lt;p&gt;Until the feds show up, Coach is ballin'. But his lust for revenge is as volatile as a Rachel - Ross romance. He logs back on the the NRSL website and checks out that user input field. This time his input looks something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5kaDBk8E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://crishanks.files.wordpress.com/2019/02/screen-shot-2019-02-23-at-1.03.08-pm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5kaDBk8E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://crishanks.files.wordpress.com/2019/02/screen-shot-2019-02-23-at-1.03.08-pm.png" alt="Screen Shot 2019-02-23 at 1.03.08 PM.png" width="800" height="376"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since they weren't protected against his SQL injection, no one gets to be a coach in the NRSL!&lt;/p&gt;

&lt;h3&gt;How Bad Could it Be?&lt;/h3&gt;

&lt;p&gt;Despite its discovery over 15 years ago, SQL injections are still one of the most prevalent threats to websites and apps. Recently, Motherboard reported &lt;a href="https://motherboard.vice.com/en_us/article/vba5nb/fornite-login-hack-epic-games-website" rel="noopener noreferrer"&gt;cybercriminals were able to use SQL Injections to log in to Fortnite, one of the most popular video games of our time, and take over any player's account.&lt;/a&gt; Rogue Media Labs discovered &lt;a href="https://roguemedialabs.com/2018/12/20/atlanta-international-airport-hacked-617-57-kb-of-data-including-700-passports-leaked-online/" rel="noopener noreferrer"&gt;hackers gained access to hundreds of customer passports&lt;/a&gt;. These are only a few recent examples. Unprotected, anyone who tries to input data into your program can (intentionally or not) bypass protected fields such as passwords to access private info (credit card numbers, email addresses, etc.), change data as it exists in the database, drop tables or even gain control over your entire system. As we learned in our future sports analogy, SQL injections can ask our programs to carry out embarrassing and harmful commands with serious consequences.&lt;/p&gt;

&lt;h3&gt;&lt;strong&gt;Protect Against SQL Injections&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;There are &lt;a href="https://www.w3schools.com/sql/sql_injection.asp"&gt;a few ways we can protect ourselves&lt;/a&gt; against vengeful coaches and other hackers using SQL injections.&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;Using SQL Parameters allow us to use a '?' and pass in a parameter instead of using string concatenation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oY__3aS_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://crishanks.files.wordpress.com/2019/02/screen-shot-2019-02-23-at-1.10.10-pm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oY__3aS_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://crishanks.files.wordpress.com/2019/02/screen-shot-2019-02-23-at-1.10.10-pm.png" alt="Screen Shot 2019-02-23 at 1.10.10 PM.png" width="800" height="78"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h6&gt;
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HvqPGome--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://crishanks.files.wordpress.com/2019/02/screen-shot-2019-02-23-at-1.12.33-pm.png" alt="Screen Shot 2019-02-23 at 1.12.33 PM.png" width="800" height="70"&gt;&lt;a href="https://www.hacksplaining.com/prevention/sql-injection"&gt;Screenshots from hacksplaining.com&lt;/a&gt;
&lt;/h6&gt;

&lt;ul&gt;
    &lt;li&gt;Provided ActiveRecord methods are pre-built with protected code. Use methods like 'find_or_create_by' instead of SQL queries like 'where'.&lt;/li&gt;
    &lt;li&gt;Sanitize your strings. In other words, inputs like '1=1' for a username seem pretty suspicious... We can run logic that checks and rejects weird inputs. For example, &lt;a href="https://medium.com/factory-mind/regex-tutorial-a-simple-cheatsheet-by-examples-649dc1c3f285"&gt;use a regex to match&lt;/a&gt; for email inputs. Make sure the alphanumerical field inputs don't contain any symbols. Take out any whitespace. There are even cool &lt;a href="https://apidock.com/rails/ActionView/Helpers/SanitizeHelper/sanitize"&gt;gems like sanitize&lt;/a&gt; that can help.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;SQL injections are not going away any time soon. And neither are disgruntled coaches. Be smart, use protection.&lt;/p&gt;

&lt;p&gt; &lt;strong&gt;I hope this was helpful&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;But you know what else is helpful... &lt;a href="https://amzn.to/48GVlcT"&gt;A shiny new mechanical keyboard&lt;/a&gt;. &lt;br&gt;
Click that if you're interested in a good one. &lt;/p&gt;

&lt;p&gt;Or click this for &lt;a href="https://amzn.to/48lQTRe"&gt;another cool option&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Or perhaps you have a good one and you want to &lt;a href="https://amzn.to/3RMztpK"&gt;spruce it up a bit&lt;/a&gt; (you know I did). &lt;/p&gt;

</description>
      <category>sql</category>
      <category>datasecurity</category>
      <category>ruby</category>
      <category>activerecord</category>
    </item>
  </channel>
</rss>
