<?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: Milu</title>
    <description>The latest articles on DEV Community by Milu (@milu_franz).</description>
    <link>https://dev.to/milu_franz</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%2F382362%2F3dd66f28-9b5c-4402-a823-58e2e898dd06.jpg</url>
      <title>DEV Community: Milu</title>
      <link>https://dev.to/milu_franz</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/milu_franz"/>
    <language>en</language>
    <item>
      <title>Create a Next.js AI Chatbot App with Vercel AI SDK</title>
      <dc:creator>Milu</dc:creator>
      <pubDate>Fri, 12 Jul 2024 02:13:00 +0000</pubDate>
      <link>https://dev.to/milu_franz/create-a-nextjs-ai-chatbot-app-with-vercel-ai-sdk-42je</link>
      <guid>https://dev.to/milu_franz/create-a-nextjs-ai-chatbot-app-with-vercel-ai-sdk-42je</guid>
      <description>&lt;p&gt;The recent advancements in Artificial Intelligence have propelled me (and probably many in the Software Engineering community) to delve deeper into this field. Initially I wasn't sure where to start, so I enrolled in the &lt;a href="https://www.coursera.org/learn/machine-learning" rel="noopener noreferrer"&gt;Supervised Machine Learning Coursera class&lt;/a&gt; to learn the basics. While the course is fantastic, my hands-on approach led me to implement a quick application to dip my toe and grasp the practical fundamentals. This is how I discovered the &lt;a href="https://sdk.vercel.ai/docs/introduction" rel="noopener noreferrer"&gt;Vercel AI SDK&lt;/a&gt;, paired with the &lt;a href="https://platform.openai.com/api-keys" rel="noopener noreferrer"&gt;OpenAI provider&lt;/a&gt;. Using one of their existing templates, I developed my version of an AI chatbot. This exercise introduced me to the variety of available providers and the possibilities of integrating these providers to offer capabilities to users. In this article, I’ll define the Vercel AI SDK, detail how to use it, and share my thoughts on this experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Vercel AI SDK?
&lt;/h2&gt;

&lt;p&gt;The Vercel AI SDK is a TypeScript toolkit designed to implement Large Language Models (LLMs) capabilities in frameworks such as React, Next.js, Vue, Svelte, Node.js, and others.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Use Vercel AI SDK?
&lt;/h2&gt;

&lt;p&gt;There are several LLM providers available for building AI-powered apps, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OpenAI&lt;/li&gt;
&lt;li&gt;Azure&lt;/li&gt;
&lt;li&gt;Anthropic&lt;/li&gt;
&lt;li&gt;Amazon Bedrock&lt;/li&gt;
&lt;li&gt;Google Generative AI&lt;/li&gt;
&lt;li&gt;Databricks&lt;/li&gt;
&lt;li&gt;Cohere&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, integrating with each provider can vary and is not always straightforward, as some offer SDKs or APIs. With the Vercel AI SDK, you can integrate multiple LLM providers using the same API, UI hooks, and stream generative user interfaces.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Use Vercel AI SDK in a Next.js App?
&lt;/h2&gt;

&lt;p&gt;Vercel offers an AI SDK RSC package that supports React Server Components, enabling you to write UI components that render on the server and stream to the client. This package uses server actions to achieve this. Let's explain some of the functions used:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;useUIState:&lt;/strong&gt; Acts like React’s &lt;code&gt;useState&lt;/code&gt; hook but allows you to access and update the visual representation of the AI state.&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;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setMessages&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useUIState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;AI&lt;/span&gt;&lt;span class="o"&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;&lt;strong&gt;useAIState:&lt;/strong&gt; Provides access to the AI state, which contains context and relevant data shared with the AI model, and allows you to update it.&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;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;aiState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setAiState&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useAIState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;getMutableAIState:&lt;/strong&gt; Provides a mutable copy of the AI state for server-side updates.&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;const&lt;/span&gt; &lt;span class="nx"&gt;aiState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getMutableAIState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;AI&lt;/span&gt;&lt;span class="o"&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;&lt;strong&gt;useActions:&lt;/strong&gt; Provides access to the server actions from the client.&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;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;submitUserMessage&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useActions&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;streamUI:&lt;/strong&gt; Calls a model and returns with a React Server component.&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;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;streamUI&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;openai&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gpt-3.5-turbo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;initial&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;SpinnerMessage&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;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[...],&lt;/span&gt;
    &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;done&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;delta&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;textNode&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;h2&gt;
  
  
  Detailed Tutorial
&lt;/h2&gt;

&lt;p&gt;You can fork the &lt;a href="https://github.com/milufranz08/ai-chatbot" rel="noopener noreferrer"&gt;simplified project I’ve worked on&lt;/a&gt; or use the &lt;a href="https://vercel.com/templates/next.js/nextjs-ai-chatbot" rel="noopener noreferrer"&gt;official Vercel template&lt;/a&gt;. Both repositories have installation information in the README.&lt;/p&gt;

&lt;p&gt;Let's dive into the key parts that make this integration work.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;components/prompt-form.tsx&lt;/em&gt;&lt;br&gt;
In this component, we use the &lt;code&gt;useUIState&lt;/code&gt; hook to update the visual representation of the AI state. We also use the &lt;code&gt;useActions&lt;/code&gt; function to access the &lt;code&gt;submitUserMessage&lt;/code&gt; function that we will create next.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;PromptForm&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;setInput&lt;/span&gt;
&lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;setInput&lt;/span&gt;&lt;span class="p"&gt;:&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;string&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;void&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;submitUserMessage&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useActions&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;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setMessages&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useUIState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;AI&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;form&lt;/span&gt;
      &lt;span class="nx"&gt;onSubmit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;any&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;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&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;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;setInput&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;

        &lt;span class="c1"&gt;// Optimistically add user message UI&lt;/span&gt;
        &lt;span class="nf"&gt;setMessages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentMessages&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;currentMessages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;nanoid&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="na"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;UserMessage&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;value&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;/UserMessage&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="c1"&gt;// Submit and get response message&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;responseMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;submitUserMessage&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="nf"&gt;setMessages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentMessages&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;currentMessages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;responseMessage&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="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="p"&gt;...&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/form&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;lib/chat/actions.tsx&lt;/em&gt;&lt;br&gt;
Now, let's explore the &lt;code&gt;submitUserMessage&lt;/code&gt; function. First, we use &lt;code&gt;getMutableAIState&lt;/code&gt; to define a variable called &lt;code&gt;aiState&lt;/code&gt; and update it with the user-submitted message.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;submitUserMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;use server&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;aiState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getMutableAIState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;AI&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;aiState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;aiState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="na"&gt;messages&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;aiState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;nanoid&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;content&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we use the &lt;code&gt;streamUI&lt;/code&gt; function to define the LLM model we want to use (in this case, gpt-3.5-turbo), set an initial loading state while waiting for the response, and provide an array containing all the messages and their context.&lt;/p&gt;

&lt;p&gt;Since we are using a streaming function, we can display the LLM results as they are received, even if they are incomplete. This enhances the user experience by showing results on the screen quickly, rather than waiting for a complete response.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;submitUserMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;textStream&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;ReturnType&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;createStreamableValue&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;textNode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="o"&gt;|&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;ReactNode&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;streamUI&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;openai&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gpt-3.5-turbo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;initial&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;SpinnerMessage&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;messages&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;aiState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;role&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;message&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="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;done&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;delta&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;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;textStream&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;textStream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createStreamableValue&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="nx"&gt;textNode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;BotMessage&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;textStream&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="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;done&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;textStream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;done&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nx"&gt;aiState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;done&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
          &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;aiState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
          &lt;span class="na"&gt;messages&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;aiState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;nanoid&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
              &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;assistant&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="nx"&gt;content&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;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;textStream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;delta&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;textNode&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;The &lt;code&gt;streamUI&lt;/code&gt; function also has a &lt;code&gt;tools&lt;/code&gt; attribute that could extend your chatbot's capabilities by defining custom tools that can be invoked during the conversation, enhancing the user experience with dynamic and context-aware responses.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;submitUserMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;streamUI&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
    &lt;span class="na"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;weather&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;location&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&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;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`/api/weather/location=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;location&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`The current weather in &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; is &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;weather&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; with a temperature of &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;temperature&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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="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;The tools attribute is added to &lt;code&gt;streamUI&lt;/code&gt; to define custom tools.&lt;br&gt;
In this example, a weather tool is defined that takes a location as an argument. The weather tool makes an API call to &lt;code&gt;/api/weather&lt;/code&gt; to fetch weather information for the given location. The API response is parsed, and a formatted weather message is returned.&lt;/p&gt;

&lt;p&gt;And there you have it! You can get an AI chatbot working pretty quickly with these functions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Thoughts on Vercel AI SDK
&lt;/h2&gt;

&lt;p&gt;The Vercel AI SDK was intuitive and easy to use, especially if you already have experience with Next.js or React. While you could implement the OpenAI SDK directly, the Vercel AI SDK’s ability to integrate multiple LLM models without additional boilerplate makes it a good choice. &lt;/p&gt;

</description>
      <category>openai</category>
      <category>nextjs</category>
      <category>beginners</category>
      <category>ai</category>
    </item>
    <item>
      <title>Terraform 101: The What, the Why, and the How</title>
      <dc:creator>Milu</dc:creator>
      <pubDate>Thu, 05 Jan 2023 18:26:23 +0000</pubDate>
      <link>https://dev.to/milu_franz/terraform-101-the-what-the-why-and-the-how-624</link>
      <guid>https://dev.to/milu_franz/terraform-101-the-what-the-why-and-the-how-624</guid>
      <description>&lt;p&gt;It's been nearly two years since I first encountered Terraform. In my first week working with Terraform, I got myself into a bad local state that led to countless error messages, many trials and errors, and the exposure to numerous Stack Overflow threads. Ultimately I manually deleted all my AWS resources. To say the least, my introduction to Terraform was a total nightmare. After that, I didn’t want to touch Terraform again. Little did I know I would learn to appreciate and even enjoy working with this powerful tool. &lt;/p&gt;

&lt;p&gt;On my journey, I struggled to find tutorials that use Terraform to set up AWS resources, so I decided to share the knowledge I acquired with the hopes you (dear reader) will be able to skip some of the troubles I encountered. This post is going to define Terraform, list the reasons why you might want to learn it and use it, and go through the set up process step by step.&lt;/p&gt;

&lt;h2&gt;
  
  
  The What
&lt;/h2&gt;

&lt;p&gt;Terraform is an infrastructure as code tool (IAC) created by &lt;a href="https://www.hashicorp.com/"&gt;HashiCorp&lt;/a&gt; that lets you automate cloud and on-prem resources. It uses configuration files written in HashiCorp Configuration Language (HCL) to declare resources (infrastructure objects) and define dependencies between them. To put it simply, this tool allows you to write a few configuration files and build a whole system’s architecture on the cloud by running a couple of commands. I found this to be a more efficient alternative to clicking through a console to create resources manually. &lt;/p&gt;

&lt;h3&gt;
  
  
  Terraform State
&lt;/h3&gt;

&lt;p&gt;Terraform keeps track of the infrastructure it created in a state file. Every time you run Terraform, it compares the latest status of your resources with the state configurations you declared and it determines what changes need to be applied.&lt;/p&gt;

