<?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: Roid</title>
    <description>The latest articles on DEV Community by Roid (@okroid).</description>
    <link>https://dev.to/okroid</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%2F158007%2F593c6f46-1d12-4584-92ee-554d9efaaa24.jpg</url>
      <title>DEV Community: Roid</title>
      <link>https://dev.to/okroid</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/okroid"/>
    <language>en</language>
    <item>
      <title>Pokédex with React</title>
      <dc:creator>Roid</dc:creator>
      <pubDate>Mon, 10 Aug 2020 01:38:05 +0000</pubDate>
      <link>https://dev.to/okroid/pokedex-with-react-364d</link>
      <guid>https://dev.to/okroid/pokedex-with-react-364d</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QoGOj9j3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/jc9hihpm6zgs2wuca84k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QoGOj9j3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/jc9hihpm6zgs2wuca84k.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a side project that I've been self studying for the past quarantine days - what day is it exactly? 🤔&lt;/p&gt;

&lt;p&gt;There are indefinitely thousands of Pokédex based projects out there no doubt about that, but what I'm trying to convey here is what I've learned so far in React.&lt;/p&gt;

&lt;h1&gt;
  
  
  Lore
&lt;/h1&gt;

&lt;p&gt;First off, I haven't touched React before and experienced it the first time back in April. It felt weird the first time you play around with it because it wasn't the typical JS,HTML,CSS that many began with and the 'Hello World' you get has already been generated for you through&lt;br&gt;
&lt;br&gt;
 &lt;code&gt;npx create-react-app hello&lt;/code&gt;&lt;br&gt;
&lt;br&gt;
 With the ongoing quarantine life, it was difficult and I had some breakdowns/meltdowns during those times. Eventually, I had to continue and keep pushing I knew the consequences of not doing anything and continue to procrastinate -felt guilty too you know. So I set the nighttime for coding during the weekdays and chill around with the dudes in Discord on the weekends. It was like that for so long that the quarantine meltdown doesn't bother me anymore. Now that it has come to this, I'd like to show what I've learned in React for the past 5 months time.&lt;/p&gt;
&lt;h1&gt;
  
  
  Concept
&lt;/h1&gt;

&lt;p&gt;Why did I pick the Pokédex as my first React project? It's simple I like Pokémon, they've provided an open public API which can be pulled from &lt;a href="https://pokeapi.co"&gt;PokéAPI&lt;/a&gt;. I've done this before but with vanilla JavaScript,HTML and CSS so it shouldn't be that bad right? Well kind of, I had to study the concepts in React, its components and API hooks that may come useful for the project.&lt;/p&gt;
&lt;h1&gt;
  
  
  Tools
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;React&lt;/li&gt;
&lt;li&gt;react-bootstrap&lt;/li&gt;
&lt;li&gt;axios&lt;/li&gt;
&lt;li&gt;pokeapi&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I thought of going react-bootstrap just because I've experienced with bootstrap before and gets the job done. Axios because of its already parsed JSON body.&lt;/p&gt;

&lt;p&gt;I'm not going to go through very thoroughly and deep but just explain the procedure and execution on what is going on in the program.&lt;/p&gt;

