<?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: A.J. Romaniello</title>
    <description>The latest articles on DEV Community by A.J. Romaniello (@ajrom).</description>
    <link>https://dev.to/ajrom</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%2F569375%2Fef792d43-539b-4dd4-8d8d-f9e81284a33c.jpeg</url>
      <title>DEV Community: A.J. Romaniello</title>
      <link>https://dev.to/ajrom</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ajrom"/>
    <language>en</language>
    <item>
      <title>Release Please for Ruby | GitHub Actions</title>
      <dc:creator>A.J. Romaniello</dc:creator>
      <pubDate>Tue, 14 Dec 2021 08:32:53 +0000</pubDate>
      <link>https://dev.to/ajrom/release-please-ci-deployment-for-ruby-gems-4md6</link>
      <guid>https://dev.to/ajrom/release-please-ci-deployment-for-ruby-gems-4md6</guid>
      <description>&lt;h2&gt;
  
  
  release-please
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/googleapis/release-please"&gt;release-please&lt;/a&gt; is a project maintained by the &lt;a href="https://github.com/googleapis"&gt;GoogleApi's team&lt;/a&gt; which automatically keeps a coherent changelog of your application as it grows as well as deploying your project with a new version tag.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Use &lt;code&gt;release-please&lt;/code&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Automatically generating CHANGELOGs.&lt;/li&gt;
&lt;li&gt;Automatically determining a semantic version bump (based on the types of commits landed).&lt;/li&gt;
&lt;li&gt;Communicating the nature of changes to teammates, the public, and other stakeholders.&lt;/li&gt;
&lt;li&gt;Triggering build and publish processes.&lt;/li&gt;
&lt;li&gt;Making it easier for people to contribute to your projects, by allowing them to explore a more structured commit history.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Source: &lt;a href="https://www.conventionalcommits.org/en/v1.0.0/#why-use-conventional-commits"&gt;conventionalcommits.org&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This project not only keeps your changelog up to date by parsing your git commit history, but ensures that updates follow a common commit message convention.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;release-please&lt;/strong&gt; abides to the &lt;a href="https://www.conventionalcommits.org/en/v1.0.0/"&gt;Conventional Commit Messages&lt;/a&gt;, which allows commits to be read by human and machine in a cohesive fashion.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conventional Commits
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Source: &lt;a href="https://www.conventionalcommits.org/en/v1.0.0/#specification"&gt;conventionalcommits.org&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This aims to create a convention for committing to repositories, some of the most important keywords are:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;fix:&lt;/code&gt;
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;A commit of the type fix patches a bug in your codebase (this correlates with PATCH in Semantic Versioning).&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"fix(&amp;lt;category&amp;gt;): my new fix"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;feat:&lt;/code&gt;
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;A commit of the type feat introduces a new feature to the codebase (this correlates with MINOR in Semantic Versioning).&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"feat(&amp;lt;category&amp;gt;): my new feature"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  BREAKING CHANGE
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;A commit that has a footer BREAKING CHANGE:, or appends a ! after the type/scope, introduces a breaking API change (correlating with MAJOR in Semantic Versioning). A BREAKING CHANGE can be part of commits of any type.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Breaking Fix&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"fix!(&amp;lt;category&amp;gt;): my breaking fix"&lt;/span&gt;

&lt;span class="c"&gt;# Breaking Feat&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"feat!(&amp;lt;category&amp;gt;): my breaking feature"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Extra
&lt;/h3&gt;

&lt;p&gt;Types other than &lt;code&gt;fix:&lt;/code&gt; and &lt;code&gt;feat:&lt;/code&gt; are allowed, for example (based on the the &lt;a href="https://github.com/conventional-changelog/commitlint/tree/master/%40commitlint/config-conventional"&gt;Angular Convention&lt;/a&gt;) recommends:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;build:&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;chore:&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ci:&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;docs:&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;style:&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;refactor:&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;perf:&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;test:&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;and &lt;a href="https://github.com/conventional-changelog/commitlint/tree/master/%40commitlint"&gt;more&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  GitHub Action Setup
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Creating the Workflow
&lt;/h3&gt;

&lt;p&gt;To get started using &lt;code&gt;release-please&lt;/code&gt;, we must create a new &lt;code&gt;.yml&lt;/code&gt; file in our &lt;code&gt;.github/workflows&lt;/code&gt; directory of our repository.&lt;/p&gt;

&lt;p&gt;We can call this file &lt;code&gt;release.yml&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;After creating our file, we can go ahead and name our new workflow.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# /.github/workflows/release.yml&lt;/span&gt;

&lt;span class="c1"&gt;# The name of the Workflow.&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;release-please&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Choosing When to Run the Action
&lt;/h3&gt;

&lt;p&gt;Since this project handles version releases and changelog updates, we only want this to run when pushes are made to our main or 'production' branch.&lt;/p&gt;

&lt;p&gt;This ensures that this does not run on subsequent commits/pull requests to our repository.&lt;/p&gt;

&lt;p&gt;The setup would look something like:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# /.github/workflows/release.yml&lt;/span&gt;

&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;release-please&lt;/span&gt;

&lt;span class="c1"&gt;# When to run this action.&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# Run on push to our 'main' branch.&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;main&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Setting Up &lt;code&gt;release-please-action&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Now that we have our workflow set up to run on pushes to our main branch, we can configure &lt;strong&gt;release-please&lt;/strong&gt; to our liking.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;release-please&lt;/strong&gt; requires a &lt;a href="https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token"&gt;personal access token&lt;/a&gt; to be able to create pull-requests and modify the changelog in your repository.&lt;/p&gt;

&lt;p&gt;Once you have generated your personal access token, &lt;a href="https://docs.github.com/en/codespaces/managing-codespaces-for-your-organization/managing-encrypted-secrets-for-your-repository-and-organization-for-codespaces"&gt;add it as a repository secret&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The secret can be named whatever you like, although must meet &lt;a href="https://docs.github.com/en/codespaces/managing-codespaces-for-your-organization/managing-encrypted-secrets-for-your-repository-and-organization-for-codespaces#naming-secrets"&gt;a few criteria&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For this example, lets call this secret: &lt;code&gt;GH_TOKEN&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The default configuration would look something like:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# /.github/workflows/release.yml&lt;/span&gt;

&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;release-please&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;master&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;release-please&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="c1"&gt;# The name of your gem/package.&lt;/span&gt;
      &lt;span class="na"&gt;GEM_NAME&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GEM&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;NAME&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;HERE"&lt;/span&gt;

    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="c1"&gt;# Use release-please-action.&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;GoogleCloudPlatform/release-please-action@v2&lt;/span&gt;

        &lt;span class="c1"&gt;# Assign an 'id' to this action&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;release&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="c1"&gt;# Personal Access Token&lt;/span&gt;
          &lt;span class="na"&gt;token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.GH_TOKEN }}&lt;/span&gt;

          &lt;span class="c1"&gt;# Use release-please/strategies/ruby.ts Release Type&lt;/span&gt;
          &lt;span class="na"&gt;release-type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ruby&lt;/span&gt;

          &lt;span class="c1"&gt;# The name of the gem.&lt;/span&gt;
          &lt;span class="na"&gt;package-name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ env.GEM_NAME }}&lt;/span&gt;

          &lt;span class="c1"&gt;# Location of the version.rb file to bump for new releases&lt;/span&gt;
          &lt;span class="na"&gt;version-file&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;lib/${{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;env.GEM_NAME&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}/version.rb"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Checkout and Publish
&lt;/h3&gt;

&lt;p&gt;If a release is found, we want to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Checkout the repository.&lt;/li&gt;
&lt;li&gt;Build the ruby gem.&lt;/li&gt;
&lt;li&gt;Publish the gem to &lt;a href="https://rubygems.org"&gt;rubygems.org&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;
  
  
  Checkout Repository
&lt;/h4&gt;

&lt;p&gt;To checkout our repository, we can simply use the &lt;code&gt;actions/checkout&lt;/code&gt; GitHub action.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# /.github/workflows/release.yml&lt;/span&gt;

&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;release-please&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;master&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;release-please&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;GEM_NAME&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GEM&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;NAME&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;HERE"&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;GoogleCloudPlatform/release-please-action@v2&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;release&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.GH_TOKEN }}&lt;/span&gt;
          &lt;span class="na"&gt;release-type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ruby&lt;/span&gt;
          &lt;span class="na"&gt;package-name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ env.GEM_NAME }}&lt;/span&gt;
          &lt;span class="na"&gt;version-file&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;lib/${{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;env.GEM_NAME&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}/version.rb"&lt;/span&gt;

      &lt;span class="c1"&gt;# Checkout the Repository if a release has been created.  &lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;
        &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ steps.release.outputs.release_created }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  Setting Up Ruby
&lt;/h4&gt;

&lt;p&gt;To be able to build our ruby gem, we first must install ruby onto our machine. We can achieve this by using the &lt;code&gt;ruby/setup-ruby&lt;/code&gt; GitHub Action.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# /.github/workflows/release.yml&lt;/span&gt;

&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;release-please&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;master&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;release-please&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;GEM_NAME&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GEM&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;NAME&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;HERE"&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;GoogleCloudPlatform/release-please-action@v2&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;release&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.GH_TOKEN }}&lt;/span&gt;
          &lt;span class="na"&gt;release-type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ruby&lt;/span&gt;
          &lt;span class="na"&gt;package-name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ env.GEM_NAME }}&lt;/span&gt;
          &lt;span class="na"&gt;version-file&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;lib/${{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;env.GEM_NAME&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}/version.rb"&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;GEM_NAME&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GEM&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;NAME&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;HERE"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;
        &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ steps.release.outputs.release_created }}&lt;/span&gt;

      &lt;span class="c1"&gt;# Set up Ruby if a release can be created.&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ruby/setup-ruby@v1&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="c1"&gt;# Latest ruby version (remove to use .ruby-version).&lt;/span&gt;
          &lt;span class="na"&gt;ruby-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3.0&lt;/span&gt;

        &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ steps.release.outputs.release_created }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  Publish Gem
&lt;/h4&gt;

&lt;p&gt;First to be able to push a new version, we must allow access via &lt;a href="https://rubygems.org"&gt;rubygems.org&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To create a new API key, head to &lt;a href="https://rubygems.org/profile/api_keys"&gt;rubygems.org&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Next, create a new repository secret. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This can be named anything, although must be referenced correctly within the workflow file.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For this example, we will call this secret: &lt;code&gt;RUBYGEMS_API_KEY&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To publish our gem, we have a couple of tasks to complete.&lt;/p&gt;