&lt;p&gt;When working with a team, you would need to manage shared storage for state files in a remote backend. This will prevent multiple team members from applying changes at the same time. Using a remote backend also provides access control management as data in the state files are stored in plain text, including passwords. A number of remote backends are supported. However, the example below will be using AWS S3 as the remote backend.&lt;/p&gt;




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

&lt;p&gt;In my opinion, the following reasons explain why using Terraform in your project is a good idea:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Speed.&lt;/strong&gt; As I mentioned above, the automation benefit of using this tool is truly the best part! By leveraging Terraform, you can configure and provision an entire infrastructure architecture for multiple environments (development, testing/staging, production) by running a few commands.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Collaboration.&lt;/strong&gt; Terraform captures the desired project goal in a state and it keeps track of all state changes in the environment. This is perfect when working in a team, every member of the team is able to contribute in the same way they would with regular application code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agentless.&lt;/strong&gt; Terraform is cloud-agnostic so you can use it with different providers such as AWS or Azure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reusability.&lt;/strong&gt; Terraform is modular. If you are provisioning similar resources, you can abstract this code, create a module and reuse it. This saves you a lot of work and reduces repetition in your code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Error reduction.&lt;/strong&gt; Standardizing the creation of cloud resources using code minimizes the probability of errors when provisioning in multiple environments.&lt;/p&gt;




&lt;h2&gt;
  
  
  The How
&lt;/h2&gt;

&lt;p&gt;It’s time to dive into the fun part! Let’s talk about how to set up Terraform in your project. &lt;/p&gt;

&lt;p&gt;1) The first thing you need to do is download &lt;a href="https://developer.hashicorp.com/terraform/downloads?ref=hackernoon.com"&gt;Terraform&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;2) Create a directory dedicated to terraform in your project. I called mine &lt;code&gt;tf&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;3) Create a &lt;code&gt;main.tf&lt;/code&gt; file in your newly created directory. Here is where you are going to define your providers. In this example, we are defining AWS as a provider.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;terraform&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;required_providers&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;aws&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;source&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"hashicorp/aws"&lt;/span&gt;
      &lt;span class="nx"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"~&amp;gt; 4.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;required_version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"~&amp;gt; 1.3.6"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4) Create a &lt;code&gt;backend.tf&lt;/code&gt; file. Here we are going to create and configure our remote state storage using a &lt;strong&gt;S3 bucket&lt;/strong&gt; and a &lt;strong&gt;DynamoDB table&lt;/strong&gt;. I’ve added comments above every resource block so you get a good idea of what these resources are doing. I encourage you to check the Terraform documentation for each resource as well. Also, here is an excellent &lt;a href="https://blog.gruntwork.io/how-to-manage-terraform-state-28f5697e68fa#aeb7"&gt;post&lt;/a&gt; that explains each line in detail.&lt;/p&gt;

&lt;p&gt;Essentially, the following code creates a S3 bucket called &lt;em&gt;“remote_state”&lt;/em&gt; that cannot be deleted, keeps versioning of every change, uses encryption by default, and blocks public access.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ----------------------------------------------------&lt;/span&gt;
&lt;span class="c1"&gt;# configure aws provider&lt;/span&gt;
&lt;span class="c1"&gt;# ----------------------------------------------------&lt;/span&gt;
&lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"aws"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;region&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"us-east-2"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# ----------------------------------------------------&lt;/span&gt;
&lt;span class="c1"&gt;# create S3 bucket (backend)&lt;/span&gt;
&lt;span class="c1"&gt;# ----------------------------------------------------&lt;/span&gt;
&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_s3_bucket"&lt;/span&gt; &lt;span class="s2"&gt;"remote_state"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;YOUR-PROJECT-NAME&amp;gt;-remote-state"&lt;/span&gt;

  &lt;span class="c1"&gt;# Prevent accidental deletion of this S3 bucket&lt;/span&gt;
  &lt;span class="nx"&gt;lifecycle&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;prevent_destroy&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="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Every update to a file in the bucket creates a new version of that file&lt;/span&gt;
&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_s3_bucket_versioning"&lt;/span&gt; &lt;span class="s2"&gt;"enabled"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_s3_bucket&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;remote_state&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
  &lt;span class="nx"&gt;versioning_configuration&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Enabled"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Turn server-side encryption on by default&lt;/span&gt;
&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_s3_bucket_server_side_encryption_configuration"&lt;/span&gt; &lt;span class="s2"&gt;"default"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_s3_bucket&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;remote_state&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;

  &lt;span class="nx"&gt;rule&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;apply_server_side_encryption_by_default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;sse_algorithm&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"AES256"&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;# Block all public access to the S3 bucket&lt;/span&gt;
&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_s3_bucket_public_access_block"&lt;/span&gt; &lt;span class="s2"&gt;"public_access"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;bucket&lt;/span&gt;                  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_s3_bucket&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;remote_state&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
  &lt;span class="nx"&gt;block_public_acls&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="nx"&gt;block_public_policy&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="nx"&gt;ignore_public_acls&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="nx"&gt;restrict_public_buckets&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In addition, we create a DynamoDB table for locking. It uses a primary key called &lt;code&gt;LockedID&lt;/code&gt; and it has to match exactly (spelling and capitalization) for locking to work.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ----------------------------------------------------&lt;/span&gt;
&lt;span class="c1"&gt;# create dynamo db table for state locking &lt;/span&gt;
&lt;span class="c1"&gt;# ----------------------------------------------------&lt;/span&gt;
&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_dynamodb_table"&lt;/span&gt; &lt;span class="s2"&gt;"terraform_statelock"&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;"&amp;lt;YOUR-PROJECT-NAME&amp;gt;-tf-statelock"&lt;/span&gt;
  &lt;span class="nx"&gt;read_capacity&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;
  &lt;span class="nx"&gt;write_capacity&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;
  &lt;span class="nx"&gt;hash_key&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"LockID"&lt;/span&gt;

  &lt;span class="nx"&gt;attribute&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;"LockID"&lt;/span&gt;
    &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"S"&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;5) Set your AWS secret access key and access key id to access the AWS api on your terminal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="nx"&gt;AWS_ACCESS_KEY_ID&lt;/span&gt;&lt;span class="o"&gt;=********&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="nx"&gt;AWS_SECRET_ACCESS_KEY&lt;/span&gt;&lt;span class="o"&gt;=********&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;6) On your terminal, &lt;code&gt;cd&lt;/code&gt; into the &lt;code&gt;tf&lt;/code&gt; directory and run &lt;code&gt;terraform init&lt;/code&gt;. This command will download the provider code. Then, run &lt;code&gt;terraform plan&lt;/code&gt; to see a list of the changes that will be recorded on your state.&lt;/p&gt;

&lt;p&gt;7) Run &lt;code&gt;terraform apply&lt;/code&gt;. This command will build the S3 bucket and the DynamoDB table we declared above.&lt;/p&gt;

&lt;p&gt;8) Now that we have provisioned the resources needed, let's add a backend configuration to the &lt;code&gt;terraform&lt;/code&gt; configuration code under the &lt;code&gt;main.tf&lt;/code&gt; file. The following code is defining S3 as our backend.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;terraform&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;...&lt;/span&gt;

  &lt;span class="nx"&gt;backend&lt;/span&gt; &lt;span class="s2"&gt;"s3"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;YOUR-PROJECT-NAME&amp;gt;-remote-state"&lt;/span&gt;
    &lt;span class="nx"&gt;key&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"global/s3/terraform.tfstate"&lt;/span&gt;
    &lt;span class="nx"&gt;region&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"us-east-2"&lt;/span&gt;

    &lt;span class="nx"&gt;dynamodb_table&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;YOUR-PROJECT-NAME&amp;gt;-tf-statelock"&lt;/span&gt;
    &lt;span class="nx"&gt;encrypt&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;9) Run &lt;code&gt;terraform init&lt;/code&gt;. This command will configure the Terraform backend to the S3 bucket as indicated above. Go to the AWS console and take a look at your DynamoDB table, you should see your first state file!&lt;/p&gt;

&lt;p&gt;10) Run &lt;code&gt;terraform apply&lt;/code&gt;. After setting up our lock DynamoDB table, this command prompts Terraform to acquire a lock before running &lt;code&gt;apply&lt;/code&gt; and releases the lock after it’s done.&lt;/p&gt;

&lt;p&gt;That’s it! Now your project is set up to use Terraform. From here, we can declare resources and provision them by running &lt;code&gt;terraform plan&lt;/code&gt; and &lt;code&gt;terraform apply&lt;/code&gt;. I’m planning to write a continuation post that uses this setup as a base to provision a simple REST api. Thank you for reading!&lt;/p&gt;

&lt;p&gt;Give this post a reaction if you found it helpful and follow me on &lt;a href="https://twitter.com/milu_franz"&gt;Twitter&lt;/a&gt; and &lt;a href="https://dev.to/milu_franz"&gt;Dev.to&lt;/a&gt; to keep up with new posts!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Resources:&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://developer.hashicorp.com/terraform/language"&gt;https://developer.hashicorp.com/terraform/language&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.linode.com/docs/guides/introduction-to-hcl/"&gt;https://www.linode.com/docs/guides/introduction-to-hcl/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://developer.hashicorp.com/terraform/language/state"&gt;https://developer.hashicorp.com/terraform/language/state&lt;/a&gt;&lt;br&gt;
&lt;a href="https://zerotomastery.io/blog/benefits-of-using-terraform/"&gt;https://zerotomastery.io/blog/benefits-of-using-terraform/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.varonis.com/blog/what-is-terraform"&gt;https://www.varonis.com/blog/what-is-terraform&lt;/a&gt;&lt;/p&gt;

</description>
      <category>terraform</category>
      <category>beginners</category>
      <category>devops</category>
      <category>aws</category>
    </item>
    <item>
      <title>Demystifying React Hooks: useReducer</title>
      <dc:creator>Milu</dc:creator>
      <pubDate>Mon, 13 Jul 2020 14:54:35 +0000</pubDate>
      <link>https://dev.to/milu_franz/demystifying-react-hooks-usereducer-3o3n</link>
      <guid>https://dev.to/milu_franz/demystifying-react-hooks-usereducer-3o3n</guid>
      <description>&lt;p&gt;React Hooks are a simpler way to encapsulate stateful behavior and side effects in functional components instead of classes. Some hooks are easier to understand than others, therefore this series of posts will focus on demystifying the hooks that are not as straightforward. &lt;/p&gt;

&lt;p&gt;So far, we have explored useCallback, useMemo, useRef, and useContext so make sure to checkout my previous posts if you haven’t already. This week, let’s start with the basics by explaining the JavaScript &lt;strong&gt;&lt;em&gt;reduce&lt;/em&gt;&lt;/strong&gt; method. Once we explore the basics, it will be much easier to understand the &lt;strong&gt;&lt;em&gt;useReducer&lt;/em&gt;&lt;/strong&gt; hook, as well as how and when to use it in your code.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a reducer?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--37pFwY3g--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/fdm463l6v56wptuga0o0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--37pFwY3g--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/fdm463l6v56wptuga0o0.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;&lt;em&gt;reducer&lt;/em&gt;&lt;/strong&gt; is the action that will be executed in order to get &lt;strong&gt;only one value.&lt;/strong&gt; The goal of a &lt;strong&gt;&lt;em&gt;reducer&lt;/em&gt;&lt;/strong&gt; is to reduce (...duh!). The value returned could be a number, a string, an array or even an object, as long as it is a singular value. Moreover, it is important to highlight that &lt;strong&gt;&lt;em&gt;reducers&lt;/em&gt;&lt;/strong&gt; return a new value instead of mutating your initial value.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;reduces&lt;/em&gt;&lt;/strong&gt; are very useful when you want to obtain a single value after applying some logic to a group of values. For instance, if you want to add up an array of numbers to obtain a total value as we do in the following example. &lt;/p&gt;