&lt;p&gt;The root/parent of the program (App.js) here uses hooks to be used for &lt;strong&gt;Context&lt;/strong&gt; and a constant for &lt;strong&gt;Memo&lt;/strong&gt;. Context here is, as referred to React &lt;a href="https://reactjs.org/docs/context.html"&gt;Docs&lt;/a&gt;, a way of passing down data through the component trees without the need to pass props manually at every level.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;App.js&lt;br&gt;
&lt;/p&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;active&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setActive&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;queryTerm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setQueryTerm&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ProviderVal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useMemo&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="nx"&gt;active&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setActive&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;queryTerm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setQueryTerm&lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;active&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setActive&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;queryTerm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setQueryTerm&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;ContextApp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Provider&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="nx"&gt;ProviderVal&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;ContextApp&lt;/span&gt;&lt;span class="p"&gt;.&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="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;There are two Hooks state used and these two should freely be able to pass down the data from child-parent and parent-child through the ContextApp. Every Context object will have a provider to allow any changes that are being made exclusively, this means it will re-render the value (in this case &lt;code&gt;ProvideVal&lt;/code&gt;) whenever the &lt;code&gt;value&lt;/code&gt; prop changes its value basically. Since ProviderVal is a JavaScript function of &lt;code&gt;useMemo()&lt;/code&gt;, useMemo itself is a HOC (Higher Order Component) that return cached values whenever the dependencies inside of the arrays changes.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;PokemonCard.js&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;PokemonCard&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;}){&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
    &lt;span class="nx"&gt;useEffect&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="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;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;res&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="p"&gt;...&lt;/span&gt;
        &lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="k"&gt;catch&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="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&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="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;url&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="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;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;memo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PokemonCard&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PokemonCard function takes in two props &lt;code&gt;{name, url}&lt;/code&gt; that will re-render whenever it is changed. Changes of &lt;code&gt;{name, url}&lt;/code&gt; takes place in PokemonList.js and Search.js, one is for listing a page filled with pokemons and the other is for searching specific pokemon. Which is why PokemonCard will need to be re-rendered several times through large collections of pokemons and its sprites and other miscellaneous items. The usual axios fetching of the api structure with the [url] as the dependency for changes that will be made in the &lt;code&gt;useEffect()&lt;/code&gt; function. Basically if the url changes, useEffect will need to be run again because it's being included and called by the dependency array.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;PokemonList.js&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;PokemonList&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
    &lt;span class="nx"&gt;useEffect&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="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentPage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;cancelToken&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CancelToken&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;c&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="nx"&gt;cancel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;c&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;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;res&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="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;catch&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;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;cancel&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;currentPage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pageNum&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;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;memo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PokemonList&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;I found this article about Axios Cancel method &lt;a href="https://dev.to/collegewap/cancelling-previous-requests-in-search-bar-using-axios-in-react-3nef"&gt;here&lt;/a&gt;. It's really well done!&lt;br&gt;
The axios fetch here is almost the same but with the [currentPage, pageNum] as the dependency array. The very last bit for exporting the function is being wrapped around the &lt;code&gt;React.memo()&lt;/code&gt; higher order function.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ContextApp.js&lt;br&gt;
&lt;/p&gt;