&lt;p&gt;Since our action will run in a new container every time it is called, we must create a &lt;code&gt;~/.gem/credentials&lt;/code&gt; file containing an API Key from the account we would like to post on for &lt;a href="https://rubygems.org"&gt;rubygems.org&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Manual installation of Bundler is required. Since we are releasing our gem from the repository it must be built and have packages updated on push. The default 'bundler-cache' will break this.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;Install the bundler gem.&lt;/li&gt;
&lt;li&gt;Unset the &lt;code&gt;BUNDLE_DEPLOYMENT&lt;/code&gt; variable.&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;bundle install&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Create &lt;code&gt;~/.gem/credentials&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Add our &lt;code&gt;RUBYGEMS_API_KEY&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Build our gem from the &lt;code&gt;*.gemspec&lt;/code&gt; file.&lt;/li&gt;
&lt;li&gt;Push the &lt;code&gt;*.gem&lt;/code&gt; to the remote server.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We can simply run these commands from within our workflow:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;gem &lt;span class="nb"&gt;install &lt;/span&gt;bundler
&lt;span class="nv"&gt;$ &lt;/span&gt;bundle config &lt;span class="nb"&gt;unset &lt;/span&gt;deployment
&lt;span class="nv"&gt;$ &lt;/span&gt;bundle &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.gem
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;touch&lt;/span&gt; &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.gem/credentials
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;chmod &lt;/span&gt;0600 &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.gem/credentials
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="s2"&gt;"---&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;:rubygems_api_key: &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;RUBYGEMS_API_KEY&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.gem/credentials
&lt;span class="nv"&gt;$ &lt;/span&gt;gem build &lt;span class="k"&gt;*&lt;/span&gt;.gemspec
&lt;span class="nv"&gt;$ &lt;/span&gt;gem push &lt;span class="k"&gt;*&lt;/span&gt;.gem
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The end result would look like:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# /.github/workflows/release.yml&lt;/span&gt;

&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;release-please&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;master&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;release-please&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;GEM_NAME&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GEM&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;NAME&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;HERE"&lt;/span&gt;

      &lt;span class="c1"&gt;# Our Ruby Gems API key&lt;/span&gt;
      &lt;span class="na"&gt;RUBYGEMS_API_KEY&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.RUBYGEMS_API_KEY }}&lt;/span&gt;

    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;GoogleCloudPlatform/release-please-action@v2&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;release&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.GH_TOKEN }}&lt;/span&gt;
          &lt;span class="na"&gt;release-type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ruby&lt;/span&gt;
          &lt;span class="na"&gt;package-name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ env.GEM_NAME }}&lt;/span&gt;
          &lt;span class="na"&gt;version-file&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;lib/${{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;env.GEM_NAME&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}/version.rb"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;
        &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ steps.release.outputs.release_created }}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ruby/setup-ruby@v1&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;ruby-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3.0&lt;/span&gt;
        &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ steps.release.outputs.release_created }}&lt;/span&gt;

      &lt;span class="c1"&gt;# Release the gem to https://rubygems.org if a release has been created.&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Release Gem&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;gem install bundler&lt;/span&gt;
          &lt;span class="s"&gt;bundle config unset deployment&lt;/span&gt;
          &lt;span class="s"&gt;bundle install&lt;/span&gt;
          &lt;span class="s"&gt;mkdir -p $HOME/.gem&lt;/span&gt;
          &lt;span class="s"&gt;touch $HOME/.gem/credentials&lt;/span&gt;
          &lt;span class="s"&gt;chmod 0600 $HOME/.gem/credentials&lt;/span&gt;
          &lt;span class="s"&gt;printf -- "---\n:rubygems_api_key: ${RUBYGEMS_API_KEY}\n" &amp;gt; $HOME/.gem/credentials&lt;/span&gt;
          &lt;span class="s"&gt;gem build *.gemspec&lt;/span&gt;
          &lt;span class="s"&gt;gem push *.gem&lt;/span&gt;
        &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ steps.release.outputs.release_created }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Creating Your First Release
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;release-please&lt;/strong&gt; will create a new pull-request automatically bumping the version of your project.&lt;/p&gt;

&lt;p&gt;This will parse your projects git commit history to group together changes in a comprehensive fashion.&lt;/p&gt;
&lt;h3&gt;
  
  
  Adding Some Changes
&lt;/h3&gt;

&lt;p&gt;Some keywords like &lt;code&gt;ci:&lt;/code&gt; will not be build a new release, as these do not change your application.&lt;/p&gt;

&lt;p&gt;Only keywords such as: &lt;code&gt;fix:&lt;/code&gt;, &lt;code&gt;feat:&lt;/code&gt;, or any &lt;code&gt;&amp;lt;type&amp;gt;!:&lt;/code&gt; (Breaking Change), will trigger a new release to be created.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Changes will be grouped together, thus adding multiple commits of &lt;code&gt;fix:&lt;/code&gt;, &lt;code&gt;feat:&lt;/code&gt;, etc would be grouped into the same version release until the release pull request is merged into the main branch.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To generate a new changelog whenever we can force run our &lt;strong&gt;release-please&lt;/strong&gt; action:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Navigate to your repository on GitHub.&lt;/li&gt;
&lt;li&gt;Click on the &lt;strong&gt;Actions&lt;/strong&gt; tab.&lt;/li&gt;
&lt;li&gt;Select: &lt;strong&gt;All Workflows&lt;/strong&gt; &amp;gt; &lt;strong&gt;release-please&lt;/strong&gt; &amp;gt; &lt;strong&gt;Run workflow&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To generate a new release and changelog, we could:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add a new empty commit with a release tag.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git commit &lt;span class="nt"&gt;--allow-empty&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"chore: release 1.0.0"&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Release-As: 1.0.0"&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;OR&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start adding commits using &lt;em&gt;conventional commit messages&lt;/em&gt;.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git add &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"feat: my new feature"&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git push
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Every time &lt;code&gt;feat:&lt;/code&gt; or &lt;code&gt;fix:&lt;/code&gt; is in the commit message, &lt;strong&gt;release-please&lt;/strong&gt; will re-parse your git commit history, create a new pull-request with the bumped version and an up-to-date changelog.&lt;/p&gt;
&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;release-please&lt;/strong&gt; adds convention to GitHub commits to allow changelogs and releases to be created without someone having to manually do so, as well as maintaining a specific committing convention.&lt;/p&gt;

&lt;p&gt;Our final &lt;code&gt;release.yml&lt;/code&gt; file may look like:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



</description>
      <category>tutorial</category>
      <category>github</category>
      <category>webdev</category>
      <category>ci</category>
    </item>
    <item>
      <title>A Full-Stack Application</title>
      <dc:creator>A.J. Romaniello</dc:creator>
      <pubDate>Thu, 16 Sep 2021 18:33:16 +0000</pubDate>
      <link>https://dev.to/ajrom/a-full-stack-application-280d</link>
      <guid>https://dev.to/ajrom/a-full-stack-application-280d</guid>
      <description>&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--566lAguM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/aj-rom"&gt;
        aj-rom
      &lt;/a&gt; / &lt;a href="https://github.com/aj-rom/hike-it-up-v2"&gt;
        hike-it-up-v2
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      The second coming of hike-it-up a React.js trail social media application. 
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;I recently have completed a &lt;em&gt;full-stack&lt;/em&gt; (backend and frontend) application, &lt;a href="https://aj-rom.github.io/hike-it-up-v2/"&gt;hike-it-up&lt;/a&gt;, and wanted to share how I went about creating this application and hosting it for &lt;strong&gt;completely free&lt;/strong&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Some Background
&lt;/h2&gt;

&lt;p&gt;I am finishing my time at &lt;a href="https://flatironschool.com/"&gt;The Flatiron School&lt;/a&gt; and wanted to showcase my new learnings by re-creating a very simple &lt;a href="http://sinatrarb.com/"&gt;Sinatra&lt;/a&gt; application that I made earlier this year. Now that I had all this great knowledge of &lt;a href="https://reactjs.org/"&gt;React&lt;/a&gt; I could combine it with my knowledge of &lt;a href="https://rubyonrails.org/"&gt;Ruby on Rails&lt;/a&gt; to create a full-stack application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Things Started
&lt;/h2&gt;

&lt;p&gt;Right off the bat, with experience from previous projects, I wanted my backend and frontend within the same GitHub repository. Both for ease of local deployment and because at the end we want to have &lt;strong&gt;3&lt;/strong&gt; branches. One for our backend, one for our frontend, and one to house everything.&lt;/p&gt;

&lt;p&gt;I initially started and used the &lt;code&gt;create-react-app&lt;/code&gt; toolchain to generate my GitHub repository and frontend services. &lt;/p&gt;

&lt;p&gt;After moving into the newly generated folder, I created a new rails API application named &lt;code&gt;backend&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Now I had a folder for my backend, a &lt;code&gt;public&lt;/code&gt; folder for my entry point, and a &lt;code&gt;src&lt;/code&gt; folder for React related files. &lt;/p&gt;

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

&lt;p&gt;I went with &lt;a href="https://picocss.com/"&gt;Pico.CSS&lt;/a&gt; for the framework, as it is a very lightweight CSS pack and has useful 'classless' styling properties.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://picocss.com/docs/"&gt;Read more on Pico.CSS&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I also wanted to have application state as well as client side routing. To achieve this I had to install some &lt;a href="https://www.npmjs.com/"&gt;npm&lt;/a&gt; packages.&lt;br&gt;
For application state I used &lt;a href="https://github.com/reduxjs/redux"&gt;redux&lt;/a&gt; with &lt;a href="https://github.com/reduxjs/redux-thunk"&gt;redux-thunk&lt;/a&gt; middleware. &lt;/p&gt;

&lt;p&gt;For client side routing, I decided to go with &lt;a href="https://reactrouter.com/"&gt;react-router&lt;/a&gt;. This allowed me to mimick route browsing of the backend on the frontend. For example, going to &lt;code&gt;/trails/1&lt;/code&gt;, should bring up the first trail. React Router passes the declarative &lt;strong&gt;id&lt;/strong&gt; of the route, in this case &lt;code&gt;/trails/:id&lt;/code&gt;, to the props of the route. &lt;/p&gt;

&lt;p&gt;This allows us to make backend server calls &lt;strong&gt;ONLY&lt;/strong&gt; when necessary, and doesn't break if someone were to link to it like &lt;a href="https://aj-rom.github.io/hike-it-up-v2/#/trails/1"&gt;this&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building Out the Backend
&lt;/h2&gt;

&lt;p&gt;I created resources for &lt;code&gt;trails&lt;/code&gt;, &lt;code&gt;users&lt;/code&gt;, and a model for &lt;code&gt;addresses&lt;/code&gt;. Full CRUD operations should be able to be performed on trails, but only limited functionality should be able to be used for users. &lt;/p&gt;

&lt;p&gt;To ensure malformed or malicious attempts would not be able to work, I built out a simple token authentication system that would verify the user for ever session. If they have the incorrect token, requests to the backend server will not be implemented.&lt;/p&gt;

&lt;p&gt;Also, because I was separating where the frontend and backend servers are hosted, I needed to configure &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS"&gt;CORS&lt;/a&gt;. This would ensure requests where only valid if they came from my frontend's location.&lt;/p&gt;

&lt;p&gt;After creating all pertinent relations and migrations I had my backend system up and running.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frontend Challenges
&lt;/h2&gt;

&lt;p&gt;When I was building out the frontend there were a couple of issues that I ran into, mostly because I was hosting this on &lt;a href="https://www.npmjs.com/package/gh-pages"&gt;gh-pages&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Switching To Hash Router
&lt;/h3&gt;