&lt;p&gt;We apply the JavaScript &lt;strong&gt;&lt;em&gt;reduce&lt;/em&gt;&lt;/strong&gt; method to an array of numbers called &lt;code&gt;nums = [1,2,3,4,5]&lt;/code&gt;. The &lt;code&gt;reduce&lt;/code&gt; method takes two parameters: &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;reducer&lt;/strong&gt; - a function that provides instructions to obtain one value. In this case, to sum up all the given values in the &lt;code&gt;nums&lt;/code&gt; array.&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;const&lt;/span&gt; &lt;span class="nx"&gt;reducer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;accumulator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;currentValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;accumulator&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;currentValue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;initialValue&lt;/strong&gt; - the starting point value when implementing the &lt;code&gt;reducer&lt;/code&gt; function's instructions. In our example, we define our initial value as 0 so the total value returned reflects only the sum of the values in the array &lt;code&gt;nums&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;initialValue&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that we defined the elements involved, let’s see it all together. The &lt;code&gt;reduce&lt;/code&gt; method takes our &lt;code&gt;initialValue&lt;/code&gt; and builds on it by following the instructions given under the &lt;code&gt;reducer&lt;/code&gt; function, adding each value in the &lt;code&gt;nums&lt;/code&gt; array until it is able to return one total value.&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;// reducer method - the action that will be executed in order to get one value&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;reducer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;accumulator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;currentValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;accumulator&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;currentValue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// array of values that we want to add up&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nums&lt;/span&gt; &lt;span class="o"&gt;=&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="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="c1"&gt;// initial value set to 0&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;initialValue&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="c1"&gt;// JavaScript reduce method receives two parameters: the reducer function and initial value defined above&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;totalValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reducer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;initialValue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What is useReducer()?
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;&lt;em&gt;useReducer&lt;/em&gt;&lt;/strong&gt; hook is used with state management. It receives the following parameters: &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;reducer&lt;/strong&gt; - a function that provides instructions on how to manage state. It takes two parameters &lt;code&gt;state&lt;/code&gt; and &lt;code&gt;action&lt;/code&gt; and it returns a new state.&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;// reducer type&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;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;newState&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;initialState&lt;/strong&gt; - the starting point value. It will change according to the &lt;code&gt;reducer&lt;/code&gt; instructions.&lt;/p&gt;

&lt;p&gt;Does it look familiar? Well yeah... It takes similar parameters as the &lt;strong&gt;&lt;em&gt;reduce&lt;/em&gt;&lt;/strong&gt; function explained above. However, the &lt;strong&gt;&lt;em&gt;useReducer&lt;/em&gt;&lt;/strong&gt; hook does not return just one value as &lt;strong&gt;&lt;em&gt;reduce&lt;/em&gt;&lt;/strong&gt; does. Instead it returns two elements as an array, the current &lt;code&gt;state&lt;/code&gt; and a &lt;code&gt;dispatch&lt;/code&gt; function.&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;const&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;dispatch&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useReducer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reducer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are familiar with React hooks, you probably have used &lt;strong&gt;&lt;em&gt;useState&lt;/em&gt;&lt;/strong&gt; before. Let’s compare these two hooks&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;// useState implementation&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;state&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="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="nx"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// useReducer implementation&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;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useReducer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reducer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;useReducer&lt;/em&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;em&gt;useState&lt;/em&gt;&lt;/strong&gt; both return a stateful value (&lt;code&gt;state&lt;/code&gt;), and a function to update the state (&lt;code&gt;setState&lt;/code&gt; and &lt;code&gt;dispatch&lt;/code&gt;). In addition, both hooks receive an initial state value (&lt;code&gt;initialValue&lt;/code&gt;). The main difference in these two initializations is that &lt;strong&gt;&lt;em&gt;useReducer&lt;/em&gt;&lt;/strong&gt; also takes a &lt;code&gt;reducer&lt;/code&gt; function, which will be called when we use the returned &lt;code&gt;dispatch&lt;/code&gt; function. Let’s explore how &lt;strong&gt;&lt;em&gt;useReducer&lt;/em&gt;&lt;/strong&gt; works in the next section.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use useReducer?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AMPFLPYx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/vy5bq1x9f26yteauzh97.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AMPFLPYx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/vy5bq1x9f26yteauzh97.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sometimes the best way to explain how something works is with an example so let’s take a look at one. Here is a definition for an &lt;code&gt;initialState&lt;/code&gt;, also called a store of data,  that contains a list of dogs up for adoption with their name, breed, and adoption status.&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;const&lt;/span&gt; &lt;span class="nx"&gt;initialState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
 &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Waffles&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;breed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Chihuahua&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;adopted&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&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="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Charlie&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;breed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Pitbull&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;adopted&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="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Prince&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;breed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;German Shepherd&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;adopted&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&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;Now let’s create a &lt;code&gt;reducer&lt;/code&gt; function to update our &lt;code&gt;initialState&lt;/code&gt; list of dogs as they get adopted or returned. This function takes the following parameters:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;state&lt;/code&gt; - the current state of our dogs in adoption.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;action&lt;/code&gt; - an object that contains the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;type&lt;/code&gt; of action we want to perform. In this case, we are only building two options, &lt;code&gt;adopt&lt;/code&gt; or ‘return’.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;payload&lt;/code&gt; optional data. In our example, we will pass the dog’s &lt;code&gt;name&lt;/code&gt; so we can identify which dog got adopted or returned.&lt;br&gt;
&lt;/p&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;reducer&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;action&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;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;ADOPT&lt;/span&gt;&lt;span class="dl"&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;state&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;dog&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="nx"&gt;dog&lt;/span&gt;&lt;span class="p"&gt;.&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;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;dog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;adopted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&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;dog&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;RETURN&lt;/span&gt;&lt;span class="dl"&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;state&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;dog&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="nx"&gt;dog&lt;/span&gt;&lt;span class="p"&gt;.&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;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;dog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;adopted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&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;dog&lt;/span&gt;&lt;span class="p"&gt;;&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now It’s finally time to implement our &lt;strong&gt;&lt;em&gt;useReducer()&lt;/em&gt;&lt;/strong&gt; hook! Take a look at the example below, where we define our &lt;strong&gt;&lt;em&gt;useReducer()&lt;/em&gt;&lt;/strong&gt; hook with the &lt;code&gt;initialState&lt;/code&gt; (adoption dogs list) and the &lt;code&gt;reducer&lt;/code&gt; function we created to handle their adoption status. &lt;/p&gt;

&lt;p&gt;We iterate through our dogs list state and display a button that will say &lt;code&gt;adopt&lt;/code&gt; or &lt;code&gt;return&lt;/code&gt; depending on their current adoption status. The &lt;code&gt;onClick&lt;/code&gt; handler assigned to our button will call a function in charge of using the &lt;code&gt;dispatch&lt;/code&gt; function returned by our &lt;strong&gt;&lt;em&gt;useReducer()&lt;/em&gt;&lt;/strong&gt; hook passing the &lt;code&gt;type&lt;/code&gt; of action it needs to perform and the dog’s name as &lt;code&gt;payload&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;adoptDog&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;dispatch&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;ADOPT&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;payload&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;dispatch&lt;/code&gt; function will pass this data to our &lt;code&gt;reducer&lt;/code&gt; function, where we will use the &lt;code&gt;type&lt;/code&gt; to identify what section of code needs to run and the &lt;code&gt;payload&lt;/code&gt; to find the dog record we need to update.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/Milu5489/embed/vYLaEzB?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  When should you use useReducer?
&lt;/h2&gt;

&lt;p&gt;When explaining the &lt;strong&gt;&lt;em&gt;useReducer&lt;/em&gt;&lt;/strong&gt; hook, we compared it to &lt;strong&gt;&lt;em&gt;useState&lt;/em&gt;&lt;/strong&gt; so you might be wondering… when should I use &lt;strong&gt;&lt;em&gt;useReducer&lt;/em&gt;&lt;/strong&gt; and when should I use &lt;strong&gt;&lt;em&gt;useState&lt;/em&gt;&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;&lt;em&gt;useReducer&lt;/em&gt;&lt;/strong&gt; hook is a preferred alternative to &lt;strong&gt;&lt;em&gt;useState&lt;/em&gt;&lt;/strong&gt; when dealing with the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Complex state logic that involves multiple sub-values&lt;/li&gt;
&lt;li&gt;State values that depend on the state of other state elements&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The JavaScript &lt;strong&gt;&lt;em&gt;reduce&lt;/em&gt;&lt;/strong&gt; method is very useful when you want to obtain a single value after applying some logic to a group of values.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;reducers&lt;/em&gt;&lt;/strong&gt; return a new value instead of mutating your initial value.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;strong&gt;&lt;em&gt;useReducer&lt;/em&gt;&lt;/strong&gt; hook is used with state management.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;strong&gt;&lt;em&gt;useReducer&lt;/em&gt;&lt;/strong&gt; hook should be used when dealing with complex state logic, multiple sub-values, or when your state depends on state sub-values.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;I hope this post helped you get a better understanding of the JavaScript &lt;strong&gt;&lt;em&gt;reduce&lt;/em&gt;&lt;/strong&gt; method and the &lt;strong&gt;&lt;em&gt;useReducer()&lt;/em&gt;&lt;/strong&gt; hook and that you will start taking advantage of these concepts in your future projects.&lt;/p&gt;

&lt;p&gt;I enjoy creating content that explains concepts in really simple terms. &lt;strong&gt;&lt;em&gt;Why?&lt;/em&gt;&lt;/strong&gt; Because knowledge is power and I want to help beginner developers expand their knowledge and thrive.&lt;/p&gt;

&lt;p&gt;Give this post a reaction if you found it helpful and follow me on &lt;a href="https://twitter.com/milu_franz"&gt;Twitter&lt;/a&gt; and &lt;a href="https://dev.to/milu_franz"&gt;Dev.to&lt;/a&gt; to keep up with new posts!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>beginners</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Demystifying React Hooks: useContext</title>
      <dc:creator>Milu</dc:creator>
      <pubDate>Sat, 27 Jun 2020 15:36:24 +0000</pubDate>
      <link>https://dev.to/milu_franz/demystifying-react-hooks-usecontext-5g4a</link>
      <guid>https://dev.to/milu_franz/demystifying-react-hooks-usecontext-5g4a</guid>
      <description>&lt;p&gt;React Hooks changed the way functional components are used providing them with a simpler way to encapsulate stateful behavior and side effects in a user interface. Since some hooks are easier to understand and use than others, this series of posts will focus on demystifying the hooks that are not as straightforward. &lt;/p&gt;