&lt;/blockquote&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="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;createContext&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="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ContextApp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Creates a context object and initialized.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Search.js&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Search&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;queryTerm&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ContextApp&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;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;queryTerm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toLowerCase&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;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`https://pokeapi.co/api/v2/pokemon/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;PokemonCard&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;url&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's a snippet of the Search function which has the &lt;code&gt;useContext()&lt;/code&gt; function that refers to the {queryTerm} variable. It returns the PokemonCard component that has custome {name} and {url} from the {queryTerm}.&lt;/p&gt;

&lt;h1&gt;
  
  
  Closing
&lt;/h1&gt;

&lt;p&gt;I guess I'm liking it? I'm not sure but I will continue with this project because there's still potential in using this API for more React APIs and concepts that I might've not known about. You can contribute to this &lt;a href="https://github.com/roidsaja/react-pokedex"&gt;project&lt;/a&gt; by creating PRs or Issues.&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>Docker on Raspberry Pi [Bahasa Indonesia]</title>
      <dc:creator>Roid</dc:creator>
      <pubDate>Mon, 01 Jun 2020 21:34:00 +0000</pubDate>
      <link>https://dev.to/okroid/docker-on-raspberry-pi-bahasa-indonesia-2fj9</link>
      <guid>https://dev.to/okroid/docker-on-raspberry-pi-bahasa-indonesia-2fj9</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Apa itu Docker?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Docker adalah alat yang membantu developers, sys-admins dan devops untuk menyebarkan aplikasi mereka di sebuah container dan dijalankan pada sistem operasi yaitu Linux.&lt;/p&gt;

&lt;p&gt;Manfaat utama menggunakan Docker adalah nge-package aplikasi dengan dependencies ke dalam satu unit yang standar. Beda dengan virtual machine, container tidak memiliki overhead yang tinggi dan karena itu memungkinkan penggunaan sistem yang lebih efisien.&lt;/p&gt;

&lt;p&gt;Saya sendiri sudah pernah experience menggunakan dan maintain aplikasi di virtual machine, itu standar industri saat ini masih banyak yang menggunakan virtual machine. Penggunaannya sendiri itu memang hebat dalam menyediakan proses isolasi penuh untuk menjalankan aplikasi. Tapi kekurangan nya VM itu di penggunaan resource dan overhead komputasi yang tinggi. Dengan adanya Docker ini, dia mempunyai prinsip yang sama yakni memanfaatkan low-level proses isolasi dari host OS dan juga menggunakan komputasi yang sangat rendah.&lt;/p&gt;

&lt;p&gt;Post ini saya cuma membahas gimana kalian bisa ngoprek2 dan bermain dengan Docker di Raspberry Pi. Jika ada yang kurang tahu apa itu Raspberry Pi, dasarnya itu komputer kecil yang kalian bisa beli di Tokopedia; Bukalapak; Shopee; dan e-commerce lainnya relatively seharga Rp.500k ribuan. Yang model baru &lt;a href="https://www.tokopedia.com/kivala/raspberry-pi-4-model-b-4gb" rel="noopener noreferrer"&gt;Raspberry Pi 4&lt;/a&gt; itu Rp.1jutaan ini juga include accessories yang diperlukan rata2 harga segituan. Kalau saya sih masih menggunakan model 3b atau 3b+ deh lupa yang mana hehe.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Trus gimana caranya bang?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Saya harap kalian bisa menginstal dan menjalankan Raspbian OS dan juga dapet access ke SSH atau VNC. Mulai sekarang saya akan menunjukkan kepada kalian bagaimana menginstal docker dari fresh Raspbian installation. &lt;/p&gt;

&lt;p&gt;Banyak cara online yang menggunakan cara ini:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;curl -sSL https://get.docker.com | sh&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;dan ini juga kadang nggak bisa diandalkan. Sebaiknya kita mengikuti dari document yang di sediakan dari Docker &lt;a href="https://docs.docker.com/engine/install/debian" rel="noopener noreferrer"&gt;[Docker Docs]&lt;/a&gt;. Saya mengikuti dari docs nya docker, dan juga menemukan masalah waktu menginstal. Kalau kalian mengikuti docs nya dan sudah mencapai di section: &lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ sudo add-apt-repository ...&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;disini saya encounter &lt;strong&gt;Traceback error&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;&lt;code&gt;Error: could not find a distribution template for Raspbian/buster&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Sampai sekarang (02 June 2020), error ini masih Open issue &lt;a href="https://github.com/moby/moby/issues/31405" rel="noopener noreferrer"&gt;disini&lt;/a&gt;. Ada work around nya bukan solusi nya, solusi dan work around berbeda ya. Saya dapat memperbaiki error dengan menggunakan work around yang di provide dari user &lt;em&gt;Chepurko&lt;/em&gt;. Work aroundnya begini&lt;br&gt;
&lt;code&gt;&lt;br&gt;
deb [arch=armhf] https://download.docker.com/linux/debian raspbian-buster main&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
Ini yang ditulis di document Docker, ditambahkan ke directory &lt;code&gt;etc/apt/sources.list.d/docker.list&lt;/code&gt;. Kalau nggak ada &lt;code&gt;docker.list&lt;/code&gt; bisa buat file yang baru dengan nama yang sama.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Docker Time&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Sekarang kita sudah menyiapkan semuanya, saatnya untuk membuat tangan kita kotor. Di bagian ini, kita akan menjalankan container Ubuntu di sistem kita dan merasakan command2 docker.&lt;/p&gt;

&lt;p&gt;Untuk memulai, mari kita jalankan yang berikut di terminal:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ sudo docker pull ubuntu&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Perintah pull ini mengambil image ubuntu dari registri Docker dan menyimpannya ke sistem kita. Kalian dapat menggunakan &lt;code&gt;$ sudo docker images&lt;/code&gt; command untuk melihat daftar semua image di sistem kalian.&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%2Fi%2Fm4lm2632ks2u3o97qoyk.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%2Fi%2Fm4lm2632ks2u3o97qoyk.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Bagus! Sekarang mari kita jalankan Docker berdasarkan image ini. Untuk melakukan itu kita akan menggunakan docker command.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ sudo docker run ubuntu&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Tunggu, keliatannya ngga ada yang terjadi?! Bisa jadi programnya kena bug? Ya tidak. Di belakang layar ada banyak hal yang terjadi dengan Docker, ketika kalian memanggil run command, client Docker menemukan imagenya ubuntu, di load ke container dan eksekusi command dalam container itu. Ketika kita menjalankannya, itu kekurangan perintah yang diperlukan supaya kita bisa menggunakannya. Dasarnya dia nge boot, menjalankan perintah kosong dan kemudian keluar. Proses ini sangat cepat, bayangkan virtual machine saja udah beda jauh di speed performance nya untuk mem-boot, menjalankan perintah dan membunuhnya. Okay, sekarang saatnya untuk melihat perintah &lt;code&gt;$ sudo docker ps&lt;/code&gt; yang menunjukkan semua container yang sedang jalan.&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%2Fi%2Fj3wyqzkmdbs0iz3hlagh.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%2Fi%2Fj3wyqzkmdbs0iz3hlagh.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Kita melihat garis kosong karena tidak ada container yang berjalan. Mari coba varian yang lebih berguna dengan menggunakan &lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ sudo docker ps -a&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Jadi apa yang kita lihat di atas adalah daftar semua container yang sedang jalan di machine saya. Perhatikan dengan STATUS column, ini menunjukkan bahwa container ini keluar beberapa menit yang lalu.&lt;/p&gt;

&lt;p&gt;Mari kita coba menggunakan flag interactive di terminal.&lt;br&gt;
&lt;code&gt;$ sudo docker run -it ubuntu&lt;/code&gt;&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%2Fi%2Fetodeybx0616qqcoi0al.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%2Fi%2Fetodeybx0616qqcoi0al.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Menjalankan command &lt;code&gt;run&lt;/code&gt; dengan flag &lt;code&gt;-it&lt;/code&gt; melampirkan kita ke tty interactive dalam container. Saya juga menggunakan &lt;code&gt;--rm&lt;/code&gt; flag, dasarnya container yang baru saya jalankan bakal di hapus pas saya sudah menggunakannya. Menghapus container juga bisa digunakan dengan command &lt;code&gt;$ sudo docker rm &amp;lt;NAMES/CONTAINER ID&amp;gt;&lt;/code&gt;. Ada banyak command yang kalian bisa main dan oprek sendiri.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Wrapping Up&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Setelah post yang panjang, melelahkan namun menyenangkan, kalian sekarang bisa menghadapi di dunia container! (still far from perfect, but like what others say "practice makes perfect" ). Saya pun sedang bermainan dengan Docker walaupun masih berkuliah, beberapa hari lagi bakal ada ujian akhir semester juga :(&lt;/p&gt;

&lt;p&gt;Saya berharap bahwa menyelesaikan post ini bisa membuat kalian lebih percaya diri kepada kemampuan kalian sebagai developer,sys-admin atau devops. Put your mind and ideas into action, Terima Kasih.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>raspberrypi</category>
      <category>containers</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