&lt;p&gt;React Router has a nifty component called &lt;a href="https://reactrouter.com/web/api/HashRouter"&gt;&lt;/a&gt;, which allows our UI to rely on the hash portion of the URL (&lt;a href="http://www.example.com/#/I/Am/The-Hash-Portion"&gt;www.example.com/#/I/Am/The-Hash-Portion&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;This was necessary because I was hosting this application on a subdirectory of my GitHub domain. For example this application is hosted at &lt;code&gt;https://aj-rom.github.io/hike-it-up-v2/&lt;/code&gt; not &lt;code&gt;https://aj-rom.github.io/&lt;/code&gt;. As normal routing would break this.&lt;/p&gt;

&lt;h3&gt;
  
  
  Persisting Application State
&lt;/h3&gt;

&lt;p&gt;I had everything working as I wanted it except one thing, my state wouldn't persist on refresh. This made sense as there was nothing keeping application state stored in the users browser.&lt;/p&gt;

&lt;p&gt;There were a couple of ways to implement this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Use &lt;a href="https://www.npmjs.com/package/redux-persist"&gt;redux-persist&lt;/a&gt; &amp;amp; &lt;a href="https://www.npmjs.com/package/redux-storage"&gt;redux-storage&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Persist application using raw JavaScript (build it myself)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;After doing some research I learned that implementing this really wouldn't be difficult at all and this will save me two packages and maybe even more.&lt;/p&gt;

&lt;p&gt;JavaScript has a nifty object accessible on every window, &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage"&gt;&lt;code&gt;window.localStorage&lt;/code&gt;&lt;/a&gt;, that allows us to store data within the users page. This even persists when the page session ends, perfect for handling refreshes.&lt;/p&gt;

&lt;p&gt;I went ahead and modified my &lt;a href="https://github.com/aj-rom/hike-it-up-v2/blob/master/src/store.js"&gt;application store&lt;/a&gt;, to continuously save to storage when it updated and then clear when the user logs out, clears their history, or deletes their account. &lt;/p&gt;

&lt;h2&gt;
  
  
  Hosting
&lt;/h2&gt;

&lt;p&gt;Hosting the application is a whole different process, but luckily I have had some experience doing this in the past and have got a decent understanding on how to do this.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Backend
&lt;/h3&gt;

&lt;p&gt;For my backend I wanted to host it on &lt;a href="https://heroku.com"&gt;Heroku&lt;/a&gt; which allows for simple deployment from GitHub repositories and is completely free. &lt;/p&gt;

&lt;p&gt;Their deployment process is quite simple, all you have to do is link to a GitHub repository and choose a branch, then deploy the application.&lt;/p&gt;

&lt;p&gt;To make my Heroku server as least crowded as possible, I created a new branch named &lt;a href="https://github.com/aj-rom/hike-it-up-v2/tree/heroku"&gt;heroku&lt;/a&gt; that would only contain the contents from the &lt;code&gt;backend&lt;/code&gt; folder.&lt;/p&gt;

&lt;p&gt;Now that I had this branch only containing Rails related files, I headed over to Heroku and deployed the application.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Frontend
&lt;/h3&gt;

&lt;p&gt;This is probably the easiest way to host a react application for completely free, especially if it lives in a GitHub repository.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/tschaub/gh-pages"&gt;gh-pages&lt;/a&gt; npm package, makes for quick and easy deployment of fully compiled react applications.&lt;/p&gt;

&lt;p&gt;After running two simple commands &lt;code&gt;npm run predeploy &amp;amp;&amp;amp; npm run deploy&lt;/code&gt;, the frontend was up and running!&lt;/p&gt;

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

&lt;p&gt;I am very happy with the final outcome for this project as it pushed the limits of my understanding of JavaScript, Rails, HTTP protocol, and full-stack development.&lt;/p&gt;

&lt;p&gt;All in all there are really only slight optimizations to be made using code splitting, and maybe implementing search functionality (which is pretty much done). &lt;/p&gt;

&lt;p&gt;I hope this can be a resource for others to learn from or get inspiration for their next project!&lt;/p&gt;

&lt;p&gt;Thanks for reading, if you would like to check out the application you can do so at &lt;a href="https://aj-rom.github.io/hike-it-up-v2/"&gt;this link&lt;/a&gt;, or if you would like to see the GitHub repository you can do so &lt;a href="https://github.com/aj-rom/hike-it-up-v2/"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>react</category>
      <category>rails</category>
      <category>showdev</category>
      <category>redux</category>
    </item>
    <item>
      <title>React.lazy() - Boost Mobile Performance</title>
      <dc:creator>A.J. Romaniello</dc:creator>
      <pubDate>Wed, 09 Jun 2021 18:44:23 +0000</pubDate>
      <link>https://dev.to/ajrom/boosting-performance-react-edition-3d8k</link>
      <guid>https://dev.to/ajrom/boosting-performance-react-edition-3d8k</guid>
      <description>&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;When creating new React applications they are set up for desktop being in mind when loading assets, not mobile connections. If we run a chrome &lt;strong&gt;Lighthouse&lt;/strong&gt; report, we can see drastic differences between desktop performance and mobile performance.&lt;/p&gt;

&lt;p&gt;As developers we want the same experience for our application regardless of whether you are on mobile or desktop.&lt;/p&gt;

&lt;p&gt;Luckily this isn't that hard to implement!&lt;/p&gt;

&lt;h3&gt;
  
  
  What Creates the Issue
&lt;/h3&gt;

&lt;p&gt;When rendering new components in React we are importing javascript file and all imports that that component may contain!&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;flow&lt;/em&gt; looks 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%2Ftjie19kc6xcmmdci1u9a.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%2Ftjie19kc6xcmmdci1u9a.png" alt="React file load"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And the issue becomes a little clearer.&lt;/p&gt;

&lt;p&gt;If we had a two files: &lt;code&gt;index.js&lt;/code&gt; and &lt;code&gt;App.js&lt;/code&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="c1"&gt;// index.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./App.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello World!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// App.js&lt;/span&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;Component&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;SomeExtraClass&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;some-package&lt;/span&gt;&lt;span class="dl"&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;func1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;func2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;func3&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;another-package&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Imported Packages!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And ended up running &lt;code&gt;index.js&lt;/code&gt;, we would see this output to our console:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/&amp;gt; "Imported Packages"
/&amp;gt; "Hello World!"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is great because it brings all of our code into one useable scope for the file we imported it into, although the issue arises when we are importing code that isn't necessary at the time it is imported.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Does It Impact Mobile?
&lt;/h3&gt;

&lt;p&gt;As we build our applications, and as react is defined, larger screen sizes will be &lt;strong&gt;rendering&lt;/strong&gt; more components to the page at a time than its &lt;em&gt;mobile&lt;/em&gt; counterpart. &lt;/p&gt;

&lt;p&gt;This can lead to components rendering in the background and leads to technically decreased performance. &lt;em&gt;Due to the user waiting to load parts of the application they don't need or will see yet.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I must note that this also impacts both &lt;em&gt;desktop&lt;/em&gt; and &lt;em&gt;mobile&lt;/em&gt; performance when we are building large applications with many nested components. The more we have to render to the end user, the longer the application will take to load.&lt;/p&gt;

&lt;p&gt;So how do we go about only loading the necessary content for the page in prioritized order?&lt;/p&gt;

&lt;p&gt;Welcome to &lt;a href="https://reactjs.org/docs/code-splitting.html#reactlazy" rel="noopener noreferrer"&gt;React.lazy&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  React.lazy
&lt;/h3&gt;

&lt;p&gt;Luckily &lt;strong&gt;React&lt;/strong&gt; has built a package that handles this for us: &lt;code&gt;React.lazy&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We can import &lt;code&gt;lazy&lt;/code&gt; as a named method from the &lt;em&gt;react&lt;/em&gt; library if we would like or call to it as &lt;code&gt;React.lazy()&lt;/code&gt;. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;React.lazy takes a function that must call a dynamic import(). This must return a Promise which resolves to a module with a default export containing a React component.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Awesome, so we can now dynamically import extra components and leave it up to React to decide when to display them!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;React.lazy is currently not supported for server-side rendering.&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Code-Splitting With React.lazy
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;Code-Splitting is a feature supported by bundlers like Webpack, Rollup and Browserify (via factor-bundle) which can create multiple bundles that can be dynamically loaded at runtime. - &lt;a href="https://reactjs.org/docs/code-splitting.html" rel="noopener noreferrer"&gt;reactjs.org&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is what allows us to dynamically load separate files. Bundlers handle the different &lt;em&gt;flows&lt;/em&gt; that our application will take when loading new files and creates separate bundle files that will be loaded for certain components.&lt;/p&gt;

&lt;p&gt;This separation of concerns for runtime is what allows us to increase performance within our applications.&lt;/p&gt;

&lt;h4&gt;
  
  
  Suspense
&lt;/h4&gt;

&lt;p&gt;Since this is loading our imports &lt;em&gt;asynchronously&lt;/em&gt;, we don't want to wait for everything to load let's do something in the meantime for those couple of milliseconds it takes to import!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Suspense&lt;/strong&gt; allows us to declare what should be displayed to the DOM while we wait on the rest of our components to load, until our promise resolves. Thanks &lt;code&gt;React.lazy&lt;/code&gt;!&lt;/p&gt;

&lt;h4&gt;
  
  
  How To Use React.lazy
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// App.js&lt;/span&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;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lazy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Suspense&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Header&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;lazy&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="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./Header.js&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;Body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;lazy&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="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./Body.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

   &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
         &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&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;Suspense&lt;/span&gt; &lt;span class="nx"&gt;fallback&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;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="nx"&gt;Loading&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&amp;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="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Loaded&lt;/span&gt; &lt;span class="nx"&gt;Page&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;Header&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;Body&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="sr"&gt;/Suspense&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;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As React goes to render our &lt;em&gt;App&lt;/em&gt; component, the lifecycle now looks like this:&lt;br&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%2Fv7e75g74vy5551wz2j9s.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%2Fv7e75g74vy5551wz2j9s.png" alt="React Lazy load"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Benefits
&lt;/h3&gt;

&lt;p&gt;Now that we are asynchronously loading our extra components and have a &lt;em&gt;fallback&lt;/em&gt; function, we no longer have to wait for components to render. As we can rely on the fallback function to handle our &lt;a href="https://developer.mozilla.org/en-US/docs/Glossary/First_contentful_paint" rel="noopener noreferrer"&gt;first contentful paint&lt;/a&gt;, and wait for them to load through &lt;code&gt;React.lazy&lt;/code&gt; and then update our component!&lt;/p&gt;

&lt;p&gt;This may only reduce loading times by a couple of milliseconds but it is better to display something like &lt;code&gt;Loading...&lt;/code&gt; or maybe a &lt;a href="https://loading.io/" rel="noopener noreferrer"&gt;loading animation&lt;/a&gt;, rather than having a blank component and then allow React to come back in and update the component once its ready to render!&lt;/p&gt;

&lt;h3&gt;
  
  
  Profiling With Lighthouse
&lt;/h3&gt;

&lt;p&gt;To prove that &lt;code&gt;React.lazy&lt;/code&gt; actually works let's profile it with Lighthouse using a basic application. You can find the example at &lt;a href="https://github.com/aj-rom/react-lazy-example" rel="noopener noreferrer"&gt;this repository&lt;/a&gt; if you would like to test it on your own machine. &lt;/p&gt;

&lt;h4&gt;
  
  
  Desktop
&lt;/h4&gt;

&lt;h5&gt;
  
  
  No Suspense
&lt;/h5&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%2Furqj9fuouy60e6h53brn.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%2Furqj9fuouy60e6h53brn.png" alt="desktop-noSuspense"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  With Suspense
&lt;/h5&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%2Fqitureplupmlexo4mcm2.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%2Fqitureplupmlexo4mcm2.png" alt="desktop-suspense"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h4&gt;
  
  
  Mobile
&lt;/h4&gt;

&lt;h5&gt;
  
  
  No Suspense
&lt;/h5&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%2F2sj4dkp5m06znkgis9ry.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%2F2sj4dkp5m06znkgis9ry.png" alt="mobile-noSuspense"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Suspense
&lt;/h4&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%2Fle0cbg6xjvmf4pctd51f.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%2Fle0cbg6xjvmf4pctd51f.png" alt="mobile-suspense"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;By using &lt;code&gt;React.lazy&lt;/code&gt; and the &lt;code&gt;Suspense&lt;/code&gt; component, we were able to drastically improve our websites loading performance by supplying a fallback render method. &lt;/p&gt;

&lt;p&gt;This will handle rendering until our component can actually be rendered to the user.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Mobile&lt;/em&gt; performance sees a much larger gain rather than &lt;em&gt;Desktop&lt;/em&gt; performance, although both are increased!&lt;/p&gt;

</description>
      <category>react</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>React &amp; Redux | A Quick Side Project</title>
      <dc:creator>A.J. Romaniello</dc:creator>
      <pubDate>Fri, 04 Jun 2021 19:08:18 +0000</pubDate>
      <link>https://dev.to/ajrom/react-redux-a-quick-side-project-19hl</link>
      <guid>https://dev.to/ajrom/react-redux-a-quick-side-project-19hl</guid>
      <description>&lt;h2&gt;
  
  
  &lt;a href="https://aj-rom.github.io/tracker"&gt;Tracker&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;As I am currently learning React and Redux I wanted to mess around with these new frameworks and get used to hosting them on GitHub for future projects.&lt;/p&gt;

&lt;p&gt;This is a very basic application that showcases DOM manipulation, via React, and state management through Redux. What it allows us to do is add items to a list, we can increase the count on each item or decrease them, and remove them from the master list. &lt;/p&gt;

&lt;p&gt;You can check out the hosted application on github pages &lt;a href="https://aj-rom.github.io/tracker"&gt;here&lt;/a&gt;, or view the source code &lt;a href="https://github.com/aj-rom/tracker"&gt;here&lt;/a&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Development Process
&lt;/h3&gt;

&lt;p&gt;As the development process goes, it is always a good idea to have something written down in what you expect your application to end up working like. I came up with the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Our ReactDOM.render method in index.js&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Provider&lt;/span&gt; &lt;span class="na"&gt;store&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;App&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Provider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="c1"&gt;// App Component&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Fragment&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt; // Where we should be able to add items to the list
   &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Body&lt;/span&gt; &lt;span class="na"&gt;items&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt; // Pass our store of props
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Fragment&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;// Connected via react-redux to pass the props from our main index.js&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h4&gt;
  
  
  Setting Up Containers
&lt;/h4&gt;

&lt;p&gt;These are simply for separating our components into a logical manner as well as increasing maintainability for future changes to components and the layout of our application.&lt;/p&gt;

&lt;h5&gt;
  
  
  Header
&lt;/h5&gt;

&lt;p&gt;This is where we want our input form to be, so we are going to wrap this section in a div giving it a unique ID for styling/DOM manipulation.&lt;/p&gt;

&lt;p&gt;Setting up our render method should like something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'add-bar'&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;AddBar&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Body
&lt;/h5&gt;

&lt;p&gt;This container should be responsible for passing the props from our main application state down to our &lt;code&gt;&amp;lt;ItemList/&amp;gt;&lt;/code&gt; component, and rendering this in a reasonable fashion.&lt;/p&gt;

&lt;p&gt;Setting up our render our&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'item-list'&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ItemList&lt;/span&gt; &lt;span class="na"&gt;items&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that we have our containers set up we can go ahead and begin building our our components.&lt;/p&gt;




&lt;h4&gt;
  
  
  Setting Up Components
&lt;/h4&gt;

&lt;p&gt;As we declared above we need at least two components: &lt;code&gt;&amp;lt;AddBar/&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;ItemList/&amp;gt;&lt;/code&gt;, and it would make sense for &lt;code&gt;&amp;lt;ItemList/&amp;gt;&lt;/code&gt; to house many components such as &lt;code&gt;&amp;lt;Item/&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So we need to declare three components &lt;code&gt;&amp;lt;AddBar/&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;ItemList/&amp;gt;&lt;/code&gt;, and &lt;code&gt;&amp;lt;Item/&amp;gt;&lt;/code&gt;. Which all need to be connected to our main application state.&lt;/p&gt;




&lt;h5&gt;
  
  
  &lt;code&gt;&amp;lt;AddBar/&amp;gt;&lt;/code&gt;
&lt;/h5&gt;

&lt;p&gt;This component should be responsible for taking user input, and adding it to our main application states list of items.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;connect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-redux&lt;/span&gt;&lt;span class="dl"&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;addItem&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;../actions/item&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../style/form.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="c1"&gt;// Material UI Components &amp;amp; Style&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;TextField&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@material-ui/core/TextField&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;Button&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@material-ui/core/Button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;AddBar&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;item&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="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;handleChange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&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;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;handleSubmit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="c1"&gt;// Passed to props via connect method for dispatch actions/item.js&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;item&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="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"add-form"&lt;/span&gt; &lt;span class="na"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handleSubmit&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TextField&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'text'&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'item'&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                           &lt;span class="na"&gt;autoComplete&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'off'&lt;/span&gt;
                           &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'Item Name'&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                           &lt;span class="na"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'Add Your Item Here'&lt;/span&gt; &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handleChange&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'Submit'&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Submit&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Pull main application state to props&lt;/span&gt;
&lt;span class="c1"&gt;// As well ass pull the addItem action to our props&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&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;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;addItem&lt;/span&gt; &lt;span class="p"&gt;})(&lt;/span&gt;&lt;span class="nx"&gt;AddBar&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h5&gt;
  
  
  &lt;code&gt;&amp;lt;ItemList/&amp;gt;&lt;/code&gt;
&lt;/h5&gt;

&lt;p&gt;This component should be responsible for passing our state and breaking it down and rendering them into specific &lt;code&gt;&amp;lt;Item/&amp;gt;&lt;/code&gt; components.&lt;/p&gt;

&lt;p&gt;Our component should be declared something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Item&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./item&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ItemList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;renderItems&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Item&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;idx&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;idx&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;item&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'item-list'&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
             &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;renderItems&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;ItemList&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice this doesn't have to use the &lt;em&gt;react-redux&lt;/em&gt; connect method, because we are passing our main application state &lt;code&gt;items&lt;/code&gt; as a prop to the &lt;code&gt;&amp;lt;Body/&amp;gt;&lt;/code&gt; container.&lt;/p&gt;

&lt;p&gt;This also allows us to render our individual items.&lt;/p&gt;




&lt;h5&gt;
  
  
  &lt;code&gt;&amp;lt;Item/&amp;gt;&lt;/code&gt;
&lt;/h5&gt;

&lt;p&gt;This component should be responsible for rendering specific items and their &lt;em&gt;count&lt;/em&gt;, as well as handling buttons for incrementing and decreasing count and removal button for removing the item from our main application state and DOM.&lt;/p&gt;

&lt;p&gt;Setting up our class would look something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lazy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Suspense&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;connect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-redux&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../style/item.css&lt;/span&gt;&lt;span class="dl"&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;removeItem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;increaseCount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;decreaseCount&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../actions/item&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Card&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@material-ui/core/Card&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@material-ui/core/Button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Typography&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@material-ui/core/Typography&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ButtonGroup&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@material-ui/core/ButtonGroup&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Item&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="nx"&gt;handleRemove&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;removeItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;handleIncrease&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;increaseCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;handleDecrease&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;decreaseCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
             &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Card&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'item-card'&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                 &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Typography&lt;/span&gt; &lt;span class="na"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;''&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'item-title'&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Typography&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                 &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Typography&lt;/span&gt; &lt;span class="na"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'subtitle1'&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'clicker'&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; times&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Typography&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                 &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ButtonGroup&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'action-row'&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                     &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handleIncrease&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'item-button'&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;+&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                     &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handleDecrease&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'item-button'&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;-&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                     &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handleRemove&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'item-button'&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Remove&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                 &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;ButtonGroup&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
             &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Card&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;removeItem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;increaseCount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;decreaseCount&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that we are pulling in &lt;strong&gt;three&lt;/strong&gt; actions: &lt;code&gt;removeItem&lt;/code&gt;, &lt;code&gt;increaseCount&lt;/code&gt;, and &lt;code&gt;decreaseCount&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Setting Up Actions
&lt;/h4&gt;

&lt;p&gt;Since this was a very simple application we only needed on action file and four total methods. All that should take an item as a parameter.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;addItem&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;addItem&lt;/span&gt; &lt;span class="o"&gt;=&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="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="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="s1"&gt;ADD_ITEM&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;item&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;removeItem&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;removeItem&lt;/span&gt; &lt;span class="o"&gt;=&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="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="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="s1"&gt;REMOVE_ITEM&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;item&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;increaseCount&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;increaseCount&lt;/span&gt; &lt;span class="o"&gt;=&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="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="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="s1"&gt;INCREASE_COUNT_OF_ITEM&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;item&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;decreaseCount&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;decreaseCount&lt;/span&gt; &lt;span class="o"&gt;=&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="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="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="s1"&gt;DECREASE_COUNT_OF_ITEM&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;item&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Setting Up a Reducer
&lt;/h4&gt;

&lt;p&gt;In order for us to handle these actions we need a reducer function to manipulate the applications state.&lt;/p&gt;

&lt;p&gt;This will usually be called &lt;code&gt;manage&amp;lt;ClassName&amp;gt;&lt;/code&gt; so we will call our file &lt;code&gt;manageItems.js&lt;/code&gt;. Our function should take two parameters, the applications state (list of items), and an action object.&lt;/p&gt;

&lt;p&gt;Leaving us with a new file that looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;manageItems&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ADD_ITEM&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;action&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="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;REMOVE_ITEM&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;splice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;INCREASE_COUNT_OF_ITEM&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&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;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;DECREASE_COUNT_OF_ITEM&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;dec&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&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;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;dec&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;

            &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dec&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nl"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;manageItems&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This connects the functionality between our Item component and our main application state by allowing us to call actions to our reducer from the Item component buttons.&lt;/p&gt;

&lt;p&gt;We set up a default parameter for our &lt;strong&gt;initial&lt;/strong&gt; state, which is being called when we use &lt;code&gt;createStore&lt;/code&gt; in our &lt;code&gt;index.js&lt;/code&gt; file. This gets overridden with our current application state every subsequent call to this method.&lt;/p&gt;




&lt;h4&gt;
  
  
  Hosting to GitHub Pages
&lt;/h4&gt;

&lt;p&gt;I wanted free hosting for this application, and as there are a couple of free options out there (&lt;a href="https://www.netlify.com/"&gt;Netlify&lt;/a&gt;, &lt;a href="https://www.heroku.com"&gt;Heroku&lt;/a&gt;, etc), my codebase was already hosted on a GitHub repository. &lt;/p&gt;

&lt;p&gt;Might as well just host it from the same location!&lt;/p&gt;

&lt;h5&gt;
  
  
  Installing &lt;code&gt;gh-pages&lt;/code&gt;
&lt;/h5&gt;

&lt;p&gt;There is a very useful npm package for achieving this extremely quickly, read more on it &lt;a href="https://www.npmjs.com/package/gh-pages"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;All I had to do was run &lt;code&gt;npm install gh-pages&lt;/code&gt;, add a&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"homepage"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://aj-rom.github.io/tracker"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
 key and value to my &lt;code&gt;package.json&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Next thing to add were the special scripts provided by &lt;code&gt;gh-pages&lt;/code&gt;, to our &lt;code&gt;package.json&lt;/code&gt; for us to be able to deploy this to github.&lt;/p&gt;

&lt;p&gt;Our scripts section should now look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"predeploy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm run build"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"deploy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"gh-pages -d build"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"react-scripts start"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"react-scripts build"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"react-scripts test"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"eject"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"react-scripts eject"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To deploy our application we run &lt;code&gt;npm run predeploy&lt;/code&gt; which creates a &lt;code&gt;/build&lt;/code&gt; directory with our production site. Navigate into the &lt;code&gt;/build&lt;/code&gt; directory and open up &lt;code&gt;index.html&lt;/code&gt; make sure everything is working the way you want and once you are satisfied go ahead and deploy it using &lt;code&gt;npm run deploy&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This creates a new branch, &lt;code&gt;gh-pages&lt;/code&gt;, and pushes only the contents of the &lt;code&gt;/build&lt;/code&gt; folder to this branch. GitHub then automatically will detect that there is a branch that should be used for GitHub pages and your application will be up and running!&lt;/p&gt;




&lt;h4&gt;
  
  
  Optimizations via Lighthouse
&lt;/h4&gt;

&lt;p&gt;Now that I got everything up and running I wanted to make sure everything was highly optimized and see how I could increase performance for any react-redux application in the future.&lt;/p&gt;

&lt;p&gt;My initial page report for desktop was flawless, 100s across the board, but mobile was drastically lower performance wise.&lt;/p&gt;

&lt;p&gt;This lead me to &lt;a href="https://reactjs.org/docs/code-splitting.html"&gt;code splitting&lt;/a&gt; with &lt;code&gt;React.lazy&lt;/code&gt; and &lt;code&gt;Suspense&lt;/code&gt;. Which increased performance on mobile to be on par with the desktop report.&lt;/p&gt;

&lt;p&gt;Feel free to run your own diagnostics check by navigating to the website &lt;a href="https://aj-rom.github.io"&gt;aj-rom.github.io/tracker&lt;/a&gt;. Open the chrome-developer console and navigate to the &lt;em&gt;Lighthouse&lt;/em&gt; section. &lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;I learned a lot while making this application when it came to separating concerns within a React-Redux application, and how to optimize component loading using code splitting. &lt;/p&gt;

</description>
      <category>showdev</category>
      <category>react</category>
      <category>redux</category>
      <category>webdev</category>
    </item>
    <item>
      <title>JavaScript Project - Twitter Clone</title>
      <dc:creator>A.J. Romaniello</dc:creator>
      <pubDate>Mon, 17 May 2021 21:37:41 +0000</pubDate>
      <link>https://dev.to/ajrom/twitter-clone-58l0</link>
      <guid>https://dev.to/ajrom/twitter-clone-58l0</guid>
      <description>&lt;h2&gt;
  
  
  Quick Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/aj-rom/twitter-clone"&gt;GitHub Repository&lt;/a&gt; - View this applications code&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://aj-rom.github.io/twitter-clone/frontend/index.html"&gt;Frontend&lt;/a&gt; - Interact with the Backend&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://ajrom-twitter-clone.herokuapp.com/"&gt;Backend&lt;/a&gt; - View raw JSON data.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What Was the Goal?
&lt;/h2&gt;

&lt;p&gt;I wanted to create a very dumbed down version of twitter for this portfolio project to showcase my knowledge in building a backend Rails api and manipulating DOM elements via javascript (for the frontend).&lt;/p&gt;

&lt;p&gt;For this we needed to be able to create new 'tweets' as a user, like certain tweets, as well as be able to leave comments on certain tweets.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Was difficult?
&lt;/h2&gt;

&lt;p&gt;Rendering changes to API data quickly without sacrificing performance was hard. This was most likely due to the way that I set up my frontend. &lt;/p&gt;

&lt;p&gt;When you originally load the site, you get the most recent tweets from our api's root.&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="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;BACKEND_URL&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
 &lt;span class="c1"&gt;// =&amp;gt; [Post, Post, Post, ...]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which then gets cached into a master list of all posts. When you send CRUD operations to the server, instead of re-loading and re-rendering all of the &lt;strong&gt;Posts&lt;/strong&gt; from our api, we manipulate the cached objects. &lt;/p&gt;

&lt;p&gt;This way we can manipulate the object for instantaneous changes on the frontend and not have to wait for responses from the server to view our changes.&lt;/p&gt;

&lt;p&gt;Although we also will be able to reload our page completely and see all of our updated changes as well! This was slightly confusing at first but after getting it figured out saved my backend from getting &lt;em&gt;unnecessary&lt;/em&gt; HTTP requests that would most likely affect server performance if this was interacted with on a larger scale.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Did I Learn?
&lt;/h2&gt;

&lt;p&gt;I learned so much through this project when it comes to manipulating DOM elements on a page and interacting with a backend API to send &lt;em&gt;POST&lt;/em&gt;, &lt;em&gt;PATCH&lt;/em&gt;, &lt;em&gt;GET&lt;/em&gt;, etc. requests.&lt;/p&gt;

&lt;p&gt;Also how learned how some systems like this really function when separating my concerns between a remote backend server (heroku) and the &lt;em&gt;static&lt;/em&gt; (yet hosted remotely and dynamic) frontend.&lt;/p&gt;

&lt;p&gt;This is a great way to showcase my work as it is completely free!&lt;/p&gt;

&lt;h3&gt;
  
  
  Backend Hosting Through Heroku
&lt;/h3&gt;

&lt;p&gt;When creating my project I separated concerns out of my backend and frontend directories. To get my rails backend hosted via heroku, I had to install their NPM package and run the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Login to heroku&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;heroku login

&lt;span class="c"&gt;# Set our remote (found in your heroku app overview)&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;heroku git:remote &lt;span class="nt"&gt;-a&lt;/span&gt; ajrom-twitter-clone

&lt;span class="c"&gt;# Push our (/backend) directory as to the master branch on heroku &lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git subtree push &lt;span class="nt"&gt;--prefix&lt;/span&gt; backend heroku master
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After getting everything setup I could seed my database by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;heroku run rake db:migrate
&lt;span class="nv"&gt;$ &lt;/span&gt;heroku run rake db:seed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And as easy as that the backend API was up and running right &lt;a href="https://ajrom-twitter-clone.herokuapp.com"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Frontend Hosting Through GitHub
&lt;/h3&gt;

&lt;p&gt;Since I already had a heroku web server running for the backend and didn't want to create a new one soley for the front end I went with the &lt;strong&gt;GitHub Pages&lt;/strong&gt; approach.&lt;/p&gt;

&lt;p&gt;GitHub Pages allows us to create static web pages, although we can manipulate the DOM via javascript to make this function dynamically with a third party server.&lt;/p&gt;

&lt;p&gt;The set up was pretty simple. I navigated to my repostiory, enabled github pages, and the frontend was fully accessible via &lt;a href="http://aj-rom.github.io/twitter-clone/frontend/index.html"&gt;this link&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;All in all I am pretty happy with the way this project turned out and learned so much in the process.&lt;/p&gt;

&lt;p&gt;Some of the additional tools and frameworks I learned while creating this project that I found very useful were &lt;a href="https://getbootstrap.com/"&gt;BootStrap&lt;/a&gt; and &lt;a href="https://www.form.io/"&gt;Form.io&lt;/a&gt;. Which helped create a responsive layout and quickly create amazing looking forms with validation via frontend declaration with Form.io.&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>javascript</category>
      <category>rails</category>
    </item>
    <item>
      <title>Rails Project - Pollen</title>
      <dc:creator>A.J. Romaniello</dc:creator>
      <pubDate>Tue, 27 Apr 2021 19:25:24 +0000</pubDate>
      <link>https://dev.to/ajrom/rails-project-pollen-59mh</link>
      <guid>https://dev.to/ajrom/rails-project-pollen-59mh</guid>
      <description>&lt;h1&gt;
  
  
  &lt;a href="https://github.com/aj-rom/pollen-site"&gt;Pollen&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;For my rails portfolio project I decided to build out an application base that will later be built on to be used for a product matching API.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why
&lt;/h2&gt;

&lt;p&gt;I have heavy feelings towards sustainability and setting up a website that will promote this was of great interest to me.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Challenges
&lt;/h2&gt;

&lt;p&gt;I wanted to keep this a barebones as possible, no generators, and no gem madness. Which lead to me learning &lt;strong&gt;a lot&lt;/strong&gt; more about the Rails framework and SCSS.&lt;/p&gt;

&lt;h3&gt;
  
  
  User Authentication
&lt;/h3&gt;

&lt;p&gt;At first I wanted to rely only on omni-auth and build out my own custom RESTful routes for logging users in, although decided to go with devise.&lt;/p&gt;

&lt;h4&gt;
  
  
  Reducing Devise
&lt;/h4&gt;

&lt;p&gt;Devise adds &lt;em&gt;a ton&lt;/em&gt; of useless stuff that I did not need for my application. I went through most of the code and views that devise included and customized and built my own methods based on the sections that I needed.&lt;/p&gt;

&lt;p&gt;This helped me keep my application smaller as well as having a deeper understanding to how tools such as devise work from the inside.&lt;/p&gt;

&lt;h4&gt;
  
  
  Default Users
&lt;/h4&gt;

&lt;p&gt;Since I originally was planning on not storing user passwords or letting them 'create an account' via my web application (only log in via third party). I needed to change a couple of things.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add Bcrypt&lt;/li&gt;
&lt;li&gt;Create a Sign Up form&lt;/li&gt;
&lt;li&gt;Allow users to sign in via email/password&lt;/li&gt;
&lt;li&gt;Generate a fake password for third-party login ins&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All in all this seemed like a large task to take on and the devise wiki made it seem even worse. Although if you have a decent understanding of html forms and rails form helpers creating dynamic links and login/signup pages actually isn't too difficult.&lt;/p&gt;

&lt;h2&gt;
  
  
  Useful Things I Learned
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Layouts
&lt;/h3&gt;

&lt;p&gt;Layouts are extremely important for keeping your views clean and lets easily style your application dynamically.&lt;/p&gt;

&lt;h3&gt;
  
  
  Helpers
&lt;/h3&gt;

&lt;p&gt;Helpers are well.... helpers. Use them! No need for a user to see any malformed data or spend a ton of time nesting objects within links. &lt;/p&gt;

&lt;p&gt;My favorite use case was creating a helper to wrap an entire div element to its associated path. Usually you would have to do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;%=&lt;/span&gt; &lt;span class="na"&gt;link_to&lt;/span&gt; &lt;span class="err"&gt;'/&lt;/span&gt;&lt;span class="na"&gt;login&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt; &lt;span class="na"&gt;do&lt;/span&gt; &lt;span class="err"&gt;%&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;%=&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;resource.name&lt;/span&gt; &lt;span class="err"&gt;%&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;%=&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;resource.description&lt;/span&gt; &lt;span class="err"&gt;%&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;%&lt;/span&gt; &lt;span class="na"&gt;end&lt;/span&gt; &lt;span class="err"&gt;%&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which would be much better if you could call something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;link_card_to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/login'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vi"&gt;@resource&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;I learned a ton over this project from rails routing, too layouts, to helpers, too SCSS. This was an awesome journey and I am excited to get into the Front-End frameworks such as Vue.js and React.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Developers Dilemma - Storing Passwords</title>
      <dc:creator>A.J. Romaniello</dc:creator>
      <pubDate>Tue, 20 Apr 2021 19:07:21 +0000</pubDate>
      <link>https://dev.to/ajrom/developers-dilemma-storing-passwords-3cal</link>
      <guid>https://dev.to/ajrom/developers-dilemma-storing-passwords-3cal</guid>
      <description>&lt;p&gt;We have all heard of the leaks major corporations can have and don't hear at all about the &lt;strong&gt;30 million&lt;/strong&gt; &lt;a href="https://purplesec.us/resources/cyber-security-statistics/#:~:text=In%202018%20there%20were%2080%2C000,30%20million%20attacks%20per%20year."&gt;cyber attacks&lt;/a&gt; each year. &lt;/p&gt;

&lt;p&gt;Which leads us developers to get cold feet when it comes to storing users sensitive data. &lt;/p&gt;

&lt;h2&gt;
  
  
  What Do I Do?
&lt;/h2&gt;

&lt;p&gt;Personally I have started using gems such as Omniauth and forcing users to use their provider of choice as the &lt;em&gt;secure entry point&lt;/em&gt; into my own application.&lt;/p&gt;

&lt;p&gt;Why spend time and resources storing their sensitive information when we can authenticate them via a third party application? (Who most likely has spent more time and money keeping their users safe.)&lt;/p&gt;

&lt;p&gt;Thus coming to my conclusion...&lt;/p&gt;

&lt;p&gt;All we need is a users email, their third-party login of choice, and that returned UID from said third-party. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fully authenticated user&lt;/li&gt;
&lt;li&gt;We get more information than a user would have to input themselves&lt;/li&gt;
&lt;li&gt;No blame on you if a third-party has compromised passwords&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Discussion
&lt;/h2&gt;

&lt;p&gt;What are your thoughts on this matter?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do you prefer using third-party authentication systems for your applications? &lt;/li&gt;
&lt;li&gt;Do you disagree with me and think we should still be storing user sensitive passwords?&lt;/li&gt;
&lt;li&gt;How do you go about securing your application users data? &lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>discuss</category>
      <category>database</category>
      <category>rails</category>
      <category>ruby</category>
    </item>
    <item>
      <title>Professionalize Your GitHub</title>
      <dc:creator>A.J. Romaniello</dc:creator>
      <pubDate>Wed, 07 Apr 2021 18:48:06 +0000</pubDate>
      <link>https://dev.to/ajrom/professionalize-your-github-4all</link>
      <guid>https://dev.to/ajrom/professionalize-your-github-4all</guid>
      <description>&lt;p&gt;Having a &lt;em&gt;professional&lt;/em&gt; looking GitHub profile is great in this age of online resumes, recruiters, and job search programs.&lt;/p&gt;

&lt;p&gt;Although some people who aren't familiar with GitHub may not know where to look to find the best information on your profile. &lt;/p&gt;

&lt;p&gt;In this guide I am going to give you a couple of good tips on how to &lt;em&gt;professionalize&lt;/em&gt; your GitHub profile and even organize it for yourself.&lt;/p&gt;

&lt;h1&gt;
  
  
  What We Are Covering
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;
Setting Up Your GitHub README

&lt;ul&gt;
&lt;li&gt;Creating The ReadMe&lt;/li&gt;
&lt;li&gt;Making It Prettier&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Choosing The Right Name&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Setting Up Your GitHub ReadMe
&lt;/h2&gt;

&lt;p&gt;If you have ever used GitHub before and created a repostiory, you should be familiar with the &lt;code&gt;README.md&lt;/code&gt; standard. This is usually a file that gives a brief overview of a project or directory withing a repository. &lt;/p&gt;

&lt;p&gt;A little while back GitHub allowed users to create a special "README" repository. Which gets featured on the users profile page before anything else!&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating The ReadMe
&lt;/h3&gt;

&lt;p&gt;GitHub has made this very easy, you just simply name a repository after your account name. For example mine would be &lt;code&gt;aj-rom/aj-rom&lt;/code&gt; and then you add a &lt;code&gt;README.md&lt;/code&gt; file. &lt;/p&gt;

&lt;p&gt;GitHub will automatically detect this as a &lt;em&gt;special&lt;/em&gt; file and your ready to start! More information can be found on the GitHub documentation &lt;a href="https://docs.github.com/en/github/setting-up-and-managing-your-github-profile/managing-your-profile-readme" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You might be thinking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why is this better than a normal GitHub profile? It shows our pinned repositories and contribution history already.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Take a look at this random &lt;a href="https://github.com/abc" rel="noopener noreferrer"&gt;users profile&lt;/a&gt; and compare it to for example &lt;a href="https://github.com/aj-rom" rel="noopener noreferrer"&gt;mine&lt;/a&gt;. With this readme someone viewing your profile will have to read this first as well as it looks a lot better than the normal layout.&lt;/p&gt;

&lt;p&gt;If you have already begun making your own readme at this point hold on one second and keep reading!&lt;/p&gt;

&lt;h3&gt;
  
  
  Making It Prettier
&lt;/h3&gt;

&lt;p&gt;There are a ton of ways to make a README better. You can use HTML and CSS within markdown files, embed videos, links, images, or anything you could on a static website within this.&lt;/p&gt;

&lt;p&gt;For example on my README, I am using a little extension called &lt;a href="https://github.com/anuraghazra/github-readme-stats" rel="noopener noreferrer"&gt;github-readme-stats&lt;/a&gt; which helps display your entire GitHub profile statistics in an awesome way. As well as mixing in some simply html code to hold &lt;code&gt;.svg&lt;/code&gt; files for my special links.&lt;/p&gt;

&lt;p&gt;This includes a variety of themes, implementation with &lt;a href="https://wakatime.com/dashboard" rel="noopener noreferrer"&gt;Wakatime&lt;/a&gt; to let you even display the time you spent on each repository and language as you develop them. &lt;/p&gt;

&lt;h2&gt;
  
  
  Choosing The Right Name
&lt;/h2&gt;

&lt;p&gt;Having a name that mimics your actual name or is somewhat professional is a must. Many more people are likely to clone and contribute to projects that are under &lt;code&gt;john-smith/some-project&lt;/code&gt; rather than &lt;code&gt;L33tCoder123xX/some-project&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;As well as recruiters trying to find you, having something that resembles your names or initials is usually the best way to go.&lt;/p&gt;

&lt;h2&gt;
  
  
  Inviting Collaboration
&lt;/h2&gt;

&lt;p&gt;One way to increase traffic to your GitHub profile and repositories is by opening issues and creating projects. &lt;/p&gt;

&lt;p&gt;If you have a repository that is open-sourced, I highly recommend creating an auto-mated kanban style project. This will automatically move new issues into the todo column and allow you to label and assign new issues quickly and orderly.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Importance of Labeling
&lt;/h3&gt;

&lt;p&gt;Another way to increase traffic and even direct this flow is through the use of labeling.&lt;/p&gt;

&lt;p&gt;Have a small feature that needs to be added or fixed but are gone for the weekend? Open up a new issue describe it and pointing to the correct location of what needs to be fixed. Then make sure to assign it correctly associated labels. &lt;/p&gt;

&lt;p&gt;(Some of the best for newcomers are 'good-first-issue')&lt;/p&gt;

&lt;p&gt;There are websites that will direct users to GitHub repositories based off the language of your repository and the issues you have open. So setting these up could lead to massive amounts of collaboration very quickly.&lt;/p&gt;

&lt;p&gt;This also can help you yourself stay organized by opening and closing issues automatically as well as getting used to the way that professionals use GitHub in large settings. &lt;/p&gt;

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

&lt;p&gt;Thank you for your time reading, if you found this helpful you may also like one of my other articles:&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/ajrom" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&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%2Fuser%2Fprofile_image%2F569375%2Fef792d43-539b-4dd4-8d8d-f9e81284a33c.jpeg" alt="ajrom"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/ajrom/how-to-teach-yourself-to-do-anything-3jfd" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;How To Teach Yourself To Do Anything&lt;/h2&gt;
      &lt;h3&gt;A.J. Romaniello ・ Mar 1 '21&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#beginners&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#productivity&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#tutorial&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#codenewbie&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>tutorial</category>
      <category>github</category>
      <category>beginners</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>GTC - 1400 Free Sessions</title>
      <dc:creator>A.J. Romaniello</dc:creator>
      <pubDate>Mon, 05 Apr 2021 17:43:51 +0000</pubDate>
      <link>https://dev.to/ajrom/gtc-1400-free-sessions-42oj</link>
      <guid>https://dev.to/ajrom/gtc-1400-free-sessions-42oj</guid>
      <description>&lt;p&gt;This is a great resource happening now until I believe the 14th of April. All sessions are completely free with registrations &lt;a href="https://www.nvidia.com/en-us/gtc/"&gt;here&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Some of the topics being covered in the more than 1400 live sessions talking with some of the most well respected individuals of the tech industry are: Artificial Intelligence, Accelerated Computing, Healthcare, Game Development and more. &lt;/p&gt;

&lt;p&gt;Hope to see some of you also attending, but thought this would be a great resource to share with everyone!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>What's your favorite ruby gem? Why?</title>
      <dc:creator>A.J. Romaniello</dc:creator>
      <pubDate>Tue, 09 Mar 2021 22:14:15 +0000</pubDate>
      <link>https://dev.to/ajrom/what-s-your-favorite-ruby-gem-why-28kg</link>
      <guid>https://dev.to/ajrom/what-s-your-favorite-ruby-gem-why-28kg</guid>
      <description>&lt;p&gt;A couple of my favorite are quite basic. I love the testing features of &lt;strong&gt;rspec&lt;/strong&gt; paired with &lt;strong&gt;capybara&lt;/strong&gt;, and am excited to explore the over &lt;a href="https://rubygems.org/"&gt;69 billion gems&lt;/a&gt; out there.&lt;/p&gt;

&lt;p&gt;Help your fellow ruby developers find that needle in the haystack! &lt;/p&gt;

&lt;p&gt;Here are a couple of questions if you can't decide what gem(s) to talk about. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What're some gems that you can't live without?&lt;/li&gt;
&lt;li&gt;What is one gem you found that makes a previously difficult processes easier?&lt;/li&gt;
&lt;li&gt;What's a gem that you thought was cool or expanded on what software engineering is capable of?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some of my favorite gems are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/rubocop/rubocop"&gt;RuboCop&lt;/a&gt; - Code styling&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/omniauth/omniauth"&gt;OmniAuth&lt;/a&gt; - ThirdParty authentication&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/puma/puma"&gt;Puma&lt;/a&gt; - Highly optimized and configurable web servers&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>How To Teach Yourself To Do Anything</title>
      <dc:creator>A.J. Romaniello</dc:creator>
      <pubDate>Mon, 01 Mar 2021 02:48:20 +0000</pubDate>
      <link>https://dev.to/ajrom/how-to-teach-yourself-to-do-anything-3jfd</link>
      <guid>https://dev.to/ajrom/how-to-teach-yourself-to-do-anything-3jfd</guid>
      <description>&lt;p&gt;Living in an advanced world allows us to access information on anything we desire in milliseconds. Using browsers and search engines we can easily browse the web over tons of documents and find relevant data.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For example: go search &lt;em&gt;potato&lt;/em&gt; on google, you might see a response of &lt;code&gt;About 539,000,000 results (0.87 seconds)&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And we could scroll through all of these millions of documents if we really wanted too. Who knows we would probably find some really interesting things about potatoes.&lt;/p&gt;

&lt;p&gt;Putting &lt;em&gt;the potatoes aside&lt;/em&gt; and getting back to the relevant topic, we can use these tools to access free educational material! Pretty awesome if you want to be a self-taught learner of anything. &lt;/p&gt;

&lt;p&gt;In this 'guide' I am going to provide some tips on how I teach myself programming languages, frameworks, tools, etc. using only the internet, but some of the tips could be helpful if your trying to learn anything else! &lt;/p&gt;




&lt;h1&gt;
  
  
  Table Of Contents
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;
About Me - Some basic information on my past experiences.&lt;/li&gt;
&lt;li&gt;
Understanding the Lingo - Your first stop for learning something new.

&lt;ul&gt;
&lt;li&gt;Read the Docs&lt;/li&gt;
&lt;li&gt;Encountering Our First Unknown Term&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
The Art of Googling - Become a googling pro.

&lt;ul&gt;
&lt;li&gt;Searching With Relevance&lt;/li&gt;
&lt;li&gt;Navigating The Sea Of Search Results&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
What To Do When I Have Errors - Reading stack traces, debugging, and where to get help.&lt;/li&gt;
&lt;li&gt;
Keeping Up The Pace - How to stay motivated to achieve your goal.

&lt;ul&gt;
&lt;li&gt;Setting Attainable Goals&lt;/li&gt;
&lt;li&gt;Managing Our Time&lt;/li&gt;
&lt;li&gt;Finding Our Happy Place&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
Experimentation - Implementing our new found ideas.

&lt;ul&gt;
&lt;li&gt;Build As You Learn&lt;/li&gt;
&lt;li&gt;Make Open Source Projects&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
Discussion - Some talking points for this thread.&lt;/li&gt;
&lt;li&gt;
Credits - Any credits needed related to this post.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  About Me
&lt;/h2&gt;

&lt;p&gt;I have been teaching myself a plethora of things using the internet ever since a young age. I started learning java when I was just 11 years old, but the internet can be used to learn anything! From my favorite meatball recipe to finding an awesome hiking trail near by, it doesn't only apply to programming. &lt;/p&gt;

&lt;p&gt;Ever since starting programming at a young age I used tools such as CodeAcademy and W3Schools to get a basic understanding of Object Oriented Programming and learning a couple languages such as HTML and CSS. From there I went and taught myself Java, SQL, MongoDB, C++, and more, since the school I went to did not offer any courses in technology. &lt;/p&gt;

&lt;p&gt;I am currently taking self-paced online courses at the &lt;a href="https://flatironschool.com/"&gt;Flatiron School&lt;/a&gt;, and utilizing what I've learned from teaching myself in the past has significantly helped me gain a deep understanding of the large amount of new material we are expected to cover. &lt;/p&gt;

&lt;p&gt;I hope this guide can help any of my fellow students in the self-paced program on how you can teach yourself and blaze through learning new tools, programming languages, or anything!&lt;/p&gt;




&lt;h2&gt;
  
  
  Understanding The Lingo
&lt;/h2&gt;

&lt;p&gt;One of the most confusing aspects of learning any tool, language, or framework is getting used to the terminology it utilizes and understanding it deeply.&lt;/p&gt;

&lt;p&gt;In my own experience, this is the hardest when switching between different programming languages due to the different syntax used and &lt;a href="https://www.cprogramming.com/langs.html"&gt;many&lt;/a&gt; other uses for them. Whereas a &lt;strong&gt;tool&lt;/strong&gt;, for example SQL, will have similar (and most likely exactly the same) functionality within any programming language, using SQL's &lt;strong&gt;lingo&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So how do we get a basic understanding of a tool, language, or frameworks lingo?&lt;/p&gt;




&lt;h3&gt;
  
  
  Read the Docs
&lt;/h3&gt;

&lt;p&gt;Before starting to learn anything, you would need to understand the pre-requisites. &lt;/p&gt;

&lt;p&gt;For example, you probably shouldn't start learning algebra without knowing pre-algebra. Or what if your spinal surgeon just switched over from being an orthodontist? You might say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Hey, are you qualified for this?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is the same way tools, languages, and frameworks expect us to function. We get used to the specific lingo by starting with the documentation. &lt;/p&gt;

&lt;p&gt;A great example of an &lt;strong&gt;amazing&lt;/strong&gt; documentation would be by the web application framework &lt;a href="https://guides.rubyonrails.org/getting_started.html"&gt;Ruby On Rails&lt;/a&gt;. Go ahead and take a look.&lt;/p&gt;

&lt;p&gt;When you click on the link you'll find a section right at the beginning that states &lt;strong&gt;Guide Assumptions&lt;/strong&gt;. This is the pre-requisite section that most documentation will have under a similar name. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Do I have to read the entire documentation?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;No, but you could if you have nothing better to do, use this as your starting point and reference point. Most documentation will have a getting started section that will help you start using whatever service they are offering. As you use the service, come back to the documentation when you want to learn about something new or if you are running into issues. &lt;/p&gt;

&lt;p&gt;You might find something really cool hidden within the docs that make your life way easier!&lt;/p&gt;

&lt;p&gt;Depending on the &lt;a href="https://en.wikipedia.org/wiki/Abstraction_(computer_science)"&gt;level of abstraction&lt;/a&gt; this could be where you run into your first bizarre looking term. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What's a web application? What's Rails?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Don't freak out! Learning the lingo and requirements is the first step in getting a &lt;strong&gt;deep understanding&lt;/strong&gt; of any tool, language, or framework. &lt;/p&gt;




&lt;h3&gt;
  
  
  Encountering Our First Unknown Term
&lt;/h3&gt;

&lt;p&gt;Well... It may be discouraging, you have to do some more research before you can even start learning. Yet the payout will be huge down the road, and you can read some more on the &lt;a href="http://www.computing.surrey.ac.uk/ai/pointer/report/section1.html"&gt;importance of terminology&lt;/a&gt; if you still aren't convinced.&lt;/p&gt;

&lt;p&gt;Our first step would be to google the term. This usually will bring up the documentation page for the specific term, a definition, or link us to stack overflows or github projects that use this terminology. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why is this important? &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We now have context for what we are trying to learn and how it can be used in the real world.&lt;/p&gt;

&lt;p&gt;Our second step is to then try and use the term. For example if you are finding yourself learning any new word you would want to be able to use it in a sentence. The same thing goes for programming lingo, we should be able to use it in a viable way that mimics real world logic.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A side note that some lingo may not do anything, although it can be a term that is used frequently within a specific language, tool, or frameworks documentation and understanding it will be necessary to continue.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This could be shown if you were using MySQL and wanted to learn about the &lt;code&gt;CREATE TABLE&lt;/code&gt; method. MySQL syntax is very logical, so a sentence like &lt;code&gt;I would like to CREATE a TABLE of cats.&lt;/code&gt; could seem reasonable. Now let's look at how we would do that in MySQL &lt;code&gt;CREATE TABLE cats&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Logical enough, but now that we have translated our understanding into the tools specific lingo, how do we use it?&lt;/p&gt;

&lt;p&gt;Finally we would want to implement this an experiment until we feel comfortable with how the lingo translates into functionality. Read more on experimentation here.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Art of Googling
&lt;/h2&gt;

&lt;p&gt;When teaching yourself google is your guide through a massive amount of completely free education material! &lt;/p&gt;

&lt;p&gt;Since there is so much material out there, and we are also going to be learning a variety of things we need to be able to google like an expert.&lt;/p&gt;




&lt;h3&gt;
  
  
  Searching With Relevance
&lt;/h3&gt;

&lt;p&gt;Whatever we are trying to learn we need to search for something relevant. &lt;/p&gt;

&lt;p&gt;For example if we were in the midst of learning Ruby and were stuck on string concatenations (follow along if you haven't heard of concatenations you'll learn something new), a google search of &lt;code&gt;Ruby String examples&lt;/code&gt; probably isn't what we would want to search. &lt;/p&gt;

&lt;p&gt;Let's make sure we are searching for &lt;a href="https://www.google.com/search?q=ruby+string+concatenation"&gt;Ruby String concatenation&lt;/a&gt;, or whatever our relevant topics would be. If we were in Java, it would make sense to search for &lt;code&gt;Java String concatenation&lt;/code&gt; and so on. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://www.howtogeek.com/106718/how-to-search-google-like-a-pro-11-tricks-you-have-to-know/"&gt;Helpful Google Guide&lt;/a&gt; - HowToGeek&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Well now that we have all of these great search results, what do we do?&lt;/p&gt;




&lt;h3&gt;
  
  
  Navigating the Sea of Search Results
&lt;/h3&gt;

&lt;p&gt;We have to always think back to our relevance when navigating the vast sea of search results. Following our example from above, we are on the ruby programming language so if we see a site, for example &lt;a href="https://www.rubyguides.com/2019/07/ruby-string-concatenation/"&gt;rubyguides.com&lt;/a&gt;, that is most likely going to be a decent guide.&lt;/p&gt;

&lt;p&gt;One notable site for getting help and more knowledge of any tool, language, framework and to keep a heads up for is &lt;a href="https://stackoverflow.com/"&gt;StackOverflow&lt;/a&gt;. This is a great place to go when experiencing technical issues, bugs, etc. More in the What To Do When I Have Errors section.&lt;/p&gt;

&lt;p&gt;You should also look for GitHub and GitLab examples, as these can further your understanding of the real world usage of what you are trying to learn.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you want to learn a language, using a website like &lt;a href="https://www.w3schools.com/"&gt;W3Schools&lt;/a&gt; or &lt;a href="https://www.codecademy.com/"&gt;Code Academy&lt;/a&gt;, are very great places to start. As they help introduce the languages to you at a beginners level.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  What To Do When I Have Errors
&lt;/h2&gt;

&lt;p&gt;Errors are frustrating. Sometimes you can't figure out what you did wrong.&lt;/p&gt;

&lt;p&gt;First thing is first, always read the &lt;code&gt;stack trace&lt;/code&gt; they might seem scary, but they are actually your best friend! These contain information that tell us exactly what is going wrong. You can read up some more on how these really help you debug your code or application here:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://jgefroh.medium.com/the-dreaded-stack-trace-2692c053b28e"&gt;The Dreaded Stack Trace&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Second thing, once we understand our errors we have to decide if its logical error, syntax error, runtime error. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Syntax Error&lt;/strong&gt; is when we typed something that the interpreter didn't like. &lt;br&gt;
&lt;strong&gt;Runtime Error&lt;/strong&gt; is a little more advanced, usually the generic error type and takes some more debugging.&lt;br&gt;
&lt;strong&gt;Logical Error&lt;/strong&gt; is us making a mistake with how our program or application functions. These can fall under a runtime error or not raise errors at all.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Fixing syntax errors is the easiest as our interpreter will usually tell us the exact file and line that it struggled to read.&lt;/p&gt;

&lt;p&gt;When it comes to the Runtime errors is when things can get difficult. I always ask myself: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Am I infinitely looping? Am I incorrectly using an external tool?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For example lets say I have this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;say_hello_five_times&lt;/span&gt;
  &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;'Hello'&lt;/span&gt;
    &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;say_hello_five_times&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It won't raise any errors, but you may notice you don't get the desired output. That's where we have to give our code what I like to call &lt;strong&gt;a walkthrough&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We walkthrough our code like the computer would, this helps us understand the code we have written and how the computer actually reads that.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# define a method (say_hello_five_times)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;say_hello_five_times&lt;/span&gt;
  &lt;span class="c1"&gt;# set a variable x to 0&lt;/span&gt;
  &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="c1"&gt;# Loop x until it is equal to 5&lt;/span&gt;
  &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
    &lt;span class="c1"&gt;# print 'Hello'&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;'Hello'&lt;/span&gt;
    &lt;span class="c1"&gt;# increase X (0 -&amp;gt; 1 -&amp;gt; 2 -&amp;gt; 3 -&amp;gt; 4 -&amp;gt; 5)&lt;/span&gt;
    &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; 
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# call the say_hello_five_times method&lt;/span&gt;
&lt;span class="n"&gt;say_hello_five_times&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And wait a second now we can see that the computer is looping through 6 times. We would need to change our &lt;code&gt;&amp;lt;=&lt;/code&gt; to &lt;code&gt;&amp;lt;&lt;/code&gt;. This is a very basic example but walking through like the computer would is a great way to find logical errors in your code.&lt;/p&gt;

&lt;p&gt;You can even test parts of your code on &lt;a href="https://www.repl.it"&gt;Repl.it&lt;/a&gt; which is very helpful for quickly debugging portions of larger applications, or even testing something before adding it to your local project.&lt;/p&gt;

&lt;p&gt;After giving your code a quick walkthrough and running through the application as your computer would. If you are still running into errors, it's time to outsource to our good friend google. &lt;/p&gt;

&lt;p&gt;Searching the exact error from our stack trace can lead us to other people who encountered similar issues (&lt;em&gt;hint: stack overflow is where you want to look here&lt;/em&gt;) or even searching it using our pro googling skills.&lt;/p&gt;

&lt;p&gt;If you are lucky enough to be a part of a community that you can reach out to and get individual help on, that is great too, but try solving it yourself first!&lt;/p&gt;

&lt;p&gt;If you can't find any solutions make a post on Stack Overflow. This won't only help you, but anyone else who runs into the issue in the future.&lt;/p&gt;




&lt;h2&gt;
  
  
  Keeping Up The Pace
&lt;/h2&gt;

&lt;p&gt;Learning can be tiring, especially if we are filling this in during our other daily activities. Time management skills are necessary to be a self-taught learner.&lt;/p&gt;




&lt;h3&gt;
  
  
  Setting Attainable Goals
&lt;/h3&gt;

&lt;p&gt;One way that I hold myself accountable is first to set a goal. This will help you feel like you've achieved something when you reach it, no matter how little or big of a win! &lt;/p&gt;

&lt;p&gt;Start with the big picture, for example if you want to be the best chef in the world that's a great goal. Sadly you don't know how to cook yet or where to get one of those fancy hats. That's where we need to set our sub-goals.&lt;/p&gt;

&lt;p&gt;For my main goal of becoming a full-stack software developer, would contain many sub-goals such as: learning Ruby, HTML, CSS, learn how to host a web application, learn ruby on rails, etc. &lt;/p&gt;

&lt;p&gt;If you're a student at the Flatiron school like me, I separate the sections out as my sub-goals either for the day or the week depending on the amount of content.&lt;/p&gt;




&lt;h3&gt;
  
  
  Managing Our Time
&lt;/h3&gt;

&lt;p&gt;If you want to complete your main goal in a year and you have all these different sub-goals, while working, or attending school, etc. it may seem stressful. This is where time management is key. &lt;/p&gt;

&lt;p&gt;It all depends on how fast you want to learn (since we are self-taught learners), but consistency is key. If you want to dedicate at least an hour a day to learning something new, stick with it. Find yourself bored in the middle of the day? &lt;strong&gt;Time to learn something.&lt;/strong&gt; Have a project you've been pushing off all week and can't sleep? Don't start watching that new Netflix show, you could read about something that can help you with the project, or find a video with some relevance to what your learning. Find a new tool to add to your project, or even work on it. &lt;/p&gt;

&lt;p&gt;Learning can be tiring, so we can make it fun or trick ourselves into relaxing while still learning!&lt;/p&gt;




&lt;h3&gt;
  
  
  Finding Our Happy Place
&lt;/h3&gt;

&lt;p&gt;You might be thinking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;AJ, you really want me to stop binging that Netflix show and learn something! How will I ever survive?!?! &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We all have our own happy place, and if it's curling up in bed and watching your favorite movie or tv show then I'm not here to judge or tell you to stop. Having this relief of relaxation, no matter what way you do it, is absolutely necessary for not getting burnt out. Both in our daily lives and whilst we are learning.&lt;/p&gt;

&lt;p&gt;Some of the ways I like to relax are by going on a hike, listening to music, or hanging out with my friends to watch a movie. Find whatever it is that is your happy place and dedicate a little bit of time out of your week to make sure you go there.&lt;/p&gt;

&lt;p&gt;This is &lt;em&gt;extremely&lt;/em&gt; important. If you are feeling overwhelmed or stress, take a step back, breathe, and then come back to it later. &lt;/p&gt;




&lt;h2&gt;
  
  
  Experimentation
&lt;/h2&gt;

&lt;p&gt;When we are learning a vast amount of things at a fast pace, it's easy to lose knowledge of something you learned before and don't use much anymore. This is where experimentation can come into play.&lt;/p&gt;




&lt;h3&gt;
  
  
  Build As You Learn
&lt;/h3&gt;

&lt;p&gt;As you are learning whatever it may be, you should try to implement this outside of just your learning environment. &lt;/p&gt;

&lt;p&gt;For example, if you still wanted to be the best chef in the world you could read up on all the best recipes and then not know how to put it together!&lt;/p&gt;

&lt;p&gt;Within learning software development it's the same way. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Implementing and experimenting with what we learn is a great way of gaining a deeper understanding of a subject and gives us real world context and usage for it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;My favorite way to do this is by creating &lt;a href="https://www.repl.it"&gt;repl's&lt;/a&gt; for new subjects and trying to expand it on my own before moving to the next step. &lt;/p&gt;

&lt;p&gt;For my fellow students at Flatiron, or others learning software development, this could be by trying to raise the level of abstraction before moving to a higher leveled framework. This helps you gain a very deep understanding of how these frameworks actually function off of each other.&lt;/p&gt;




&lt;h3&gt;
  
  
  Make Open Source Projects
&lt;/h3&gt;

&lt;p&gt;This is a great way to get used to working with teams (some all the way around the world) and learning in a collaborative environment. &lt;/p&gt;

&lt;p&gt;Open-Sourcing your work, especially while learning, is a great way to build a portfolio and get experience in the field your studying. Having it be open source lets other people like you who want to learn about similar projects use yours as learning material.&lt;/p&gt;




&lt;h3&gt;
  
  
  Discussion
&lt;/h3&gt;

&lt;p&gt;A couple points for discussion that I would love to here from the community are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What are your favorite ways to relax? (ie: your happy place!)&lt;/li&gt;
&lt;li&gt;What tools have you found useful in your self-teaching experience?&lt;/li&gt;
&lt;li&gt;What's a win you've had recently? (ie: something new you've learnt or built.)&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Credits
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.freepik.com/free-vector/education-horizontal-typography-banner-set-with-learning-knowledge-symbols-flat-illustration_6871644.htm"&gt;Header Image&lt;/a&gt; - Designed by &lt;a href="https://www.freepik.com/macrovector"&gt;macrovector&lt;/a&gt; / &lt;a href="https://www.freepik.com/"&gt;Freepik&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Found an error? Please reach out either on this thread or to me personally so I can fix it.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>productivity</category>
      <category>tutorial</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>Sinatra on Heroku</title>
      <dc:creator>A.J. Romaniello</dc:creator>
      <pubDate>Wed, 24 Feb 2021 22:21:57 +0000</pubDate>
      <link>https://dev.to/ajrom/sinatra-on-heroku-2ld6</link>
      <guid>https://dev.to/ajrom/sinatra-on-heroku-2ld6</guid>
      <description>&lt;h1&gt;
  
  
  Building my first Sinatra Application
&lt;/h1&gt;

&lt;p&gt;I needed to create an application with a basic MVC structure. I chose to go with a Trail rating application that would let users browse and leave reviews on a number of trails. &lt;/p&gt;

&lt;p&gt;You can view the project hosted on heroku here: &lt;a href="https://hike-it-up.herokuapp.com/"&gt;hike-it-up.herokuapp.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CAc0GzUW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ft9onjupbaogtjpvkyjs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CAc0GzUW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ft9onjupbaogtjpvkyjs.png" alt="Hike-It-Up Homepage"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Development
&lt;/h2&gt;

&lt;p&gt;Starting out I used a gem called &lt;a href="https://github.com/thebrianemory/corneal"&gt;Corneal&lt;/a&gt; which is used to generate scaffolding for a basic Sinatra application. Very useful and exactly what I needed to get started.&lt;/p&gt;

&lt;p&gt;I wanted to use &lt;a href="https://github.com/puma/puma"&gt;Puma&lt;/a&gt; over Thin as a webserver which limited me from using &lt;code&gt;shotgun&lt;/code&gt;. Puma is recommended for the production environment over Thin on &lt;a href="https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server"&gt;Heroku&lt;/a&gt;. As well as Heroku not supporting SQLite3, I had to switch to PostgreSQL and for this reason I just all in all removed thin and shotgun from my project.&lt;/p&gt;

&lt;p&gt;As in the development environment puma automatically would update like shotgun would if the changes were to html files.&lt;/p&gt;

&lt;p&gt;As for the database, PostgreSQL is faster, so might as well go with the more optimized option.&lt;/p&gt;

&lt;h2&gt;
  
  
  Production
&lt;/h2&gt;

&lt;p&gt;To deploy this project to Heroku I needed to learn how to correctly configure a Puma web server using workers. Luckily their guide was thorough and helpful when running into errors.&lt;/p&gt;

&lt;p&gt;Heroku also automatically will redeploy your app if you link it to a github repository. This made production even easier once the initial setup was done.&lt;/p&gt;

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

&lt;p&gt;After building this project I am extremely excited for the automation of Rails to build models, views, and controllers as well as dynamically building routes. After learning Sinatra I thought that it felt like magic, yet Rails takes things to a whole new level. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;P.S.&lt;/strong&gt; If you made it this far... thank you! Feel free to check out more information in the projects &lt;a href="https://github.com/CoachLuck/hike-it-up"&gt;README&lt;/a&gt; on github. &lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