&lt;p&gt;So far, we explored useCallback, useMemo, and useRef in depth. This post will start by exploring the difference in between &lt;strong&gt;&lt;em&gt;prop drilling&lt;/em&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;em&gt;context&lt;/em&gt;&lt;/strong&gt;, followed by defining a &lt;strong&gt;&lt;em&gt;context object&lt;/em&gt;&lt;/strong&gt;, explaining &lt;strong&gt;&lt;em&gt;how to use the useContext() hook&lt;/em&gt;&lt;/strong&gt;, and &lt;strong&gt;&lt;em&gt;how to optimize its performance.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Prop drilling vs Context
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rzvehWlw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/fpgl2l61he7v9t8npp0b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rzvehWlw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/fpgl2l61he7v9t8npp0b.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;React provides us with a data-flow where a parent component uses props to share data with its children. This way of tracking data works great for small apps, however, as your application grows you might find yourself passing a prop through multiple layers of components. This is called &lt;strong&gt;&lt;em&gt;prop drilling.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When passing props through multiple layers, identifying where data is being initialized and when data is actually being used can become very challenging and cumbersome. In addition, refactoring your code could lead to passing unnecessary props or using multiple names for one prop (AKA bugs!). &lt;/p&gt;

&lt;p&gt;An alternative to &lt;strong&gt;&lt;em&gt;prop drilling&lt;/em&gt;&lt;/strong&gt; is to use &lt;strong&gt;&lt;em&gt;Context&lt;/em&gt;&lt;/strong&gt;,  a simple and light solution that gives us  the capability of accessing data across components even when they don’t have a parent-child relationship.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a context object?
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;&lt;em&gt;context object&lt;/em&gt;&lt;/strong&gt; is created using the &lt;code&gt;createContext()&lt;/code&gt; API and its composed by two elements:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Provider:&lt;/strong&gt; it provides the value&lt;br&gt;
&lt;strong&gt;Consumer:&lt;/strong&gt; it consumes the value&lt;/p&gt;

&lt;p&gt;To create a context object, you can initialize it empty or with a value:&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;const&lt;/span&gt; &lt;span class="nx"&gt;testContext&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And you can access its elements by destructuring them in this way:&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;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Provider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Consumer&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;testContext&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How to use the Provider?
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;Provider&lt;/code&gt; in your &lt;strong&gt;&lt;em&gt;context object&lt;/em&gt;&lt;/strong&gt; needs to wrap around the parent element of a component-tree. This gives every component under that component-tree access to your global data. Take a look at the &lt;code&gt;&amp;lt;Provider&amp;gt;&lt;/code&gt; tags below, they are making the &lt;code&gt;name&lt;/code&gt; state accessible to all the components being wrapped. Now, the components &lt;code&gt;&amp;lt;NameModifier /&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;NamePrinter /&amp;gt;&lt;/code&gt; (and any of their children) have access to the state &lt;code&gt;name&lt;/code&gt; even though we are not passing &lt;code&gt;name&lt;/code&gt; as a prop.&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;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="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;Provider&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;testContext&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;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setTestName&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="err"&gt;“&lt;/span&gt;&lt;span class="nx"&gt;Milu&lt;/span&gt;&lt;span class="err"&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;Provider&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&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="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;NameModifier&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;NamePrinter&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;/Provider&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How to access our global data using useContext()?
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;&lt;em&gt;useContext()&lt;/em&gt;&lt;/strong&gt; hook accepts a &lt;strong&gt;&lt;em&gt;context object&lt;/em&gt;&lt;/strong&gt; (defined above) and returns the current values made available by the Provider as static variables. &lt;/p&gt;

&lt;p&gt;Here we have our &lt;code&gt;&amp;lt;NamePrinter /&amp;gt;&lt;/code&gt; component (wrapped by the Provider tag in the previous section of code) and we are accessing the value of &lt;code&gt;name&lt;/code&gt; by using our &lt;code&gt;userContext()&lt;/code&gt; hook.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;NamePrinter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="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;name&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;testContext&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&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="nx"&gt;My&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="nx"&gt;is&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="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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Did you notice how &lt;code&gt;&amp;lt;NamePrinter /&amp;gt;&lt;/code&gt; is not taking any props? The &lt;code&gt;name&lt;/code&gt; value is being accessed using the &lt;strong&gt;&lt;em&gt;useContext()&lt;/em&gt;&lt;/strong&gt; hook instead.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  How do I update my context?
&lt;/h2&gt;

&lt;p&gt;You can also make functions available through your &lt;strong&gt;&lt;em&gt;Provider&lt;/em&gt;&lt;/strong&gt;! &lt;/p&gt;

&lt;p&gt;In the following example, I’ve created a function called &lt;code&gt;updateName()&lt;/code&gt; that allows you to modify the &lt;code&gt;name&lt;/code&gt; state. If you take a look at the &lt;code&gt;&amp;lt;NameModifier /&amp;gt;&lt;/code&gt; component, I’m accessing the &lt;code&gt;updateName()&lt;/code&gt; function using the useContext hook and calling it every time my input changes.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/Milu5489/embed/vYLJRwR?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  What about performance?
&lt;/h2&gt;

&lt;p&gt;A component that uses &lt;strong&gt;&lt;em&gt;useContext()&lt;/em&gt;&lt;/strong&gt; will re-render when the value in the &lt;strong&gt;&lt;em&gt;context object&lt;/em&gt;&lt;/strong&gt; is updated. You could run into an instance where one of the values in your context changes very often, which could cause all your components using &lt;strong&gt;&lt;em&gt;useContext()&lt;/em&gt;&lt;/strong&gt; to re-render even though the fast-changing-value is only used in a small component-tree. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The recommended solution is to split Context.&lt;/strong&gt; Therefore if you have Light/Dark Themes and a toggle to choose in between them that most likely won’t change too often in comparison to other values being shared by your context, you want to create a &lt;code&gt;ThemeContext&lt;/code&gt; and &lt;code&gt;AppContext&lt;/code&gt; as shown below.&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;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;themeToggle&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ThemeProvider&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;themeToggle&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;AppContext&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HomePage&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;/AppContext&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;/ThemeProvider&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;The use of a &lt;strong&gt;&lt;em&gt;context&lt;/em&gt;&lt;/strong&gt; object is a great alternative to &lt;strong&gt;&lt;em&gt;prop drilling&lt;/em&gt;&lt;/strong&gt;. It allows you to access global data without passing it as props and it subscribes to it to re-render when it changes.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;&lt;em&gt;context&lt;/em&gt;&lt;/strong&gt; object contains two elements: &lt;code&gt;Provider&lt;/code&gt; and &lt;code&gt;Consumer&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Provider&lt;/code&gt; element needs to wrap the component-tree that will have access to the global data.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;&lt;em&gt;useContext()&lt;/em&gt;&lt;/strong&gt; hook allows you to access the global data from any child components in the component-tree under the &lt;code&gt;Provider&lt;/code&gt; wrapper.&lt;/p&gt;

&lt;p&gt;To avoid unnecessary re-renders, split your &lt;strong&gt;&lt;em&gt;context&lt;/em&gt;&lt;/strong&gt;. i.e. using &lt;code&gt;ThemeContext&lt;/code&gt; and &lt;code&gt;AppContext&lt;/code&gt;.&lt;/p&gt;




&lt;p&gt;I hope this explanation of &lt;strong&gt;&lt;em&gt;useContext()&lt;/em&gt;&lt;/strong&gt; was helpful and that you will be applying these new concepts in future applications!&lt;/p&gt;

&lt;p&gt;I post new content every week. We will be exploring a different React hook next Weekend. Follow me on &lt;a href="https://twitter.com/milu_franz"&gt;Twitter&lt;/a&gt; and &lt;a href="https://dev.to/milu_franz"&gt;Dev.to&lt;/a&gt; to keep up with new posts!&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Demystifying React Hooks: useRef</title>
      <dc:creator>Milu</dc:creator>
      <pubDate>Sat, 20 Jun 2020 17:02:13 +0000</pubDate>
      <link>https://dev.to/milu_franz/demystifying-react-hooks-useref-2ddp</link>
      <guid>https://dev.to/milu_franz/demystifying-react-hooks-useref-2ddp</guid>
      <description>&lt;p&gt;React Hooks changed the game when they came out! They are a simpler way to encapsulate stateful behavior and side effects in a user interface while using less code and increasing readability. Some hooks are easier to understand and use than others, this is why this series of posts will focus on demystifying the hooks that are not as straightforward. &lt;/p&gt;

&lt;p&gt;Last week, we explored useCallback and useMemo in depth. Today, let’s start by explaining what it means to &lt;strong&gt;imperatively modify a child and the DOM&lt;/strong&gt;, continue by focusing on &lt;strong&gt;defining the useRef hook&lt;/strong&gt; and &lt;strong&gt;discussing how, when, and where to use it.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Imperatively modify a child and the DOM
&lt;/h2&gt;

&lt;p&gt;If you have worked with React before, you must be familiar with how a parent component uses props to interact with its children. In order to re-render a child component with different data, the parent component passes new props. &lt;/p&gt;

&lt;p&gt;At times, we face situations where we need to imperatively modify a child component outside of the typical "passing props" dataflow or we want to manually access DOM nodes or React elements created in the render method. Here is when &lt;strong&gt;useRef()&lt;/strong&gt; becomes handy!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xHmFlsGU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/h7byyoql47rsn7emwl6z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xHmFlsGU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/h7byyoql47rsn7emwl6z.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why is useRef() Hook special?
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;useRef()&lt;/strong&gt; hook persists in between component renders (like state).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The magic of useRef is that it can be mutated without causing your component to re-update because the useRef value exists outside of the render cycle.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  How to use useRef() Hook?
&lt;/h2&gt;

&lt;p&gt;You initialize a &lt;strong&gt;useRef()&lt;/strong&gt; hook by passing an initial value to it or initializing it empty and updating its value later:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;const testRef = useRef(1)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;useRef()&lt;/strong&gt; stores an object that contains an attribute called &lt;code&gt;current&lt;/code&gt;, which stores the passed value, in our example, it would hold the value 1.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;testRef = { current: 1 }&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  When to use useRef() Hook?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;To manage focus, text selection, or media playback.&lt;/em&gt;&lt;/strong&gt; Most elements inside of your document have a ref attribute, which facilitates the use of useRef to reference elements inside of your HTML. As an example, take a look at this &lt;code&gt;&amp;lt;input/&amp;gt;&lt;/code&gt; HTML tag, we created a useRef value and passed it to &lt;code&gt;&amp;lt;input/&amp;gt;&lt;/code&gt; as a ref attribute. Now, we are able to imperatively modify the input element with a couple of functions that get the &lt;code&gt;&amp;lt;input/&amp;gt;&lt;/code&gt; to focus or blur.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/Milu5489/embed/dyGNaLd?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;To access a previous value.&lt;/em&gt;&lt;/strong&gt; Another helpful use for useRef is to store the previous value of your state. Take a look at the example below, we have a list of three Pokemon and you need to select your favorite. Currently Pikachu is selected… but let’s be real, Pikachu is overrated. Select any of the other options and you will see your previous selection at the bottom. This is possible as a result of the use of our useRef hook:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;const previousSelected = useRef()&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then, everytime we select a different option, we keep track of the previous selection in our changeSelection() function:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;previousSelected.current = favPokemon&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/Milu5489/embed/abdpepX?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Also, according to React Docs, refs are useful to &lt;strong&gt;&lt;em&gt;trigger imperative animations&lt;/em&gt;&lt;/strong&gt; and to &lt;strong&gt;&lt;em&gt;integrate with third-party DOM libraries.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Where should you update a useRef() value?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KHJDpcuX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/x8zj95nowqrcvfgnr8w0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KHJDpcuX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/x8zj95nowqrcvfgnr8w0.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Updating a ref value is considered a side effect.&lt;/em&gt;&lt;/strong&gt; This is the reason why you want to update your ref value in event handlers and effects and not during rendering (unless you are working on lazy initialization). React docs warns us that not following this rule could lead to unexpected behaviors.&lt;/p&gt;

&lt;h2&gt;
  
  
  Should you use refs instead of state?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Big NO. Refs aren’t reactive,&lt;/em&gt;&lt;/strong&gt; which means changing its value won’t cause the HTML to update. &lt;/p&gt;

&lt;p&gt;Take a look at the following example to make sure you understand why refs should not replace state. &lt;/p&gt;

&lt;p&gt;We initialized a state and a ref with $1000 dollars. This component allows you to spend this value dollar-by-dollar every time you click the button &lt;code&gt;Spend&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;When you spend the money value stored in state, it triggers a re-render and it updates the view to show you the new value.&lt;/p&gt;

&lt;p&gt;Now, if you spend the money value stored in ref, it will also subtract a dollar on every click, however, this change won’t trigger a re-render so you won’t see a change in your HTML.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/Milu5489/embed/jOWBNEe?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;You can check out the console to see that ref value is truly changing inside the component.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--z2uRPhkr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/7e01qnhmjsr1cucyxddf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--z2uRPhkr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/7e01qnhmjsr1cucyxddf.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Is useRef() the same as createRef?
&lt;/h2&gt;

&lt;p&gt;No.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;createRef()&lt;/strong&gt; useful to access DOM nodes or React elements. &lt;strong&gt;&lt;em&gt;BUT&lt;/em&gt;&lt;/strong&gt; it creates a new instance of the ref on every render instead of keeping a value between renders when used in functional components (This does not apply if you are using a class component!). &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;useRef()&lt;/strong&gt; useful to access DOM nodes or React elements &lt;strong&gt;&lt;em&gt;AND&lt;/em&gt;&lt;/strong&gt; it holds a value even when a component re-renders. Here is an example that will help you see the difference.&lt;/p&gt;

&lt;p&gt;Take a look at the following code, we are initializing two ref values as null, using &lt;code&gt;createRef&lt;/code&gt; and the &lt;code&gt;useRef&lt;/code&gt; respectively. &lt;/p&gt;

&lt;p&gt;Everytime we click on the &lt;code&gt;Add a render!&lt;/code&gt; button, we update the &lt;code&gt;renderCounter&lt;/code&gt; state triggering a re-render. On every render, we check if the refs values are null and if they are, we assign the current &lt;code&gt;renderCounter&lt;/code&gt; state value to it.&lt;/p&gt;

&lt;p&gt;Notice that the ref value created using useRef is only null on the first render, so it is set to 1 once and never again.&lt;/p&gt;

&lt;p&gt;On the other hand, the ref value created using &lt;code&gt;createRef&lt;/code&gt; is created on every single render, so it always starts as null and then it is reassigned the current state value under  &lt;code&gt;renderCounter&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/Milu5489/embed/GRoWKXG?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Side note:&lt;/em&gt;&lt;/strong&gt; This is a simple example to illustrate the difference in between createRef and useRef. However, modifying the value of a ref should occur in an effect or event handler, not as shown in this example.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;useRef()&lt;/strong&gt; hook helps create mutable variables inside a functional component that won’t update on every render.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Refs are helpful to access DOM nodes or React elements (what is being rendered) and for keeping values in between renders, such as the previous value of a state.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;useRef() should not be used to replace state because it is not reactive and it won’t trigger a re-render.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Refs should be updated inside effects and event handlers to avoid weird behaviors.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;I hope this post helped you expand your understanding of &lt;strong&gt;useRef()&lt;/strong&gt; and that you will start taking advantage of this feature in your future projects.&lt;/p&gt;

&lt;p&gt;I post new content every week. We will be exploring a different React hook next Weekend!&lt;/p&gt;

&lt;p&gt;Follow me on &lt;a href="https://twitter.com/milu_franz"&gt;Twitter&lt;/a&gt; and &lt;a href="https://dev.to/milu_franz"&gt;Dev.to&lt;/a&gt; to keep up with new posts!&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Demystifying React Hooks: useCallback and useMemo</title>
      <dc:creator>Milu</dc:creator>
      <pubDate>Sun, 14 Jun 2020 22:49:17 +0000</pubDate>
      <link>https://dev.to/milu_franz/demystifying-react-hooks-usecallback-and-usememo-1a8j</link>
      <guid>https://dev.to/milu_franz/demystifying-react-hooks-usecallback-and-usememo-1a8j</guid>
      <description>&lt;p&gt;React Hooks introduced the capability to use state and other lifecycle features while using functional components instead of classes. Hooks are a simpler way to encapsulate stateful behavior and side effects in a user interface while using less code and increasing readability. &lt;/p&gt;

&lt;p&gt;Some hooks are easier to understand and use than others, therefore this series of posts will focus on demystifying the hooks that are not as straightforward. Let’s start by explaining &lt;strong&gt;what occurs when a component re-renders&lt;/strong&gt;, followed by &lt;strong&gt;defining the purpose of useCallback and useMemo&lt;/strong&gt;, and finally discussing &lt;strong&gt;when it is and when it is not appropriate to use these hooks.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What occurs when a component re-renders?
&lt;/h3&gt;

&lt;p&gt;As you might already know, React re-renders components on every state change or when props change. Since functions are considered objects in JavaScript, all objects (including functions) created under a React functional component will be created again on every re-render. This occurs as a consequence of &lt;strong&gt;referential equality&lt;/strong&gt;, which means that two objects that look exactly alike are not the same unless they both point at the same object. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gfthZclY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/0b1rgm43es84yvxrge0t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gfthZclY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/0b1rgm43es84yvxrge0t.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In other words, when a React component is about to re-render, it compares each object created under its original component with the new version of itself. And even though the objects are exactly the same, they are not pointing at the same object, therefore React identifies them as different objects and it allows their re-creation all over again under each re-render.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the purpose of useCallback and useMemo?
&lt;/h3&gt;

&lt;p&gt;The purpose of &lt;strong&gt;&lt;em&gt;useCallback&lt;/em&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;em&gt;useMemo&lt;/em&gt;&lt;/strong&gt;, if used correctly, is to prevent unnecessary re-renders and make your code more efficient. &lt;/p&gt;

&lt;p&gt;Let’s take a look at their structure. Both of these hooks receive two parameters:&lt;/p&gt;

&lt;p&gt;1) a function &lt;br&gt;
2) an array of dependencies &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fTq805Xc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/aih5bphgx59cqe7s1p6a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fTq805Xc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/aih5bphgx59cqe7s1p6a.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;useCallback&lt;/strong&gt; hook returns the same instance of the function being passed (parameter #1) instead of creating a new one every time a component re-renders. &lt;/p&gt;

&lt;p&gt;It creates a new instance of the function being passed (parameter #1) only when the array of dependencies (parameter #2) changes.&lt;/p&gt;

&lt;p&gt;Let’s look at an example, here we have a simple app that adds two values. The user can increment the first value and/or decrease the second value and the result will update accordingly. We also have a third &lt;code&gt;extra&lt;/code&gt; value that the user can update, however, this number is not being used in the computation.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/Milu5489/embed/qBbNMNa?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;If the user interacts with the &lt;code&gt;extra&lt;/code&gt; state value, the component would re-render creating a new copy of the additionResult function even though extraVal is not used in it. In this example, we implement the &lt;strong&gt;&lt;em&gt;useCallback&lt;/em&gt;&lt;/strong&gt; hook to only create a new copy of the additionResult function if firstVal or secondVal are updated.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HEqJWs2f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/hwt6836u6kp4z0ndhwfj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HEqJWs2f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/hwt6836u6kp4z0ndhwfj.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;useMemo&lt;/strong&gt; hook is very similar, however, instead of returning an uncalled function as useCallback does, it calls the function being passed and only returns a result value when the array of parameters change. In other words, &lt;strong&gt;&lt;em&gt;useMemo&lt;/em&gt;&lt;/strong&gt; calls the passed function only when necessary and it returns a cached value on all the other renders.&lt;/p&gt;

&lt;p&gt;In this example, we implemented an app that accepts a number and it returns it's factorial. For instance, if we typed the number 5, it would use a recursive function to compute 5!= 5*4*3*2*1=120. In this case, we used the useMemo hook to tell React to only recalculate when the number changes.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/Milu5489/embed/QWyEZXv?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  When to use them?
&lt;/h3&gt;

&lt;p&gt;If you are thinking of adding &lt;strong&gt;&lt;em&gt;useCallback&lt;/em&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;em&gt;useMemo&lt;/em&gt;&lt;/strong&gt; hooks everywhere in your component, please don’t. &lt;/p&gt;

&lt;p&gt;Both of these hooks add some extra complexity to your code and they require a lot of things working under the hood. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Adding performance optimizations using useCallback and useMemo is expensive and these optimizations don’t always bring enough benefits to offset their cost.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You should consider using &lt;strong&gt;&lt;em&gt;useCallback&lt;/em&gt;&lt;/strong&gt; and/or &lt;strong&gt;&lt;em&gt;useMemo&lt;/em&gt;&lt;/strong&gt; hooks on the following situations:&lt;/p&gt;

&lt;p&gt;1) Processing large amounts of data&lt;br&gt;
2) Working with interactive graphs and charts&lt;br&gt;
3) Implementing animations&lt;br&gt;
4) Incorporating component lazy loading (useMemo specifically)&lt;/p&gt;

&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;When a component is re-rendered, it creates new instances of all objects, including all the functions in it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;useCallback&lt;/em&gt;&lt;/strong&gt; - Allows you to cache an instance of a function between renders.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;useMemo&lt;/em&gt;&lt;/strong&gt; - Allows you to cache a value between renders.&lt;/p&gt;




&lt;p&gt;I hope you found this post helpful and that you will start using &lt;strong&gt;useCallback&lt;/strong&gt; and &lt;strong&gt;useMemo&lt;/strong&gt; with confidence in your next project. &lt;/p&gt;

&lt;p&gt;I post new content every week. We will be exploring a different React hook next Sunday!&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Git Explained: Tips and Tricks</title>
      <dc:creator>Milu</dc:creator>
      <pubDate>Sat, 06 Jun 2020 13:41:30 +0000</pubDate>
      <link>https://dev.to/milu_franz/git-explained-tips-and-tricks-4299</link>
      <guid>https://dev.to/milu_franz/git-explained-tips-and-tricks-4299</guid>
      <description>&lt;p&gt;As you learn Git and start getting more comfortable with the basics, you also want to learn ways to speed up your workflow. Git is such a powerful tool and there are numerous ways to achieve an intended action, however, some methods are quicker than others. &lt;strong&gt;Today we are going to discuss a few tips and tricks that will lead to a more productive way of interacting with version control on your daily development tasks.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Checkout your last branch
&lt;/h2&gt;

&lt;p&gt;We already learned that in order to move in between branches we need to use the command &lt;code&gt;git checkout [branch-name]&lt;/code&gt;. You can also quickly switch to the last branch you were in, without having to remember its name, by using the following command:&lt;/p&gt;

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

&lt;/div&gt;
&lt;h2&gt;
  
  
  Copy a file from another branch with one command
&lt;/h2&gt;

&lt;p&gt;Sometimes you want to reference code that lives in another branch that hasn’t been merged into master yet. The obvious thing to do with the basic commands you have mastered so far is to stash your changes, checkout the other branch, copy or just look at the file contents you want to reference, and then switch back to your current branch. Let me show you a way to get this same intended action with just one command:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git checkout [branch-name] -- [path/to/file-name]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Restore a deleted file
&lt;/h2&gt;

&lt;p&gt;Have you ever cleaned up a project and then realized you actually wanted to keep one of the files you removed? (Sigh...). Here is a way to restore it in one command:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git checkout [deleting-commit]^ -- [path/to/file-name]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Auto-correct Git Commands
&lt;/h2&gt;

&lt;p&gt;Git can help you by auto-correcting a mistyped command too! By setting up the following configuration, if you type something like ‘chekcout’ instead of ‘checkout’, Git will automatically fix it for you.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git config --global help.autocorrect 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Undo committed changes to a single file
&lt;/h2&gt;

&lt;p&gt;Every so often, you will commit some changes and then realize that you committed changes to a file by accident (Another sigh...). Here is one command that will allow you to remove the changes made to that file in your last commit:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git reset HEAD^ [file-name] git commit --amend
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Create your own shortcuts with Git aliases
&lt;/h2&gt;

&lt;p&gt;Some Git commands can get pretty long and Git does not infer the command you are typing as you type it (silly Git!). The solution for this is to set up aliases for your most used commands using the following &lt;code&gt;git config&lt;/code&gt; command: &lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git config --global alist.[shortcut-name] [command]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The following command will allow you to use the shortcut &lt;code&gt;git co [branch-name]&lt;/code&gt; instead of &lt;code&gt;git checkout [branch-name]&lt;/code&gt; every time you want to switch in between branches:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git config --global alias.co checkout
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Here are some other useful aliases you can use to speed up your workflow:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You can also add an alias for those commands that you wish git offered out of the box!&lt;br&gt;
For instance, If you wish Git had an &lt;code&gt;unstage&lt;/code&gt; command, you can create your own using the following:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git config --global alias.unstage ‘reset HEAD --’
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now you only need to use &lt;code&gt;git unstage [fileName]&lt;/code&gt; to unstage a specific file.&lt;/p&gt;

&lt;p&gt;To list all the alias and configs you have setup so far:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git config --list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;p&gt;I hope you give these shortcuts and configurations a try! I promise they will save you some precious time that can be wisely used to continue solving complex problems.&lt;/p&gt;

&lt;p&gt;If you enjoy learning and growing your Git skills and understanding, make sure to check out my other previous Git posts!&lt;/p&gt;

</description>
      <category>git</category>
      <category>github</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Git Explained: A Project Umbrella Structure Using Git Submodules</title>
      <dc:creator>Milu</dc:creator>
      <pubDate>Sat, 30 May 2020 19:23:45 +0000</pubDate>
      <link>https://dev.to/milu_franz/git-explained-an-umbrella-structure-using-git-submodules-20dl</link>
      <guid>https://dev.to/milu_franz/git-explained-an-umbrella-structure-using-git-submodules-20dl</guid>
      <description>&lt;p&gt;Oftentimes, a team of developers will be faced with the decision of implementing a Git structure to handle the different parts that a project entails. Some teams opt for a &lt;strong&gt;&lt;em&gt;monorepo&lt;/em&gt;&lt;/strong&gt;, while others decide to break it down into &lt;strong&gt;&lt;em&gt;sub-projects&lt;/em&gt;&lt;/strong&gt;, for instance, a repository for the UI and another one for the API. Both Git structures have advantages and drawbacks. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Monorepos&lt;/em&gt;&lt;/strong&gt; offer benefits such as code sharing, less code duplication, a single build, and atomic commits. However, &lt;strong&gt;&lt;em&gt;monorepos&lt;/em&gt;&lt;/strong&gt; also deal with a large number of commits in unrelated parts of the tree, as well as potential performance issues when cloning, fetching, and pushing code. On the other hand, maintaining &lt;strong&gt;&lt;em&gt;sub-projects&lt;/em&gt;&lt;/strong&gt; also translates into multiple repositories to clone, multiple sets of instructions to follow in order to install and build, and multiple directories to keep up with. &lt;/p&gt;

&lt;p&gt;Recently, I’ve been introduced to the use of &lt;strong&gt;Git Submodules&lt;/strong&gt; to create a central umbrella repository that points to a particular commit in both the UI and API external repositories. This umbrella structure allows you to keep a sub-project composition with some of the advantages of using a monorepo such as managing documentation and configurations in one central place, and the ability to pull the whole project, including sub-projects, in one step. This post is going to discuss the benefits of using an umbrella repository structure using Git Submodules, the struggles that come with it, and the commands that you need to learn to start using this Git structure.&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%2Fi%2F487gofjnuacom8xphemo.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%2F487gofjnuacom8xphemo.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The benefits
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Sub-project composition.&lt;/strong&gt; Having multiple repositories for the different parts of your project allows you to give limited access on a “need to code” basis. For instance, you might be in a situation where a frontend developer is added to your team for a few weeks to speed up the UI implementation. This developer can easily choose to pull only your UI repository, without having to mess with the API.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Continuous Development.&lt;/strong&gt; The proposed umbrella structure using Git Submodules keeps a sub-project composition that allows each repository to have it’s own deployment process.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Documentation in one place.&lt;/strong&gt; The umbrella repository gives you space to store documentation that applies to the whole project in a single location. I personally like to keep a global markdown file with the instructions to build and run the whole project using &lt;a href="https://www.docker.com" rel="noopener noreferrer"&gt;Docker&lt;/a&gt; in the umbrella repository and a markdown file in each repository with instructions on how to install and use each sub-project locally. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Configurations in one place.&lt;/strong&gt; Our team uses Docker containers to create, deploy and run applications. The umbrella repository is a fantastic spot to place a &lt;code&gt;docker-compose.yml&lt;/code&gt; file that builds and runs a database image, your api, and ui environments with one command.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Atomic code pulling.&lt;/strong&gt; By using the &lt;code&gt;--recurse-submodules&lt;/code&gt; flag when cloning an umbrella repository, you get all the nested directories that contain submodules in one command. In other words, you get your UI and API repositories all at once.&lt;/p&gt;




&lt;h2&gt;
  
  
  The struggles
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Need to specify the use of Git Submodules in instructions.&lt;/strong&gt; If your team is not used to this Git structure, they most likely won’t know how to clone or handle them correctly. Git does not download submodule contents by default, so make sure to include this information in your README.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Manual retrieval of submodules updates.&lt;/strong&gt; Git won’t automatically register the updates to submodules. You need to run &lt;code&gt;git submodule update --remote&lt;/code&gt; to see changes made to a submodule.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Simple implementations only.&lt;/strong&gt; So far, I’ve only used this umbrella structure to link the UI and API repositories per project. I can see how keeping up with more than two submodules could get challenging and might require you to look into a different implementation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mostly useful when using Docker.&lt;/strong&gt; If you are not using Docker, the benefits of this structure might not be as impactful.&lt;/p&gt;




&lt;h2&gt;
  
  
  The commands
&lt;/h2&gt;

&lt;p&gt;Let’s discuss the possibilities and commands you have in your toolbox to implement this umbrella structure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a project with submodules&lt;/li&gt;
&lt;li&gt;Rename a submodule&lt;/li&gt;
&lt;li&gt;Clone a project with submodules&lt;/li&gt;
&lt;li&gt;Work in a submodule&lt;/li&gt;
&lt;li&gt;Check and pull submodule updates&lt;/li&gt;
&lt;li&gt;Update umbrella project with latest submodule commits&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Create a project with submodules
&lt;/h3&gt;

&lt;p&gt;To explain this action clearly, I will create a repository called umbrella and two repositories called umbrella-ui and umbrella-api in GitHub. You can check them out &lt;a href="https://github.com/milufranz08/umbrella" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd[umbrella-project-name]
git submodule add [git@github.com:your-account/umbrella-ui.git] [name]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: the name parameter is optional. If you don’t pass a name, you will get the submodule repository name. In this case, I will give it the “ui” name parameter because I don’t want a redundant directory name like “umbrella-ui” inside my “umbrella” project.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Run the &lt;code&gt;ls -a&lt;/code&gt; command to see a new directory called &lt;code&gt;ui&lt;/code&gt; and a new file called &lt;code&gt;.gitmodules&lt;/code&gt;. The &lt;code&gt;.gitmodules&lt;/code&gt; file is a configuration that stores the mapping between your main project and its submodules. It will look similar to the following:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[submodule “ui”]
path = ui
url = git@github.com:your-account/umbrella-ui.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;After committing and pushing this change, you should see a folder for your submodule that points to the latest commit in the submodule's master branch.&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%2Fi%2Fgez5k4ly4zyz4shrfsf1.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%2Fgez5k4ly4zyz4shrfsf1.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Rename a submodule
&lt;/h3&gt;

&lt;p&gt;If you forget to pass a name parameter when adding your submodule, you can still change your submodule directory name using the following command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git mv [old-name] [new-name]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Clone a project with submodules
&lt;/h3&gt;

&lt;p&gt;Pass the following command to automatically clone your project and its submodules. If you don’t pass the &lt;code&gt;--recurse-submodules&lt;/code&gt; flag, your directory will be empty.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone --recurse-submodules [git-repo-url]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Work in a submodule
&lt;/h3&gt;

&lt;p&gt;This is the same process that you follow when dealing with a regular repository. You make changes, commit them, push them to remote.&lt;/p&gt;
&lt;h3&gt;
  
  
  Check for submodule updates
&lt;/h3&gt;

&lt;p&gt;When changes in submodules are pushed to their remote repository, you are going to need to check for these changes and update your umbrella repository because the commit pointers will be out of date.&lt;/p&gt;

&lt;p&gt;To make sure you understand this concept, I will show you the &lt;code&gt;umbrella-api&lt;/code&gt; repository, which has been updated and the last commit in master is &lt;code&gt;6302c8…&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwky2dtbge6hups6nf3ek.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%2Fwky2dtbge6hups6nf3ek.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now let’s look at our umbrella repository, &lt;strong&gt;&lt;em&gt;the &lt;code&gt;api&lt;/code&gt; submodule is not pointing to the latest commit in &lt;code&gt;umbrella-api&lt;/code&gt;. Instead, it is pointing at an old commit &lt;code&gt;15a146…&lt;/code&gt;&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F82a0ky61l0t249m5mnx1.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%2F82a0ky61l0t249m5mnx1.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can pull the changes made in all your submodules directly from the umbrella directory with the following command:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// fetch all new updates in submodules
git submodule update --remote

// see which submodule has been modified
git status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9byhvzorelfbrkh4aw9z.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%2F9byhvzorelfbrkh4aw9z.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// see all new commits that have been pulled down
git diff
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6a09mb93epebdzwn226b.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%2F6a09mb93epebdzwn226b.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Update umbrella project with latest submodule commits
&lt;/h3&gt;

&lt;p&gt;Now that we pulled changes made in our submodules, we need to update our umbrella project pointers. This is VERY IMPORTANT because &lt;strong&gt;&lt;em&gt;if someone clones our umbrella project in this state, they won’t get the newest code under our submodules.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// add all submodules changes
git add .

// commit new pointers
git commit -m “Update submodule pointers”

// publish the changes
git push origin master
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Note:&lt;/em&gt;&lt;/strong&gt; You can also use the following shortcut to pull the latest changes made to your submodules and get your umbrella project to point to the last commits.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git submodule update --remote --merge
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now our umbrella project points to the latest commits in both submodules, umbrella-ui and umbrella api.&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%2Fi%2Fi60y8pweft6sg0slrucp.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%2Fi60y8pweft6sg0slrucp.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Have you used Git Submodules in a similar umbrella structure before? If not, I hope it sparks your interest and you give it a try.&lt;/p&gt;

&lt;p&gt;Thank you for reading, liking, and sharing my Git Explained series posts, it truly means a lot to me. I enjoy putting them together and love your questions and suggestions.&lt;/p&gt;

&lt;p&gt;Checkout my other Git Explained posts and keep an eye for the next one. I explore, define, and explain Git concepts every Saturday!&lt;/p&gt;

</description>
      <category>git</category>
      <category>github</category>
      <category>beginners</category>
      <category>docker</category>
    </item>
    <item>
      <title>Git Explained: Proper Team Etiquette</title>
      <dc:creator>Milu</dc:creator>
      <pubDate>Sat, 23 May 2020 19:38:01 +0000</pubDate>
      <link>https://dev.to/milu_franz/git-explained-proper-team-etiquette-1od</link>
      <guid>https://dev.to/milu_franz/git-explained-proper-team-etiquette-1od</guid>
      <description>&lt;p&gt;Proper team etiquette will assist your team to achieve seamless collaboration and productivity. These rules are often gained with experience as most developers who are starting to grasp challenging new concepts do not prioritize proper Git etiquette. Even though these rules might not seem essential at first, they are immensely helpful during debugging, merging code, and managing pull requests. &lt;/p&gt;

&lt;p&gt;This post aims to help you maximize your team’s use of Git by discussing &lt;strong&gt;etiquette pointers that will support you when creating branches and commits, as well as handling unnecessary, private, or large files.&lt;/strong&gt; In addition, we will look at the different commands we can use to amend common mistakes that could hurt your workflow and team collaboration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Branches
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4lmfezvt9jq1t0rlsfr2.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%2F4lmfezvt9jq1t0rlsfr2.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A repository always has a main branch called &lt;code&gt;origin/master&lt;/code&gt;, which reflects the &lt;strong&gt;&lt;em&gt;production-ready state&lt;/em&gt;&lt;/strong&gt; or &lt;strong&gt;&lt;em&gt;already deployed&lt;/em&gt;&lt;/strong&gt; code, and developers branch and merge from it. During the implementation of a project, many supporting branches will be created. These branches should have a specific purpose, a limited life time, and a descriptive name. Here are some guidelines to create effective branches:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create a branch per issue.&lt;/strong&gt; You will have to create a merge request at some point in order to get your supporting branch merged into master. Merge requests are a great opportunity for feedback that will help you grow. Overly long merge requests get procrastinated or simply not reviewed in detail. In other words, you would miss out on getting feedback from your team that would help you grow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use a token at the beginning of your branch name.&lt;/strong&gt; Tokens are groups agreed by your team that quickly communicate in which part of your workflow each branch belongs. Some popular tokens are &lt;strong&gt;&lt;em&gt;feature/&lt;/em&gt;&lt;/strong&gt; or &lt;strong&gt;&lt;em&gt;feature-&lt;/em&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;em&gt;bug/&lt;/em&gt;&lt;/strong&gt; or &lt;strong&gt;&lt;em&gt;bug-&lt;/em&gt;&lt;/strong&gt;. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The use of &lt;code&gt;/&lt;/code&gt; in your naming convention might break your CI/CD pipeline if using Jenkins or other third-party tools. Make sure you talk to your team before choosing a token name convention.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This convention also allows you to list them by group: &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git branch --list “feature/*”
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Include issue number.&lt;/strong&gt; This comes handy when your issues are not automatically linked to your branches. For instance, my team is currently using JIRA to track issues and Gitlab as our Git repository hosting service. It is really nice to be able to glance at a branch and know which issue it belongs to. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use a descriptive and short name.&lt;/strong&gt; Do your best to select short and well-defined names that communicate the task’s purpose clearly. &lt;/p&gt;

&lt;p&gt;A well-thought-out branch name example for a new feature that adds a search bar under ticket #28 would be the following: &lt;/p&gt;

&lt;p&gt;&lt;code&gt;feature/28-search-bar&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If you are reading this post and suddenly realized your branches are not following any of these rules… don’t panic! Let’s take a look at how you can rename your branches locally and remotely: &lt;/p&gt;

&lt;p&gt;To rename your local branch:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# if HEAD is in the branch you want to change
git branch -m [new-name]

# if HEAD is in another branch
git branch -m [old-name] [new-name]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;To rename a remote branch:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Rename your local branch (step above)

# Delete your old remote branch
git push --delete remote branch-name

# Or use this shortcut
git push origin :[old-name] 

# Push your new-name branch to remote
git push origin [new-name]

# Reset the upstream branch for the new-name local branch
git push origin -u [new-name]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Clean unused and already merged branches.&lt;/strong&gt; When you create a merge request, make sure you select the merging option that deletes your branch after merging. Moreover, make sure you exercise good housekeeping by deleting unused branches locally and remotely.&lt;/p&gt;

&lt;p&gt;To prune all stale referenced remote branches:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git fetch --prune --all
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;To delete a branch locally:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# safely - Git prevents you from deleting it if it hasn’t been merged
git branch -d [branch-name]

# force delete
git branch -D [branch-name]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;To delete a branch remotely:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git push origin :[old-name]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




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

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1vbwmhj9uzp81hqrqy7u.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%2F1vbwmhj9uzp81hqrqy7u.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Good commit messages matter because they allow you to explain the changes you have made and why when you look back in history or when a team member is reviewing your merge request. Here are some guidelines to compose precise commit messages:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A commit should consist of a single logical change.&lt;/strong&gt; This one can be hard, especially since it’s very tempting to commit all changes in one commit after several were made. Here is a flag that could help you out:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git add --patch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;It will go through all the changes you made, one change at a time, and ask you if you want to commit that specific change.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keep it short.&lt;/strong&gt; No more than 50 characters please. If you are modifying or refactoring already existing code, give a short explanation of why you made that change. Not sure what to include in your commit message? Use the following command to see a list of changes in between your working tree:&lt;/p&gt;

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

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Start with a capital letter.&lt;/strong&gt; And keep it consistent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No punctuation at the end.&lt;/strong&gt; It's not necessary.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Start the sentence with a verb.&lt;/strong&gt; Your commit message should complete the following sentence: &lt;/p&gt;

&lt;p&gt;&lt;code&gt;“This commit will…[commit-message]”&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Good examples:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;“Redirect user to the requested page after login”&lt;/code&gt;&lt;br&gt;
&lt;code&gt;“Fix typo in introduction to the user tools”&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Are you not happy with your last commit? Use the following command to change it:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git commit --amend -m “New message”
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You can also use this command if you want to make a change to your previous commit but want to leave your message intact. For instance, sometimes I forget to remove a log message and I don’t want to create another commit just for that.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git add changed/file.ts
git commit --amend --no-edit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;h2&gt;
  
  
  Ignore files
&lt;/h2&gt;

&lt;p&gt;Files that are not required by your project should not be tracked by Git. Understanding what to ignore is beneficial because it will help you keep an unclutter and secure project for you and your team members. Here is a list of common type of files to ignore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Operating system files&lt;/li&gt;
&lt;li&gt;Language and framework files&lt;/li&gt;
&lt;li&gt;File downloaded with package managers&lt;/li&gt;
&lt;li&gt;Usernames and passwords &lt;/li&gt;
&lt;li&gt;Debugging logs&lt;/li&gt;
&lt;/ul&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%2Fi%2Fwig2emn718hg2vejrjez.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%2Fwig2emn718hg2vejrjez.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add a local &lt;code&gt;.gitignore&lt;/code&gt; file to the root of your project with the following command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;touch .gitignore
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Include any file or folder that you would like Git to ignore on each line. Here are some examples:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Ignore operating system files
.DS_store

# Ignore SASS config files
.sass-cache

# Ignore npm dependencies folder
/node_modules

# Ignore API credentials
.env

# Ignore all logs
*.log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Note:&lt;/em&gt;&lt;/strong&gt; A DEV community member recommended &lt;a href="https://gitignore.io/" rel="noopener noreferrer"&gt;gitignore.io&lt;/a&gt; to generate a &lt;code&gt;.gitignore&lt;/code&gt; file in one step. This tool allows you to enter Operating Systems, IDEs, Programming Language, or Frameworks and it generates a useful &lt;code&gt;.gitignore&lt;/code&gt; file for your project! They also have documentation to help you access their API using your command line.&lt;/p&gt;

&lt;p&gt;Did you already commit a file you meant to ignore? It happens to the best of us! Let’s take a look at how to fix it:&lt;/p&gt;

&lt;p&gt;First you need to remove the file from your repository. The following command will get Git to stop tracking [file-name], however, the file won’t be deleted from your working system.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git rm --cached [file-name]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Then add it to your .gitignore file and commit this change.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Ignore [file-name]
[file-name]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;h2&gt;
  
  
  Handle large files
&lt;/h2&gt;

&lt;p&gt;Uploading large files to Git is uncommon, however, you could be faced in a situation where you might want to share some large data files with your team members. This could be a problem as cloning, fetching or pulling from a repository that stores large files takes a long time as every version of each large file is downloaded. Don’t cause your team members a headache by doing this, instead share big files through Git LFS (Large File Storage), an open source Git extension. This tool is useful because it replaces large files in your repository with small pointer files. Here are some instructions to use this tool:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Download and install &lt;a href="https://git-lfs.github.com" rel="noopener noreferrer"&gt;Git LFS&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git lfs install&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Track your large files&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git lfs track “files/*.csv”&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This command will create or update a file called &lt;code&gt;.gitattributes&lt;/code&gt;, which binds tracked file patterns. You will need to commit this file to your repository.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Notes:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To stop tracking a file with Git LFS, remove it from the &lt;code&gt;.gitattributes&lt;/code&gt; file.&lt;/li&gt;
&lt;li&gt;Cloning and pulling from a Git LFS is the same as using a normal repository.&lt;/li&gt;
&lt;/ul&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%2Fi%2Fp3nnjql18icn3lj0r6wu.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%2Fp3nnjql18icn3lj0r6wu.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These are some of the Git guidelines I’ve learned through working with different people in different projects. Everybody has different preferences, however it is important to choose a consistent set of Git rules when collaborating with a team so everybody is on the same page. Let me know in the comments if you have another rule you recommend!&lt;/p&gt;

&lt;p&gt;Checkout my previous posts:&lt;br&gt;
&lt;a href="https://dev.to/milu_franz/git-explained-the-basics-igc"&gt;Git Explained: The Basics&lt;/a&gt;&lt;br&gt;
&lt;a href="https://dev.to/milu_franz/git-explained-an-in-depth-comparison-18mk"&gt;Git Explained: In-depth Comparison&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I explore, define, and explain Git concepts every Saturday! &lt;/p&gt;

</description>
      <category>git</category>
      <category>github</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Git Explained: An In-Depth Comparison</title>
      <dc:creator>Milu</dc:creator>
      <pubDate>Sat, 16 May 2020 19:40:01 +0000</pubDate>
      <link>https://dev.to/milu_franz/git-explained-an-in-depth-comparison-18mk</link>
      <guid>https://dev.to/milu_franz/git-explained-an-in-depth-comparison-18mk</guid>
      <description>&lt;p&gt;Git is a very powerful tool and It has a long list of capabilities available at your disposition. Some commands provide slightly similar results and it is worth understanding and comparing them in order to choose the one that satisfies your needs and improves your workflow. This post is going to define and compare the following commands: &lt;strong&gt;revert, checkout, reset, merge, and rebase.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Revert vs. checkout vs. reset
&lt;/h2&gt;

&lt;p&gt;These tools allow you to undo and manipulate changes in your repository. The problem is that they are very similar, therefore it is really easy to get them confused. We will define each of them in detail and list their similarities and differences.&lt;/p&gt;

&lt;h4&gt;
  
  
  Git revert
&lt;/h4&gt;

&lt;p&gt;This is an &lt;strong&gt;&lt;em&gt;unconventional&lt;/em&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;em&gt;safe&lt;/em&gt;&lt;/strong&gt; way to revoke an operation as it prevents you from losing history. Git revert inverts the changes that were added in a commit and adds a new commit with the inverted content. This command is especially helpful when you have already pushed your changes to a remote repository as it keeps your original commit intact.&lt;/p&gt;

&lt;p&gt;To revert using commit hashes: &lt;code&gt;git revert [SHA]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To revert using ranges: &lt;code&gt;git revert HEAD~[num-of-commits-back]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--P4GtBOHm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/aa6ib33jkkidt8vteola.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P4GtBOHm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/aa6ib33jkkidt8vteola.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Git checkout
&lt;/h4&gt;

&lt;p&gt;This is a versatile tool, it allows you to switch in between branches, inspect older commits, and undo local uncommitted changes by moving HEAD and updating your working directory accordingly. &lt;/p&gt;

&lt;p&gt;To switch in between branches: &lt;code&gt;git checkout [branch-name]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To inspect an older commit using commit hashes: &lt;code&gt;git checkout [SHA]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To inspect an older commit using ranges: &lt;code&gt;git checkout HEAD~[num-of-commits-back]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mXdha_c---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/oxae7junzcrx8dsvdi0f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mXdha_c---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/oxae7junzcrx8dsvdi0f.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Notes:&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When moving HEAD to a different branch or commit, you are going to need to commit or stash any uncommitted changes that could be lost.&lt;/li&gt;
&lt;li&gt;You will be in a &lt;strong&gt;&lt;em&gt;detached HEAD&lt;/em&gt;&lt;/strong&gt; state by switching to an old commit, which is great for inspection but not for modifications. In other words,  you are not in your branch anymore so don’t add any commits on a &lt;strong&gt;&lt;em&gt;detached HEAD&lt;/em&gt;&lt;/strong&gt; because you are going to lose them when you switch to another branch. If you are planning to commit changes on a detached HEAD, make sure to create a new branch from it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To undo all local uncommitted changes: &lt;code&gt;git checkout .&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To undo a specific local uncommitted change: &lt;code&gt;git checkout -- [file-name]&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Git reset
&lt;/h4&gt;

&lt;p&gt;This is a powerful but complex way to undo an operation. There are three available arguments: &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;--mixed&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
This is the default mode so &lt;code&gt;git reset --mixed&lt;/code&gt; is the same as &lt;code&gt;git reset&lt;/code&gt;. By using any of these commands you will move HEAD to the latest commit and all the changes that were added after that commit will be available as &lt;em&gt;untracked&lt;/em&gt; changes in your working directory.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;--soft&lt;/em&gt;&lt;/strong&gt; &lt;br&gt;
This operation is similar to the one executed using the --mixed argument. HEAD is moved to the latest commit, however, the changes that were added after that commit are left &lt;em&gt;staged&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;--hard&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
Use the command &lt;code&gt;git reset --hard&lt;/code&gt; only when you know what you are doing as it is very dangerous. By resetting the hard way, you will move HEAD to the latest commit and destroy the changes that were added after. This cannot be undone so use it wisely.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--40sVTNnJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/isq14omx8r55yqtmrs3a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--40sVTNnJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/isq14omx8r55yqtmrs3a.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You should not use &lt;code&gt;git reset&lt;/code&gt; when you have already pushed to a remote repository. Removing a commit that other team members have continued building upon is hard and it would disrupt your team member’s workflow.&lt;/p&gt;

&lt;p&gt;Bonus action: Use &lt;code&gt;git reset -- [file-name]&lt;/code&gt; to unstage a file that hasn't been committed yet.&lt;/p&gt;




&lt;h2&gt;
  
  
  Merge vs. rebase
&lt;/h2&gt;

&lt;p&gt;When multiple people are working in a project you will need to combine your code at some point. Git rebase and merge have different approaches to consolidate the changes from one branch into another one. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Z72JV_hE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/u9tvsfhh64jlusek5hlx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Z72JV_hE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/u9tvsfhh64jlusek5hlx.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Git merge
&lt;/h4&gt;

&lt;p&gt;It uses a non-destructive operation to combine two branches’ histories without changing them. In addition, it creates a new “merge commit” every time it’s used. This is a great way to consolidate changes, however your commit history could get several merge commits depending on how active your master branch is, which can get cumbersome.&lt;/p&gt;

&lt;p&gt;To combine the latest changes from master into your branch:&lt;br&gt;
&lt;code&gt;git checkout [branch-name]&lt;br&gt;
git merge master&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Git rebase
&lt;/h4&gt;

&lt;p&gt;This is a destructive operation as it moves an entire branch’s history on top of another one by rewriting the project history with new commits.&lt;/p&gt;

&lt;p&gt;This command is useful if you prefer a clean and linear project history. However, it is not safe to rebase on changes that have been pushed to a remote repository master branch because you would be changing the master branch’s history while your team members continue working on a diverged version of it. &lt;/p&gt;

&lt;p&gt;In addition, Git will not allow you to easily push a rebased branch back to a remote repository. You are going to need to force it by using &lt;code&gt;git push --force&lt;/code&gt;, which overwrites the remote branch and could cause issues with other collaborators. In other words, stop yourself from confusing your team members and creating tedious conflicts by only using rebase to cleanup in-progress features and not the master branch.&lt;/p&gt;

&lt;p&gt;I hope you found these comparisons helpful and easy to follow. I explore, define, and explain git concepts every Saturday! &lt;/p&gt;

&lt;p&gt;If you are new to git, checkout my previous post &lt;a href="https://dev.to/milu_franz/git-explained-the-basics-igc"&gt;Git Explained: The Basics&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>git</category>
      <category>github</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Git Explained: The Basics</title>
      <dc:creator>Milu</dc:creator>
      <pubDate>Sat, 09 May 2020 16:35:45 +0000</pubDate>
      <link>https://dev.to/milu_franz/git-explained-the-basics-igc</link>
      <guid>https://dev.to/milu_franz/git-explained-the-basics-igc</guid>
      <description>&lt;p&gt;Git is scary when you are starting up. There is this imminent fear that you could possibly lose hours of hard work by using the wrong commands. Keep reading if this is how you feel every time you are about to use git. This post is going to define git, explain why you need to learn it, and break down the following basic commands in detail: &lt;strong&gt;clone, checkout, pull, add, commit, stash, and push.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What is git and why do you need it?
&lt;/h3&gt;

&lt;p&gt;Git is one of the most popular version control systems and it helps software developing teams manage changes to their source code over time. In other words, version control keeps track of every change in your code and it allows you to go back in time when something goes wrong. &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%2Fi%2Fyi9n7h1klm5m6e3odcsa.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%2Fyi9n7h1klm5m6e3odcsa.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also, it is really helpful to prevent concurrent work from conflicting when multiple people are working in the same project. An individual may be working on the sidebar navigation while another one is simultaneously updating the header. &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%2Fi%2F8ito8dl7a62luwhp18xv.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%2F8ito8dl7a62luwhp18xv.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Version control systems facilitate the work of multiple individuals by allowing them to use different branches as part of one “file tree” and merge their updated code to one source of truth when it's ready.&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%2Fi%2F3n38o2kxyjai6ophizhw.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%2F3n38o2kxyjai6ophizhw.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Git clone
&lt;/h4&gt;

&lt;p&gt;Downloads a copy of the project (remote repository) to your local computer. To use this command, follow these steps:&lt;/p&gt;

&lt;p&gt;1) Copy the clone or download link&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%2Fi%2Fj3bj8cy3equfos30g535.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%2Fj3bj8cy3equfos30g535.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2) Open your terminal&lt;/p&gt;

&lt;p&gt;3) Access the location on your computer where you want to copy the project: &lt;code&gt;cd [desired-location]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;3) Clone the project: &lt;code&gt;git clone [copied-link]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;4) Use the commands &lt;code&gt;cd [project-name]&lt;/code&gt;, followed by &lt;code&gt;ls&lt;/code&gt; and you should see the list of files you just cloned! &lt;/p&gt;

&lt;h4&gt;
  
  
  Git branch
&lt;/h4&gt;

&lt;p&gt;Lists all your project branches and highlights your current branch. If you just cloned a project, you are going to be in the master branch (your source of truth). It is not advised to work directly on the master branch because there is a big chance you would have a broken project while you are adding some progress. Instead, you want to create a different branch, work on your changes or new feature and when you are done and everything is working as expected, merge that branch into master.&lt;/p&gt;

&lt;h4&gt;
  
  
  Git checkout
&lt;/h4&gt;

&lt;p&gt;Selects the branch you want to work on.&lt;/p&gt;

&lt;p&gt;If the branch already exists:&lt;br&gt;
&lt;code&gt;git checkout [branch-name]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If you want to create a new branch:&lt;br&gt;
&lt;code&gt;git checkout -b [branch-name]&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Git pull
&lt;/h4&gt;

&lt;p&gt;Pulls recent changes from the remote repository to your local files. If one of your team members merged a new feature into master, you need to pull the recent code added to master to keep your local files up to date.&lt;/p&gt;

&lt;h4&gt;
  
  
  Git status
&lt;/h4&gt;

&lt;p&gt;Lists all the files that you have worked on and have not been saved in a commit yet.&lt;/p&gt;

&lt;h4&gt;
  
  
  Git add
&lt;/h4&gt;

&lt;p&gt;Stages file that you would like to commit.&lt;/p&gt;

&lt;p&gt;If you want to stage all the files that you have worked on: &lt;code&gt;git add .&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If you want to stage only one particular file: &lt;code&gt;git add [file-name]&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Git commit
&lt;/h4&gt;

&lt;p&gt;Saves the group of changes you staged to your local repository. Add a comment with each commit that summarizes the change. &lt;br&gt;
&lt;code&gt;git commit -m “commit message”&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Git stash
&lt;/h4&gt;

&lt;p&gt;Saves any changes you have made locally and it reverts the working directory to match the HEAD of your last commit. &lt;/p&gt;

&lt;p&gt;See a list of all the changes you have stashed: &lt;code&gt;git stash list&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Bring back the last changes you stashed: &lt;code&gt;git stash pop&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Clear all your stashed entries: &lt;code&gt;git stash clear&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Git push
&lt;/h4&gt;

&lt;p&gt;Saves your local committed changes into the remote repository so everybody else has access to your work.&lt;br&gt;
&lt;code&gt;git push origin [branch-name]&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What is next?
&lt;/h3&gt;

&lt;p&gt;This is the first one from a series of posts about git. We will explore more advanced commands, git submodules, multiple remotes, and squashing commits before a pull request in the next weeks. &lt;/p&gt;

&lt;p&gt;I hope this information was helpful and you feel a little more confident about working with git!&lt;/p&gt;

</description>
      <category>git</category>
      <category>beginners</category>
      <category>github</category>
    </item>
  </channel>
</rss>
