<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Bhanu Teja Pachipulusu's blog]]></title><description><![CDATA[A Software Engineer, a Full Stack Developer and an Entrepreneur. Cofounded Coderplex and is based in India. Currently building https://wordplex.app. ]]></description><link>https://blog.bhanuteja.dev</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1601991997123/FWMBCoTmq.png</url><title>Bhanu Teja Pachipulusu&apos;s blog</title><link>https://blog.bhanuteja.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Thu, 14 May 2026 01:19:51 GMT</lastBuildDate><atom:link href="https://blog.bhanuteja.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[How I built a Serverless Micro-Blogging Site Using Next.js and Fauna]]></title><description><![CDATA[Authored in connection with the Write With Fauna program.


Table of Contents

Authentication
Setting up Fauna in Next.js
Installing Fauna
Setting up Migrations Tool


Authentication and Authorization in Fauna
Next.js Serverless Function Setup for Fa...]]></description><link>https://blog.bhanuteja.dev/how-i-built-a-serverless-micro-blogging-site-using-nextjs-and-fauna</link><guid isPermaLink="true">https://blog.bhanuteja.dev/how-i-built-a-serverless-micro-blogging-site-using-nextjs-and-fauna</guid><category><![CDATA[serverless]]></category><category><![CDATA[Next.js]]></category><category><![CDATA[React]]></category><category><![CDATA[JavaScript]]></category><dc:creator><![CDATA[Bhanu Teja Pachipulusu]]></dc:creator><pubDate>Mon, 29 Mar 2021 15:38:02 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1617031896590/S0nTav26n.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote>
<p>Authored in connection with the <a target="_blank" href="https://fauna.com/blog/write-with-fauna">Write With Fauna</a> program.</p>
</blockquote>
<hr />
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><a class="post-section-overview" href="#authentication">Authentication</a></li>
<li><a class="post-section-overview" href="#setting-up-fauna-in-nextjs">Setting up Fauna in Next.js</a><ul>
<li><a class="post-section-overview" href="#installing-fauna">Installing Fauna</a></li>
<li><a class="post-section-overview" href="#setting-up-migrations-tool">Setting up Migrations Tool</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#authentication-and-authorization-in-fauna">Authentication and Authorization in Fauna</a><ul>
<li><a class="post-section-overview" href="#nextjs-serverless-function-setup-for-fauna">Next.js Serverless Function Setup for Fauna</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#nextauth">NextAuth</a></li>
<li><a class="post-section-overview" href="#requirements-and-features">Requirements and Features</a></li>
<li><a class="post-section-overview" href="#modelling-the-data">Modelling the data</a><ul>
<li><a class="post-section-overview" href="#goals">Goals</a></li>
<li><a class="post-section-overview" href="#goal-participants">Goal Participants</a></li>
<li><a class="post-section-overview" href="#goal-updates">Goal Updates</a></li>
<li><a class="post-section-overview" href="#update-likes">Update Likes</a></li>
<li><a class="post-section-overview" href="#update-comments">Update Comments</a></li>
<li><a class="post-section-overview" href="#comment-likes">Comment Likes</a></li>
<li><a class="post-section-overview" href="#activities">Activities</a></li>
<li><a class="post-section-overview" href="#notifications">Notifications</a></li>
<li><a class="post-section-overview" href="#notification-statuses">Notification Statuses</a></li>
<li><a class="post-section-overview" href="#user-followers">User Followers</a></li>
<li><a class="post-section-overview" href="#users">Users</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#conclusion">Conclusion</a></li>
</ul>
<p>I have recently built a website for our local developer community <a target="_blank" href="https://coderplex.org">Coderplex</a> completely Serverless. We were able to start from scratch and got it launched within just 3 weeks of time. In this article, I will show what the website is about, how I built it, and also show the areas of improvement and the new features that we are planning to add to it.</p>
<p>The website is basically a platform like Twitter where you post updates. The only difference is that it's aimed towards developers(has things like markdown editor), and it's goal-centric. As soon as the users log in to the site, they will be prompted to set their goal. You will be asked to set a title for the goal, write the plan of action of how you want to achieve that goal, and finally, you will be asked to set a deadline, before which you intend to achieve that goal. After that, you will be allowed to post updates whenever you want, showing what you are doing in order to reach that goal.</p>
<h2 id="heading-authentication">Authentication</h2>
<p>We only have one mode of authentication i.e., through GitHub login. We are using <code>next-auth</code> package for this.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1617021529104/aZwMegx4x1.png" alt="Screenshot_2021-03-15_at_6.34.40_AM.png" /></p>
<p>Check out the following blog post which I published a few weeks ago to know more about setting up GitHub authentication using <code>next-auth</code>.</p>
<p><a target="_blank" href="https://blog.bhanuteja.dev/3-simple-steps-to-setup-authentication-in-nextjs">3 Simple Steps To Setup Authentication in Next.js</a></p>
<h2 id="heading-setting-up-fauna-in-nextjs">Setting up Fauna in Next.js</h2>
<h3 id="heading-installing-fauna">Installing Fauna</h3>
<p>Before we go through other features of coderplex.org, let's see how I have set up my Fauna in Next.js and how my Fauna workflow is.</p>
<p>Install <code>faunadb</code> (javascript driver for Fauna DB) as a dependency in your Next.js project</p>
<pre><code class="lang-bash">yarn add faunadb
<span class="hljs-comment"># npm install faunadb</span>
</code></pre>
<p>While developing locally, you have two choices:</p>
<ol>
<li>You can either create a test database in the Fauna cloud directly.</li>
<li>You can set up the Fauna Dev Docker container locally.</li>
</ol>
<p>I personally have set up the Docker container and have been using that for local development.</p>
<p>To know more about setting up the Fauna Dev container, go to the <a target="_blank" href="https://docs.fauna.com/fauna/current/integrations/dev">relevant section in the documentation</a>.</p>
<p>To summarize, here is what I have done.</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Pull the latest Docker image of faunadb</span>
docker pull fauna/faunadb:latest

<span class="hljs-comment"># Verify if it installed correctly</span>
docker run fauna/faunadb --<span class="hljs-built_in">help</span>

<span class="hljs-comment"># Run the Fauna Dev</span>
docker run --rm --name faunadb -p 8443:8443 -p 8084:8084 fauna/faunadb

<span class="hljs-comment"># After this, the Fauna Dev is started locally at port 8443</span>
</code></pre>
<p>If you go through the <a target="_blank" href="https://docs.fauna.com/fauna/current/integrations/dev">documentation</a>, you will see that there are so many ways to run the Fauna Dev. I chose the first approach because I want to start with a fresh state every time I start the database. In this approach, as soon as you stop the container, all the data will be erased, and whenever you start the container again, you will be starting with a fresh instance of Fauna.</p>
<h3 id="heading-setting-up-migrations-tool">Setting up Migrations Tool</h3>
<p>If you come from a background of Laravel/Django/Rails/Node, you are most probably be aware of migrations. In simple terms, the migrations are the set of files. They help manage the changes in the database schema. The files are usually associated with timestamps of the time when the migrations are created. There will usually be a way to apply a migration or rollback(unapply) a migration. These are incremental steps that you need to perform to get the fresh database to the same state as the current database.</p>
<p>In Fauna, there is no native solution to achieve this. But very recently, an unofficial tool has been created by a developer advocate at Fauna. I have been using that tool for setting up migrations in my projects.</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Install the tool as a dev dependency</span>
yarn add -D fauna-schema-migrate 

<span class="hljs-comment"># If you use npm, run the following command to install it.</span>
<span class="hljs-comment"># npm install -D fauna-schema-migrate</span>

<span class="hljs-comment"># Initialize the folders and config needed for this tool</span>
npx fauna-schema-migrate init
</code></pre>
<p>This will create some files and folders which we later use to set up migrations for the collections and indexes that we create. Go through the <a target="_blank" href="https://github.com/fauna-brecht/fauna-schema-migrate">GitHub REAMDE</a> to know more about this tool. To summarize, here's how it works.</p>
<ol>
<li>You add all your collections, indexes, etc in your <code>fauna/resources</code> folder. </li>
<li>Based on the changes in the resources folder, you will be able to generate migrations. These migrations will get generated in your <code>fauna/migrations</code> folder.</li>
<li>You will have the ability to see the state of the database. You will be able to see what all migrations have been applied and what migrations are yet to be applied.</li>
<li>You will be able to apply the migrations or rollback the applied migrations.</li>
<li>While running any of these commands, you will be asked to enter the <code>FAUNA ADMIN KEY</code>.<ul>
<li>You will be able to generate this key from the Security tab of the Fauna dashboard.</li>
<li>You can also set the environment variables <code>FAUNA_ADMIN_KEY</code>, <code>FAUNADB_DOMAIN</code>, <code>FAUNADB_SCHEME</code>, and <code>FAUNADB_PORT</code>.</li>
<li>While connecting to the cloud database, you will only need to set <code>FAUNA_ADMIN_KEY</code>.</li>
<li>If you are working with the Fauna Dev Docker container, you need to set up other variables too.<ul>
<li>Since I am using Fauna Dev for local development, I have set up these as per my configuration.</li>
</ul>
</li>
</ul>
</li>
</ol>
<pre><code class="lang-bash"><span class="hljs-built_in">export</span> FAUNA_ADMIN_KEY=secret <span class="hljs-comment"># This is the default secret for Fauna Dev</span>
<span class="hljs-built_in">export</span> FAUNADB_DOMAIN=localhost
<span class="hljs-built_in">export</span> FAUNADB_SCHEME=http
<span class="hljs-built_in">export</span> FAUNADB_PORT=8443
</code></pre>
<h2 id="heading-authentication-and-authorization-in-fauna">Authentication and Authorization in Fauna</h2>
<p>Fauna has its own authentication system. But in this project, I have been using a <code>next-auth</code> adapter for authentication. Basically what this means is that I will handle all the authentication and authorization elsewhere(in the serverless functions of my app), and only allow the users to access the resources that they are authorized to access. Doing things this way is definitely not ideal. Fauna offers a very powerful security system out of the box. But it's a bit tricky to make it work with <code>next-auth</code> system. But I am definitely planning to make use of Fauna's security system in the future and will try to make it work with <code>next-auth</code> without losing any of the capabilities of Fauna. </p>
<h3 id="heading-nextjs-serverless-function-setup-for-fauna">Next.js Serverless Function Setup for Fauna</h3>
<p>This is how all my serverless functions look like in my Next.js app</p>
<p><strong>Fauna DB Client Setup</strong></p>
<p>I use Docker container locally, and use Fauna Cloud when the app is in production</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> faunadb <span class="hljs-keyword">from</span> <span class="hljs-string">'faunadb'</span>

<span class="hljs-comment">// Checking if the app is in production</span>
<span class="hljs-keyword">const</span> isProduction = process.env.NODE_ENV === <span class="hljs-string">'production'</span>

<span class="hljs-comment">// Using Fauna Dev Docker container when running locally</span>
<span class="hljs-comment">// Using Fauna Cloud when in production</span>
<span class="hljs-keyword">const</span> client = <span class="hljs-keyword">new</span> faunadb.Client({
  <span class="hljs-attr">secret</span>: process.env.FAUNADB_SECRET ?? <span class="hljs-string">'secret'</span>,
  <span class="hljs-attr">scheme</span>: isProduction ? <span class="hljs-string">'https'</span> : <span class="hljs-string">'http'</span>,
  <span class="hljs-attr">domain</span>: isProduction ? <span class="hljs-string">'db.fauna.com'</span> : <span class="hljs-string">'localhost'</span>,
  ...(isProduction ? {} : { <span class="hljs-attr">port</span>: <span class="hljs-number">8443</span> }),
})
</code></pre>
<p><strong>Requires Authentication</strong></p>
<p>If it requires the user to be authenticated, then I use <code>next-auth</code> <code>getSession</code> function to check if the user is authenticated.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { getSession } <span class="hljs-keyword">from</span> <span class="hljs-string">'next-auth/client'</span>

<span class="hljs-keyword">const</span> Handler = <span class="hljs-keyword">async</span> (req, res) =&gt; {

    <span class="hljs-comment">// If the user needs authentication</span>
  <span class="hljs-keyword">const</span> session = <span class="hljs-keyword">await</span> getSession({ req })

  <span class="hljs-keyword">if</span> (!session) {
    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">401</span>).json({ <span class="hljs-attr">message</span>: <span class="hljs-string">'Not logged in (UnAuthenticated)'</span> })
  }

    <span class="hljs-comment">// other code</span>
    <span class="hljs-comment">// ...</span>
    <span class="hljs-comment">// ...</span>
    <span class="hljs-comment">// ...</span>
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Handler
</code></pre>
<p><strong>Requires Authorization</strong></p>
<p>If only a particular user is authorized to run this function, then I send the <code>id</code> of the authorized user in the request body, and manually check if the currently logged-in user is the same as that of the authorized user.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { getSession } <span class="hljs-keyword">from</span> <span class="hljs-string">'next-auth/client'</span>

<span class="hljs-keyword">const</span> Handler = <span class="hljs-keyword">async</span> (req, res) =&gt; {

    <span class="hljs-comment">// If the user needs authentication</span>
  <span class="hljs-keyword">const</span> session = <span class="hljs-keyword">await</span> getSession({ req })

  <span class="hljs-keyword">if</span> (!session) {
    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">401</span>).json({ <span class="hljs-attr">message</span>: <span class="hljs-string">'Not logged in (UnAuthenticated)'</span> })
  }

  <span class="hljs-keyword">const</span> { authorizedUserId } = req.body

  <span class="hljs-keyword">const</span> loggedInUserId = session.user.id

  <span class="hljs-keyword">if</span> (loggedInUserId !== authorizedUserId) {
    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">403</span>).json({ <span class="hljs-attr">message</span>: <span class="hljs-string">'Access Forbidden'</span> })
  }

    <span class="hljs-comment">// other code</span>
    <span class="hljs-comment">// ...</span>
    <span class="hljs-comment">// ...</span>
    <span class="hljs-comment">// ...</span>

}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Handler
</code></pre>
<p>Putting it all together, this is how a typical serverless function looks like in my nextjs app.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { getSession } <span class="hljs-keyword">from</span> <span class="hljs-string">'next-auth/client'</span>

<span class="hljs-keyword">import</span> faunadb <span class="hljs-keyword">from</span> <span class="hljs-string">'faunadb'</span>
<span class="hljs-keyword">const</span> isProduction = process.env.NODE_ENV === <span class="hljs-string">'production'</span>
<span class="hljs-keyword">const</span> client = <span class="hljs-keyword">new</span> faunadb.Client({
  <span class="hljs-attr">secret</span>: process.env.FAUNADB_SECRET ?? <span class="hljs-string">'secret'</span>,
  <span class="hljs-attr">scheme</span>: isProduction ? <span class="hljs-string">'https'</span> : <span class="hljs-string">'http'</span>,
  <span class="hljs-attr">domain</span>: isProduction ? <span class="hljs-string">'db.fauna.com'</span> : <span class="hljs-string">'localhost'</span>,
  ...(isProduction ? {} : { <span class="hljs-attr">port</span>: <span class="hljs-number">8443</span> }),
})
<span class="hljs-keyword">const</span> q = faunadb.query

<span class="hljs-keyword">const</span> Handler = <span class="hljs-keyword">async</span> (req, res) =&gt; {

    <span class="hljs-comment">// If the user needs authentication</span>
  <span class="hljs-keyword">const</span> session = <span class="hljs-keyword">await</span> getSession({ req })
  <span class="hljs-keyword">if</span> (!session) {
    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">401</span>).json({ <span class="hljs-attr">message</span>: <span class="hljs-string">'Not logged in (UnAuthenticated)'</span> })
  }

  <span class="hljs-keyword">const</span> { authorizedUserId } = req.body

  <span class="hljs-keyword">const</span> loggedInUserId = session.user.id

  <span class="hljs-keyword">if</span> (loggedInUserId !== authorizedUserId) {
    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">403</span>).json({ <span class="hljs-attr">message</span>: <span class="hljs-string">'Access Forbidden'</span> })
  }

    <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> response: any = <span class="hljs-keyword">await</span> client.query(
            q.Do(
                <span class="hljs-comment">// Execute some fauna code here</span>
            )
        )

        <span class="hljs-comment">// Some code</span>
        <span class="hljs-comment">// ...</span>
        <span class="hljs-comment">// ...</span>
        <span class="hljs-comment">// ...</span>
    res.status(<span class="hljs-number">200</span>).json(response)
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-built_in">console</span>.error(error)
    res.status(<span class="hljs-number">500</span>).json({ <span class="hljs-attr">message</span>: error.message })
  }  
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Handler
</code></pre>
<h2 id="heading-nextauth">NextAuth</h2>
<p>We need a few collections and indexes to work with <code>next-auth</code>'s Fauna adapter. So, let's add those in <code>fauna/resources</code> folder. I have created two directories inside the <code>resources</code> folder. One is for <code>collections</code> and another for <code>indexes</code>.</p>
<p>These are the collections that I need for the <code>next-auth</code>'s Fauna adapter.</p>
<pre><code class="lang-jsx"><span class="hljs-comment">// fauna/resources/collections/accounts.fql</span>
CreateCollection({ 
  <span class="hljs-attr">name</span>: <span class="hljs-string">'accounts'</span> 
})

<span class="hljs-comment">// fauna/resources/collections/users.fql</span>
CreateCollection({ 
  <span class="hljs-attr">name</span>: <span class="hljs-string">'users'</span> 
})

<span class="hljs-comment">// fauna/resources/collections/sessions.fql</span>
CreateCollection({ 
  <span class="hljs-attr">name</span>: <span class="hljs-string">'sessions'</span> 
})

<span class="hljs-comment">// fauna/resources/collections/verification_requests.fql</span>
CreateCollection({ 
  <span class="hljs-attr">name</span>: <span class="hljs-string">'verification_requests'</span> 
})
</code></pre>
<p>Each of the above FQL queries is in a different file inside the <code>resources/collections</code> folder.</p>
<p>We also need a few indexes for the <code>next-auth</code>'s Fauna adapter.</p>
<pre><code class="lang-jsx"><span class="hljs-comment">// fauna/resources/indexes/account_by_provider_account_id.fql</span>
CreateIndex({
  <span class="hljs-attr">name</span>: <span class="hljs-string">'account_by_provider_account_id'</span>,
  <span class="hljs-attr">source</span>: Collection(<span class="hljs-string">'accounts'</span>),
  <span class="hljs-attr">unique</span>: <span class="hljs-literal">true</span>,
  <span class="hljs-attr">terms</span>: [
    { <span class="hljs-attr">field</span>: [<span class="hljs-string">'data'</span>, <span class="hljs-string">'providerId'</span>] },
    { <span class="hljs-attr">field</span>: [<span class="hljs-string">'data'</span>, <span class="hljs-string">'providerAccountId'</span>] },
  ],
})

<span class="hljs-comment">// fauna/resources/indexes/session_by_token.fql</span>
CreateIndex({
  <span class="hljs-attr">name</span>: <span class="hljs-string">'session_by_token'</span>,
  <span class="hljs-attr">source</span>: Collection(<span class="hljs-string">'sessions'</span>),
  <span class="hljs-attr">unique</span>: <span class="hljs-literal">true</span>,
  <span class="hljs-attr">terms</span>: [{ <span class="hljs-attr">field</span>: [<span class="hljs-string">'data'</span>, <span class="hljs-string">'sessionToken'</span>] }],
})

<span class="hljs-comment">// fauna/resources/indexes/user_by_email.fql</span>
CreateIndex({
  <span class="hljs-attr">name</span>: <span class="hljs-string">'user_by_email'</span>,
  <span class="hljs-attr">source</span>: Collection(<span class="hljs-string">'users'</span>),
  <span class="hljs-attr">unique</span>: <span class="hljs-literal">true</span>,
  <span class="hljs-attr">terms</span>: [{ <span class="hljs-attr">field</span>: [<span class="hljs-string">'data'</span>, <span class="hljs-string">'email'</span>] }],
})

<span class="hljs-comment">// fauna/resources/indexes/verification_request_by_token.fql</span>
CreateIndex({
  <span class="hljs-attr">name</span>: <span class="hljs-string">'verification_request_by_token'</span>,
  <span class="hljs-attr">source</span>: Collection(<span class="hljs-string">'verification_requests'</span>),
  <span class="hljs-attr">unique</span>: <span class="hljs-literal">true</span>,
  <span class="hljs-attr">terms</span>: [{ <span class="hljs-attr">field</span>: [<span class="hljs-string">'data'</span>, <span class="hljs-string">'token'</span>] }],
})

<span class="hljs-comment">// fauna/resources/indexes/user_by_username.fql</span>
CreateIndex({
  <span class="hljs-attr">name</span>: <span class="hljs-string">'user_by_username'</span>,
  <span class="hljs-attr">source</span>: Collection(<span class="hljs-string">'users'</span>),
  <span class="hljs-attr">unique</span>: <span class="hljs-literal">true</span>,
  <span class="hljs-attr">terms</span>: [{ <span class="hljs-attr">field</span>: [<span class="hljs-string">'data'</span>, <span class="hljs-string">'username'</span>] }],
})
</code></pre>
<p>Now we need to generate the corresponding migrations for these resources. To do that, you can just run <code>npx fauna-schema-migrate generate</code>. This will create a new folder in the <code>fauna/migrations</code> folder, inside which there are files for each of the resource files that we created. You can apply all of these migrations in one go by running <code>npx fauna-schema-migrate apply all</code>.</p>
<p>Now that we are all set up, let's start working on the actual features of the application.</p>
<h2 id="heading-requirements-and-features">Requirements and Features</h2>
<p>In <a target="_blank" href="http://coderplex.org">coderplex.org</a> app, each user will be able to do all of the following things:</p>
<ul>
<li>Goals<ul>
<li>Set a goal with title, description(goal plan – which also accepts MDX), and deadline.</li>
<li>Currently, only 1 user will correspond to 1 goal. In other words, each goal will have a single participant, but in the future, multiple users can participate in the same goal. So the schema should take care of that.</li>
</ul>
</li>
<li>Updates<ul>
<li>Post an update to the goal<ul>
<li>An update is very similar to a tweet that you have on Twitter. The only difference is that each update will correspond to a goal.</li>
<li>The update will also accept markdown(MDX).</li>
</ul>
</li>
<li>Edit your update</li>
<li>Like any update</li>
</ul>
</li>
<li>Comments<ul>
<li>Add a comment to an update (also accepts MDX)</li>
<li>Edit your comment.</li>
<li>Like any comment</li>
</ul>
</li>
<li>Follow any other user</li>
<li>Notifications<ul>
<li>Whenever another user likes your update/comment.</li>
<li>Whenever another user follows you.</li>
<li>Whenever another user comments on your update.</li>
<li>Users should see the unread notification count.</li>
<li>When they open the notifications, they should also be able to differentiate unread-notifications from read-notifications.</li>
<li>All the notifications should be marked as read, by the next time they open the notifications, and the notification count should be reset to 0.</li>
</ul>
</li>
<li>Users should be able to edit/add the details like their social media links, their name, etc.</li>
</ul>
<p>These are the requirements and features that we have in <a target="_blank" href="http://coderplex.org">coderplex.org</a> app.</p>
<h2 id="heading-modelling-the-data">Modelling the data</h2>
<p>These are the following collections that I have created.</p>
<ul>
<li>goals</li>
<li>goal_participants</li>
<li>goal_updates</li>
<li>update_likes</li>
<li>update_comments</li>
<li>comment_likes</li>
<li>activities</li>
<li>notifications</li>
<li>notification_statuses</li>
<li>user_followers</li>
<li>users</li>
</ul>
<h3 id="heading-goals">Goals</h3>
<p>This is how an example goal will look like. Each goal will have a reference to the <code>user</code> who created the goal.</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"ref"</span>: Ref(Collection(<span class="hljs-string">"goals"</span>), <span class="hljs-attr">"291155149010764290"</span>),
  <span class="hljs-attr">"ts"</span>: <span class="hljs-number">1614490198607000</span>,
  <span class="hljs-attr">"data"</span>: {
    <span class="hljs-attr">"createdBy"</span>: Ref(Collection(<span class="hljs-string">"users"</span>), <span class="hljs-attr">"291151577246335494"</span>),
    <span class="hljs-attr">"title"</span>: <span class="hljs-string">"Learn NextJS"</span>,
    <span class="hljs-attr">"description"</span>: <span class="hljs-string">"I will go through the following resources......"</span>,
    <span class="hljs-attr">"timestamps"</span>: {
      <span class="hljs-attr">"createdAt"</span>: Time(<span class="hljs-string">"2021-02-21T16:47:17.542336Z"</span>),
      <span class="hljs-attr">"updatedAt"</span>: Time(<span class="hljs-string">"2021-02-28T05:29:58.485254Z"</span>)
    },
    <span class="hljs-attr">"deadline"</span>: Time(<span class="hljs-string">"2021-03-12T00:00:00Z"</span>)
  }
}
</code></pre>
<h3 id="heading-goal-participants">Goal Participants</h3>
<p>Currently, the user who created a goal will be the only participant of the goal. But even if there are multiple participants of a goal, it will just be another new document in this collection. Each document of this collection will have a reference to the <code>goal</code> and also to the <code>user</code> collections.</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"ref"</span>: Ref(Collection(<span class="hljs-string">"goal_participants"</span>), <span class="hljs-attr">"291155149149176322"</span>),
  <span class="hljs-attr">"ts"</span>: <span class="hljs-number">1613926037910000</span>,
  <span class="hljs-attr">"data"</span>: {
    <span class="hljs-attr">"goal"</span>: Ref(Collection(<span class="hljs-string">"goals"</span>), <span class="hljs-attr">"291155149010764290"</span>),
    <span class="hljs-attr">"participant"</span>: Ref(Collection(<span class="hljs-string">"users"</span>), <span class="hljs-attr">"291151577246335494"</span>),
    <span class="hljs-attr">"timestamps"</span>: {
      <span class="hljs-attr">"createdAt"</span>: Time(<span class="hljs-string">"2021-02-21T16:47:17.542336Z"</span>),
      <span class="hljs-attr">"updatedAt"</span>: Time(<span class="hljs-string">"2021-02-21T16:47:17.542336Z"</span>)
    }
  }
}
</code></pre>
<h3 id="heading-goal-updates">Goal Updates</h3>
<p>Each goal update will have reference to the <code>goal</code> to which this update belongs to, and also to the <code>user</code> who is posting this update.</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"ref"</span>: Ref(Collection(<span class="hljs-string">"goal_updates"</span>), <span class="hljs-attr">"291156218380026372"</span>),
  <span class="hljs-attr">"ts"</span>: <span class="hljs-number">1613927057530000</span>,
  <span class="hljs-attr">"data"</span>: {
    <span class="hljs-attr">"goal"</span>: Ref(Collection(<span class="hljs-string">"goals"</span>), <span class="hljs-attr">"291155149010764290"</span>),
    <span class="hljs-attr">"postedBy"</span>: Ref(Collection(<span class="hljs-string">"users"</span>), <span class="hljs-attr">"291151577246335494"</span>),
    <span class="hljs-attr">"description"</span>: <span class="hljs-string">"Finished the \"Create a Next.js App\" section from the NextJS basics tutorial "</span>,
    <span class="hljs-attr">"timestamps"</span>: {
      <span class="hljs-attr">"createdAt"</span>: Time(<span class="hljs-string">"2021-02-21T17:04:17.345236Z"</span>),
      <span class="hljs-attr">"updatedAt"</span>: Time(<span class="hljs-string">"2021-02-21T17:04:17.345236Z"</span>)
    }
  }
}
</code></pre>
<h3 id="heading-update-likes">Update Likes</h3>
<p>Each document of this collection will have a reference to the <code>user</code> who performed this action and also to the <code>update</code> on which this action is performed on. Here the action is either <code>like</code> or <code>unlike</code>. Whenever a user likes an update for the first time, a new document is created in this collection, with <code>liked</code> set to <code>true</code>. Whenever the user unlikes an update, since the document is already created, we would just toggle the <code>liked</code> to <code>false</code>. Similarly, when the user likes the update for the second time after unliking, instead of creating a new document, <code>liked</code> is again set back to <code>true</code>.</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"ref"</span>: Ref(Collection(<span class="hljs-string">"update_likes"</span>), <span class="hljs-attr">"291156291484647936"</span>),
  <span class="hljs-attr">"ts"</span>: <span class="hljs-number">1613927127890000</span>,
  <span class="hljs-attr">"data"</span>: {
    <span class="hljs-attr">"user"</span>: Ref(Collection(<span class="hljs-string">"users"</span>), <span class="hljs-attr">"291150570318725632"</span>),
    <span class="hljs-attr">"update"</span>: Ref(Collection(<span class="hljs-string">"goal_updates"</span>), <span class="hljs-attr">"291156254585258502"</span>),
    <span class="hljs-attr">"liked"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">"timestamps"</span>: {
      <span class="hljs-attr">"createdAt"</span>: Time(<span class="hljs-string">"2021-02-21T17:05:26.235891Z"</span>),
      <span class="hljs-attr">"updatedAt"</span>: Time(<span class="hljs-string">"2021-02-21T17:05:26.235891Z"</span>)
    }
  }
}
</code></pre>
<h3 id="heading-update-comments">Update Comments</h3>
<p>Each document in this collection will have reference to the <code>user</code> who posted this comment and also to the <code>update</code> under which this comment is posted.</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"ref"</span>: Ref(Collection(<span class="hljs-string">"update_comments"</span>), <span class="hljs-attr">"291226260758069760"</span>),
  <span class="hljs-attr">"ts"</span>: <span class="hljs-number">1613993855415000</span>,
  <span class="hljs-attr">"data"</span>: {
    <span class="hljs-attr">"postedBy"</span>: Ref(Collection(<span class="hljs-string">"users"</span>), <span class="hljs-attr">"291151577246335494"</span>),
    <span class="hljs-attr">"update"</span>: Ref(Collection(<span class="hljs-string">"goal_updates"</span>), <span class="hljs-attr">"291226189279789572"</span>),
    <span class="hljs-attr">"description"</span>: <span class="hljs-string">"Nice job! "</span>,
    <span class="hljs-attr">"timestamps"</span>: {
      <span class="hljs-attr">"createdAt"</span>: Time(<span class="hljs-string">"2021-02-22T11:37:34.940974Z"</span>),
      <span class="hljs-attr">"updatedAt"</span>: Time(<span class="hljs-string">"2021-02-22T11:37:34.940974Z"</span>)
    }
  }
}
</code></pre>
<h3 id="heading-comment-likes">Comment Likes</h3>
<p>A comment like is very similar to <code>update_like</code>, the only difference is that the user is liking/unliking a comment instead of an update.</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"ref"</span>: Ref(Collection(<span class="hljs-string">"comment_likes"</span>), <span class="hljs-attr">"291748514516435458"</span>),
  <span class="hljs-attr">"ts"</span>: <span class="hljs-number">1614491916980000</span>,
  <span class="hljs-attr">"data"</span>: {
    <span class="hljs-attr">"user"</span>: Ref(Collection(<span class="hljs-string">"users"</span>), <span class="hljs-attr">"291196688254632454"</span>),
    <span class="hljs-attr">"comment"</span>: Ref(Collection(<span class="hljs-string">"update_comments"</span>), <span class="hljs-attr">"291748498072666628"</span>),
    <span class="hljs-attr">"liked"</span>: <span class="hljs-literal">false</span>,
    <span class="hljs-attr">"timestamps"</span>: {
      <span class="hljs-attr">"createdAt"</span>: Time(<span class="hljs-string">"2021-02-28T05:58:34.974710Z"</span>),
      <span class="hljs-attr">"updatedAt"</span>: Time(<span class="hljs-string">"2021-02-28T05:58:36.839458Z"</span>)
    }
  }
}
</code></pre>
<h3 id="heading-activities">Activities</h3>
<p>Whenever an activity is performed, a new document will be created in this collection. An activity can be <code>LIKED_UPDATE</code>, <code>UNLIKED_UPDATE</code>, <code>LIKED_COMMENT</code>, <code>UNIKED_COMMENT</code>, <code>COMMENTED</code>, <code>FOLLOWED</code>, <code>UNFOLLOWED</code>. Each document in this collection will have a reference to the <code>user</code> who performed this activity and also to the <code>resource</code>, which has been added/changes as a result of this activity. For example, if the activity is <code>LIKED_UPDATE</code>, then the resource is from the <code>update_likes</code> collection because that is where we are storing the likes of the updates. </p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"ref"</span>: Ref(Collection(<span class="hljs-string">"activities"</span>), <span class="hljs-attr">"291746021461983744"</span>),
  <span class="hljs-attr">"ts"</span>: <span class="hljs-number">1614489537610000</span>,
  <span class="hljs-attr">"data"</span>: {
    <span class="hljs-attr">"user"</span>: Ref(Collection(<span class="hljs-string">"users"</span>), <span class="hljs-attr">"291151577246335494"</span>),
    <span class="hljs-attr">"resource"</span>: Ref(Collection(<span class="hljs-string">"update_likes"</span>), <span class="hljs-attr">"291701773249282560"</span>),
    <span class="hljs-attr">"type"</span>: <span class="hljs-string">"LIKED_UPDATE"</span>,
    <span class="hljs-attr">"timestamps"</span>: {
      <span class="hljs-attr">"createdAt"</span>: Time(<span class="hljs-string">"2021-02-28T05:18:57.449934Z"</span>),
      <span class="hljs-attr">"updatedAt"</span>: Time(<span class="hljs-string">"2021-02-28T05:18:57.449934Z"</span>)
    }
  }
}
</code></pre>
<h3 id="heading-notifications">Notifications</h3>
<p>This is the place where we store the notifications. Each document in this collection will have a reference to the <code>user</code> to which this notification should be shown. It will also have a reference to the <code>activity</code> based on which this notification is created. We will not create notifications for all the activities. For example, if one user unfollowed another user, we don't want to show that notification. So we only create notifications for some of the activities.</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"ref"</span>: Ref(Collection(<span class="hljs-string">"notifications"</span>), <span class="hljs-attr">"291746542632567300"</span>),
  <span class="hljs-attr">"ts"</span>: <span class="hljs-number">1614490034620000</span>,
  <span class="hljs-attr">"data"</span>: {
    <span class="hljs-attr">"user"</span>: Ref(Collection(<span class="hljs-string">"users"</span>), <span class="hljs-attr">"291299459214606850"</span>),
    <span class="hljs-attr">"activity"</span>: Ref(Collection(<span class="hljs-string">"activities"</span>), <span class="hljs-attr">"291746542630470148"</span>),
    <span class="hljs-attr">"timestamps"</span>: {
      <span class="hljs-attr">"createdAt"</span>: Time(<span class="hljs-string">"2021-02-28T05:27:14.492640Z"</span>),
      <span class="hljs-attr">"updatedAt"</span>: Time(<span class="hljs-string">"2021-02-28T05:27:14.492640Z"</span>)
    }
  }
}
</code></pre>
<h3 id="heading-notification-statuses">Notification Statuses</h3>
<p>In this collection, we store the number of notifications read by the user. Each document in this collection will have a reference to the <code>user</code>. This is how we will know how many unread notifications are present for a user. For example, if we have a total of <code>60</code> notifications for a user, and in <code>notification_statuses</code> collection, the same user has count as <code>58</code>, then we know that the user has <code>2</code> new notifications, and we show the recent two notifications as <code>unread</code> in the UI.</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"ref"</span>: Ref(Collection(<span class="hljs-string">"notification_statuses"</span>), <span class="hljs-attr">"291746117445485062"</span>),
  <span class="hljs-attr">"ts"</span>: <span class="hljs-number">1615246280027000</span>,
  <span class="hljs-attr">"data"</span>: {
    <span class="hljs-attr">"user"</span>: Ref(Collection(<span class="hljs-string">"users"</span>), <span class="hljs-attr">"291150570318725632"</span>),
    <span class="hljs-attr">"count"</span>: <span class="hljs-number">58</span>,
    <span class="hljs-attr">"timestamps"</span>: {
      <span class="hljs-attr">"createdAt"</span>: Time(<span class="hljs-string">"2021-02-28T05:20:28.984137Z"</span>),
      <span class="hljs-attr">"updatedAt"</span>: Time(<span class="hljs-string">"2021-03-08T23:31:19.808558Z"</span>)
    }
  }
}
</code></pre>
<h3 id="heading-user-followers">User Followers</h3>
<p>This collection is very similar to the <code>update_likes</code> collection. Instead of <code>liked</code>, here you will have <code>isFollowing</code>. This will also have references to the <code>user</code> who is being followed, and also the <code>user</code> who is following the other user.</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"ref"</span>: Ref(Collection(<span class="hljs-string">"user_followers"</span>), <span class="hljs-attr">"291151670793994758"</span>),
  <span class="hljs-attr">"ts"</span>: <span class="hljs-number">1614489819630000</span>,
  <span class="hljs-attr">"data"</span>: {
    <span class="hljs-attr">"user"</span>: Ref(Collection(<span class="hljs-string">"users"</span>), <span class="hljs-attr">"291151577246335494"</span>),
    <span class="hljs-attr">"follower"</span>: Ref(Collection(<span class="hljs-string">"users"</span>), <span class="hljs-attr">"291150570318725632"</span>),
    <span class="hljs-attr">"isFollowing"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">"timestamps"</span>: {
      <span class="hljs-attr">"createdAt"</span>: Time(<span class="hljs-string">"2021-02-21T15:52:00.472819Z"</span>),
      <span class="hljs-attr">"updatedAt"</span>: Time(<span class="hljs-string">"2021-02-28T05:23:39.192197Z"</span>)
    }
  }
}
</code></pre>
<h3 id="heading-users">Users</h3>
<p>This is an example document in <code>users</code> collection.</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"ref"</span>: Ref(Collection(<span class="hljs-string">"users"</span>), <span class="hljs-attr">"292150540328725632"</span>),
  <span class="hljs-attr">"ts"</span>: <span class="hljs-number">1613940787978000</span>,
  <span class="hljs-attr">"data"</span>: {
    <span class="hljs-attr">"email"</span>: <span class="hljs-string">"pbteja1998@gmail.com"</span>,
    <span class="hljs-attr">"image"</span>: <span class="hljs-string">"https://avatars.githubusercontent.com/u/17903466?v=4"</span>,
    <span class="hljs-attr">"account"</span>: {
      <span class="hljs-attr">"firstName"</span>: <span class="hljs-string">"Bhanu Teja"</span>,
      <span class="hljs-attr">"lastName"</span>: <span class="hljs-string">"Pachipulusu"</span>,
      <span class="hljs-attr">"bio"</span>: <span class="hljs-string">"Software Engineer"</span>
    },
    <span class="hljs-attr">"socials"</span>: {
      <span class="hljs-attr">"github"</span>: <span class="hljs-string">"pbteja1998"</span>,
      <span class="hljs-attr">"twitter"</span>: <span class="hljs-string">"pbteja1998"</span>,
      <span class="hljs-attr">"blog"</span>: <span class="hljs-string">"https://bhanuteja.dev/"</span>,
      <span class="hljs-attr">"facebook"</span>: <span class="hljs-string">"pbteja1998"</span>,
      <span class="hljs-attr">"linkedin"</span>: <span class="hljs-string">"pbteja1998"</span>,
      <span class="hljs-attr">"codepen"</span>: <span class="hljs-string">"pbteja1998"</span>,
      <span class="hljs-attr">"discord"</span>: <span class="hljs-string">"BhanuTeja#4468"</span>
    },
    <span class="hljs-attr">"otherDetails"</span>: {
      <span class="hljs-attr">"company"</span>: <span class="hljs-string">"Coderplex"</span>,
      <span class="hljs-attr">"userType"</span>: <span class="hljs-string">"yes"</span>,
      <span class="hljs-attr">"mobile"</span>: <span class="hljs-string">"9876543210"</span>,
      <span class="hljs-attr">"isCurrentlyWorking"</span>: <span class="hljs-string">"yes"</span>
    },
    <span class="hljs-attr">"username"</span>: <span class="hljs-string">"pbteja1998"</span>,
    <span class="hljs-attr">"timestamps"</span>: {
      <span class="hljs-attr">"createdAt"</span>: Time(<span class="hljs-string">"2021-02-21T15:34:30.938680Z"</span>),
      <span class="hljs-attr">"updatedAt"</span>: Time(<span class="hljs-string">"2021-02-21T20:53:07.848454Z"</span>)
    },
    <span class="hljs-attr">"loggedInFromCoderplexOrg"</span>: <span class="hljs-literal">true</span>
  }
}
</code></pre>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this blog post, I have tried to explain how I use Fauna DB in my Next.js applications. I also showed how I modeled the data for the application. In the next blog post, I would write about different parts of the home page of the application, and also the queries to fetch the data required to show everything that is there on the home page.</p>
<div class="hn-embed-widget" id="newsletter"></div>]]></content:encoded></item><item><title><![CDATA[My 2020 Blogging Journey]]></title><description><![CDATA[I wanted to start blogging in Aug of 2020. I decided to use @hashnode for my blog. It was the best decision that I made.
I wrote 27 technical articles so far. Most of them are about frontend web development.
A thread 🧵 about each of these articles i...]]></description><link>https://blog.bhanuteja.dev/my-2020-blogging-journey</link><guid isPermaLink="true">https://blog.bhanuteja.dev/my-2020-blogging-journey</guid><category><![CDATA[general]]></category><category><![CDATA[General Advice]]></category><category><![CDATA[statistics]]></category><dc:creator><![CDATA[Bhanu Teja Pachipulusu]]></dc:creator><pubDate>Thu, 31 Dec 2020 08:22:03 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1609402647949/mAqDE0UzG.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I wanted to start blogging in Aug of 2020. I decided to use @hashnode for my blog. It was the best decision that I made.</p>
<p>I wrote 27 technical articles so far. Most of them are about frontend web development.</p>
<p>A thread 🧵 about each of these articles including the stats below 👇</p>
<blockquote>
<p>This started as a Twitter thread. But it became so long that I decided to turn it into a blog post.</p>
</blockquote>
<h2 id="heading-8j2xlpcdmilwnze0ipcdn63wnztlcdwnzu8j2frpcdn67wnzsic0g8j2xlpcdl7hwnzexipcdl6fwnzig8j2xvfcdl7lwnzia8j2xspcdl7wnze28j2xvfcdmieg8j2ygfcdl7wg8j2yhvcdl7zwnzic8j2xvydwnzeh8j2xsvcdmixwnziblvcdl7fwnziaipcdl73wnze8j2xvpcdl7fwnzey8j2xspcdmiegkpcdn60v8j2frvcdn7mp">𝗔𝘂𝗴 𝟭𝟭, 𝟮𝟬𝟮𝟬 - 𝗔𝗱𝗱 𝗧𝘆𝗽𝗲𝘀𝗰𝗿𝗶𝗽𝘁 𝘁𝗼 𝘆𝗼𝘂𝗿 𝗡𝗲𝘅𝘁.𝗷𝘀 𝗽𝗿𝗼𝗷𝗲𝗰𝘁 (𝟭/𝟮𝟳)</h2>
<p>It was when I just started learning React and started exploring Next.js and TypeScript. I was surprised to see how easy it was to add TypeScript to a Next.js project...</p>
<p>I thought to write a blog post about it to show it to others - more importantly for me to refer back to it when needed. I didn't want to spend time creating a blog. I wanted to start blogging right away...</p>
<p>Fortunately, I heard about @hashnode from a friend of mine and decided to give it a try. The selling factor for me about @hashnode was the ability to bring my own domain for my blog and the automatic backup of the articles on my own GitHub repo...</p>
<p>At that time, I didn't know that I was gonna write more than 1 article or that even anyone would wanna read the things that I write. But regardless, I went ahead and published my first article.</p>
<p>On the first day, the article has got around 20 views...</p>
<p>My main motive for writing articles was that they would act as a journal for whatever I was learning - so that I can get back to those when in need. So, I was more than happy with even 20 people reading it...</p>
<p>This is that article.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://blog.bhanuteja.dev/add-typescript-to-your-nextjs-project">https://blog.bhanuteja.dev/add-typescript-to-your-nextjs-project</a></div>
<p>As you can see, it's a very short article with a bunch of screenshots pasted together...</p>
<p>At the time of writing this tweet, this article has got about 𝟮𝟴𝟱 views. I myself have referred to it many times.</p>
<p>I decided to write even more articles at that time. And then my journey of tech blogging took off...</p>
<h2 id="heading-8j2xlpcdmilwnze0ipcdn63wnzulcdwnzu8j2frpcdn67wnzsic0g8j2xovcdl73wnzib8j2xtvcdl7rwnze28j2yhcdl7ig8j2xrpcdl7zwnzic8j2xvydwnzeq8j2xsvcdl6wnzia8j2xtvcdmihwnzeyipcdl5nwnze88j2xvydwnzem8j2xvpcdl7dwnze28j2xrvcdl7kg8j2xopcdl7lwnzex8j2xtvcdl64g8j2xocdl7nwnzeu8j2ygfcdl7pwnze88j2xvcdl7rwnziaicjwnzulcdn67wnzzkq">𝗔𝘂𝗴 𝟭𝟮, 𝟮𝟬𝟮𝟬 - 𝗢𝗽𝘁𝗶𝗺𝗶𝘇𝗲 𝗬𝗼𝘂𝗿 𝗪𝗲𝗯𝘀𝗶𝘁𝗲 𝗙𝗼𝗿 𝗦𝗼𝗰𝗶𝗮𝗹 𝗠𝗲𝗱𝗶𝗮 𝗣𝗹𝗮𝘁𝗳𝗼𝗿𝗺𝘀 (𝟮/𝟮𝟳)</h2>
<p>I was developing a website at that time. I noticed that when my website link is shared on platforms like Twitter...</p>
<p>I don't see any previews that I usually get when I share other links. I started exploring more about this and found out about meta tags and open graph protocol and also how some of the platforms like Twitter look for their own custom meta tags...</p>
<p>I decided to write an article about my findings and how/what meta tags to add to the website to make the platforms show nice previews for the website links that are being shared. I also added the tools that you can use to validate these tags in the article...</p>
<p>The result of this is the following article.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://blog.bhanuteja.dev/optimize-your-website-for-social-media-platforms">https://blog.bhanuteja.dev/optimize-your-website-for-social-media-platforms</a></div>
<p>At the time of writing this tweet, this article has got around 𝟮𝟵𝟰 views...</p>
<h2 id="heading-8j2xlpcdmilwnze0ipcdn63wnzxlcdwnzu8j2frpcdn67wnzsic0g8j2xlvcdl7wnzey8j2xrvcdmihwnzeyipcdl5bwnzic8j2ygpcdmihwnze88j2xuidwnzeg8j2xrvcdl7wnze48j2xsfcdl7zwnzie8j2xuydwnzej8j2xrvcdl7wnzia8j2xsvcdl78gkpcdn68v8j2frvcdn7mp">𝗔𝘂𝗴 𝟭𝟱, 𝟮𝟬𝟮𝟬 - 𝗖𝗿𝗲𝗮𝘁𝗲 𝗖𝘂𝘀𝘁𝗼𝗺 𝗠𝗮𝗿𝗸𝗱𝗼𝘄𝗻 𝗣𝗮𝗿𝘀𝗲𝗿 (𝟯/𝟮𝟳)</h2>
<p>I decided to write my first ever tutorial on how to create a markdown editor with the ability to embed YouTube videos, code sandboxes, code pens, etc...</p>
<p>I didn't know about MDX back then. That is a story for another time. In the markdown I know, it is not directly possible to embed things like YouTube videos and other things. But in one of my projects, I had this requirement...</p>
<p>So it seemed like a good tutorial that will be helpful to others and of-course as a reference to me in the future. I decided to split this into two articles. In hindsight, this was a mistake. I should have just written the article in a single go...</p>
<p>The first article in this two-part series is the following article.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://blog.bhanuteja.dev/create-custom-markdown-parser">https://blog.bhanuteja.dev/create-custom-markdown-parser</a></div>
<p>At the time of writing this tweet, this article has got around 𝟱𝟮𝟭 views.</p>
<h2 id="heading-8j2xlpcdmilwnze0ipcdn63wnzylcdwnzu8j2frpcdn67wnzsic0g8j2xmcdl7zwnzieipcdmihwnze8ipcdl5zwnze68j2xvfcdl7zwnze8j2ygsdwnzem8j2xqfcdl5rwnziaipcdl7bwnze78j2ygfcdl7wg8j2yhvcdl7zwnzic8j2xvydwnzeh8j2xsvcdmixwnziblvcdl7fwnziaipcdl6pwnze8j2xvpcdl7fwnzey8j2xspcdmieicjwnzwlcdn67wnzzkq">𝗔𝘂𝗴 𝟭𝟲, 𝟮𝟬𝟮𝟬 - 𝗛𝗼𝘄 𝘁𝗼 𝗜𝗺𝗽𝗼𝗿𝘁 𝗦𝗩𝗚𝘀 𝗶𝗻𝘁𝗼 𝘆𝗼𝘂𝗿 𝗡𝗲𝘅𝘁.𝗷𝘀 𝗣𝗿𝗼𝗷𝗲𝗰𝘁? (𝟰/𝟮𝟳)</h2>
<p>This is the article that has got the most organic views from Google among all the other articles that I ever wrote until today...</p>
<p>Like all my other articles, this article came out of my need. I got a use-case where I had to use and import SVGs into my Next.js project. I searched around and found many solutions. Two solutions stood out for me - SVGR and babel-plugin-inline-react-svg...</p>
<p>I found the babel plugin to be easier to use and ended up using it. I then wrote about it in the following article detailing how people can use it in their own projects.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://blog.bhanuteja.dev/how-to-import-svgs-into-your-nextjs-project">https://blog.bhanuteja.dev/how-to-import-svgs-into-your-nextjs-project</a></div>
<p>Up until today...</p>
<p>This article has been getting at least around 10 organic views for this article from Google every single day since then.</p>
<p>At the time of writing this tweet, the article has around 2.2K views...</p>
<h2 id="heading-8j2xlpcdmilwnze0ipcdn63wnzylcdwnzu8j2frpcdn67wnzsic0g8j2xlvcdl7wnzey8j2xrvcdmihwnzeyipcdl6hwnzey8j2yhcdwnzew8j2xvpcdl7hwnzey8j2xocdl7lwnze78j2ygcdwnzeu8j2xucdl7eg8j2xlvcdl7zwnzex8j2xsvcdl6bwnzeu8j2xucdl7hwnzev8j2xvpcdmixwnzey8j2ygcdwnzec8j2xucdmidwnzib8j2xrvcdl7vwnzib8j2xufcdmiyg8j2xqvcdl7bwnzib8j2xtsdwnzet8j2xmpcdl6xwnzeiipcdl7dwnze58j2xtvcdl7dwnze48j2ygcao8j2fsswnzu8j2fsyk">𝗔𝘂𝗴 𝟭𝟲, 𝟮𝟬𝟮𝟬 - 𝗖𝗿𝗲𝗮𝘁𝗲 𝗡𝗲𝘄 𝗖𝗼𝗱𝗲𝗣𝗲𝗻𝘀 𝗮𝗻𝗱 𝗖𝗼𝗱𝗲𝗦𝗮𝗻𝗱𝗯𝗼𝘅𝗲𝘀 𝗜𝗻𝘀𝘁𝗮𝗻𝘁𝗹𝘆 𝗪𝗶𝘁𝗵 𝗭𝗘𝗥𝗢 𝗰𝗹𝗶𝗰𝗸𝘀 (𝟱/𝟮𝟳)</h2>
<p>This is a very short article that I wrote when I found out that CodePen and CodeSandbox launched short URLs...</p>
<p>...that can be used to set up sandboxes with your favorite framework configured. For example, to create a sandbox with Reactjs, you can just go to react.new and you are done. I decided to list down all such URLs in a blog post.</p>
<p>The result is the following very short article...</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://blog.bhanuteja.dev/create-new-codepens-and-codesandboxes-instantly-with-zero-clicks">https://blog.bhanuteja.dev/create-new-codepens-and-codesandboxes-instantly-with-zero-clicks</a></div>
<p>At the time of writing this tweet, this article has got around 𝟭𝟭𝟰 views.</p>
<h2 id="heading-8j2xlpcdmilwnze0ipcdn63wnz0lcdwnzu8j2frpcdn67wnzsic0g8j2xocdl7wnzey8j2ygcdl7lwnze78j2ygsdwnzel8j2xsvcdmipwnzey8j2xvcdmidwnzeyipcdl6fwnzeu8j2xrcdl7vwnzeu8j2xrcdl6wnze28j2xucdl7qg8j2xlpcdmihwnzib8j2xrvcdl7dwnze48j2ygcdwnzeq8j2xtvcdmihwnze1ipcdl6pwnze8j2xvpcdl73wnzey8j2xvydwnze78j2xvpcdl7zwnze98j2xsvcdl7vwnzey8j2xvywg8j2xucdl7zwnze8j2xsvcdl7pwnzey8j2xvcdl7wnzey8j2xvywg8j2xrvcdl7vwnzexipcdl7vwnze88j2xscdl7zwnze58j2xufcdl7zwnzieipcdl5twnzib8j2ygfcdl7wnze28j2xrcdmilwnzib8j2xtvcdl7zwnze7ic0gkpcdn7iv8j2frvcdn7mp">𝗔𝘂𝗴 𝟭𝟴, 𝟮𝟬𝟮𝟬 - 𝗣𝗿𝗲𝘃𝗲𝗻𝘁 𝗥𝗲𝘃𝗲𝗿𝘀𝗲 𝗧𝗮𝗯𝗻𝗮𝗯𝗯𝗶𝗻𝗴 𝗔𝘁𝘁𝗮𝗰𝗸𝘀 𝗪𝗶𝘁𝗵 𝗣𝗿𝗼𝗽𝗲𝗿 𝗻𝗼𝗼𝗽𝗲𝗻𝗲𝗿, 𝗻𝗼𝗿𝗲𝗳𝗲𝗿𝗿𝗲𝗿, 𝗮𝗻𝗱 𝗻𝗼𝗳𝗼𝗹𝗹𝗼𝘄 𝗔𝘁𝘁𝗿𝗶𝗯𝘂𝘁𝗶𝗼𝗻 - (𝟲/𝟮𝟳)</h2>
<p>This article came out of my search for the meaning of 'rel' attribute for anchor <code>&lt;a&gt;</code> tags. 
 Turns out that there is a security risk for not adding noopener/noreferrer value to 'rel' attribute when you set the link to open in a new tab...</p>
<p>I ended up writing the article about the same detailing what each of the values noopener, noreferrer, nofollow mean and when should you use each of them. I recently cross-posted this article to HackerNoon...</p>
<p>To my surprise, it is marked as a #hackernoon-top-story which I think is pretty amazing.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://blog.bhanuteja.dev/noopener-noreferrer-and-nofollow-when-to-use-them-how-can-these-prevent-phishing-attacks">https://blog.bhanuteja.dev/noopener-noreferrer-and-nofollow-when-to-use-them-how-can-these-prevent-phishing-attacks</a></div>
<p>At the time of writing this tweet, this has got around 𝟭.𝟲𝗞 views</p>
<p>HackerNoon link of the same article.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://hackernoon.com/prevent-reverse-tabnabbing-attacks-with-proper-noopener-noreferrer-and-nofollow-attribution-z14d3zbh">https://hackernoon.com/prevent-reverse-tabnabbing-attacks-with-proper-noopener-noreferrer-and-nofollow-attribution-z14d3zbh</a></div>
<p>At the time of writing this tweet, this has got around 𝟰𝟬𝟳 views on HackerNoon...</p>
<h2 id="heading-8j2xlpcdmilwnze0ipcdn67wnzslcdwnzu8j2frpcdn67wnzsic0g8j2xlfcdl67wnzev8j2xsvcdl7kg8j2xocdl7nwnzic8j2xtpcdl7bwnze7ipcdl6fwnze8ipcdl6xwnzey8j2xuvcdl7zwnzid8j2xsidwnzew8j2xvpcdl7vwnzia8j2xvpcdl7nwnzeyipcdl5wnze88j2xtpcdmiag8j2xnpcdl7sg8j2xocdl7wnze88j2xsfcdmilwnzew8j2ygfcdl7bwnze88j2xuyao8j2fsywnzu8j2fsyk">𝗔𝘂𝗴 𝟮𝟬, 𝟮𝟬𝟮𝟬 - 𝗕𝗮𝗯𝗲𝗹 𝗣𝗹𝘂𝗴𝗶𝗻 𝗧𝗼 𝗥𝗲𝗺𝗼𝘃𝗲 𝗖𝗼𝗻𝘀𝗼𝗹𝗲 𝗟𝗼𝗴𝘀 𝗜𝗻 𝗣𝗿𝗼𝗱𝘂𝗰𝘁𝗶𝗼𝗻 (𝟳/𝟮𝟳)</h2>
<p>I always find myself leaving console logs in production which I should not...</p>
<p>I started looking for a solution to this problem and found a babel plugin that you can use to remove console logs automatically when deployed to production. I ended up writing a very short article detailing how to use this plugin...</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://blog.bhanuteja.dev/babel-plugin-to-remove-console-logs-in-production">https://blog.bhanuteja.dev/babel-plugin-to-remove-console-logs-in-production</a></div>
<p>At the time of writing this tweet, this article has got around 𝟭𝟰𝟳 views...</p>
<h2 id="heading-8j2xlpcdmilwnze0ipcdn67wnzvlcdwnzu8j2frpcdn67wnzsic0g8j2xmpcdl7rwnzev8j2xsvcdl7eg8j2xrpcdl7zwnzic8j2ygfcdmilwnzev8j2xsidwnzep8j2xtvcdl7hwnzey8j2xvpcdmiag8j2xtvcdl7vwnzib8j2xvcdwnzes8j2xvpcdmilwnzeipcdl6dwnzeu8j2xvcdl7jwnzex8j2xvpcdmitwnze7ipcdl5jwnzex8j2xtvcdmihwnze88j2xvyao8j2ftcwnzu8j2fsyk">𝗔𝘂𝗴 𝟮𝟯, 𝟮𝟬𝟮𝟬 - 𝗘𝗺𝗯𝗲𝗱 𝗬𝗼𝘂𝘁𝘂𝗯𝗲 𝗩𝗶𝗱𝗲𝗼𝘀 𝗶𝗻𝘁𝗼 𝗬𝗼𝘂𝗿 𝗠𝗮𝗿𝗸𝗱𝗼𝘄𝗻 𝗘𝗱𝗶𝘁𝗼𝗿 (𝟴/𝟮𝟳)</h2>
<p>Remember the 3rd article where I started a 2-part tutorial series about creating a custom markdown editor...</p>
<p>...this is the other part. I wrote this after writing 4 other completely unrelated articles. I should have written both of these in a single article or I should have written this immediately after the first one...</p>
<p>At the time of writing this tweet, this article has got around 𝟭𝟯𝟭 views.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://blog.bhanuteja.dev/embed-you-tube-videos-into-your-markdown-editor">https://blog.bhanuteja.dev/embed-you-tube-videos-into-your-markdown-editor</a></div>
<h2 id="heading-8j2xlpcdmilwnze0ipcdn67wnzylcdwnzu8j2frpcdn67wnzsic0g8j2xpcdl5zwnzefoidwnzeb8j2yhvcdl73wnze18j2xsvcdl7vwnzeu8j2ygfcdl7ig8j2yhpcdl7xwnzey8j2xuydwnzig8j2xvpcdmiig8j2xtcdmilwnzia8j2ygfcdl7bwnzez8j2yhidwnzib8j2xsvcdmixwnzibicjwnz1lcdn67wnzzkq">𝗔𝘂𝗴 𝟮𝟲, 𝟮𝟬𝟮𝟬 - 𝗧𝗜𝗟: 𝗛𝘆𝗽𝗵𝗲𝗻𝗮𝘁𝗲 𝘄𝗵𝗲𝗻 𝘆𝗼𝘂 𝗷𝘂𝘀𝘁𝗶𝗳𝘆 𝘁𝗲𝘅𝘁 (𝟵/𝟮𝟳)</h2>
<p>This article is the first and the last 😅article in which I wrote something new that I learned that day.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://blog.bhanuteja.dev/til-hyphenate-when-you-justify-text">https://blog.bhanuteja.dev/til-hyphenate-when-you-justify-text</a></div>
<p>This article is about the CSS property <code>hyphens</code> which I did not know about then.</p>
<p>At the time of writing this tweet, this article has got around 𝟭𝟬𝟰 views.</p>
<h2 id="heading-8j2xlpcdmilwnze0ipcdn67wnz0lcdwnzu8j2frpcdn67wnzsic0g8j2xqvcdl7xwnzigipcdmibwnze88j2ygidwnzia8j2xtfcdl7zwnzic8j2xufcdl7eg8j2ygpcdmihwnzeu8j2xvcdmieg8j2ygvcdmidwnze28j2xucdl7qg8j2xmcdl6bwnzefipcdl7dwnze88j2xufcdl7zwnzeipcdl7pwnze88j2xvcdl7rwnzeu8j2ygsao8j2frfcdn6wv8j2frvcdn7mp">𝗔𝘂𝗴 𝟮𝟴, 𝟮𝟬𝟮𝟬 - 𝗪𝗵𝘆 𝘆𝗼𝘂 𝘀𝗵𝗼𝘂𝗹𝗱 𝘀𝘁𝗮𝗿𝘁 𝘂𝘀𝗶𝗻𝗴 𝗛𝗦𝗟 𝗰𝗼𝗹𝗼𝗿 𝗳𝗼𝗿𝗺𝗮𝘁 (𝟭𝟬/𝟮𝟳)</h2>
<p>This is the article on which I have spent a huge amount of time to write among all of the previous 9 articles that I have written until then.</p>
<p>This article is about the HSL color format and why I think more people should start using it. I found the HSL color system to be more intuitive and closer to how humans perceive color. I wrote about what each of H, S and L mean in HSL...</p>
<p>...and how easy it is to create color schemes like Complementary Colors, Split Complementary Colors, Different shades of the same color using HSL color system.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://blog.bhanuteja.dev/why-you-should-start-using-hsl-color-format">https://blog.bhanuteja.dev/why-you-should-start-using-hsl-color-format</a></div>
<p>At the time of writing this tweet, this article has got around 𝟲𝟭𝟬 views.</p>
<h2 id="heading-8j2xlpcdmilwnze0ipcdn67wnz1lcdwnzu8j2frpcdn67wnzsic0g8j2xlvcdl7wnzey8j2xrvcdmihwnzeyipcdl6zwnze88j2ygvcdl78g8j2xovcdmitwnze7ipcdl6bwnzic8j2xvfcdl7lwnzeipcdl6bwnze28j2xuvcdl73wnze58j2xsidwnzeo8j2xpfcdl58g8j2xpvcdl7xwnze88j2xvcdmihwnzey8j2xucdl7lwnzeicjwnzt8j2frswnzu8j2fsyk">𝗔𝘂𝗴 𝟮𝟵, 𝟮𝟬𝟮𝟬 - 𝗖𝗿𝗲𝗮𝘁𝗲 𝗬𝗼𝘂𝗿 𝗢𝘄𝗻 𝗦𝘂𝗽𝗲𝗿 𝗦𝗶𝗺𝗽𝗹𝗲 𝗨𝗥𝗟 𝗦𝗵𝗼𝗿𝘁𝗲𝗻𝗲𝗿 (𝟭𝟭/𝟮𝟳)</h2>
<p>This blog post came out when I came across the following quoted tweet from @kentcdodds</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://twitter.com/kentcdodds/status/1296524239701327873?s=20">https://twitter.com/kentcdodds/status/1296524239701327873?s=20</a></div>
<p>The tweet contains a link to a youtube video where he explained about the npm package that he made which can be used to create a super simple URL shortener. I found the concept behind it to be genius. They are making use of Netlify Redirects to create a URL shortener...</p>
<p>My immediate reaction was that why didn't I think of that. Nevertheless, I ended up using the same package to create my own URL shortener to shorten many of my links. I ended up writing an article about the same, hoping that more people would benefit from this package.</p>
<p>At the time of writing this tweet, this article has got around 𝟱𝟳𝟯 views.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://blog.bhanuteja.dev/create-your-own-super-simple-url-shortener">https://blog.bhanuteja.dev/create-your-own-super-simple-url-shortener</a></div>
<p>This was the final article in the month of August...</p>
<p>I wrote a total of 11 articles in that month, a feat which I am never going to repeat. I had no schedule when I was writing these articles. I wrote and published articles whenever I felt like it - which was a mistake on my part.</p>
<p>I eventually figured out that consistency is far more important than writing a lot of articles at once. Eventually, I stuck to the schedule of writing 2 articles per week which helped me a lot more than writing whenever I felt like it.</p>
<p>It is a lot better to write a single article every two weeks than writing 10 articles in a week and then not writing anything for more than a month or two.</p>
<p>I now strongly believe that Consistency is the key to get things done or to get better in anything including writing.</p>
<h2 id="heading-8j2xpvcdl7lwnze9ipcdn64sipcdn67wnzs8j2frvcdn6wglsdwnzel8j2xsvcdl67wnzew8j2ygsdwnzez8j2ygvcdl7vwnzex8j2xrvcdl7rwnzey8j2xucdmihwnzeu8j2xufcdmiagkpcdn63wnzulcdn67wnzzkq">𝗦𝗲𝗽 𝟮, 𝟮𝟬𝟮𝟬 - 𝗥𝗲𝗮𝗰𝘁 𝗙𝘂𝗻𝗱𝗮𝗺𝗲𝗻𝘁𝗮𝗹𝘀 (𝟭𝟮/𝟮𝟳)</h2>
<p>I just found out about EpicReact.Dev workshops by @kentcdodds just then. I found that the source code of these workshops is open source...</p>
<p>I decided to go through them on my own before the course is actually released. This article is a result of that. I went through the React Fundamentals workshop and wrote about what I learned in my own words -- mainly to reinforce what I learned....</p>
<p>It was then I decided to buy #EpicReactDev as soon as it gets released. And I did just that later.</p>
<p>This is the article which I wrote.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://blog.bhanuteja.dev/react-fundamentals">https://blog.bhanuteja.dev/react-fundamentals</a></div>
<p>At the time of writing this tweet, this article has got around 1.6K views...</p>
<p>In the following days, I got covid and decided to take a break from everything.</p>
<p>After about a month later, EpicReact.Dev got released and I immediately bought it. It was the best decision ever...</p>
<h2 id="heading-8j2xovcdl7dwnzibipcdn7esipcdn67wnzs8j2frvcdn6wglsdwnzeg8j2yhidwnzel8j2xsvcdmipwnze28j2xsvcdmiqg8j2xvpcdl7mg8j2xnvcdl7lwnze78j2ygsdwnzewlidwnzex8j2xvpcdl7hwnzex8j2ygcfwnziaipcdl5jwnze98j2xtvcdl7dwnzel8j2xsvcdl67wnzew8j2ygs7wnzex8j2xsvcdmim6ipcdl5zwnze78j2ygfcdl7wnze88j2xsfcdmilwnzew8j2ygfcdl7bwnze88j2xuyao8j2frfcdn68v8j2frvcdn7mp">𝗢𝗰𝘁 𝟱, 𝟮𝟬𝟮𝟬 - 𝗠𝘆 𝗥𝗲𝘃𝗶𝗲𝘄 𝗼𝗳 𝗞𝗲𝗻𝘁 𝗖. 𝗗𝗼𝗱𝗱𝘀'𝘀 𝗘𝗽𝗶𝗰𝗥𝗲𝗮𝗰𝘁.𝗗𝗲𝘃: 𝗜𝗻𝘁𝗿𝗼𝗱𝘂𝗰𝘁𝗶𝗼𝗻 (𝟭𝟯/𝟮𝟳)</h2>
<p>I publicly committed to writing articles based on what I learned in #EpicReactDev workshops. This article is a result of that...</p>
<p>This has nothing more than the topics that will be covered in #EpicReactDev workshops. I have learned so much more from watching the videos than I did when I went through the open-source material on my own...</p>
<p>So many people messaged me saying that they want to buy this license, but wanted to know if it was worth it. My answer is always a huge YES. It definitely is. Many people started following along with what I wrote about these workshops and...</p>
<p>...many told me that they found these articles to be very helpful.</p>
<p>This 👇 is the first article when I publicly committed to it.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://blog.bhanuteja.dev/epic-react-introduction">https://blog.bhanuteja.dev/epic-react-introduction</a></div>
<p>At the time of writing this tweet, this article has got around 2K views...</p>
<h2 id="heading-8j2xovcdl7dwnzibipcdn7qsipcdn67wnzs8j2frvcdn6wglsdwnzed8j2xrvcdmipwnzeu8j2ygpcdl7dwnze8j2xtvcdl73wnzibipcdl6zwnze88j2ygidwnzeh8j2xsvcdl7lwnzexipcdl6fwnze8ipcdl57wnze78j2xvpcdmiqg8j2xmfcdl7zwnzeipcdl6xwnzey8j2xrvcdl7dwnzibicjwnzt8j2fscwnzu8j2fsyk">𝗢𝗰𝘁 𝟴, 𝟮𝟬𝟮𝟬 - 𝗝𝗮𝘃𝗮𝘀𝗰𝗿𝗶𝗽𝘁 𝗬𝗼𝘂 𝗡𝗲𝗲𝗱 𝗧𝗼 𝗞𝗻𝗼𝘄 𝗙𝗼𝗿 𝗥𝗲𝗮𝗰𝘁 (𝟭𝟰/𝟮𝟳)</h2>
<p>Before writing about the #EpicReactDev workshops, I wanted to write about Javascript concepts that I wish I had learned before starting to learn Reactjs...</p>
<p>This was the longest article and most read article that I have ever written. It even got featured on @hashnode</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://blog.bhanuteja.dev/epic-react-javascript-you-need-to-know-for-react">https://blog.bhanuteja.dev/epic-react-javascript-you-need-to-know-for-react</a></div>
<p>At the time of writing this tweet, this article has got around 6.9K views.</p>
<p>More than the views, I got personal messages from people thanking me for writing this. It felt really good 🙂</p>
<h2 id="heading-8j2xovcdl7dwnzibipcdn63wnzslcdwnzu8j2frpcdn67wnzsic0g8j2xmcdl7zwnzieipcdl5wg8j2xmvcdl67wnzid8j2xsidwnzeuipcdl6dwnze88j2xsfcdl7lwnze8j2xuydwnzef8j2xvpcdl7zwnze4ipcdl5nwnze88j2xvydwnzeb8j2xrvcdl7dwnze48j2xsvcdl7wnzeh8j2xsvcdmitwnziaipcdl5nwnzey8j2xsvcdl7egkpcdn63wnzxlcdn67wnzzkq">𝗢𝗰𝘁 𝟭𝟬, 𝟮𝟬𝟮𝟬 - 𝗛𝗼𝘄 𝗜 𝗚𝗮𝘃𝗲 𝗔 𝗠𝗼𝗱𝗲𝗿𝗻 𝗟𝗼𝗼𝗸 𝗙𝗼𝗿 𝗛𝗮𝗰𝗸𝗲𝗿𝗡𝗲𝘄𝘀 𝗙𝗲𝗲𝗱 (𝟭𝟱/𝟮𝟳)</h2>
<p>I took a very long break from coding the previous month. To get back to it, I decided to make a few fun projects.</p>
<p>For funsies, I tried to redesign the HackerNews website and this article is a result of that in which I showed the demo of the redesigned website.</p>
<p>I am attaching a few screenshots of the website.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://blog.bhanuteja.dev/how-i-gave-a-modern-look-for-hackernews-feed">https://blog.bhanuteja.dev/how-i-gave-a-modern-look-for-hackernews-feed</a></div>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1609397007377/3bSRu7SOrR.jpeg" alt="1.jpeg" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1609397014942/BH4BvzDLZ.jpeg" alt="2.jpeg" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1609397022098/6FuYJ-OFG.jpeg" alt="3.jpeg" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1609397030167/sdK9bSpoE.jpeg" alt="4.jpeg" /></p>
<p>At the time of writing this tweet, this article has got around 4.6K views.</p>
<h2 id="heading-8j2xovcdl7dwnzibipcdn63wnzulcdwnzu8j2frpcdn67wnzsic0g8j2xpfcdl7lwnzeu8j2xspcdmieg8j2xmfcdmilwnze78j2xsfcdl67wnze68j2xsvcdl7vwnzib8j2xrvcdl7nwnziaoidwnzec8j2xucdmihwnze8j2xvcdwnzib8j2xvcdwnzel8j2xsvcdl67wnzew8j2ygsdwnzel8j2xrvcdmiqg8j2xlpcdl6pwnzec8j2ygcao8j2frfcdn7iv8j2frvcdn7mp">𝗢𝗰𝘁 𝟭𝟮, 𝟮𝟬𝟮𝟬 - 𝗥𝗲𝗮𝗰𝘁 𝗙𝘂𝗻𝗱𝗮𝗺𝗲𝗻𝘁𝗮𝗹𝘀: 𝗜𝗻𝘁𝗿𝗼 𝘁𝗼 𝗥𝗲𝗮𝗰𝘁 𝗥𝗮𝘄 𝗔𝗣𝗜𝘀 (𝟭𝟲/𝟮𝟳)</h2>
<p>This was the "first" article in the series of articles based on #EpicReactDev.</p>
<p>In this article, I wrote about raw React APIs like React.createElement() and ReactDOM.render() methods.</p>
<p>At the time of writing this tweet, this article has got around 1.2K views.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://blog.bhanuteja.dev/epic-react-react-fundamentals-part-1">https://blog.bhanuteja.dev/epic-react-react-fundamentals-part-1</a></div>
<h2 id="heading-8j2xovcdl7dwnzibipcdn63wnzxlcdwnzu8j2frpcdn67wnzsic0g8j2xpfcdl7lwnzeu8j2xspcdmieg8j2xmfcdmilwnze78j2xsfcdl67wnze68j2xsvcdl7vwnzib8j2xrvcdl7nwnziaoidwnzeo8j2xucdl7hwnzey8j2xvcdmidwnzib8j2xrvcdl7vwnzex8j2xtvcdl7vwnze0ipcdl53wnzem8j2xqyao8j2frfcdn7mv8j2frvcdn7mp">𝗢𝗰𝘁 𝟭𝟱, 𝟮𝟬𝟮𝟬 - 𝗥𝗲𝗮𝗰𝘁 𝗙𝘂𝗻𝗱𝗮𝗺𝗲𝗻𝘁𝗮𝗹𝘀: 𝗨𝗻𝗱𝗲𝗿𝘀𝘁𝗮𝗻𝗱𝗶𝗻𝗴 𝗝𝗦𝗫 (𝟭𝟳/𝟮𝟳)</h2>
<p>This was the second article of the series. In this, I wrote about JSX - what is it, how to use it, how to add props to JSX elements.</p>
<p>I also wrote about interpolation in JSX and spreading props. The outline of this article is mostly based on the React Fundamentals workshop of #EpicReactDev.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://blog.bhanuteja.dev/react-fundamentals-understanding-jsx">https://blog.bhanuteja.dev/react-fundamentals-understanding-jsx</a></div>
<p>This has got around 716 views.</p>
<h2 id="heading-8j2xovcdl7dwnzibipcdn63wnzzlcdwnzu8j2frpcdn67wnzsic0g8j2xpfcdl7lwnzid8j2xrvcdl7rwnze98j2xsvcdl7eg8j2xmvcdl7bwnzib8j2xmcdmilwnzevipcdl53wnze88j2xrcdmiag8j2xqvcdl7lwnzev8j2ygpcdl7bwnzib8j2xsidwnzeo8j2ygpcdl7bwnze78j2xtcdwnzex8j2xsvcdmidwnze28j2xtpcdl7sg8j2xmfcdl7wnze88j2xuidwnzez8j2xvcdl7zwnze78j2ygfcdl7lwnze78j2xssdwnzeg8j2xsvcdl7vwnzib8j2xvpcdl78gkpcdn63wnz0lcdn67wnzzkq">𝗢𝗰𝘁 𝟭𝟳, 𝟮𝟬𝟮𝟬 - 𝗥𝗲𝘃𝗮𝗺𝗽𝗲𝗱 𝗚𝗶𝘁𝗛𝘂𝗯 𝗝𝗼𝗯𝘀 𝗪𝗲𝗯𝘀𝗶𝘁𝗲 𝗨𝘀𝗶𝗻𝗴 𝗗𝗲𝘀𝗶𝗴𝗻 𝗙𝗿𝗼𝗺 𝗙𝗿𝗼𝗻𝘁𝗲𝗻𝗱 𝗠𝗲𝗻𝘁𝗼𝗿 (𝟭𝟴/𝟮𝟳)</h2>
<p>I decided to do a @frontendmentor challenge and I wanted to choose a challenge that requires using some sort of APIs.</p>
<p>I chose GitHub jobs clone website and this article is a result of that showcasing the demo of that.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://blog.bhanuteja.dev/i-revamped-github-jobs-website-using-design-from-frontend-mentor">https://blog.bhanuteja.dev/i-revamped-github-jobs-website-using-design-from-frontend-mentor</a></div>
<p>The design also has a dark theme which I wanted to try.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1609397097536/Xt3DRUpQY.jpeg" alt="5.jpeg" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1609397105606/A3aX_e1CU.jpeg" alt="6.jpeg" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1609397115109/sHFo561rD.jpeg" alt="7.jpeg" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1609397128559/n0J1g3bYX.jpeg" alt="8.jpeg" /></p>
<p>I used Next.js, Tailwind CSS, React Query to make this site. At the time of writing this tweet, this article has got around 2.9K views and it also got featured on @dailydotdev</p>
<p>This was the first-ever site in which I used Tailwind CSS and React Query...</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1609397150414/Jj8d9f3VB.jpeg" alt="9.jpeg" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1609397159973/9oI6XQZ3y.jpeg" alt="10.jpeg" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1609397169000/Mzfn0AVjy.jpeg" alt="11.jpeg" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1609397189303/nkWp5g7So.jpeg" alt="12.jpeg" /></p>
<p>Needless to say, I never went back. These two became my most favorite tools/packages after Next.js. I decided to include these in all of my future projects.</p>
<p>I even made myself a boilerplate template with all of these pre-configured - which later became an open-source repo.</p>
<h2 id="heading-8j2xovcdl7dwnzibipcdn63wnz1lcdwnzu8j2frpcdn67wnzsic0g8j2xpfcdl7lwnzeu8j2xspcdmieg8j2xmfcdmilwnze78j2xsfcdl67wnze68j2xsvcdl7vwnzib8j2xrvcdl7nwnziaoidwnzew8j2xvcdl7lwnzeu8j2ygfcdl7bwnze78j2xtcdwnzew8j2ygvcdmidwnzib8j2xvpcdl7og8j2xlvcdl7zwnze68j2xvfcdl7zwnze78j2xsvcdl7vwnzib8j2ygcao8j2frfcdn7uv8j2frvcdn7mp">𝗢𝗰𝘁 𝟭𝟵, 𝟮𝟬𝟮𝟬 - 𝗥𝗲𝗮𝗰𝘁 𝗙𝘂𝗻𝗱𝗮𝗺𝗲𝗻𝘁𝗮𝗹𝘀: 𝗖𝗿𝗲𝗮𝘁𝗶𝗻𝗴 𝗖𝘂𝘀𝘁𝗼𝗺 𝗖𝗼𝗺𝗽𝗼𝗻𝗲𝗻𝘁𝘀 (𝟭𝟵/𝟮𝟳)</h2>
<p>This article is again a part of my review of EpicReactDev workshops. In this, I wrote about creating components, prop-types, React Fragments, etc...</p>
<p>At the time of writing this tweet, this article has got around 375 views.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://blog.bhanuteja.dev/react-fundamentals-creating-custom-components">https://blog.bhanuteja.dev/react-fundamentals-creating-custom-components</a></div>
<h2 id="heading-8j2xovcdl7dwnzibipcdn67wnzulcdwnzu8j2frpcdn67wnzsic0g8j2xpfcdl7lwnzeu8j2xspcdmieg8j2xmfcdmilwnze78j2xsfcdl67wnze68j2xsvcdl7vwnzib8j2xrvcdl7nwnziaoidwnzem8j2ygfcdmibwnze58j2xtvcdl7vwnze0ipcdl5twnze78j2xssdwnzeb8j2xrvcdl7vwnzex8j2xufcdl7bwnze78j2xtcdwnzez8j2xvpcdl7wnze68j2ygcao8j2frvcdn6wv8j2frvcdn7mp">𝗢𝗰𝘁 𝟮𝟮, 𝟮𝟬𝟮𝟬 - 𝗥𝗲𝗮𝗰𝘁 𝗙𝘂𝗻𝗱𝗮𝗺𝗲𝗻𝘁𝗮𝗹𝘀: 𝗦𝘁𝘆𝗹𝗶𝗻𝗴 𝗔𝗻𝗱 𝗛𝗮𝗻𝗱𝗹𝗶𝗻𝗴 𝗙𝗼𝗿𝗺𝘀 (𝟮𝟬/𝟮𝟳)</h2>
<p>In this article, I wrote about basic styling methods and also about handling forms in React.</p>
<p>At the time of writing this tweet, this article has got around 421 views.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://blog.bhanuteja.dev/react-fundamentals-styling-and-handling-forms">https://blog.bhanuteja.dev/react-fundamentals-styling-and-handling-forms</a></div>
<h2 id="heading-8j2xovcdl7dwnzibipcdn67wnzylcdwnzu8j2frpcdn67wnzsic0g8j2xpfcdl7lwnzeu8j2xspcdmieg8j2xmcdl7zwnze88j2xupcdmia6ipcdl6dwnzeu8j2xucdl67wnze08j2xtvcdl7vwnze0ipcdl6bwnzib8j2xrvcdmihwnzeyipcdl6rwnze28j2ygfcdl7ug8j2ygvcdmidwnzey8j2xpvcdmihwnzeu8j2ygfcdl7ig8j2xmcdl7zwnze88j2xucao8j2frvcdn60v8j2frvcdn7mp">𝗢𝗰𝘁 𝟮𝟲, 𝟮𝟬𝟮𝟬 - 𝗥𝗲𝗮𝗰𝘁 𝗛𝗼𝗼𝗸𝘀: 𝗠𝗮𝗻𝗮𝗴𝗶𝗻𝗴 𝗦𝘁𝗮𝘁𝗲 𝗪𝗶𝘁𝗵 𝘂𝘀𝗲𝗦𝘁𝗮𝘁𝗲 𝗛𝗼𝗼𝗸 (𝟮𝟭/𝟮𝟳)</h2>
<p>This article is about useState hook in React. I wrote about what it is, and how to use it. I also wrote about Functional Updates in useState...</p>
<p>... and when it can be useful. I finally ended the article by explaining about Lazy Initialization and also using this with objects.</p>
<p>At the time of writing this tweet, this has got around 358 views.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://blog.bhanuteja.dev/react-hooks-managing-state-with-usestate-hook">https://blog.bhanuteja.dev/react-hooks-managing-state-with-usestate-hook</a></div>
<h2 id="heading-8j2xovcdl7dwnzibipcdn67wnz1lcdwnzu8j2frpcdn67wnzsic0g8j2xmcdl7zwnzieipcdmihwnze8ipcdl5bwnze8j2xsvcdl67wnzib8j2xsidwnzeuipcdl6xwnzey8j2ygvcdmidwnzeu8j2xrcdl7nwnzeyipcdl5wnze88j2xspcdl67wnze58j2xpvcdmihwnze88j2xvcdl67wnze08j2xsidwnzeb8j2xvpcdl7zwnze4icjwnzu8j2friwnzu8j2fsyk">𝗢𝗰𝘁 𝟮𝟵, 𝟮𝟬𝟮𝟬 - 𝗛𝗼𝘄 𝘁𝗼 𝗖𝗿𝗲𝗮𝘁𝗲 𝗮 𝗥𝗲𝘂𝘀𝗮𝗯𝗹𝗲 𝗟𝗼𝗰𝗮𝗹𝗦𝘁𝗼𝗿𝗮𝗴𝗲 𝗛𝗼𝗼𝗸 (𝟮𝟮/𝟮𝟳)</h2>
<p>This article is about creating a reusable local storage hook that syncs the state to local storage automatically. I saw this example in the #EpicReactDev</p>
<p>I usually use <code>use-persisted-state</code> package for my projects for this purpose because of some of the features that the package has. Nevertheless, it was good to explore how to make a custom one when required.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://github.com/donavon/use-persisted-state">https://github.com/donavon/use-persisted-state</a></div>
<p>At the time of writing this tweet, this article has got around 1.3K views.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://blog.bhanuteja.dev/how-to-create-a-reusable-localstorage-hook">https://blog.bhanuteja.dev/how-to-create-a-reusable-localstorage-hook</a></div>
<p>That's it for October. In that month, I wrote a total of 10 articles - at least 2 every week.</p>
<h2 id="heading-8j2xofcdl7zwnzidipcdn64sipcdn67wnzs8j2frvcdn6wglsdwnzey8j2xrvcdmidwnze28j2xufcdmiyg8j2xlcdl7lwnzib8j2xsvcdl7dwnzibipcdl6lwnzic8j2ygfcdmidwnze28j2xsfcdl7ig8j2xlvcdl7nwnze28j2xspcdl7gg8j2xqpcdmidwnze28j2xucdl7qg8j2ygvcdmidwnzey8j2xpfcdl7lwnzezipcdl5vwnze88j2xvpcdl7ggkpcdn67wnzvlcdn67wnzzkq">𝗡𝗼𝘃 𝟮, 𝟮𝟬𝟮𝟬 - 𝗘𝗮𝘀𝗶𝗹𝘆 𝗗𝗲𝘁𝗲𝗰𝘁 𝗢𝘂𝘁𝘀𝗶𝗱𝗲 𝗖𝗹𝗶𝗰𝗸 𝗨𝘀𝗶𝗻𝗴 𝘂𝘀𝗲𝗥𝗲𝗳 𝗛𝗼𝗼𝗸 (𝟮𝟯/𝟮𝟳)</h2>
<p>I was doing a project in which I had to close the modal/dialog whenever I clicked at any place outside of it. I made a custom hook for this using useRef...</p>
<p>In this article, I wrote about the same explaining the process which I took to make this hook.</p>
<p>At the time of writing this tweet, this article has got around 1.3K views.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://blog.bhanuteja.dev/easily-detect-outside-click-using-useref-hook">https://blog.bhanuteja.dev/easily-detect-outside-click-using-useref-hook</a></div>
<h2 id="heading-8j2xofcdl7zwnzidipcdn7esipcdn67wnzs8j2frvcdn6wglsdwnzvipcdl6bwnze28j2xuvcdl73wnze58j2xsidwnzem8j2ygfcdl7lwnze98j2ygcdwnzen8j2xvcdwnzem8j2xsvcdmihwnzic8j2xvsdwnzeu8j2ygvcdmihwnze18j2xsvcdl7vwnzib8j2xtvcdl7dwnzeu8j2ygfcdl7bwnze88j2xuydwnze28j2xuydwnzeh8j2xsvcdmixwnziblvcdl7fwnziaicjwnzu8j2fscwnzu8j2fsyk">𝗡𝗼𝘃 𝟱, 𝟮𝟬𝟮𝟬 - 𝟯 𝗦𝗶𝗺𝗽𝗹𝗲 𝗦𝘁𝗲𝗽𝘀 𝗧𝗼 𝗦𝗲𝘁𝘂𝗽 𝗔𝘂𝘁𝗵𝗲𝗻𝘁𝗶𝗰𝗮𝘁𝗶𝗼𝗻 𝗶𝗻 𝗡𝗲𝘅𝘁.𝗷𝘀 (𝟮𝟰/𝟮𝟳)</h2>
<p>In all of my previous Next.js projects, I have set up my own authentication in a custom Node backend. I know that I could use services like Auth0...</p>
<p>... but it was too expensive for me after a couple of users. Hence I decided to make my own. @benawad 's YouTube videos helped me a lot in this regard.</p>
<p>This is the video that I referred to.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://www.youtube.com/watch?v=25GS0MLT8JU">https://www.youtube.com/watch?v=25GS0MLT8JU</a></div>
<p>It was then, I discovered an open-source package called NextAuth.js which made it super simple to set up authentication in Next.js projects. I immediately tried it and it was so easy to set up. It also has providers for most of the OAuth providers like Google, GitHub, etc.</p>
<p>It even has a provider for setting up password-less login. You can also bring your own database.</p>
<p>The following article came as a result of this -- showing how easy it is to set up auth in Next.js</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://blog.bhanuteja.dev/3-simple-steps-to-setup-authentication-in-nextjs">https://blog.bhanuteja.dev/3-simple-steps-to-setup-authentication-in-nextjs</a></div>
<p>At the time of writing this tweet, this article has got around 880 views.</p>
<h2 id="heading-8j2xofcdl7zwnzidipcdn63wnzslcdwnzu8j2frpcdn67wnzsic0g8j2xpcdl7xwnzeyipcdl5wnze28j2xscdl7lwnzew8j2yhvcdl7dwnze58j2xsidwnze88j2xsydwnzel8j2xsvcdl67wnzew8j2ygsdwnzeb8j2xvpcdl7zwnze48j2ygcdwnzew8j2xvpcdl7rwnze98j2xvpcdl7vwnzey8j2xucdmiegkpcdn67wnzxlcdn67wnzzkq">𝗡𝗼𝘃 𝟭𝟬, 𝟮𝟬𝟮𝟬 - 𝗧𝗵𝗲 𝗟𝗶𝗳𝗲𝗰𝘆𝗰𝗹𝗲 𝗼𝗳 𝗥𝗲𝗮𝗰𝘁 𝗛𝗼𝗼𝗸𝘀 𝗖𝗼𝗺𝗽𝗼𝗻𝗲𝗻𝘁 (𝟮𝟱/𝟮𝟳)</h2>
<p>This is again something that I learned from #EpicReactDev workshops.</p>
<p>In this article, I wrote about the life cycle of useEffect hooks in functional components. It was a little difficult for me to get the hang of useEffect hook when I was learning it for the first time. This video from #EpicReactDev workshops made it so simple.</p>
<p>At the time of writing this tweet, this article has got around 2.3K views. I myself have referred to this article a countless number of times. I am very glad that I wrote this.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://blog.bhanuteja.dev/the-lifecycle-of-react-hooks-component">https://blog.bhanuteja.dev/the-lifecycle-of-react-hooks-component</a></div>
<h2 id="heading-8j2xofcdl7zwnzidipcdn63wnzvlcdwnzu8j2frpcdn67wnzsic0g8j2frcdn6wripcdl5rwnze28j2ygsdwnzew8j2xvpcdl7rwnze68j2xrvcdl7vwnzex8j2ygcdwnzen8j2xtfcdl67wnzibipcdl5wg8j2xmfcdl7wnzey8j2xvvcdmilwnzey8j2xucdmihwnze58j2yhidwnzeo8j2ygpcdl7igkpcdn67wnzylcdn67wnzzkq">𝗡𝗼𝘃 𝟭𝟯, 𝟮𝟬𝟮𝟬 - 𝟯𝟬+ 𝗚𝗶𝘁 𝗖𝗼𝗺𝗺𝗮𝗻𝗱𝘀 𝗧𝗵𝗮𝘁 𝗜 𝗙𝗿𝗲𝗾𝘂𝗲𝗻𝘁𝗹𝘆 𝗨𝘀𝗲 (𝟮𝟲/𝟮𝟳)</h2>
<p>This is the article that took the least effort to write. In this article, I have just listed down the most frequent Git commands that I use in my daily workflow.</p>
<p>This article also got featured in @hashnode 's <strong>Become A Better Dev In 2021</strong> e-book. If you haven't checked it out, check out that ebook. It's really good.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://hashnode.com/better-dev-2021">https://hashnode.com/better-dev-2021</a></div>
<p>At the time of writing this tweet, this article has got around 4K views - which is surprising considering the amount of time that I spent writing it.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://blog.bhanuteja.dev/30-git-commands-that-i-frequently-use">https://blog.bhanuteja.dev/30-git-commands-that-i-frequently-use</a></div>
<h2 id="heading-8j2xofcdl7zwnzidipcdn67wnztlcdwnzu8j2frpcdn67wnzsic0g8j2xofcdl7lwnzif8j2ygs7wnze38j2ygcdwnzem8j2ygfcdl67wnze8j2ygfcdl7lwnzeipcdl6fwnzey8j2xuvcdl73wnze58j2xrvcdmihwnzeyipcdl6rwnze28j2ygfcdl7ug8j2xlpcdmilwnzib8j2xtfcdl7lwnze78j2ygfcdl7bwnzew8j2xrvcdmihwnze28j2xvpcdl7sgkydwnzel8j2xsvcdl67wnzew8j2ygsdwnzt8j2fsyaripcdl6fwnzig8j2xvfcdl7lwnzem8j2xspcdl7wnze28j2xvfcdmiegkydwnzen8j2xrvcdl7bwnze58j2yhpcdl7bwnze78j2xssdwnzew8j2xpvcdl6yg8j2friaripcdl5jwnzem8j2xncdl7bwnze78j2ygsao8j2frvcdn7mv8j2frvcdn7mp">𝗡𝗼𝘃 𝟮𝟭, 𝟮𝟬𝟮𝟬 - 𝗡𝗲𝘅𝘁.𝗷𝘀 𝗦𝘁𝗮𝗿𝘁𝗲𝗿 𝗧𝗲𝗺𝗽𝗹𝗮𝘁𝗲 𝗪𝗶𝘁𝗵 𝗔𝘂𝘁𝗵𝗲𝗻𝘁𝗶𝗰𝗮𝘁𝗶𝗼𝗻 + 𝗥𝗲𝗮𝗰𝘁 𝟭𝟳 + 𝗧𝘆𝗽𝗲𝗦𝗰𝗿𝗶𝗽𝘁 + 𝗧𝗮𝗶𝗹𝘄𝗶𝗻𝗱 𝗖𝗦𝗦 𝟮 + 𝗘𝗦𝗟𝗶𝗻𝘁 (𝟮𝟳/𝟮𝟳)</h2>
<p>This is the final article of the month of November and the year 2020.</p>
<p>I created a Next.js starter template with things like Authentication, TypeScript, Tailwind CSS, ESLint, Prettier, React Query, Prisma with Postgres pre-configured. I made it open-source and wrote an article on how to deploy it to Vercel.</p>
<p>This article also got featured on @dailydotdev</p>
<p>At the time of writing this tweet, this article has got around 3.7K views.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://blog.bhanuteja.dev/nextjs-starter-with-authentication-react-17-typescript-tailwind-css-2-eslint">https://blog.bhanuteja.dev/nextjs-starter-with-authentication-react-17-typescript-tailwind-css-2-eslint</a></div>
<p>Right now, the repo just crossed 150 stars on GitHub and has been forked 16 times.</p>
<p>Link to the GitHub Repo: </p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://github.com/pbteja1998/nextjs-starter">https://github.com/pbteja1998/nextjs-starter</a></div>
<p>Link to the live demo:</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://next-starter.bhanuteja.dev/">https://next-starter.bhanuteja.dev/</a></div>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1609397241952/BYhXX5tNK.png" alt="Screenshot 2020-12-31 at 11.31.25 AM.png" /></p>
<p>I recently discovered Fauna DB and I liked it very much. This also has a generous free tier to it. I have replaced Prisma + Postgres with Fauna DB in this template since then.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://fauna.com/">https://fauna.com/</a></div>
<p>I haven't written any article in the month of December 2020 due to my other commitments. Hopefully, I will get back to it soon from 2021.</p>
<p>I have attached the stats of all the articles that I have written in 2020.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1609397282339/W88iSDL11.png" alt="Screenshot 2020-12-31 at 11.38.19 AM.png" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1609397290851/GQvJZ-Dss.png" alt="Screenshot 2020-12-31 at 11.38.32 AM.png" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1609397301816/-buGabcdE.png" alt="Screenshot 2020-12-31 at 11.38.42 AM.png" /></p>
<p>I have a total of around 48K page views until now. I never thought that anyone would be interested in reading what I write. But unless you try, you never know. The worst thing that can happen is you end up getting good at writing and reinforce the concepts that you write.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1609397343501/kcr3-uky_.png" alt="Screenshot 2020-12-31 at 11.41.54 AM.png" /></p>
<p><strong>Audience Overview</strong>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1609402538715/tXhXqSr9M.png" alt="Audience Overview.png" /></p>
<p><strong>Acquisition Overview</strong>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1609402559699/qAeIm9K3I.png" alt="Acquisition Overview.png" /></p>
<p><strong>Behaviour Overview</strong>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1609402572650/01bgI-X-4.png" alt="Behaviour Overview.png" /></p>
<p>This wouldn't have been possible without @hashnode and I have nothing but gratitude towards them.</p>
<p>If you are a developer and you don't have a blog yet. There is no time better than now to start a blog and write down your thoughts...</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://pbt.im/join-hn">https://pbt.im/join-hn</a></div>
<p>I don't assume anyone reading this very long thread completely. But if you did, you are a legend. Hopefully, this thread inspires at least one person to start blogging 🤞</p>
<p>If you have any questions that you want to ask, my <a target="_blank" href="https://twitter.com/pbteja1998">DM</a>s are always open.</p>
<div class="hn-embed-widget" id="newsletter"></div>]]></content:encoded></item><item><title><![CDATA[Next.js Starter Template With Authentication + React 17 + TypeScript + Tailwind CSS 2 + ESLint]]></title><description><![CDATA[Next.js has become my go-to framework for almost every project that I make. So, I made a starter template that I can just use and get started easily.
In this article, I will show you how to use the starter template that I made and deploy it with Verc...]]></description><link>https://blog.bhanuteja.dev/nextjs-starter-with-authentication-react-17-typescript-tailwind-css-2-eslint</link><guid isPermaLink="true">https://blog.bhanuteja.dev/nextjs-starter-with-authentication-react-17-typescript-tailwind-css-2-eslint</guid><category><![CDATA[Next.js]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Tailwind CSS]]></category><category><![CDATA[React]]></category><dc:creator><![CDATA[Bhanu Teja Pachipulusu]]></dc:creator><pubDate>Sat, 21 Nov 2020 08:11:56 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1605944363452/YMD_kEZmE.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Next.js has become my go-to framework for almost every project that I make. So, I made a starter template that I can just use and get started easily.</p>
<p>In this article, I will show you how to use the starter template that I made and deploy it with Vercel. I will also be connecting a Postgres database which I will create on Heroku.</p>
<h3 id="heading-what-all-does-this-starter-template-has">What all does this starter template has?</h3>
<ul>
<li>Next.js/React 17</li>
<li>TypeScript</li>
<li>Tailwind CSS 2</li>
<li>React Query</li>
<li>React Query Dev Tools</li>
<li>Prisma 2</li>
<li>GitHub Auth</li>
<li>Email + Passwordless Auth</li>
<li>Postgres</li>
<li>ESLint</li>
<li>Prettier</li>
<li>Husky</li>
</ul>
<p>If this is the tech stack that you are interested in, then follow along.</p>
<ul>
<li><a target="_blank" href="https://github.com/pbteja1998/nextjs-starter">Github Repo</a></li>
<li><a target="_blank" href="https://next-starter.bhanuteja.dev">Live Demo</a></li>
</ul>
<h3 id="heading-1-use-template">1. Use Template</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1605936676564/_4P5Oj3Dv.png" alt="Screenshot 2020-11-21 at 10.57.39 AM.png" /></p>
<p>Go to <a target="_blank" href="https://github.com/pbteja1998/nextjs-starter">pbteja1998/nextjs-starter</a> repo and click on <code>Use this template</code> button.</p>
<hr />
<h3 id="heading-2-create-repo">2. Create Repo</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1605936868332/RxLZWQGem.png" alt="Screenshot 2020-11-21 at 11.04.02 AM.png" /></p>
<p>Follow the instructions and create your repo</p>
<hr />
<h3 id="heading-3-deploy-to-vercel">3. Deploy to Vercel</h3>
<h4 id="heading-31-import-project">3.1. Import Project</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1605937097391/9Lczi_Jp0.png" alt="Screenshot 2020-11-21 at 11.06.58 AM.png" /></p>
<p>Login to <a target="_blank" href="https://vercel.com">vercel</a> and click on <code>Import Project</code>.</p>
<hr />
<h4 id="heading-32-import-git-repo">3.2. Import Git Repo</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1605937245104/x80XJkRGs.png" alt="Screenshot 2020-11-21 at 11.09.32 AM.png" /></p>
<p>Let's import from Git Repository</p>
<hr />
<h4 id="heading-33">3.3.</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1605937391460/29tPukIQq.png" alt="Screenshot 2020-11-21 at 11.12.12 AM.png" /></p>
<p>Enter the URL of the repo that you created earlier and <code>Continue</code>.</p>
<hr />
<h4 id="heading-34-create-vercel-project">3.4. Create Vercel Project</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1605937524068/jiJCAks3J.png" alt="Screenshot 2020-11-21 at 11.14.49 AM.png" /></p>
<p>Choose the name of the project and <code>Deploy</code>. We will be adding the required environment variables later.</p>
<hr />
<h4 id="heading-35-successful-deployment">3.5. Successful Deployment</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1605937865940/ACjD9b5Zw.png" alt="Screenshot 2020-11-21 at 11.19.33 AM.png" /></p>
<p>You should see this once deployed. Open the dashboard after a successful deployment.</p>
<hr />
<h4 id="heading-36-dashboard">3.6. Dashboard</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1605937993723/DTsKaDryF.png" alt="Screenshot 2020-11-21 at 11.21.52 AM.png" /></p>
<p>That's it. Your Next.js starter application has been deployed to Vercel. You can click on <code>Visit</code> to open the website.</p>
<hr />
<h4 id="heading-37-web-application-demo">3.7.  Web Application Demo</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1605938157984/LypP5IspB.png" alt="Screenshot 2020-11-21 at 11.25.37 AM.png" /></p>
<p>You should see something like this. This home page template is taken from one of the examples in <a target="_blank" href="https://tailwindcss.com">tailwindcss.com</a></p>
<hr />
<h3 id="heading-4-create-a-database">4. Create a database</h3>
<p>We need a database to store users and user sessions. I will be using the Postgres database. But you can use whatever you want. If you already have a URL for your database, you can skip this step. I will be using Heroku to create a Postgres database.</p>
<h4 id="heading-41-create-a-new-heroku-app">4.1. Create a new Heroku app</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1605938707438/tZ6AVYcRJ.png" alt="Screenshot 2020-11-21 at 11.34.16 AM.png" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1605938825143/vEkLidE2-.png" alt="Screenshot 2020-11-21 at 11.35.53 AM.png" /></p>
<hr />
<h4 id="heading-42-go-to-resources-tab-and-add-heroku-postgres-addon">4.2. Go to Resources Tab and add <code>Heroku Postgres</code> addon</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1605939118945/c56DV1RVA.png" alt="Screenshot 2020-11-21 at 11.40.52 AM.png" /></p>
<hr />
<h4 id="heading-43">4.3.</h4>
<p><code>Heroku Postgres</code> has a free tier available. I will be using that for the demonstration.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1605939266087/fR-CWaH2Q.png" alt="Screenshot 2020-11-21 at 11.42.27 AM.png" /></p>
<hr />
<h4 id="heading-44-you-now-have-a-new-postgres-db-created-click-on-the-addon-to-open-the-database-dashboard">4.4. You now have a new Postgres DB created. Click on the addon to open the database dashboard</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1605939387242/eG2XADex3.png" alt="Screenshot 2020-11-21 at 11.45.58 AM.png" /></p>
<hr />
<h4 id="heading-45-view-credentials">4.5. View Credentials</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1605939581690/PNnkecquC.png" alt="Screenshot 2020-11-21 at 11.48.16 AM.png" /></p>
<p>Click on <code>Settings</code> and then <code>View Credentials</code>.</p>
<hr />
<h4 id="heading-46-copy-database-uri">4.6. Copy Database URI</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1605939762750/5GT1OhGNu.png" alt="Screenshot 2020-11-21 at 11.50.40 AM.png" /></p>
<p>You should be able to see the database URI now. Copy that we will be using it later.
Also, note that the free tier Heroku database credentials are not permanent. They change periodically. So, when you are deploying for production, use some other database that is stable or upgrade your Heroku database to a paid plan. </p>
<hr />
<h3 id="heading-5-setup-environment-variables">5. Setup Environment Variables</h3>
<h4 id="heading-51-open-env-vars-dashboard-in-your-newly-created-vercel-project">5.1. Open Env Vars dashboard in your newly created Vercel project</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1605940349623/dg7bHlDqP.png" alt="Screenshot 2020-11-21 at 12.01.30 PM.png" /></p>
<h4 id="heading-52-add-databaseurl">5.2. Add DATABASE_URL</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1605940625455/slKyASNuB.png" alt="Screenshot 2020-11-21 at 12.06.46 PM.png" /></p>
<hr />
<h4 id="heading-create-a-new-secret">Create a new secret</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1605940580529/vmxVupL7h.png" alt="Screenshot 2020-11-21 at 12.05.18 PM.png" /></p>
<hr />
<h4 id="heading-save-environment-variable">Save environment variable</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1605940717998/z-1EW3JEj.png" alt="Screenshot 2020-11-21 at 12.08.06 PM.png" /></p>
<hr />
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1605940767744/IkfA61e0t.png" alt="Screenshot 2020-11-21 at 12.09.18 PM.png" /></p>
<hr />
<h4 id="heading-create-nextauthurl-variable">Create <code>NEXTAUTH_URL</code> variable</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1605941015388/FwqVAppLt.png" alt="Screenshot 2020-11-21 at 12.13.20 PM.png" /></p>
<p>This is the URL of the deployment. </p>
<hr />
<p>Similarly, create all the variables that you can see in <a target="_blank" href="https://github.com/pbteja1998/nextjs-starter/blob/master/.env.example">.env.example</a> file of the repo.</p>
<ul>
<li><code>SECRET</code><ul>
<li>Some random string</li>
</ul>
</li>
<li>SMTP_HOST<ul>
<li>SMTP host to send emails from. Example: <code>smtp.zoho.com</code></li>
</ul>
</li>
<li>SMTP_PORT<ul>
<li>Your SMTP port. Example: <code>465</code></li>
</ul>
</li>
<li>SMTP_USER<ul>
<li>Your SMTP user. Example: <code>bhanuteja@mycompany.org</code></li>
</ul>
</li>
<li>SMTP_PASSWORD<ul>
<li>Your email/SMTP password.</li>
</ul>
</li>
<li>SMTP_FROM<ul>
<li>Email address from where you want your emails to come from.</li>
</ul>
</li>
<li>GITHUB_ID<ul>
<li>Your Github OAuth App ID</li>
</ul>
</li>
<li>GITHUB_SECRET<ul>
<li>Your Github OAuth App Secret</li>
</ul>
</li>
</ul>
<p>You can follow the steps described <a target="_blank" href="https://developer.github.com/apps/building-oauth-apps/creating-an-oauth-app/">here</a> to create a GitHub OAuth application. While creating that OAuth app, add <code>https://&lt;vercel-deployment-url&gt;/api/auth</code> as <code>Authorization callback URL</code>. For example, in my case, I will add <code>https://nextjs-starter-kit-psi.vercel.app/api/auth</code> The rest of the fields, you can fill with anything.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1605941558383/XlkQ3GbRK.png" alt="Screenshot 2020-11-21 at 12.22.28 PM.png" /></p>
<hr />
<p>After adding all the environment variables, you need to redeploy the application for the changes to take effect.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1605941835866/FsveQ_Ups.png" alt="Screenshot 2020-11-21 at 12.26.01 PM.png" /></p>
<hr />
<p>Now, your new deployment will have GitHub authentication and passwordless login with email.</p>
<hr />
<p>I will also make a slim version of the starter kit in the future which will not require any database setup. </p>
<p>If you have any suggestions or face any problems setting this up, <a target="_blank" href="https://github.com/pbteja1998/nextjs-starter/issues/new">open a new issue in the repo</a>. I will be more than happy to help you resolve those. If you like this starter kit, give a star to <a target="_blank" href="https://github.com/pbteja1998/nextjs-starter">pbteja1998/nextjs-starter</a> repo.</p>
<h4 id="heading-until-next-time">Until Next Time 👋</h4>
<p>If you liked this article, check out</p>
<ul>
<li><a target="_blank" href="https://blog.bhanuteja.dev/3-simple-steps-to-setup-authentication-in-nextjs">3 Simple Steps To Setup Authentication in Next.js</a></li>
<li><a target="_blank" href="https://blog.bhanuteja.dev/how-to-import-svgs-into-your-nextjs-project">How to Import SVGs into your Next.js Project?</a></li>
<li><a target="_blank" href="https://blog.bhanuteja.dev/add-typescript-to-your-nextjs-project">Add Typescript to your Next.js project</a></li>
</ul>
<p>If you have any comments, please leave them below or you can also @ me on Twitter (<a target="_blank" href="https://twitter.com/pbteja1998">@pbteja1998</a>), or feel free to follow me.</p>
<h4 id="heading-links-and-references">Links and References:</h4>
<ul>
<li><a target="_blank" href="https://dev.to/prisma/passwordless-authentication-with-next-js-prisma-and-next-auth-5g8g">Passwordless Authentication with Next.js, Prisma, and next-auth</a></li>
<li><a target="_blank" href="https://next-auth.js.org/">NextAuth.js</a></li>
<li><a target="_blank" href="https://github.com/pbteja1998/nextjs-starter">pbteja1998/nextjs-starter</a></li>
<li><a target="_blank" href="https://next-starter.bhanuteja.dev">Nextjs Starter Demo</a></li>
<li><a target="_blank" href="https://vercel.com">Vercel</a></li>
<li><a target="_blank" href="http://heroku.com/">Heroku</a></li>
</ul>
<div class="hn-embed-widget" id="newsletter"></div>]]></content:encoded></item><item><title><![CDATA[30+ Git Commands That I Frequently Use]]></title><description><![CDATA[In this article, I will list out all the git commands that I use very frequently. This is not in any way a complete list, just the commands that I use very often. This is intended to be used as a quick reference to perform an action that you want. 

...]]></description><link>https://blog.bhanuteja.dev/30-git-commands-that-i-frequently-use</link><guid isPermaLink="true">https://blog.bhanuteja.dev/30-git-commands-that-i-frequently-use</guid><category><![CDATA[Git]]></category><category><![CDATA[GitHub]]></category><category><![CDATA[General Programming]]></category><category><![CDATA[Productivity]]></category><dc:creator><![CDATA[Bhanu Teja Pachipulusu]]></dc:creator><pubDate>Fri, 13 Nov 2020 07:09:17 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1605251295341/hdv1Hk4fu.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this article, I will list out all the git commands that I use very frequently. This is not in any way a complete list, just the commands that I use very often. This is intended to be used as a quick reference to perform an action that you want. </p>
<ul>
<li><a class="post-section-overview" href="#git-clone">Clone repo</a></li>
<li><a class="post-section-overview" href="#git-clone">Clone repo into specified directory</a></li>
<li><a class="post-section-overview" href="#git-init">Initialize current directory as a git repo</a></li>
<li><a class="post-section-overview" href="#git-add">Add a file</a></li>
<li><a class="post-section-overview" href="#git-add">Add all the files in current directory</a></li>
<li><a class="post-section-overview" href="#git-add">Add all the files including files in .gitignore</a></li>
<li><a class="post-section-overview" href="#git-commit">Create a new commit</a></li>
<li><a class="post-section-overview" href="#git-commit">Add changes to existing commit</a></li>
<li><a class="post-section-overview" href="#git-status">Show status</a></li>
<li><a class="post-section-overview" href="#git-status">Show status in short format</a></li>
<li><a class="post-section-overview" href="#git-status">Show status in short format and show branch</a></li>
<li><a class="post-section-overview" href="#git-log">Show the commit logs</a></li>
<li><a class="post-section-overview" href="#git-diff">Show the diff for unstaged files</a></li>
<li><a class="post-section-overview" href="#git-diff">Show the diff for staged files</a></li>
<li><a class="post-section-overview" href="#git-remote">Show all the remotes with URLs</a></li>
<li><a class="post-section-overview" href="#git-remote">Add a new remote</a></li>
<li><a class="post-section-overview" href="#git-remote">Change URL for existing remote</a></li>
<li><a class="post-section-overview" href="#git-checkout">Switch to another branch</a></li>
<li><a class="post-section-overview" href="#git-checkout">Create a new branch and switch to it</a></li>
<li><a class="post-section-overview" href="#git-checkout">Remove all the unstaged changes in the current directory</a></li>
<li><a class="post-section-overview" href="#git-checkout">Remove all the unstaged changes for a file</a></li>
<li><a class="post-section-overview" href="#git-push">Push local changes to the remote repo</a></li>
<li><a class="post-section-overview" href="#git-push">Push and set the remote as upstream</a></li>
<li><a class="post-section-overview" href="#git-push">Force push local changes to the remote repo</a></li>
<li><a class="post-section-overview" href="#git-push">Delete the branch in the remote repo</a></li>
<li><a class="post-section-overview" href="#git-branch">Delete the branch locally</a></li>
<li><a class="post-section-overview" href="#git-branch">Force delete the branch locally</a></li>
<li><a class="post-section-overview" href="#git-clean">Remove all untracked files and directories</a></li>
<li><a class="post-section-overview" href="#git-merge">Merge the branch to the current branch</a></li>
<li><a class="post-section-overview" href="#git-pull">Fetch changes from the remote and merge</a></li>
<li><a class="post-section-overview" href="#git-reset">Remove all the changes to the tracked files that haven't been committed yet</a></li>
</ul>
<h3 id="heading-git-clone">git clone</h3>
<pre><code class="lang-sh"><span class="hljs-comment"># Create 'blogs' folder and clone the 'pbteja1998/blogs' repo into it</span>
git <span class="hljs-built_in">clone</span> https://github.com/pbteja1998/blogs.git

<span class="hljs-comment"># Create `my-blogs` folder and clone the `pbteja1998/blogs` repo into it</span>
git <span class="hljs-built_in">clone</span> https://github.com/pbteja1998/blogs.git my-blogs
</code></pre>
<h3 id="heading-git-init">git init</h3>
<pre><code class="lang-sh"><span class="hljs-comment"># Initializes the current directory as a git repo</span>
git init
</code></pre>
<h3 id="heading-git-add">git add</h3>
<pre><code class="lang-sh"><span class="hljs-comment"># Adds the file contents to the index</span>
<span class="hljs-comment"># Ready to be committed next time you run `git commit`</span>
<span class="hljs-comment"># By default, Ignores the files present in `.gitignore`</span>

<span class="hljs-comment"># Add a single file</span>
git add README.md

<span class="hljs-comment"># Add all the files in the current directory</span>
git add .

<span class="hljs-comment"># Also adds the files present in `.gitignore`</span>
git add -f .
</code></pre>
<h3 id="heading-git-commit">git commit</h3>
<pre><code class="lang-sh"><span class="hljs-comment"># Commits/Records the changes to the local repo</span>
git commit -m <span class="hljs-string">"some message"</span>

<span class="hljs-comment"># Does not create a new commit</span>
<span class="hljs-comment"># Adds the changes to the most recent commit</span>
git commit --amend
</code></pre>
<h3 id="heading-git-status">git status</h3>
<pre><code class="lang-sh"><span class="hljs-comment"># Shows the status of the working tree</span>
git status

<span class="hljs-comment"># Shows the output in short format</span>
git status -s

<span class="hljs-comment"># Shows the branch even in short format</span>
git status -sb
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1605245389283/23Tok2fCR.png" alt="Screenshot 2020-11-13 at 10.59.31 AM.png" /></p>
<h3 id="heading-git-log">git log</h3>
<pre><code class="lang-sh"><span class="hljs-comment"># Shows the commit logs</span>
git <span class="hljs-built_in">log</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1605244215553/QCNWhim_s.png" alt="Screenshot 2020-11-13 at 10.39.39 AM.png" /></p>
<h3 id="heading-git-diff">git diff</h3>
<pre><code class="lang-sh"><span class="hljs-comment"># Shows the changes between unstaged files and the commits</span>
git diff

<span class="hljs-comment"># Shows the changes between staged(ready-to-be-committed) files and the commits</span>
git diff --staged
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1605244442028/73XfwnHzS.png" alt="Screenshot 2020-11-13 at 10.41.43 AM.png" /></p>
<h3 id="heading-git-remote">git remote</h3>
<pre><code class="lang-sh"><span class="hljs-comment"># Shows all the remotes configured and their remote URL</span>
git remote -v

<span class="hljs-comment"># Adds a remote</span>
<span class="hljs-comment"># git remote add &lt;remote-name&gt; &lt;remote-url&gt;</span>
git remote add upstream https://github.com/something/blogs.git

<span class="hljs-comment"># Changes the URL of the remote</span>
git remote set-url upstream https://github.com/some-thing/blogs.git
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1605245169242/6n7-C9q05.png" alt="Screenshot 2020-11-13 at 10.55.54 AM.png" /></p>
<h3 id="heading-git-checkout">git checkout</h3>
<pre><code class="lang-sh"><span class="hljs-comment"># Switch to branch </span>
<span class="hljs-comment"># git checkout &lt;branch&gt;</span>
git checkout master

<span class="hljs-comment"># Creates a new branch and switch to that</span>
git checkout -b new-feature

<span class="hljs-comment"># Removes all the unstaged changes in the current directory</span>
git checkout .

<span class="hljs-comment"># Removes all the unstaged changes for a file</span>
git checkout -- README.md
</code></pre>
<h3 id="heading-git-push">git push</h3>
<pre><code class="lang-sh"><span class="hljs-comment"># Pushes the local changes to the remote to keep it up-to-date</span>
git push origin master

<span class="hljs-comment"># Force push the local changes to the remote</span>
<span class="hljs-comment"># Usually git will not allow you to push to the remote if the remote has some commits that are not present in the local repo</span>
<span class="hljs-comment"># This will override that check and lets you force push to the remote</span>
<span class="hljs-comment"># This may cause the remote to lose some commits. So use it carefully.</span>
git push -f origin master

<span class="hljs-comment"># Push and set the remote as upstream </span>
<span class="hljs-comment"># same as `git push --set-upstream origin feature-branch`</span>
git push -u origin feature-branch

<span class="hljs-comment"># Deletes the branch in the remote</span>
<span class="hljs-comment"># same as `git push --delete origin new-feature`</span>
git push -d origin new-feature
</code></pre>
<h3 id="heading-git-branch">git branch</h3>
<pre><code class="lang-sh"><span class="hljs-comment"># Deletes the branch locally</span>
<span class="hljs-comment"># same as `git branch --delete feature-branch`</span>
git branch -d feature-branch

<span class="hljs-comment"># Force delete a branch even if it's not merged</span>
<span class="hljs-comment"># same as `git branch --delete --force feature-branch`</span>
git branch -D feature-branch
</code></pre>
<h3 id="heading-git-clean">git clean</h3>
<pre><code class="lang-sh"><span class="hljs-comment"># Removes all the files and directories that are not yet tracked by git</span>
git clean -fd
</code></pre>
<h3 id="heading-git-merge">git merge</h3>
<pre><code class="lang-sh"><span class="hljs-comment"># Merges the &lt;branch&gt; to the current branch</span>
<span class="hljs-comment"># git merge &lt;branch&gt;</span>
git merge feature-branch
</code></pre>
<h3 id="heading-git-pull">git pull</h3>
<pre><code class="lang-sh"><span class="hljs-comment"># Fetches the changes from the remote and merge it into local repo</span>
git pull origin master
</code></pre>
<h3 id="heading-git-reset">git reset</h3>
<pre><code class="lang-sh"><span class="hljs-comment"># Removes all the changes to the tracked files that have not yet been committed</span>
git reset --hard
</code></pre>
<h2 id="heading-whats-next">What's Next?</h2>
<p>The next article will most probably be a part of <a target="_blank" href="https://hashnode.com/series/my-review-of-kent-c-doddss-epicreactdev-ckfv4gidh08efu9s1408v8tgp">My Review of Kent C. Dodds's EpicReact.Dev</a>. Check out the series page for more info.</p>
<h4 id="heading-until-next-time">Until Next Time 👋</h4>
<p>If you liked this article, check out</p>
<ul>
<li><a target="_blank" href="https://blog.bhanuteja.dev/create-your-own-super-simple-url-shortener">Create Your Own Super Simple URL Shortener</a></li>
<li><a target="_blank" href="https://blog.bhanuteja.dev/why-you-should-start-using-hsl-color-format">Why you should start using HSL color format</a></li>
<li><a target="_blank" href="https://blog.bhanuteja.dev/til-hyphenate-when-you-justify-text">Hyphenate when you justify text</a></li>
</ul>
<p>If you have any comments, please leave them below or you can also @ me on Twitter (<a target="_blank" href="https://twitter.com/pbteja1998">@pbteja1998</a>), or feel free to follow me.</p>
<div class="hn-embed-widget" id="newsletter"></div>]]></content:encoded></item><item><title><![CDATA[The Lifecycle of React Hooks Component]]></title><description><![CDATA[In this article, we will see the order in which different useEffect callbacks and cleanups happen. We will also see how it differs when the app mounts, unmounts, updates.



This image is taken from https://github.com/donavon/hook-flow.
I took the ex...]]></description><link>https://blog.bhanuteja.dev/the-lifecycle-of-react-hooks-component</link><guid isPermaLink="true">https://blog.bhanuteja.dev/the-lifecycle-of-react-hooks-component</guid><category><![CDATA[React]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[react hooks]]></category><category><![CDATA[Web Development]]></category><dc:creator><![CDATA[Bhanu Teja Pachipulusu]]></dc:creator><pubDate>Tue, 10 Nov 2020 06:54:34 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1604980248876/j59xm8CTZ.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this article, we will see the order in which different <code>useEffect</code> callbacks and cleanups happen. We will also see how it differs when the app mounts, unmounts, updates.</p>

<p><img src="https://raw.githubusercontent.com/donavon/hook-flow/master/hook-flow.png" alt="hook-flow" /></p>
<blockquote>
<p>This image is taken from https://github.com/donavon/hook-flow.</p>
<p>I took the example shown in this article from <code>React Hooks</code> workshop in <a target="_blank" href="https://epicreact.dev">EpicReact.Dev</a> by <a target="_blank" href="https://kentcdodds.com">Kent C. Dodds</a>.</p>
<p>I have added relevant links at the end of this article. Check those out for more detailed video explanations given by <a target="_blank" href="https://kentcdodds.com">Kent C. Dodds</a>. </p>
</blockquote>
<p>Every component has three phases:</p>
<ol>
<li>Mount</li>
<li>Update</li>
<li>Unmount</li>
</ol>
<h3 id="heading-mount-hooks-flow">Mount - Hooks Flow</h3>
<p>This stage is when the component initially mounts on a page.
In this stage, the flow of hooks is as follows:</p>
<ol>
<li>Run lazy initializers<ul>
<li>Lazy initializers are functions that we pass to <code>useState</code> and <code>useReducer</code>. Those functions will be run only in this mount stage.</li>
</ul>
</li>
<li>Render<ul>
<li>This is where all the <code>useState</code> hooks and other things are present.</li>
</ul>
</li>
<li>React updates DOM<ul>
<li>Updating of DOM is not same as the browser painting the screen.</li>
</ul>
</li>
<li>Run Layout Effects<ul>
<li>We will see layout effects in future articles.</li>
</ul>
</li>
<li>Browser paints the screen</li>
<li>Run Effects</li>
</ol>
<h3 id="heading-update-hooks-flow">Update - Hooks Flow</h3>
<p>This stage is when the component updates. 
An update can happen for all the following reasons:</p>
<ul>
<li>Parent of the component re-renders</li>
<li>State of the component changes</li>
<li>Context changes</li>
</ul>
<p>In this stage, the flow of hooks is as follows:</p>
<ul>
<li>Render</li>
<li>React updates DOM</li>
<li>Cleanup Layout Effects<ul>
<li>(Like <code>useEffect</code>) <code>useLayoutEffect</code> also has a cleanup phase.</li>
</ul>
</li>
<li>Run Layout Effects</li>
<li>Browser paints the screen</li>
<li>Cleanup Effects</li>
<li>Run Effects</li>
</ul>
<p>As you can see, this is similar to what we saw for the mount stage, except that this also has <code>Cleanup Layout Effects</code> and <code>Cleanup Effects</code>.</p>
<h3 id="heading-unmount-hooks-flow">Unmount - Hooks Flow</h3>
<p>This stage is when the component unmounts from a page.</p>
<p>In this stage, the flow of hooks is as follows:</p>
<ul>
<li>Cleanup Layout Effects</li>
<li>Cleanup Effects</li>
</ul>
<p>Only cleanups will be run in this stage.</p>
<h3 id="heading-types-of-useeffect-callbacks">Types of useEffect callbacks</h3>
<p>Before we see an example, let's take a look at 3 different types of <code>useEffect</code> callbacks.</p>
<ol>
<li>useEffect with no dependencies</li>
<li>useEffect with empty dependencies</li>
<li>useEffect with some dependencies</li>
</ol>
<h4 id="heading-1-useeffect-with-no-dependencies">1. useEffect with no dependencies</h4>
<pre><code class="lang-js">useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'useEffect(() =&gt; {})'</span>) <span class="hljs-comment">// Line 1</span>
    <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> {
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'useEffect(() =&gt; {}) cleanup'</span>) <span class="hljs-comment">// Line 2</span>
    }
})
</code></pre>
<p>This <code>useEffect</code> callback has no dependencies. </p>
<ul>
<li>Callback function(Line 1) will be run when:<ul>
<li>Component is mounted</li>
<li>Component is updated</li>
</ul>
</li>
<li>Cleanup function(Line 2) will be run when:<ul>
<li>Component is updated</li>
<li>Component is unmounted</li>
</ul>
</li>
</ul>
<h4 id="heading-2-useeffect-with-empty-dependencies">2. useEffect with empty dependencies</h4>
<pre><code class="lang-js">useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'useEffect(() =&gt; {}, [])'</span>) <span class="hljs-comment">// Line 1</span>
    <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> {
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'useEffect(() =&gt; {}, []) cleanup'</span>) <span class="hljs-comment">// Line 2</span>
    }
}, [])
</code></pre>
<p>This <code>useEffect</code> callback has empty dependencies. </p>
<ul>
<li>Callback function(Line 1) will be run when:<ul>
<li>Component is mounted</li>
</ul>
</li>
<li>Cleanup function(Line 2) will be run when:<ul>
<li>Component is unmounted</li>
</ul>
</li>
</ul>
<p><strong>Note:</strong> This <code>useEffect</code> callback will not be executed when the component updates because of the empty dependency array.</p>
<h4 id="heading-3-useeffect-with-some-dependencies">3. useEffect with some dependencies</h4>
<pre><code class="lang-js">useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'useEffect(() =&gt; {}, [count])'</span>) <span class="hljs-comment">// Line 1</span>
    <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> {
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'useEffect(() =&gt; {}, [count]) cleanup'</span>) <span class="hljs-comment">// Line 2</span>
    }
}, [count])
</code></pre>
<p>This <code>useEffect</code> callback has one or more dependencies. </p>
<ul>
<li>Callback function(Line 1) will be run when:<ul>
<li>Component is mounted</li>
<li>Any of the dependency is changed - In this case when the count is changed.</li>
</ul>
</li>
<li>Cleanup function(Line 2) will be run when:<ul>
<li>Any of the dependency is changed - In this case when the count is changed.</li>
<li>Component is unmounted</li>
</ul>
</li>
</ul>
<h2 id="heading-example">Example</h2>
<p>Consider the below example</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"App: render start"</span>);

  <span class="hljs-keyword">const</span> [showChild, setShowChild] = React.useState(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"App: useState(() =&gt; false)"</span>);
    <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
  });

  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`App: showChild = <span class="hljs-subst">${showChild}</span>`</span>);

  React.useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"App: useEffect(() =&gt; {})"</span>);
    <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> {
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"App: useEffect(() =&gt; {}) cleanup"</span>);
    };
  });

  React.useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"App: useEffect(() =&gt; {}, [])"</span>);
    <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> {
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"App: useEffect(() =&gt; {}, []) cleanup"</span>);
    };
  }, []);

  React.useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"App: useEffect(() =&gt; {}, [showChild])"</span>);
    <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> {
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"App: useEffect(() =&gt; {}, [showChild]) cleanup"</span>);
    };
  }, [showChild]);

  <span class="hljs-keyword">const</span> element = (
    <span class="xml"><span class="hljs-tag">&lt;&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
          <span class="hljs-attr">type</span>=<span class="hljs-string">"checkbox"</span>
          <span class="hljs-attr">checked</span>=<span class="hljs-string">{showChild}</span>
          <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> setShowChild(e.target.checked)}
        /&gt;{" "}
        show child
      <span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
        {showChild ? <span class="hljs-tag">&lt;<span class="hljs-name">Child</span> /&gt;</span> : null}
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/&gt;</span></span>
  );

  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"App: render end"</span>);

  <span class="hljs-keyword">return</span> element;
}
</code></pre>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Child</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"    Child: render start"</span>);

  <span class="hljs-keyword">const</span> [count, setCount] = React.useState(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"    Child: useState(() =&gt; 0)"</span>);
    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
  });

  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`    Child: count = <span class="hljs-subst">${count}</span>`</span>);

  React.useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"    Child: useEffect(() =&gt; {})"</span>);
    <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> {
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"    Child: useEffect(() =&gt; {}) cleanup"</span>);
    };
  });

  React.useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"    Child: useEffect(() =&gt; {}, [])"</span>);
    <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> {
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"    Child: useEffect(() =&gt; {}, []) cleanup"</span>);
    };
  }, []);

  React.useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"    Child: useEffect(() =&gt; {}, [count])"</span>);
    <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> {
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"    Child: useEffect(() =&gt; {}, [count]) cleanup"</span>);
    };
  }, [count]);

  <span class="hljs-keyword">const</span> element = (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> setCount((previousCount) =&gt; previousCount + 1)}&gt;
      {count}
    <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
  );

  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"    Child: render end"</span>);

  <span class="hljs-keyword">return</span> element;
}
</code></pre>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://codesandbox.io/s/kentcdodds-hooks-flow-dc9w0">https://codesandbox.io/s/kentcdodds-hooks-flow-dc9w0</a></div>
<ul>
<li>we have an <code>App</code> component and <code>Child</code> component.</li>
<li><code>App</code> component has a state which decides whether to show the <code>Child</code> component or not.</li>
<li><code>Child</code> component has a <code>count</code> state.</li>
<li><code>Child</code> has a button to update the <code>count</code>.</li>
<li>Both <code>App</code> and <code>Child</code> has three types of <code>useEffect</code> callbacks<ul>
<li><code>useEffect</code> with no dependencies</li>
<li><code>useEffect</code> with empty dependencies</li>
<li><code>useEffect</code> with one or more dependencies.</li>
</ul>
</li>
</ul>
<p>We will see how the flow looks like for each of the following steps:</p>
<ol>
<li>App is mounted</li>
<li>Child is mounted by updating the state in App</li>
<li>Child is updated by updating the count in Child</li>
<li>Child is unmounted by updating the state in App</li>
</ol>
<h3 id="heading-1-app-is-mounted">1. App is mounted</h3>
<p>Here the <code>App</code> is in mount phase, so from the diagram, the order should be</p>
<ol>
<li>✅ Run lazy initializers of App</li>
<li>✅ Render of App</li>
<li>✅ React updates DOM of App</li>
<li>❌ Cleanup layout effects of App</li>
<li>✅ Run Layout Effects of App</li>
<li>✅ Browser paints screen of App</li>
<li>❌ Cleanup Effects of App</li>
<li>✅ Run Effects of App</li>
</ol>
<p>When the <code>App</code> is mounted, we see the following console logs.</p>
<ol>
<li>App: render start <ul>
<li>App rendering starts.</li>
</ul>
</li>
<li>App: useState(() =&gt; false) <ul>
<li>App lazy initializer is getting executed.</li>
</ul>
</li>
<li>App: showChild = false <ul>
<li>App renders.</li>
</ul>
</li>
<li>App: render end <ul>
<li>App rendering finishes.</li>
</ul>
</li>
<li>App: useEffect(() =&gt; {}) <ul>
<li>App <code>useEffect</code> with no dependecies is being executed.</li>
</ul>
</li>
<li>App: useEffect(() =&gt; {}, []) <ul>
<li>App <code>useEffect</code> with empty dependecies is being executed.</li>
<li>This is getting called because this is the mount phase of the <code>App</code> component, and in mount phase all the <code>useEffect</code> callbacks will be called.</li>
</ul>
</li>
<li>App: useEffect(() =&gt; {}, [showChild]) <ul>
<li>App <code>useEffect</code> with <code>showChild</code> as dependecy is being executed.</li>
<li>This is getting called because this is the mount phase of the <code>App</code> component, and in mount phase all the <code>useEffect</code> callbacks will be called.</li>
</ul>
</li>
</ol>
<p><strong>Notes:</strong></p>
<ul>
<li>All the <code>useEffect</code> callbacks will get executed on the initial mount of the component</li>
<li><code>useEffect</code> callbacks will be run in the order in which they appear.</li>
</ul>
<h3 id="heading-2-child-is-mounted-by-updating-the-state-in-app">2. Child is mounted by updating the state in App</h3>
<p>Let's click on <code>show child</code> checkbox. This will mount the <code>Child</code> component.</p>
<p>Here <code>Child</code> will be in the mount phase and <code>App</code> will be in the update phase.</p>
<p>As per diagram, the order for <code>Child</code> will be</p>
<ol>
<li>✅ Run lazy initializers of Child</li>
<li>✅ Render of Child</li>
<li>✅ React updates DOM of Child</li>
<li>❌ Cleanup layout effects of Child</li>
<li>✅ Run Layout Effects of Child</li>
<li>✅ Browser paints screen of Child</li>
<li>❌ Cleanup Effects of Child</li>
<li>✅ Run Effects of Child</li>
</ol>
<p>And for <code>App</code>, </p>
<ol>
<li>❌ Run lazy initializers of App</li>
<li>✅ Render of App</li>
<li>✅ React updates DOM of App</li>
<li>✅ Cleanup layout effects of App</li>
<li>✅ Run Layout Effects of App</li>
<li>✅ Browser paints screen of App</li>
<li>✅ Cleanup Effects of App</li>
<li>✅ Run Effects of App</li>
</ol>
<p>We will see the following console logs.</p>
<ol>
<li>App: render start <ul>
<li>App rendering starts.</li>
<li>Lazy initializer will <strong>NOT</strong> be run now. It runs only on the initial mount.</li>
</ul>
</li>
<li>App: showChild = true <ul>
<li>App renders.</li>
</ul>
</li>
<li>App: render end<ul>
<li>App rendering finishes.</li>
</ul>
</li>
<li>Child: render start <ul>
<li>Child is mounted and Child starts getting rendered.</li>
</ul>
</li>
<li>Child: useState(() =&gt; 0) <ul>
<li>Child lazy initializer is getting executed since this is the mount phase of Child.</li>
</ul>
</li>
<li>Child: count = 0 <ul>
<li>Child renders.</li>
</ul>
</li>
<li>Child: render end .<ul>
<li>Child rendering finishes.</li>
</ul>
</li>
<li>App: useEffect(() =&gt; {}) cleanup <ul>
<li>App useEffect with no dependencies cleanup.</li>
</ul>
</li>
<li>App: useEffect(() =&gt; {}, [showChild]) cleanup <ul>
<li>App useEffect with <code>showChild</code> dependencies cleanup.</li>
<li>This cleanup happens because <code>showChild</code> is getting updated here.</li>
</ul>
</li>
<li>Child: useEffect(() =&gt; {}) <ul>
<li>Child useEffect with no dependencies is being executed.</li>
</ul>
</li>
<li>Child: useEffect(() =&gt; {}, []) <ul>
<li>Child useEffect with empty dependencies is being executed.</li>
<li>This is getting called because this is the mount phase of the <code>Child</code> component, and in mount phase all the <code>useEffect</code> callbacks will be called.</li>
</ul>
</li>
<li>Child: useEffect(() =&gt; {}, [count]) <ul>
<li>Child useEffect with <code>count</code> as dependency is being executed.</li>
<li>This is getting called because this is the mount phase of the <code>Child</code> component, and in mount phase all the <code>useEffect</code> callbacks will be called.</li>
</ul>
</li>
<li>App: useEffect(() =&gt; {}) <ul>
<li>App useEffect with no dependencies is being executed.</li>
</ul>
</li>
<li>App: useEffect(() =&gt; {}, [showChild]) <ul>
<li>App useEffect with <code>showChild</code> dependencies is being executed.</li>
<li>This is getting called because <code>showChild</code> has updated.</li>
</ul>
</li>
</ol>
<p><strong>Notes:</strong></p>
<ul>
<li>While rendering the <code>App</code> component, we have <code>&lt;Child /&gt;</code> in its markup. But you can see the <code>Child</code> render starts after the <code>App</code> render ends.</li>
<li>This is because <code>&lt;Child /&gt;</code> is not same as calling calling <code>Child</code> function. It's basically calling <code>React.createElement(Child)</code>. </li>
<li>React will only start calling <code>Child</code> when it's time for rendering it.</li>
</ul>
<h3 id="heading-3-child-is-updated-by-updating-the-count-in-child">3. Child is updated by updating the count in Child</h3>
<p>Let's click on the <code>count</code> button to update the <code>count</code> present in <code>Child</code>.</p>
<p>Here <code>Child</code> will be in the update phase and <code>App</code> has no change.</p>
<p>As per diagram, the order for <code>Child</code> will be</p>
<ol>
<li>❌ Run lazy initializers of Child</li>
<li>✅ Render of Child</li>
<li>✅ React updates DOM of Child</li>
<li>✅ Cleanup layout effects of Child</li>
<li>✅ Run Layout Effects of Child</li>
<li>✅ Browser paints screen of Child</li>
<li>✅ Cleanup Effects of Child</li>
<li>✅ Run Effects of Child</li>
</ol>
<p>We will see the following console logs</p>
<ol>
<li>Child: render start <ul>
<li>Child rendering starts.</li>
</ul>
</li>
<li>Child: count = 1 <ul>
<li>Child renders</li>
</ul>
</li>
<li>Child: render end <ul>
<li>Child rendering ends.</li>
</ul>
</li>
<li>Child: useEffect(() =&gt; {}) cleanup <ul>
<li>Child useEffect with no dependencies cleanup.</li>
</ul>
</li>
<li>Child: useEffect(() =&gt; {}, [count]) cleanup <ul>
<li>Child useEffect with <code>count</code> as dependency cleanup.</li>
<li>This is getting called because <code>count</code> has updated. </li>
</ul>
</li>
<li>Child: useEffect(() =&gt; {}) <ul>
<li>Child useEffect with no dependencies is being executed.</li>
</ul>
</li>
<li>Child: useEffect(() =&gt; {}, [count]) <ul>
<li>Child useEffect with <code>count</code> as dependency is being executed.</li>
<li>This is getting called because <code>count</code> has updated.</li>
</ul>
</li>
</ol>
<h4 id="heading-4-child-is-unmounted-by-updating-the-state-in-app">4. Child is unmounted by updating the state in App</h4>
<p>Let's click on the <code>show child</code> checkbox to unmount the <code>Child</code> component.</p>
<p>Here <code>Child</code> will be in unmount phase and <code>App</code> will be in update phase</p>
<p>As per diagram, the order for <code>Child</code> will be</p>
<ol>
<li>❌ Run lazy initializers of Child</li>
<li>❌ Render of Child</li>
<li>❌ React updates DOM of Child</li>
<li>✅ Cleanup layout effects of Child</li>
<li>❌ Run Layout Effects of Child</li>
<li>❌ Browser paints screen of Child</li>
<li>✅ Cleanup Effects of Child</li>
<li>❌ Run Effects of Child</li>
</ol>
<p>And for App,</p>
<ol>
<li>❌ Run lazy initializers of App</li>
<li>✅ Render of App</li>
<li>✅ React updates DOM of App</li>
<li>✅ Cleanup layout effects of App</li>
<li>✅ Run Layout Effects of App</li>
<li>✅ Browser paints screen of App</li>
<li>✅ Cleanup Effects of App</li>
<li>✅ Run Effects of App</li>
</ol>
<p>We will see the following console logs</p>
<ol>
<li>App: render start<ul>
<li>App rendering starts.</li>
</ul>
</li>
<li>App: showChild = false <ul>
<li>App renders</li>
</ul>
</li>
<li>App: render end <ul>
<li>App rendering ends</li>
</ul>
</li>
<li>Child: useEffect(() =&gt; {}) cleanup <ul>
<li>Child useEffect with no dependencies cleanup</li>
</ul>
</li>
<li>Child: useEffect(() =&gt; {}, []) cleanup <ul>
<li>Child useEffect with empty dependencies cleanup</li>
<li>This is getting called here because this in unmount phase and in unmount phase all the cleanups will be called.</li>
</ul>
</li>
<li>Child: useEffect(() =&gt; {}, [count]) cleanup <ul>
<li>Child useEffect with <code>count</code> as dependency cleanup</li>
<li>This is getting called here because this in unmount phase and in unmount phase all the cleanups will be called.</li>
</ul>
</li>
<li>App: useEffect(() =&gt; {}) cleanup <ul>
<li>App useEffect with no dependencies clean up</li>
</ul>
</li>
<li>App: useEffect(() =&gt; {}, [showChild]) cleanup <ul>
<li>App useEffect with <code>showChild</code> as dependency clean up.</li>
<li>This is getting called because <code>showChild</code> has updated here.</li>
</ul>
</li>
<li>App: useEffect(() =&gt; {}) <ul>
<li>App useEffect with no dependencies is getting executed</li>
</ul>
</li>
<li>App: useEffect(() =&gt; {}, [showChild]) <ul>
<li>App useEffect with <code>showChild</code> as dependency is getting executed</li>
<li>This is getting called because <code>showChild</code> has updated here.</li>
</ul>
</li>
</ol>
<p>And finally, when the <code>App</code> component also unmounts, the <code>cleanup</code> of all the <code>App</code> <code>useEffect</code>s will be called.</p>
<h3 id="heading-links-and-references">Links and References:</h3>
<ul>
<li><a target="_blank" href="https://epicreact.dev/modules/react-hooks/hooks-flow">Hooks Flow</a> in <code>EpicReact.Dev</code> by <a target="_blank" href="https://kentcdodds.com">Kent C. Dodds</a></li>
<li><a target="_blank" href="https://egghead.io/lessons/react-understand-the-react-hook-flow">Understand the React Hook Flow</a> in <code>The Beginners Guide To React</code> by <a target="_blank" href="https://kentcdodds.com">Kent C. Dodds</a></li>
<li><a target="_blank" href="https://github.com/donavon/hook-flow">Hook Flow Diagram</a></li>
</ul>
<h2 id="heading-whats-next">What's Next?</h2>
<p>In the next article, we will look at what lifting state and colocating state mean in React. And also we will see when they will be useful.</p>
<h4 id="heading-until-next-time">Until Next Time 👋</h4>
<p>If you liked this article, check out</p>
<ul>
<li><a target="_blank" href="https://blog.bhanuteja.dev/react-hooks-managing-state-with-usestate-hook">React Hooks: Managing State With useState Hook</a></li>
<li><a target="_blank" href="https://blog.bhanuteja.dev/how-to-create-a-reusable-localstorage-hook">How to Create a Reusable LocalStorage Hook</a></li>
<li><a target="_blank" href="https://blog.bhanuteja.dev/easily-detect-outside-click-using-useref-hook">Easily Detect Outside Click Using useRef Hook</a></li>
</ul>
<p>If you have any comments, please leave them below or you can also @ me on Twitter (<a target="_blank" href="https://twitter.com/pbteja1998">@pbteja1998</a>), or feel free to follow me.</p>
<div class="hn-embed-widget" id="newsletter"></div>]]></content:encoded></item><item><title><![CDATA[3 Simple Steps To Setup Authentication in Next.js]]></title><description><![CDATA[In this tutorial, we will see how to easily set up authentication for Next.js apps.
Step 1. Create Next.js application
yarn create next-app next-auth
# npx create-next-app next-auth

This will create a new Next.js application. You can remove unnecess...]]></description><link>https://blog.bhanuteja.dev/3-simple-steps-to-setup-authentication-in-nextjs</link><guid isPermaLink="true">https://blog.bhanuteja.dev/3-simple-steps-to-setup-authentication-in-nextjs</guid><category><![CDATA[Auth ]]></category><category><![CDATA[Next.js]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[React]]></category><dc:creator><![CDATA[Bhanu Teja Pachipulusu]]></dc:creator><pubDate>Thu, 05 Nov 2020 07:45:02 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1604561824346/H_uNvsMDj.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this tutorial, we will see how to easily set up authentication for Next.js apps.</p>
<h2 id="heading-step-1-create-nextjs-application">Step 1. Create Next.js application</h2>
<pre><code class="lang-sh">yarn create next-app next-auth
<span class="hljs-comment"># npx create-next-app next-auth</span>
</code></pre>
<p>This will create a new Next.js application. You can remove unnecessary files and make the structure as below.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1604558247983/LY4N6z0we.png" alt="Screenshot 2020-11-05 at 12.07.01 PM.png" /></p>
<p>My <code>pages/index.js</code> just contains the following</p>
<pre><code class="lang-js"><span class="hljs-comment">// pages/index.js</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Home</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Hello World<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  )
}
</code></pre>
<h2 id="heading-step-2-install-nextauth-and-sqlite-packages">Step 2: Install NextAuth and SQLite packages</h2>
<p>I will be using SQLite as my database for this tutorial, but <code>next-auth</code> supports all of the popular databases.</p>
<pre><code class="lang-sh">yarn add next-auth sqlite3
<span class="hljs-comment"># npm install next-auth sqlite3</span>
</code></pre>
<h2 id="heading-step-3-setup-nextauth-api-route">Step 3: Setup NextAuth API Route</h2>
<p>Create a file with name <code>[...nextauth].js</code> under <code>/pages/api/auth</code> and add the following content in it.</p>
<pre><code class="lang-js"><span class="hljs-comment">// pages/api/auth/[...nextauth].js</span>

<span class="hljs-keyword">import</span> NextAuth <span class="hljs-keyword">from</span> <span class="hljs-string">'next-auth'</span>
<span class="hljs-keyword">import</span> Providers <span class="hljs-keyword">from</span> <span class="hljs-string">'next-auth/providers'</span>

<span class="hljs-keyword">const</span> options = {
  <span class="hljs-attr">providers</span>: [
    Providers.GitHub({
      <span class="hljs-attr">clientId</span>: process.env.GITHUB_ID,
      <span class="hljs-attr">clientSecret</span>: process.env.GITHUB_SECRET
    }),
  ],
  <span class="hljs-attr">database</span>: process.env.DATABASE_URL,
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> (req, res) =&gt; NextAuth(req, res, options)
</code></pre>
<p>Now, all the calls made to <code>/api/auth/*</code> will be handled by <code>next-auth</code>.</p>
<p>In this example, only the GitHub authentication provider is added. But <code>next-auth</code> supports all of the following providers by default.</p>
<pre><code>Apple            Email            Okta
Auth0            Facebook         Reddit
Basecamp         GitHub           Slack
BattleNet        GitLab           Spotify
Box              Google           Twitch
Cognito          IdentityServer4  Twitter
Credentials      LinkedIn         Yandex
Discord          Mixer
</code></pre><p>You can even add your own provider. More details <a target="_blank" href="https://next-auth.js.org/configuration/providers#using-a-custom-provider">here</a>.</p>
<p>Create <code>.env.local</code> file at the root of the project and add the environment keys that we used in the <code>[...nextauth].js</code> file.</p>
<pre><code># .env.local
GITHUB_ID=a8451b4a*********
GITHUB_SECRET=<span class="hljs-number">95</span>be17c33**********
DATABASE_URL=sqlite:<span class="hljs-comment">//localhost/:memory:?synchronize=true</span>
</code></pre><p>Replace values for <code>GITHUB_ID</code> and <code>GITHUB_SECRET</code> with your own keys. You can follow the steps described <a target="_blank" href="https://developer.github.com/apps/building-oauth-apps/creating-an-oauth-app/">here</a>. While creating that OAuth app, add <code>http://localhost:3000/api/auth</code> as <code>Authorization callback URL</code>. The rest of the fields, you can fill with anything.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1604567674351/2mlzCN5Fk.png" alt="Screenshot 2020-11-05 at 2.44.12 PM.png" /></p>
<p>After this, go to https://github.com/settings/developers and open the newly created OAuth App to get <code>GITHUB_ID</code> and <code>GITHUB_SECRET</code> and add them to the <code>.env.local</code> file.</p>
<p>Now, add <code>SignIn</code> and <code>SignOut</code> buttons in your <code>index.js</code> page.</p>
<pre><code><span class="hljs-comment">// pages/index.js</span>
<span class="hljs-keyword">import</span> { signIn, signOut, useSession } <span class="hljs-keyword">from</span> <span class="hljs-string">'next-auth/client'</span>

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Home</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [ session ] = useSession()
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Hello World<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
      {session ? (
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> signOut()}&gt;Signout<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
      ) : (
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> signIn()}&gt;SignIn<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span> 
        )}
      {session &amp;&amp; (
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">small</span>&gt;</span>Signed in as<span class="hljs-tag">&lt;/<span class="hljs-name">small</span>&gt;</span>
         <span class="hljs-tag">&lt;<span class="hljs-name">br</span>/&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">strong</span>&gt;</span>{session.user.email || session.user.name}<span class="hljs-tag">&lt;/<span class="hljs-name">strong</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      )}
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  )
}
</code></pre><p>That's it. Your app now has GitHub authentication setup.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1604560242786/rMiqSlfUm.gif" alt="next-auth.gif" /></p>
<p>If you want to see a more full-fledged example, you can download <a target="_blank" href="https://github.com/nextauthjs/next-auth-example">official next-auth-example</a> provided by <a target="_blank" href="https://next-auth.js.org/">NextAuth.js</a>.</p>
<p>Another important thing to note here is that <code>NextAuth.js</code> can be used with or without a database. It also has a password-less login built-in similar to the one you have on <a class="user-mention" href="https://hashnode.com/@hashnode">Hashnode</a>. You just have to provide the EMAIL_SERVER details, and you are set up. This package makes setting up authentication a breeze. You no longer need to have a separate backend just for the sake of having authentication.</p>
<h3 id="heading-links-and-references">Links and References:</h3>
<ul>
<li><a target="_blank" href="https://next-auth.js.org/">NextAuth.js</a></li>
<li><a target="_blank" href="https://nextjs.org">Next.js</a></li>
</ul>
<h2 id="heading-whats-next">What's Next?</h2>
<p>The next article will most probably be a part of <a target="_blank" href="https://hashnode.com/series/my-review-of-kent-c-doddss-epicreactdev-ckfv4gidh08efu9s1408v8tgp">My Review of Kent C. Dodds's EpicReact.Dev</a> series. Go to that series page to know more.</p>
<h4 id="heading-until-next-time">Until Next Time 👋</h4>
<p>If you liked this article, check out</p>
<ul>
<li><a target="_blank" href="https://blog.bhanuteja.dev/add-typescript-to-your-nextjs-project">Add Typescript to your Next.js project</a></li>
<li><a target="_blank" href="https://blog.bhanuteja.dev/how-to-import-svgs-into-your-nextjs-project">How to Import SVGs into your Next.js Project?</a></li>
</ul>
<p>You can @ me on Twitter (<a target="_blank" href="https://twitter.com/pbteja1998">@pbteja1998</a>) with comments, or feel free to follow me.</p>
<div class="hn-embed-widget" id="newsletter"></div>]]></content:encoded></item><item><title><![CDATA[Easily Detect Outside Click Using useRef Hook]]></title><description><![CDATA[Hello World 👋
Hooks are special types of functions in React that you can call inside React functional components. They let you store data, add interactivity, and perform some actions, otherwise known as side-effects.
The most common hooks are:

useS...]]></description><link>https://blog.bhanuteja.dev/easily-detect-outside-click-using-useref-hook</link><guid isPermaLink="true">https://blog.bhanuteja.dev/easily-detect-outside-click-using-useref-hook</guid><category><![CDATA[React]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[2Articles1Week]]></category><category><![CDATA[ReactHooks]]></category><dc:creator><![CDATA[Bhanu Teja Pachipulusu]]></dc:creator><pubDate>Mon, 02 Nov 2020 07:16:28 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1604296704650/cdXf8aGEp.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-hello-world">Hello World 👋</h2>
<p>Hooks are special types of functions in React that you can call inside React functional components. They let you store data, add interactivity, and perform some actions, otherwise known as side-effects.</p>
<p>The most common hooks are:</p>
<ul>
<li>useState</li>
<li>useEffect</li>
<li>useRef</li>
<li>useContext</li>
<li>useReducer</li>
</ul>
<p>In the previous article (<a target="_blank" href="https://blog.bhanuteja.dev/how-to-create-a-reusable-localstorage-hook">How to Create a Reusable LocalStorage Hook</a>), we learned about <code>useEffect</code> hook and how we can use it to create a custom and reusable hook that persists the state by storing it in local storage. If you haven't read that article, please go and read it before going through this article. We will be using <code>useEffect</code> in this article.</p>
<h2 id="heading-useref">useRef</h2>
<p>This is a special inbuilt function in React that gives you a direct reference to DOM node. Usually, in React, you won't have access to the DOM nodes directly. But sometimes, you may want to get access to DOM nodes directly because of various reasons, like the library that you use may need that.</p>
<p>useRef takes a single argument which is the initial value for the ref and creates and returns a ref.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> elementRef = useRef(<span class="hljs-literal">null</span>)
</code></pre>
<p>Now, the way to ask React to give you the access to DOM node is to assign the created ref to the <code>ref</code> prop of the element in JSX.</p>
<p>For example,</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">HelloWorld</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-comment">// create the ref</span>
    <span class="hljs-keyword">const</span> elementRef = useRef(<span class="hljs-literal">null</span>)

    <span class="hljs-keyword">return</span> (
            { <span class="hljs-comment">/* Asking React for the access to the DOM node */</span> }
        &lt;&gt;
            <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">{elementRef}</span>&gt;</span>
                Hello World
            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
        &lt;/&gt;
    )
}
</code></pre>
<p>Now, when you add the <code>ref</code> prop for the JSX element, React understands that you want direct reference to the DOM node of that element, and then it sets the <code>current</code> property of that <code>elementRef</code> to the DOM node.</p>
<p>In the above example, you can access the DOM node by using <code>elementRef.current</code></p>
<h2 id="heading-detect-click-outside">Detect Click Outside</h2>
<p>Let's use this to detect whenever you click outside of an element.</p>
<p>Some of the practical use-cases where you may want to detect if you clicked outside of an element are:</p>
<ul>
<li>When you have a modal(popup/dialog), and you want to close the modal whenever you click outside of it.</li>
<li>When you have a dropdown, and you want to close it whenever you click outside of it.</li>
</ul>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">const</span> [isOpen, setIsOpen] = useState(<span class="hljs-literal">true</span>)
    <span class="hljs-keyword">return</span> (
        <span class="xml"><span class="hljs-tag">&lt;&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>App with a Modal<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> setIsOpen(true)}&gt;Open Modal<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"modal"</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">Modal</span> <span class="hljs-attr">isOpen</span>=<span class="hljs-string">{isOpen}</span>&gt;</span>
                        This is the modal dialog
                    <span class="hljs-tag">&lt;/<span class="hljs-name">Modal</span>&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;/&gt;</span>
    )
}</span>
</code></pre>
<p>Let's take this simple component. It has a heading, a button which when clicked opens the modal.</p>
<p>Our goal is to detect and execute <code>setIsOpen(false)</code> whenever we click outside of div with id <code>modal</code>.</p>
<p>Let's see how we can achieve this. </p>
<ol>
<li>We need a reference to the div with id <code>modal</code>.</li>
<li>We need to detect a click.</li>
<li>We need to see if the click happened outside of the modal div.</li>
<li>Then we need to execute <code>setIsOpen(false)</code></li>
</ol>
<h3 id="heading-step-1-getting-reference-to-modal">Step 1: Getting reference to Modal</h3>
<p>We can use <code>useRef</code> for this.</p>
<pre><code class="lang-jsx"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">const</span> [isOpen, setIsOpen] = useState(<span class="hljs-literal">true</span>)
    <span class="hljs-comment">// change starts here</span>
    <span class="hljs-keyword">const</span> modalRef = useRef()
    <span class="hljs-comment">// change ends here</span>
    <span class="hljs-keyword">return</span> (
        <span class="xml"><span class="hljs-tag">&lt;&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>App with a Modal<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> setIsOpen(true)}&gt;Open Modal<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
               <span class="hljs-comment">&lt;!-- Change starts here --&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"modal"</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">{modalRef}</span>&gt;</span>
               <span class="hljs-comment">&lt;!-- Change ends here --&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">Modal</span> <span class="hljs-attr">isOpen</span>=<span class="hljs-string">{isOpen}</span>&gt;</span>
                        This is the modal dialog
                    <span class="hljs-tag">&lt;/<span class="hljs-name">Modal</span>&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;/&gt;</span>
    )
}</span>
</code></pre>
<p>Now, after the app gets rendered, <code>modalRef.current</code> will have access to the required DOM node.</p>
<h3 id="heading-step-2-add-a-click-event-listener">Step 2. Add a click event listener</h3>
<p>We can add an event listener inside <code>useEffect</code>.</p>
<pre><code class="lang-jsx">useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handler</span>(<span class="hljs-params">event</span>) </span>{
        <span class="hljs-built_in">console</span>.log(event, <span class="hljs-string">'clicked somewhere'</span>)   
    }
    <span class="hljs-built_in">window</span>.addEventListener(<span class="hljs-string">'click'</span>, handler)
    <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">window</span>.removeEventListener(<span class="hljs-string">'click'</span>, handler)
}, [])
</code></pre>
<p>Here we added a <code>click</code> event listener to the entire window to detect the click anywhere on the window.</p>
<h3 id="heading-step-3-detect-if-the-click-happened-outside-of-the-window">Step 3: Detect if the click happened outside of the window</h3>
<p>We can know where the click happened based on <code>event.target</code>. We just have to check if our <code>modal</code> div contains <code>event.target</code> or not.</p>
<pre><code class="lang-jsx">useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handler</span>(<span class="hljs-params">event</span>) </span>{
        <span class="hljs-comment">// change starts here</span>
        <span class="hljs-keyword">if</span>(!modalRef.current?.contains(event.target)) {
            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'clicked outside of modal'</span>)
        }
        <span class="hljs-comment">// change starts here</span>
    }
    <span class="hljs-built_in">window</span>.addEventListener(<span class="hljs-string">'click'</span>, handler)
    <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">window</span>.removeEventListener(<span class="hljs-string">'click'</span>, handler)
}, [])
</code></pre>
<h3 id="heading-step-4-close-the-modal-whenever-you-click-outside-of-modal">Step 4: Close the modal whenever you click outside of modal</h3>
<p>This step is straight-forward. We just have to execute <code>setIsOpen(false)</code> whenever we detect the click outside the modal.</p>
<pre><code class="lang-jsx">useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handler</span>(<span class="hljs-params">event</span>) </span>{
        <span class="hljs-keyword">if</span>(!modalRef.current?.contains(event.target)) {
            <span class="hljs-comment">// change starts here</span>
            setIsOpen(<span class="hljs-literal">false</span>)
            <span class="hljs-comment">// change starts here</span>
        }
    }
    <span class="hljs-built_in">window</span>.addEventListener(<span class="hljs-string">'click'</span>, handler)
    <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">window</span>.removeEventListener(<span class="hljs-string">'click'</span>, handler)
}, [])
</code></pre>
<p>Let's put everything together.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">const</span> [isOpen, setIsOpen] = useState(<span class="hljs-literal">true</span>)
    <span class="hljs-keyword">const</span> modalRef = useRef()

    useEffect(<span class="hljs-function">() =&gt;</span> {
        <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handler</span>(<span class="hljs-params">event</span>) </span>{
            <span class="hljs-keyword">if</span>(!modalRef.current?.contains(event.target)) {
                setIsOpen(<span class="hljs-literal">false</span>)
            }
        }
        <span class="hljs-built_in">window</span>.addEventListener(<span class="hljs-string">'click'</span>, handler)
        <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">window</span>.removeEventListener(<span class="hljs-string">'click'</span>, handler)
    }, [])

    <span class="hljs-keyword">return</span> (
        <span class="xml"><span class="hljs-tag">&lt;&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>App with a Modal<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> setIsOpen(true)}&gt;Open Modal<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"modal"</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">{modalRef}</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">Modal</span> <span class="hljs-attr">isOpen</span>=<span class="hljs-string">{isOpen}</span>&gt;</span>
                        This is the modal dialog
                    <span class="hljs-tag">&lt;/<span class="hljs-name">Modal</span>&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;/&gt;</span>
    )
}</span>
</code></pre>
<h2 id="heading-creating-a-reusable-hook">Creating a reusable hook</h2>
<p>We can create a reusable hook out of this that you can use anywhere.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { useEffect, useRef } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">useOnClickOutsideRef</span>(<span class="hljs-params">callback, initialValue = null</span>) </span>{
  <span class="hljs-keyword">const</span> elementRef = useRef(initialValue)
  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handler</span>(<span class="hljs-params">event</span>) </span>{
      <span class="hljs-keyword">if</span> (!elementRef.current?.contains(event.target)) {
        callback()
      }
    }
    <span class="hljs-built_in">window</span>.addEventListener(<span class="hljs-string">'click'</span>, handler)
    <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">window</span>.removeEventListener(<span class="hljs-string">'click'</span>, handler)
  }, [callback])
  <span class="hljs-keyword">return</span> elementRef
}
</code></pre>
<p>In this hook, we are creating a ref and then returning it at the end. This way, the API looks kinda similar to how you create a <code>ref</code> using <code>useRef</code>. But the ref created using this custom hook has the additional functionality to detect and execute a callback whenever a click is detected outside.</p>
<p>Let's change our example to use this hook.</p>
<pre><code class="lang-jsx"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">const</span> [isOpen, setIsOpen] = useState(<span class="hljs-literal">true</span>)
    <span class="hljs-keyword">const</span> modalRef = useOnClickOutsideRef(<span class="hljs-function">() =&gt;</span> setIsOpen(<span class="hljs-literal">false</span>))

    <span class="hljs-keyword">return</span> (
        <span class="xml"><span class="hljs-tag">&lt;&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>App with a Modal<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> setIsOpen(true)}&gt;Open Modal<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"modal"</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">{modalRef}</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">Modal</span> <span class="hljs-attr">isOpen</span>=<span class="hljs-string">{isOpen}</span>&gt;</span>
                        This is the modal dialog
                    <span class="hljs-tag">&lt;/<span class="hljs-name">Modal</span>&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;/&gt;</span>
    )
}</span>
</code></pre>
<p>That's it. You now have the exact same functionality as you have before. The only thing you changed here is changing <code>useRef()</code> to <code>useOnClickOutsideRef(() =&gt; setIsOpen(false))</code>.</p>
<p>Accessing DOM nodes is not the only case when you can use ref. You can use <code>ref</code> to keep a reference to any value. You can even mutate the <code>ref</code> directly using <code>exampleRef.current = 'something'</code>. Mutating the ref will not cause the component to re-render. So, whenever you want to keep track of a value and want to mutate it without causing the component to re-render, you can make use of <code>useRef</code> hook.</p>
<p>To know a practical use-case which uses useRef to keep track of a value, checkout this excellent article by <a class="user-mention" href="https://hashnode.com/@atapas">Tapas Adhikary</a> - <a target="_blank" href="https://blog.greenroots.info/how-to-use-javascript-scheduling-methods-with-react-hooks-ckh1jzb0u01sg2ps1cvm4afzr">How to use JavaScript scheduling methods with React hooks</a></p>
<h2 id="heading-what-have-you-learned">What have you learned?</h2>
<ul>
<li>useRef Hook<ul>
<li>It is used to create refs. It takes the initial value of ref as a single argument.</li>
<li>When you assign the <code>ref</code> (created using <code>useRef</code> hook)  to the <code>ref</code> property of JSX element, React automatically sets the <code>current</code> property of that <code>ref</code> to the DOM node of the corresponsing element.</li>
<li>You can mutate the <code>ref.current</code> property directly and mutating it does not cause the component to re-render.</li>
</ul>
</li>
<li>We also learned how to create a <code>useOnClickOutsideRef</code> using <code>useRef</code> and <code>useEffect</code> - which can detect and execute a callback whenever you clicked outside of an element.</li>
</ul>
<h2 id="heading-whats-next">What's Next?</h2>
<p>In the next article, we will look at the hooks flow to see in which order different hooks will get executed. We will also see what lifting state and colocating state mean and when to use each of them.</p>
<h4 id="heading-until-next-time">Until Next Time 👋</h4>
<p>If you liked this article, check out</p>
<ul>
<li><a target="_blank" href="https://blog.bhanuteja.dev/how-to-create-a-reusable-localstorage-hook">How to Create a Reusable LocalStorage Hook</a></li>
<li><a target="_blank" href="https://blog.bhanuteja.dev/react-hooks-managing-state-with-usestate-hook">React Hooks: Managing State With useState Hook</a></li>
</ul>
<p>You can also follow me on Twitter at <a target="_blank" href="https://twitter.com/pbteja1998">@pbteja1998</a>.</p>
<div class="hn-embed-widget" id="newsletter"></div>]]></content:encoded></item><item><title><![CDATA[How to Create a Reusable LocalStorage Hook]]></title><description><![CDATA[Hello World 👋
Hooks are special types of functions in React that you can call inside React functional components. They let you store data, add interactivity, and perform some actions, otherwise known as side-effects.
The most common hooks are:

useS...]]></description><link>https://blog.bhanuteja.dev/how-to-create-a-reusable-localstorage-hook</link><guid isPermaLink="true">https://blog.bhanuteja.dev/how-to-create-a-reusable-localstorage-hook</guid><category><![CDATA[React]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[2Articles1Week]]></category><category><![CDATA[ReactHooks]]></category><category><![CDATA[localstorage]]></category><dc:creator><![CDATA[Bhanu Teja Pachipulusu]]></dc:creator><pubDate>Thu, 29 Oct 2020 06:56:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1603944322525/3H0iip75s.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-hello-world">Hello World 👋</h2>
<p>Hooks are special types of functions in React that you can call inside React functional components. They let you store data, add interactivity, and perform some actions, otherwise known as side-effects.</p>
<p>The most common hooks are:</p>
<ul>
<li>useState</li>
<li>useEffect</li>
<li>useRef</li>
<li>useContext</li>
<li>useReducer</li>
</ul>
<p>In the previous article (<a target="_blank" href="https://blog.bhanuteja.dev/react-hooks-managing-state-with-usestate-hook">React Hooks: Managing State With useState Hook</a>), we learned about <code>useState</code> hook. We will be using the <code>useState</code> hook in this article, so if you haven't read the previous one yet, please go and read that before going through this. In this article, we will learn about <code>useEffect</code> hook and then later use it to build a custom and reusable localStorage hook.</p>
<h2 id="heading-useeffect">useEffect</h2>
<p><code>useEffect</code> is a built-in function in React. It takes a callback function as an argument and does not return anything.</p>
<p>For example,</p>
<pre><code class="lang-js">useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-comment">//...do something here</span>
})
</code></pre>
<p><strong>Note:</strong></p>
<ul>
<li>React runs the callback present in <code>useEffect</code> after every render and rerender of the component.</li>
</ul>
<h2 id="heading-creating-a-reusable-localstorage-hook">Creating a reusable LocalStorage Hook</h2>
<h3 id="heading-simple-useeffect">Simple useEffect</h3>
<p>Let's take a simple <code>counter</code> example as shown below.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Counter</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [count, setCount] = useState(<span class="hljs-number">0</span>);
  <span class="hljs-keyword">const</span> incrementCount = <span class="hljs-function">() =&gt;</span> {
    setCount(count + <span class="hljs-number">1</span>);
  };
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{incrementCount}</span>&gt;</span>{count}<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>;
}
</code></pre>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://codesandbox.io/s/use-effect-simple-counter-sdyy9">https://codesandbox.io/s/use-effect-simple-counter-sdyy9</a></div>
<p>Try to increment the counter in the above sandbox and reload the sandbox page. You will see that as soon as you reload the page, the counter is reset to 0. Let's say that we don't want that. We want the counter to stay at the same value even after you reload the sandbox page. One way to do this is to store the value of the counter in local storage and sync the counter state from there when you reload.</p>
<p>Let's see how we can achieve that using <code>useEffect</code>.</p>
<pre><code class="lang-js">useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">localStorage</span>.setItem(<span class="hljs-string">'count'</span>, count)
})
</code></pre>
<p>What this does is, every time the component rerenders, it updates the value of the <code>count</code> key in local storage. </p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Counter</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [count, setCount] = useState(<span class="hljs-number">0</span>);
  <span class="hljs-keyword">const</span> incrementCount = <span class="hljs-function">() =&gt;</span> {
    setCount(count + <span class="hljs-number">1</span>);
  };
  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">localStorage</span>.setItem(<span class="hljs-string">'count'</span>, count)
  })
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{incrementCount}</span>&gt;</span>{count}<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>;
}
</code></pre>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://codesandbox.io/s/use-effect-1-2s34t">https://codesandbox.io/s/use-effect-1-2s34t</a></div>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1603935924392/sFxmYhgXh.png" alt="Screenshot 2020-10-29 at 7.15.05 AM.png" />
As you increase the count, you will see that the count in localStorage is getting increased. But as soon as you realod the page, the count is being reset to 0 again, even in localStorage. This is because we are not getting the initial value of <code>count</code> from localStorage.</p>
<p>Let's change the component to get the initial value from localstorage.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Counter</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [count, setCount] = useState(<span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">localStorage</span>.getItem(<span class="hljs-string">'count'</span>) || <span class="hljs-number">0</span>);
  <span class="hljs-keyword">const</span> incrementCount = <span class="hljs-function">() =&gt;</span> {
    setCount(count + <span class="hljs-number">1</span>);
  };
  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">localStorage</span>.setItem(<span class="hljs-string">'count'</span>, count)
  })
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{incrementCount}</span>&gt;</span>{count}<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>;
}
</code></pre>
<p><strong>Note:</strong>
Here we are doing a <a target="_blank" href="https://blog.bhanuteja.dev/react-hooks-managing-state-with-usestate-hook#lazy-initialization">lazy initialization</a> of the state. </p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://codesandbox.io/s/use-effect-2-kefrj">https://codesandbox.io/s/use-effect-2-kefrj</a></div>
<p>Try to increment the count and reload the sandbox. You will see that the counter no longer resets to 0. But, we are facing a new problem.</p>
<p>To reproduce the problem,</p>
<ul>
<li>Increment the count a few times.</li>
<li>Reload the page.</li>
<li>Now increment the count again by clicking the count button.</li>
<li>You will see that instead of incrementing the count by 1, one is getting concatenated to the existing count.</li>
</ul>
<p>This is happening because of how localStorage stores the values. It stores everything in the form of a string. So even when we try to store the number in localStorage, it converts it into a string and then stores it. So, when we fetch the value from localStorage, we are getting a string instead of a number. That is why incrementing the count is not behaving as it should.</p>
<p>Let's try to fix this.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">convertNumberToString</span>(<span class="hljs-params">num</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-string">`<span class="hljs-subst">${num}</span>`</span>
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">convertStringToNumber</span>(<span class="hljs-params">str</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-built_in">Number</span>(str)
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getInitialValue</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> localStorageValue = <span class="hljs-built_in">localStorage</span>.getItem(<span class="hljs-string">'count'</span>)

  <span class="hljs-comment">// here we are converting the string in localStorage to number before returning</span>
  <span class="hljs-keyword">return</span> convertStringToNumber(localStorageValue) || <span class="hljs-number">0</span>
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Counter</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [count, setCount] = useState(<span class="hljs-function">() =&gt;</span> getInitialValue());
  <span class="hljs-keyword">const</span> incrementCount = <span class="hljs-function">() =&gt;</span> {
    setCount(count + <span class="hljs-number">1</span>);
  };
  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-comment">// we are converting the number to string before storing in localStorage</span>
    <span class="hljs-comment">// This way, we can control how the conversion happens</span>
    <span class="hljs-built_in">localStorage</span>.setItem(<span class="hljs-string">'count'</span>, convertNumberToString(count))
  })
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{incrementCount}</span>&gt;</span>{count}<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>;
}
</code></pre>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://codesandbox.io/s/use-effect-3-rlp43">https://codesandbox.io/s/use-effect-3-rlp43</a></div>
<p>Now, everything seems to work. But, we can optimize this even further. </p>
<h3 id="heading-dependency-array">Dependency Array</h3>
<p>Let's try to add a console log in the useEffect and see when it is being run.</p>
<pre><code class="lang-js">useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'useEffect callback is getting executed'</span>)
    <span class="hljs-built_in">localStorage</span>.setItem(<span class="hljs-string">'count'</span>, convertNumberToString(count))
})
</code></pre>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://codesandbox.io/s/use-effect-4-s85vu">https://codesandbox.io/s/use-effect-4-s85vu</a></div>
<p>You will see that the <code>useEffect</code> callback is getting executed every time the component re-renders. Try to click on "UPDATE SOME OTHER STATE" button. You will see that even though the count doesn't change, the <code>useEffect</code> is getting called. This is the expected behavior. But we want to set the value in localStorage only when the value of count changes.</p>
<p>React gives us a way to achieve this.</p>
<p><code>useEffect</code> takes an array as the second argument. It is called <code>dependency array</code>. You can specify all the dependencies that your <code>useEffect</code> depends on, in that array. And that <code>useEffect</code> callback will only run when any of those dependencies change.</p>
<p>For example, we want the <code>useEffect</code> in our example to run only when count changes. You can achieve this as follows.</p>
<pre><code class="lang-js">useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'useEffect callback is getting executed'</span>)
    <span class="hljs-built_in">localStorage</span>.setItem(<span class="hljs-string">'count'</span>, convertNumberToString(count))
}, [count])
</code></pre>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://codesandbox.io/s/use-effect-5-ek9bf?file=/src/Counter.js">https://codesandbox.io/s/use-effect-5-ek9bf?file=/src/Counter.js</a></div>
<p>Now, when you try to click on "UPDATE SOME OTHER STATE", the component rerenders, but the <code>useEffect</code> callback will not get executed.</p>
<p>Let's put everything together.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React, { useState, useEffect } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">convertNumberToString</span>(<span class="hljs-params">num</span>) </span>{
    <span class="hljs-keyword">return</span> <span class="hljs-string">`<span class="hljs-subst">${num}</span>`</span>;
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">convertStringToNumber</span>(<span class="hljs-params">str</span>) </span>{
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">Number</span>(str);
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getInitialValue</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">const</span> localStorageValue = <span class="hljs-built_in">localStorage</span>.getItem(<span class="hljs-string">"count"</span>);
    <span class="hljs-keyword">return</span> convertStringToNumber(localStorageValue) || <span class="hljs-number">0</span>;
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Counter</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">const</span> [count, setCount] = useState(<span class="hljs-function">() =&gt;</span> getInitialValue());
    <span class="hljs-keyword">const</span> incrementCount = <span class="hljs-function">() =&gt;</span> {
        setCount(count + <span class="hljs-number">1</span>);
    };
    useEffect(<span class="hljs-function">() =&gt;</span> {
        <span class="hljs-built_in">localStorage</span>.setItem(<span class="hljs-string">"count"</span>, convertNumberToString(count));
    }, [count]);
    <span class="hljs-keyword">return</span> (
        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"btn"</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{incrementCount}</span>&gt;</span>
            {count}
        <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
    );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Counter;
</code></pre>
<h2 id="heading-creating-a-reusable-hook">Creating a reusable hook</h2>
<blockquote>
<p>The <code>useLocalStorageState</code> hook example shown here is based on the example from <a target="_blank" href="https://kentcdodds.com">Kent C. Dodds</a>'s <a target="_blank" href="https://epicreact.dev">EpicReact.Dev</a> <code>React Hooks</code> workshop.</p>
</blockquote>
<p>Since we may need the same logic of storing state in localStorage at many places, we can create a custom hook that does it, and then we can use it wherever we want to store the state in localStorage.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">convertNumberToString</span>(<span class="hljs-params">num</span>) </span>{
    <span class="hljs-keyword">return</span> <span class="hljs-string">`<span class="hljs-subst">${num}</span>`</span>;
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">convertStringToNumber</span>(<span class="hljs-params">str</span>) </span>{
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">Number</span>(str);
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getInitialValue</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">const</span> localStorageValue = <span class="hljs-built_in">localStorage</span>.getItem(<span class="hljs-string">"count"</span>);
    <span class="hljs-keyword">return</span> convertStringToNumber(localStorageValue) || <span class="hljs-number">0</span>;
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">useLocalStorageState</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">const</span> [count, setCount] = useState(<span class="hljs-function">() =&gt;</span> getInitialValue());
    <span class="hljs-keyword">const</span> incrementCount = <span class="hljs-function">() =&gt;</span> {
        setCount(count + <span class="hljs-number">1</span>);
    };
    useEffect(<span class="hljs-function">() =&gt;</span> {
        <span class="hljs-built_in">localStorage</span>.setItem(<span class="hljs-string">"count"</span>, convertNumberToString(count));
    }, [count]);
    <span class="hljs-keyword">return</span> [count, setCount]
}
</code></pre>
<p>This is what we have until now. Let's refactor this a bit to generalize things.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getInitialValue</span>(<span class="hljs-params">key, defaultValue, convertFromString</span>) </span>{
  <span class="hljs-keyword">const</span> localStorageValue = <span class="hljs-built_in">localStorage</span>.getItem(key);
  <span class="hljs-keyword">return</span> convertFromString(localStorageValue) || defaultValue;
}
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">useLocalStorageState</span>(<span class="hljs-params">
  key,
  defaultValue = <span class="hljs-string">""</span>,
  { convertToString = JSON.stringify, convertFromString = JSON.parse } = {}
</span>) </span>{
  <span class="hljs-keyword">const</span> [state, setState] = useState(<span class="hljs-function">() =&gt;</span>
    getInitialValue(key, defaultValue, convertFromString)
  );

  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">localStorage</span>.setItem(key, convertToString(state));
  }, [key, state, convertToString]);

  <span class="hljs-keyword">return</span> [state, setState];
}
</code></pre>
<p><strong>What did we do here?</strong></p>
<ul>
<li>We changed the variable <code>count</code> and <code>setCount</code> to <code>state</code> and <code>setState</code></li>
<li>We are asking the user to provide the <code>key</code> as an argument. We will store the state in this key in localStorage.</li>
<li>We are asking the user to also pass the initial default value as an argument. Previously in our example, it was 0.</li>
<li>We are asking the user to optionally pass the <code>convertToString</code> and <code>convertFromString</code> functions as arguments.<ul>
<li>If the user doesn't provide them, we are defaulting them to <code>JSON.stringify</code> and <code>JSON.parse</code>.</li>
</ul>
</li>
<li>We updated the dependency array of <code>useEffect</code> and added all of its dependents.</li>
<li>Finally, we are returning <code>state</code> and <code>useState</code> in the form of an array, similar to how the inbuilt <code>useState</code> hook returns an array.</li>
</ul>
<p>Let's change our example to use this custom hook.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Counter</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">const</span> [count, setCount] = useLocalStorageHook(<span class="hljs-string">'count'</span>, <span class="hljs-number">0</span>);
    <span class="hljs-keyword">const</span> incrementCount = <span class="hljs-function">() =&gt;</span> {
        setCount(count + <span class="hljs-number">1</span>);
    };
    <span class="hljs-keyword">return</span> (
        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"btn"</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{incrementCount}</span>&gt;</span>
            {count}
        <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
    );
}
</code></pre>
<p>We can go a bit further and allow the user to also pass a function as the initial value, similar to how useState works.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getInitialValue</span>(<span class="hljs-params">key, defaultValue, convertFromString</span>) </span>{
  <span class="hljs-keyword">const</span> localStorageValue = <span class="hljs-built_in">localStorage</span>.getItem(key);

 <span class="hljs-comment">// change starts here</span>
  <span class="hljs-keyword">if</span>(localStorageValue) {
    <span class="hljs-keyword">return</span> convertFromString(localStorageValue)
  }
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">typeof</span> defaultValue === <span class="hljs-string">'function'</span> ? defaultValue() : defaultValue
 <span class="hljs-comment">// change ends here</span>
}
</code></pre>
<p>Sometimes, the <code>convertFromString</code> function can throw an error when the value against the given key already exists in the local storage. In that case, we can remove the corresponding key-value pair from local storage before adding it with new values.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getInitialValue</span>(<span class="hljs-params">key, defaultValue, convertFromString</span>) </span>{
  <span class="hljs-keyword">const</span> localStorageValue = <span class="hljs-built_in">localStorage</span>.getItem(key);

  <span class="hljs-keyword">if</span>(localStorageValue) {
    <span class="hljs-comment">// change starts here</span>
    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">return</span> convertFromString(localStorageValue)
    } <span class="hljs-keyword">catch</span> {
      <span class="hljs-built_in">localStorage</span>.removeItem(key)
    }
    <span class="hljs-comment">// change ends here</span>
  }
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">typeof</span> defaultValue === <span class="hljs-string">'function'</span> ? defaultValue() : defaultValue
}
</code></pre>
<p>Let's put everything together.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getInitialValue</span>(<span class="hljs-params">key, defaultValue, convertFromString</span>) </span>{
  <span class="hljs-keyword">const</span> localStorageValue = <span class="hljs-built_in">localStorage</span>.getItem(key);
  <span class="hljs-keyword">if</span>(localStorageValue) {
    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">return</span> convertFromString(localStorageValue)
    } <span class="hljs-keyword">catch</span> {
      <span class="hljs-built_in">localStorage</span>.removeItem(key)
    }
  }
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">typeof</span> defaultValue === <span class="hljs-string">'function'</span> ? defaultValue() : defaultValue
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">useLocalStorageState</span>(<span class="hljs-params">
  key,
  defaultValue = <span class="hljs-string">""</span>,
  { convertToString = JSON.stringify, convertFromString = JSON.parse } = {}
</span>) </span>{
  <span class="hljs-keyword">const</span> [state, setState] = useState(<span class="hljs-function">() =&gt;</span>
    getInitialValue(key, defaultValue, convertFromString)
  );

  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">localStorage</span>.setItem(key, convertToString(state));
  }, [key, state, convertToString]);

  <span class="hljs-keyword">return</span> [state, setState];
}
</code></pre>
<p>That's it. You can use this hook whenever you want to store the state in localStorage and keep it in sync with the actual state. The API is also very similar to how you use <code>useState</code></p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> [state, setState] = useLocalStorageState(<span class="hljs-string">'state'</span>, {})
</code></pre>
<h2 id="heading-what-have-you-learned">What have you learned?</h2>
<ul>
<li>useEffect hook<ul>
<li>It runs every time the component renders and re-renders when no dependency array is passed.</li>
<li>You can pass a dependency array as a second argument. </li>
<li>Callback in <code>useEffect</code> only runs when any of the value in the dependency array changes.</li>
<li>If you pass an empty array as a dependency array, then the callback will only run after the component is first rendered.</li>
</ul>
</li>
<li>We also learned how to create a reusable localStorage hook using <code>useState</code> and <code>useEffect</code>.</li>
</ul>
<h2 id="heading-whats-next">What's Next?</h2>
<p>In the next article, we will see the flow of hooks. We will see exactly at what time different hooks will be run in the component lifecycle especially <code>useState</code> and <code>useEffect</code>.</p>
<h4 id="heading-until-next-time">Until Next Time 👋</h4>
<hr />
<h3 id="heading-references">References:</h3>
<ul>
<li><a target="_blank" href="https://epicreact.dev">EpicReact.Dev</a> by <a target="_blank" href="https://kentcdodds.com">Kent C. Dodds</a></li>
<li><a target="_blank" href="http://react-hooks.netlify.app/">React Hooks Workshop Prod Deployment</a></li>
<li><a target="_blank" href="https://github.com/kentcdodds/react-hooks">React Hooks Workshop Repo</a></li>
</ul>
<hr />
<p>If this was helpful to you, Please <strong>Like</strong> and <strong>Share</strong> so that it reaches others as well. To get email notifications on my latest articles, please subscribe to <a target="_blank" href="https://blog.bhanuteja.dev">my blog</a> by hitting the <strong>Subscribe</strong> button at the top of the page. You can also follow me on Twitter <a target="_blank" href="https://twitter.com/pbteja1998">@pbteja1998</a>.</p>
<div class="hn-embed-widget" id="newsletter"></div>]]></content:encoded></item><item><title><![CDATA[React Hooks: Managing State With useState Hook]]></title><description><![CDATA[Hello World 👋
Hooks are special types of functions in React that you can call inside React functional components. They let you store data, add interactivity, and perform some actions, otherwise known as side-effects.
Below are the most common hooks ...]]></description><link>https://blog.bhanuteja.dev/react-hooks-managing-state-with-usestate-hook</link><guid isPermaLink="true">https://blog.bhanuteja.dev/react-hooks-managing-state-with-usestate-hook</guid><category><![CDATA[React]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[2Articles1Week]]></category><dc:creator><![CDATA[Bhanu Teja Pachipulusu]]></dc:creator><pubDate>Mon, 26 Oct 2020 06:57:39 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1603669964734/yxsxtPAd3.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-hello-world">Hello World 👋</h2>
<p>Hooks are special types of functions in React that you can call inside React functional components. They let you store data, add interactivity, and perform some actions, otherwise known as side-effects.</p>
<p>Below are the most common hooks that you use:</p>
<ul>
<li>useState</li>
<li>useEffect</li>
<li>useRef</li>
<li>useContext</li>
<li>useReducer</li>
</ul>
<p>In this article, we will learn in-depth about <code>useState</code> hook.</p>
<h2 id="heading-usestate">useState</h2>
<p><code>useState</code> is a built-in function in React. It takes a single argument and returns an array of two elements when executed.</p>
<p>Let's see an example.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> [count, setCount] = useState(<span class="hljs-number">0</span>)
</code></pre>
<ul>
<li>It is used to manage the state of the component.</li>
<li>When the state of a component changes, React re-renders that component and all of its child components automatically.</li>
<li>It takes the initial value of the state as an argument.</li>
<li>It returns an array of two elements.<ul>
<li>The first element is the value of the state.</li>
<li>The second element is a function that you can use to set the value of the state</li>
<li>You can name these elements whatever you like, but the common practice is to name them as <code>var</code> and <code>setVar</code>. For instance, in the above example, we named it as <code>count</code> and <code>setCount</code>.</li>
</ul>
</li>
</ul>
<p>In the above example, we called <code>useState</code> with the argument of 0. This means that the initial value of the state is 0. <code>count</code> contains the value of the state. <code>setCount</code> is a function you can use to set the value of count.</p>
<p>Let's see the complete example of a component to get an idea of how <code>useState</code> is used in React.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React, { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Counter</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">const</span> [count, setCount] = useState(<span class="hljs-number">0</span>)
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">increment</span>(<span class="hljs-params"></span>) </span>{
        setCount(count + <span class="hljs-number">1</span>)
    }
    <span class="hljs-keyword">return</span> (
        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{increment}</span>&gt;</span>{count}<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
    )
}
</code></pre>
<p>This renders a simple button that shows the value of count. Initially, it is 0. Whenever you click on the button, the count value is increased by 1 by using <code>setCount</code>. And as soon as the state changes, the component rerenders and the new value of count is shown in the button.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://codesandbox.io/s/simple-counter-k5io2">https://codesandbox.io/s/simple-counter-k5io2</a></div>
<h3 id="heading-functional-updates">Functional Updates</h3>
<p>Let's slightly change the above component.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React, { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Counter</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">const</span> [count, setCount] = useState(<span class="hljs-number">0</span>)
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">incrementBy3</span>(<span class="hljs-params"></span>) </span>{
        setCount(count + <span class="hljs-number">2</span>)
        setCount(count + <span class="hljs-number">1</span>)
    }
    <span class="hljs-keyword">return</span> (
        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{incrementBy3}</span>&gt;</span>{count}<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
    )
}
</code></pre>
<p>Now, when you click on the button, what would you expect the increment to be. Will the count be incremented by 2? (or) Will it be incremented by 1? (or) Will it be incremented by 3?</p>
<p>Click and try it out.</p>
<p>Here is the corresponding code sandbox for it.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://codesandbox.io/s/simple-counter-2-ff4pc">https://codesandbox.io/s/simple-counter-2-ff4pc</a></div>
<p>You can observe that the count will only be incremented by 1. This is because of how React makes state updates. Many state updates are batched together and performed in an asynchronous manner. So, if you have two setState calls at the same place, you cannot rely on React to complete the first state update before doing the second state update.</p>
<p>Let's take the above example. </p>
<ul>
<li>Initially, the <code>count</code> is 0.</li>
<li>Button is clicked.</li>
<li>First, React starts executing <code>setCount(count + 2)</code>. <ul>
<li>The value of <code>count</code> in that render is <code>0</code>. </li>
<li>React calculates the value of <code>count</code> for the next render to be <code>count + 2</code>, which is 2. </li>
<li>But the component is not yet re-rendered. So the current value of the variable count is still <code>0</code>.</li>
</ul>
</li>
<li>Now, React starts executing <code>setCount(count + 1)</code>. <ul>
<li>Since the value of <code>count</code> is still 0, React calculates the value of <code>count</code> for the next render to be <code>count + 1</code> which is 1. </li>
<li>The value of next state was 2 when <code>setCount(count+2)</code> is executed. Now, it got overridden by the value of next state of <code>setCount(count+1)</code> which is 1.</li>
</ul>
</li>
<li>Now since all the state updates are executed, React starts rerendering the component with the value of the next state which is 1.</li>
<li>And this is the reason why, when you click on the button only 1 is getting incremented instead of 3.</li>
</ul>
<p>Even though it takes a while to understand the problem that is occurring, the solution to fix this problem is not that complicated.</p>
<p>Till now we have seen that <code>setCount</code> takes a value as an argument. But it also takes a callback as the argument of <code>setCount</code>. The first argument of that callback function is the previous value of the state.</p>
<p>For example, if we want to increment the count by 1, you can do it as follows:</p>
<pre><code class="lang-js">setCount(<span class="hljs-function"><span class="hljs-params">previousCount</span> =&gt;</span> previousCount + <span class="hljs-number">1</span>)
</code></pre>
<p>When you use this type of callback function to update the state, you can be assured that the <code>prevCount</code> will always have the correct value of the state even though the component is not yet rerendered. That is why it is always recommended to use this type of update whenever the next value of the state is computed from the previous value of the state.</p>
<p>Let's use this approach and rewrite the above example.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React, { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Counter</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">const</span> [count, setCount] = useState(<span class="hljs-number">0</span>)
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">incrementBy3</span>(<span class="hljs-params"></span>) </span>{
        setCount(<span class="hljs-function"><span class="hljs-params">previousCount</span> =&gt;</span> previousCount + <span class="hljs-number">2</span>)
        setCount(<span class="hljs-function"><span class="hljs-params">previousCount</span> =&gt;</span> previousCount + <span class="hljs-number">1</span>)
    }
    <span class="hljs-keyword">return</span> (
        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{incrementBy3}</span>&gt;</span>{count}<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
    )
}
</code></pre>
<p>This correctly increments the count by 3.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://codesandbox.io/s/simple-counter-3-9cxe0">https://codesandbox.io/s/simple-counter-3-9cxe0</a></div>
<h3 id="heading-lazy-initialization">Lazy Initialization</h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> initialValue = resultOfSomeExpensiveOperation()
<span class="hljs-keyword">const</span> [state, setState] = useState(initialValue)
</code></pre>
<p>Previously we have seen that the <code>useState</code> takes the initial value as an argument. </p>
<p>Technically React only needs the initialValue when the component is first mounted. After that, the initialValue is no longer applicable. So if the initial value is calculated through some expensive operations, we want those operations to run only at the start. Let's see if that is actually happening or not through an example.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React, { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getInitialValue</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'getInitialValue is getting executed'</span>);
  <span class="hljs-comment">// ... do some expensive operations</span>
  <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Counter</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [count, setCount] = useState(getInitialValue());
  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">increment</span>(<span class="hljs-params"></span>) </span>{
    setCount(count + <span class="hljs-number">1</span>);
  }
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{increment}</span>&gt;</span>{count}<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>;
}
</code></pre>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://codesandbox.io/s/simple-counter-4-8w5u2">https://codesandbox.io/s/simple-counter-4-8w5u2</a></div>
<p>Try to click on the button and check the console. </p>
<ul>
<li>You will see that the <code>getInitialValue</code> function is being executed every time the button is clicked. So, it is getting called on every rerender.</li>
<li>So, if there are any expensive operations to be made in that function, they will be executed after every rerender.</li>
<li>But only the first execution of the <code>getInitialValue</code> is useful for React. All others will be thrown away as the state is already set in the subsequent rerenders.</li>
<li>You can see why this might cause performance problems for your application.</li>
</ul>
<p>React gives us a way to handle this type of situation. It's called <code>Lazy Initialization of State</code>.</p>
<p>Instead of directly passing the value as an argument, you have the option to pass a callback function which when executed gives you the initial value. React executes this function only when it is needed. This is needed only at the first, so React executes this function only once at the start.</p>
<p>Let's rewrite the above example to use lazy state initialization.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React, { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getInitialValue</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'getInitialValue is getting executed'</span>);
  <span class="hljs-comment">// ... do some expensive operations</span>
  <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Counter</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [count, setCount] = useState(<span class="hljs-function">() =&gt;</span> getInitialValue());
  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">increment</span>(<span class="hljs-params"></span>) </span>{
    setCount(count + <span class="hljs-number">1</span>);
  }
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{increment}</span>&gt;</span>{count}<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>;
}
</code></pre>
<p>All we changed in the above example is that: <code>useState(getInitialValue())</code> is changed to <code>useState(() =&gt; getInitialValue())</code>.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://codesandbox.io/s/simple-counter-5-2rois">https://codesandbox.io/s/simple-counter-5-2rois</a></div>
<p>You can check the console of the above code sandbox. You will see that <code>getInitialValue</code> is not getting called when you click on the button. It is only called at the start. </p>
<h3 id="heading-usestate-with-objects">useState with Objects</h3>
<p>You can manage any type of state with <code>useState</code> hook, even objects.</p>
<p>For example, let's use useState hook to manage firstName and lastName states in a single object.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> [name, setName] = useState({
    <span class="hljs-attr">firstName</span>: <span class="hljs-string">'Bhanu Teja'</span>,
    <span class="hljs-attr">lastName</span>: <span class="hljs-string">'P'</span>
})
</code></pre>
<p>Now, whenever you call <code>setName</code> to update the name object, you have to provide both firstName and lastName.</p>
<p>For example,</p>
<pre><code class="lang-js">setName({
    <span class="hljs-attr">firstName</span>: <span class="hljs-string">'New First Name'</span>,
    <span class="hljs-attr">lastName</span>: <span class="hljs-string">'New Last Name'</span>
})
</code></pre>
<p>What if we want to update only the firstName or only the lastName. You can do so by using the spread operator.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">setFirstName</span>(<span class="hljs-params">firstName</span>) </span>{
    setName({
        ...name,
        firstName
    })
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">setLastName</span>(<span class="hljs-params">lastName</span>) </span>{
    setName({
        ...name,
        lastName
    })
}
</code></pre>
<p>Let's put everything together.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React, { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [name, setName] = useState({
    <span class="hljs-attr">firstName</span>: <span class="hljs-string">"Bhanu Teja"</span>,
    <span class="hljs-attr">lastName</span>: <span class="hljs-string">"P"</span>
  });

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">setFirstName</span>(<span class="hljs-params">firstName</span>) </span>{
    setName({
      ...name,
      firstName
    });
  }

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">setLastName</span>(<span class="hljs-params">lastName</span>) </span>{
    setName({
      ...name,
      lastName
    });
  }

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
        <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"First Name"</span>
        <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span>
        <span class="hljs-attr">value</span>=<span class="hljs-string">{name.firstName}</span>
        <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> setFirstName(e.target.value)}
      /&gt;
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
        <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Last Name"</span>
        <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span>
        <span class="hljs-attr">value</span>=<span class="hljs-string">{name.lastName}</span>
        <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> setLastName(e.target.value)}
      /&gt;
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>
        Your name is:{" "}
        <span class="hljs-tag">&lt;<span class="hljs-name">strong</span>&gt;</span>
          {name.firstName}.{name.lastName}
        <span class="hljs-tag">&lt;/<span class="hljs-name">strong</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;/&gt;</span></span>
  );
}
</code></pre>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://codesandbox.io/s/usestate-with-objects-2r78p">https://codesandbox.io/s/usestate-with-objects-2r78p</a></div>
<p>Usage of <code>useState</code> with arrays is very similar to that of with objects.</p>
<h2 id="heading-what-have-you-learned">What have you learned?</h2>
<p>You learned about:</p>
<ul>
<li>What are hooks and what are some of the common hooks in React ?</li>
<li><code>useState</code> hook:<ul>
<li>It takes the initial value of the state as an argument and returns an array of two elements - one has the value of the state and the other is a function to update the value of the state.</li>
<li>How to do functional updates for the state? </li>
<li>Why, not using functional updates, causes a problem in certain situations ?</li>
<li>It is always recommended to use functional updates to update the state when the next state is computed from the previous state.</li>
<li>Lazy initialization of state and when it can be useful.</li>
<li>Usage of <code>useState</code> with objects and arrays.</li>
</ul>
</li>
</ul>
<h2 id="heading-whats-next">What's Next?</h2>
<p>In the next article, we will learn everything about <code>useEffect</code> hook.</p>
<h4 id="heading-until-next-time">Until Next Time 👋</h4>
<hr />
<p>If this was helpful to you, Please <strong>Like</strong> and <strong>Share</strong> so that it reaches others as well. To get email notifications on my latest articles, please subscribe to <a target="_blank" href="https://blog.bhanuteja.dev">my blog</a> by hitting the <strong>Subscribe</strong> button at the top of the page. You can also follow me on Twitter <a target="_blank" href="https://twitter.com/pbteja1998">@pbteja1998</a>.</p>
<div class="hn-embed-widget" id="newsletter"></div>]]></content:encoded></item><item><title><![CDATA[React Fundamentals: Styling And Handling Forms]]></title><description><![CDATA[Hello World 👋

This is the 6th article of the series My Review of Kent C. Dodds's EpicReact.Dev. Please note that this blog post series is just my review of the EpicReact.Dev workshop material. I am just trying to explain what I learned and understo...]]></description><link>https://blog.bhanuteja.dev/react-fundamentals-styling-and-handling-forms</link><guid isPermaLink="true">https://blog.bhanuteja.dev/react-fundamentals-styling-and-handling-forms</guid><category><![CDATA[React]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[2Articles1Week]]></category><dc:creator><![CDATA[Bhanu Teja Pachipulusu]]></dc:creator><pubDate>Thu, 22 Oct 2020 07:09:55 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1603323346188/sGPf2hFqt.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-hello-world">Hello World 👋</h2>
<blockquote>
<p>This is the 6th article of the series <a target="_blank" href="https://hashnode.com/series/my-review-of-kent-c-doddss-epicreactdev-ckfv4gidh08efu9s1408v8tgp">My Review of Kent C. Dodds's EpicReact.Dev</a>. Please note that this blog post series is just my review of the <a target="_blank" href="https://epicreact.dev">EpicReact.Dev</a> workshop material. I am just trying to explain what I learned and understood in my own way. This is not in any way officially associated with <a target="_blank" href="https://epicreact.dev">Kent C. Dodds</a> or <a target="_blank" href="https://epicreact.dev">EpicReact.Dev</a>. You would learn a lot more when you actually go through the <code>EpicReact.Dev</code> video explanations and workshop material yourself. The workshop material is also self-paced and open source. So, if you want to do the workshop yourself, you can go to <a target="_blank" href="https://github.com/kentcdodds/react-fundamentals">React Fundamentals Workshop Repo</a> and follow the instructions there.</p>
</blockquote>
<p>In this article, you will learn about how to do styling in React. You will also learn how to handle forms in React.</p>
<ul>
<li><a class="post-section-overview" href="#styling">Styling</a><ul>
<li><a class="post-section-overview" href="#inline-css">Inline CSS</a></li>
<li><a class="post-section-overview" href="#regular-css">Regular CSS</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#handling-forms">Handling Forms</a><ul>
<li><a class="post-section-overview" href="#using-eventtarget">Using event.target</a></li>
<li><a class="post-section-overview" href="#using-refs">Using Refs</a></li>
<li><a class="post-section-overview" href="#using-usestate">Using useState</a></li>
</ul>
</li>
</ul>
<h3 id="heading-styling">Styling</h3>
<p>In React, there are primarily two ways to style the elements. One is through inline CSS and the other is to just add a className and style it in an external CSS file.</p>
<h4 id="heading-inline-css">Inline CSS</h4>
<p>In HTML, you can add inline styles to elements by adding your styles as a string to the <code>style</code> attribute.</p>
<pre><code>&lt;div style=<span class="hljs-string">"color: red; font-style: italic;"</span>&gt;Red Italic Text&lt;/div&gt;
</code></pre><p>In <code>React</code>, you would add your styles to the <code>style</code> prop, but instead of a <code>string</code>, the <code>style</code> prop accepts a <a target="_blank" href="https://www.w3schools.com/jsref/dom_obj_style.asp">Style Object</a>. </p>
<p><strong>Note:</strong></p>
<ul>
<li>The properties in the style object are camel-cased.<ul>
<li>For example, <code>background-color</code> in CSS is <code>backgroundColor</code> in the style object.</li>
<li><a target="_blank" href="https://www.w3schools.com/jsref/dom_obj_style.asp">Know More</a></li>
</ul>
</li>
</ul>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> elementStyle = {
    <span class="hljs-attr">color</span>: <span class="hljs-string">'red'</span>,
    <span class="hljs-attr">fontStyle</span>: <span class="hljs-string">'italic'</span>
}
</code></pre>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{elementStyle}</span>&gt;</span>Red Italic Text<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>You can even inline <code>elementStyle</code> if you like</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{{</span> <span class="hljs-attr">color:</span> '<span class="hljs-attr">red</span>', <span class="hljs-attr">fontStyle:</span> '<span class="hljs-attr">italic</span>' }}&gt;</span>
    Red Italic Text
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<h4 id="heading-regular-css">Regular CSS</h4>
<p>You can add styles to the elements by adding the <code>className</code> attribute and then styling it in an external CSS file.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"container"</span>&gt;</span>Hello World<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<pre><code class="lang-css"><span class="hljs-selector-class">.container</span> {
    <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span> auto;
    <span class="hljs-attribute">background-color</span>: red;
}
</code></pre>
<hr />
<h3 id="heading-handling-forms">Handling Forms</h3>
<blockquote>
<p>The example used in this section is directly taken from <a target="_blank" href="https://github.com/kentcdodds/react-fundamentals">React Fundamentals Workshop</a> by <a target="_blank" href="https://kentcdodds.com">Kent C. Dodds's</a></p>
</blockquote>
<h4 id="heading-using-eventtarget">Using event.target</h4>
<p>Consider the following form</p>
<pre><code>&lt;form&gt;
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">htmlFor</span>=<span class="hljs-string">"usernameId"</span>&gt;</span>Username:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"usernameId"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"username"</span> /&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Submit<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
&lt;/form&gt;
</code></pre><p>Now handling forms in React is very similar to how we do in normal javascript. You just define a submit handler and then assign it to the onSubmit event of the form.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">onSubmit</span>=<span class="hljs-string">{handleSubmit}</span>&gt;</span>
    ...
    ...
    ...
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
</code></pre>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleSubmit</span>(<span class="hljs-params">event</span>) </span>{
    <span class="hljs-comment">// This prevents the default behaviour of form submission</span>
    <span class="hljs-comment">// If you don't add this, the page will be refreshed </span>
    event.preventDefault()

    <span class="hljs-comment">/** 
     You can get the value of username in one of the following ways.        
        (through the position of input)
        -&gt; event.target.elements[0].value

        (through id)
        -&gt; event.target.elements.usernameId.value

        (through name)
        -&gt; event.target.elements.username.value
    **/</span>

   <span class="hljs-comment">// Do whatever you want with the username</span>
}
</code></pre>
<p><strong>Notes:</strong></p>
<ul>
<li><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault">Know more about Event.preventDefault</a></li>
</ul>
<h4 id="heading-using-refs">Using Refs</h4>
<p>There is another way to get the reference to an element in React - using Refs.
Refs are special objects in react that stay consistent between rerenders of the component and also changing it will not cause the component to rerender.</p>
<p>You can create a Ref using <code>React.useRef()</code></p>
<pre><code><span class="hljs-keyword">const</span> myRef = React.useRef()
</code></pre><p>Refs will have a <code>current</code> property which contains the value of ref. If you assign a <code>ref</code> to a React element, <code>ref.current</code> will automatically have the reference to the object.</p>
<p>For example</p>
<pre><code>&lt;input ref={myRef} /&gt;
</code></pre><p>Now <code>myRef.current</code> will have reference to that input element.</p>
<p>Let's make use of ref to get the username in our form.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">UsernameForm</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> usernameInputRef = React.useRef()

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleSubmit</span>(<span class="hljs-params">event</span>) </span>{
    event.preventDefault()
    <span class="hljs-comment">// usernameInputRef.current.value will have the value of the input</span>
  }

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">onSubmit</span>=<span class="hljs-string">{handleSubmit}</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">htmlFor</span>=<span class="hljs-string">"usernameInput"</span>&gt;</span>Username:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"usernameInput"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">{usernameInputRef}</span> /&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Submit<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span></span>
  )
}
</code></pre>
<p>Go through <a target="_blank" href="https://reactjs.org/docs/hooks-reference.html#useref">useRef - official docs</a> to learn more about refs.</p>
<h4 id="heading-using-usestate">Using useState</h4>
<p>This is the most common way that is used to handle forms in React.</p>
<p>We store the value of the input in a state variable and then add an <code>onChange</code> handler to the input which updates the state variable.</p>
<p>In React, there is a special function called <code>useState</code> which you can use to handle state. It returns an array of two values. </p>
<ol>
<li>The value of the state</li>
<li>A function to update the value of the state</li>
</ol>
<p><strong>Note:</strong></p>
<ul>
<li><code>useState</code> also takes the initial value of the state as its single argument.</li>
</ul>
<p>Example:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> [count, setCount] = useState(<span class="hljs-number">0</span>)
</code></pre>
<ul>
<li>Here <code>count</code> hold the value of the state.</li>
<li><code>setCount</code> is a function that can update the value of <code>count</code>.</li>
<li><code>0</code> is the initial value of <code>count</code>.</li>
</ul>
<p>Let's use this to handle forms.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">UsernameForm</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [username, setUsername] = useState(<span class="hljs-string">''</span>)

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleSubmit</span>(<span class="hljs-params">event</span>) </span>{
    event.preventDefault()
    <span class="hljs-comment">// 'username' will have the value of the input</span>
  }
  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleChange</span>(<span class="hljs-params">event</span>) </span>{
    setUsername(event.target.value)
  }

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">onSubmit</span>=<span class="hljs-string">{handleSubmit}</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">htmlFor</span>=<span class="hljs-string">"usernameInput"</span>&gt;</span>Username:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> 
            <span class="hljs-attr">id</span>=<span class="hljs-string">"usernameInput"</span> 
            <span class="hljs-attr">value</span>=<span class="hljs-string">{username}</span> 
            <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> 
            <span class="hljs-attr">onChange</span>=<span class="hljs-string">{handleChange}</span> 
        /&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Submit<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span></span>
  )
}
</code></pre>
<p><strong>Note:</strong></p>
<ul>
<li>The reason why we are using <code>useState</code> to handle the state of the application and not normal variables is that if we have a normal variable that holds state, changing it will not cause the component to rerender. So, even though the value changes, we can't see the change. But if we use the function that we got from <code>useState</code> to update the state, then React knows that the state of the application is changed, and it automatically rerenders the component.</li>
<li>We will learn about <code>useState</code> hook in more detail in later articles.</li>
<li>This type of input where the value of input is set through <code>value</code> attribute and then updating of that value is handled with <code>onChange</code> event handler is called <code>controlled input</code>.</li>
</ul>
<p>Go through <a target="_blank" href="https://reactjs.org/docs/forms.html">official docs</a> to learn more about handling forms in React.</p>
<h3 id="heading-whats-next">What's Next</h3>
<p>This is the last article where we learn about React Fundamentals. The next article in this series is about different hooks in React.</p>
<h4 id="heading-until-next-time">Until Next Time 👋</h4>
<hr />
<p>If this was helpful to you, Please <strong>Like</strong> and <strong>Share</strong> so that it reaches others as well. To get email notifications on my latest articles, please subscribe to <a target="_blank" href="https://blog.bhanuteja.dev">my blog</a> by hitting the <strong>Subscribe</strong> button at the top of the page. You can also follow me on Twitter <a target="_blank" href="https://twitter.com/pbteja1998">@pbteja1998</a>.</p>
<div class="hn-embed-widget" id="newsletter"></div>]]></content:encoded></item><item><title><![CDATA[React Fundamentals: Creating Custom Components]]></title><description><![CDATA[Hello World 👋
Welcome to the 5th article of the series My Review of Kent C. Dodds's EpicReact.Dev. Please note that this blog post series is just my review of the EpicReact.Dev workshop material. I am just trying to explain what I learned and unders...]]></description><link>https://blog.bhanuteja.dev/react-fundamentals-creating-custom-components</link><guid isPermaLink="true">https://blog.bhanuteja.dev/react-fundamentals-creating-custom-components</guid><category><![CDATA[React]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[2Articles1Week]]></category><dc:creator><![CDATA[Bhanu Teja Pachipulusu]]></dc:creator><pubDate>Mon, 19 Oct 2020 06:42:40 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1603056928046/FmBYwcOCr.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-hello-world">Hello World 👋</h2>
<p>Welcome to the 5th article of the series <a target="_blank" href="https://hashnode.com/series/my-review-of-kent-c-doddss-epicreactdev-ckfv4gidh08efu9s1408v8tgp">My Review of Kent C. Dodds's EpicReact.Dev</a>. Please note that this blog post series is just my review of the <a target="_blank" href="https://epicreact.dev">EpicReact.Dev</a> workshop material. I am just trying to explain what I learned and understood in my own way. This is not in any way officially associated with <a target="_blank" href="https://epicreact.dev">Kent C. Dodds</a> or <a target="_blank" href="https://epicreact.dev">EpicReact.Dev</a>. You would learn a lot more when you actually go through the <code>EpicReact.Dev</code> video explanations and workshop material yourself. The workshop material is also self-paced and open source. So, if you want to do the workshop yourself, you can go to <a target="_blank" href="https://github.com/kentcdodds/react-fundamentals">React Fundamentals Workshop Repo</a> and follow the instructions there.</p>
<p>If you haven't read the previous articles in this series, please go and read them first before you continue. I will add links to the articles below.</p>
<ol>
<li><a target="_blank" href="https://blog.bhanuteja.dev/epic-react-introduction">Introduction</a></li>
<li><a target="_blank" href="https://blog.bhanuteja.dev/epic-react-javascript-you-need-to-know-for-react">Javascript You Need To Know For React</a></li>
<li><a target="_blank" href="https://blog.bhanuteja.dev/epic-react-react-fundamentals-part-1">React Fundamentals - Intro to React Raw APIs</a></li>
<li><a target="_blank" href="https://blog.bhanuteja.dev/react-fundamentals-understanding-jsx">React Fundamentals - Understanding JSX</a></li>
</ol>
<p>In the previous article, you have learned different things about JSX like converting React.createElement() calls to JSX and vice-versa, interpolation in JSX, spreading props in JSX, etc. In this article, we will learn how to create custom components in JSX.</p>
<h3 id="heading-table-of-contents">Table of Contents</h3>
<ul>
<li><a class="post-section-overview" href="#creating-basic-reusable-function">Creating Basic Reusable Function</a></li>
<li><a class="post-section-overview" href="#using-reactcreateelement">Using React.createElement</a></li>
<li><a class="post-section-overview" href="#using-jsx">Using JSX</a></li>
<li><a class="post-section-overview" href="#validation-with-proptypes">Validation with PropTypes</a></li>
<li><a class="post-section-overview" href="#using-prop-types-package">Using prop-types Package</a></li>
<li><a class="post-section-overview" href="#react-fragments">React Fragments</a></li>
</ul>
<blockquote>
<p>The examples shown in this article are taken from <a target="_blank" href="https://kentcdodds.com">Kent C. Dodds</a>'s <a target="_blank" href="https://github.com/kentcdodds/react-fundamentals">React Fundamentals</a> workshop repo.</p>
</blockquote>
<h3 id="heading-creating-basic-reusable-function">Creating Basic Reusable Function</h3>
<p>Consider the following JSX markup.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"container"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"message"</span>&gt;</span>Hello World<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"message"</span>&gt;</span>GoodBye World<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>Now, our goal is to avoid the duplication <code>&lt;div className="message"&gt;...&lt;/div&gt;</code>.</p>
<p>Like we normally would do in vanilla javascript, let's create a reusable function that takes the text as an argument and returns the JSX that we need.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">message</span>(<span class="hljs-params">text</span>) </span>{
    <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"message"</span>&gt;</span>{text}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
}
</code></pre>
<p>Now we can write our JSX markup in the following manner.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"container"</span>&gt;</span>
    {message("Hello World")}
    {message("GoodBye World")}
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>Let's refactor this a bit, instead of accepting the string value as an argument, let's pass an object that has a <code>children</code> key in it.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">message</span>(<span class="hljs-params">props</span>) </span>{
    <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"message"</span>&gt;</span>{props.children}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
}
</code></pre>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"container"</span>&gt;</span>
    {message({children: "Hello World"})}
    {message({children: "GoodBye World"})}
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>We can even go a step further and destructure the children prop.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">message</span>(<span class="hljs-params">{children}</span>) </span>{
    <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"message"</span>&gt;</span>{children}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
}
</code></pre>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"container"</span>&gt;</span>
    {message({children: "Hello World"})}
    {message({children: "GoodBye World"})}
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<h3 id="heading-using-reactcreateelement">Using React.createElement</h3>
<p>Previously we have seen that the first argument of the <code>React.createElement()</code> is the type of tag that we want to render.</p>
<p>For example, <code>React.createElement('div', {}, 'Hello World')</code> will render <code>&lt;div&gt;Hello World&lt;/div&gt;</code>.</p>
<p>But, the first argument of the <code>React.createElement()</code> will also accept a function as its arguments that generate something renderable like JSX, an expression like string, number, etc. </p>
<p>So, let's refactor the above code and use <code>React.createElement()</code></p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">message</span>(<span class="hljs-params">{children}</span>) </span>{
    <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"message"</span>&gt;</span>{children}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
}
</code></pre>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"container"</span>&gt;</span>
    {React.createElement(message, {children: "Hello World"})}
    {React.createElement(message, {children: "GoodBye World"})}
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<h3 id="heading-using-jsx">Using JSX</h3>
<p>In the previous article, we have seen how to convert <code>React.createElement()</code> calls to JSX.</p>
<p>For example, JSX for <code>{React.createElement("div", {children: "Hello World"})}</code> is <code>&lt;div&gt;Hello World&lt;/div&gt;</code></p>
<p>Let's try to use the similar approach to convert <code>{React.createElement(message, {children: "Hello World"})}</code> to JSX.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">message</span>&gt;</span>Hello World<span class="hljs-tag">&lt;/<span class="hljs-name">message</span>&gt;</span>
</code></pre>
<p>If we follow the same approach, we would end up with the above JSX markup.</p>
<p>As per our knowledge until now, the above code should work as intended. But it will not. It is because of how babel compiles JSX to React.createElement().</p>
<p>The above JSX will be compiled to <code>React.createElement("message", {children: "Hello World"})</code> instead of <code>React.createElement(message, {children: "Hello World"})</code>.  Notice the difference. In the first case, the argument is the string <code>"message"</code> whereas in the second case, the argument is the reference to the <code>message</code> function. </p>
<p>The way we can achieve this is very simple. We simply have to make the first letter of the name of the function as uppercase.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Message</span>(<span class="hljs-params">{children}</span>) </span>{
    <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"message"</span>&gt;</span>{children}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
}
</code></pre>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"container"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">Message</span>&gt;</span>Hello World<span class="hljs-tag">&lt;/<span class="hljs-name">Message</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">Message</span>&gt;</span>GoodBye World<span class="hljs-tag">&lt;/<span class="hljs-name">Message</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>Now, this <code>&lt;Message&gt;Hello World&lt;/Message&gt;</code> will be compiled to <code>React.createElement(Message, {children: "Hello World"})</code> which is exactly what we need.</p>
<p>Check the below examples to see how Babel compiles each of the JSX formats.</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>JSX</td><td>React.createElement()</td></tr>
</thead>
<tbody>
<tr>
<td><code>&lt;Capitalized /&gt;</code></td><td><code>React.createElement(Capitalized)</code></td></tr>
<tr>
<td><code>&lt;property.access /&gt;</code></td><td><code>React.createElement(property.access)</code></td></tr>
<tr>
<td><code>&lt;Property.Access /&gt;</code></td><td><code>React.createElement(Property.Access)</code></td></tr>
<tr>
<td><code>&lt;Property['Access'] /&gt;</code></td><td><code>SyntaxError</code></td></tr>
<tr>
<td><code>&lt;lowercase /&gt;</code></td><td><code>React.createElement('lowercase')</code></td></tr>
<tr>
<td><code>&lt;kebab-case /&gt;</code></td><td><code>React.createElement('kebab-case')</code></td></tr>
<tr>
<td><code>&lt;Upper-Kebab-Case /&gt;</code></td><td><code>React.createElement('Upper-Kebab-Case')</code></td></tr>
<tr>
<td><code>&lt;Upper_Snake_Case /&gt;</code></td><td><code>React.createElement(Upper_Snake_Case)</code></td></tr>
<tr>
<td><code>&lt;lower_snake_case /&gt;</code></td><td><code>React.createElement('lower_snake_case')</code></td></tr>
</tbody>
</table>
</div><h3 id="heading-validation-with-proptypes">Validation with PropTypes</h3>
<p>Consider the following Message component.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Message</span>(<span class="hljs-params">{name}</span>) </span>{
    <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'message'</span>&gt;</span>Hi, your name is {name}.<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
}
</code></pre>
<p>Let's use this component in the following way.</p>
<pre><code>&lt;Message name=<span class="hljs-string">"foo"</span> /&gt;
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Message</span> /&gt;</span></span>
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Message</span> <span class="hljs-attr">name</span>=<span class="hljs-string">{2}</span> /&gt;</span></span>
</code></pre><p>This produces</p>
<pre><code><span class="hljs-comment">// OK</span>
Hi, your name is foo.

<span class="hljs-comment">// Should ideally throw an error</span>
Hi, your name is .

<span class="hljs-comment">// Should ideally throw an error</span>
Hi, your name is <span class="hljs-number">2.</span>
</code></pre><p>So, If we pass a number as a name prop or if we don't pass any prop, even then the text is rendered, but ideally, it should throw an error because <code>Hi, your name is .</code> doesn't make sense.</p>
<p>Luckily, React gives us a way to achieve this using PropTypes.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> PropTypes = {
    string(props, propName, componentName) {
        <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> props[propName] !== <span class="hljs-string">'string'</span>) {
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">`In component <span class="hljs-subst">${componentName}</span>, <span class="hljs-subst">${propName}</span> needs to be a string, but it was of type <span class="hljs-subst">${<span class="hljs-keyword">typeof</span> props[propName]}</span>`</span>)
        }
    },
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Message</span>(<span class="hljs-params">{name}</span>) </span>{
    <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'message'</span>&gt;</span>Hi, your name is {name}.<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
}

<span class="hljs-comment">// Component accepts an object as its `propTypes`. </span>
<span class="hljs-comment">// Each key in that object is the name of each prop. </span>
<span class="hljs-comment">// Each value is a function that takes (props, propName, componentName) </span>
<span class="hljs-comment">//      as its arguments and returns an error if validation fails.</span>
Message.propTypes = {
    <span class="hljs-attr">name</span>: PropTypes.string,
}
</code></pre>
<p>Now, whenever you try to pass anything other than a string to <code>name</code> prop, it will throw an error.</p>
<p><strong>Note:</strong></p>
<ul>
<li>PropTypes will be disabled by React in production environments for performance reasons.</li>
</ul>
<h3 id="heading-using-prop-types-package">Using <code>prop-types</code> Package</h3>
<p>Since cases like the above are so common, React team created a package called <code>prop-types</code> which will work in a similar manner. For example, if we want the <code>name</code> prop to be required and also a string, we can do so with the <code>prop-types</code> package in the following manner.</p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Message</span>(<span class="hljs-params">{name}</span>) </span>{
    <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'message'</span>&gt;</span>Hi, your name is {name}.<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
}

Message.propTypes = {
    <span class="hljs-attr">name</span>: PropTypes.isRequired.string,
}
</code></pre><p>Check out <a target="_blank" href="https://github.com/facebook/prop-types">prop-types</a> repo for more details.</p>
<h3 id="heading-react-fragments">React Fragments</h3>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">'root'</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>Let's consider the following use case.
You have to add <code>&lt;span&gt;Hello&lt;/span&gt;</code> and <code>&lt;span&gt;World&lt;/span&gt;</code> to the <code>rootElement</code> using React.</p>
<p>In the end, the markup should look like</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">'root'</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>Hello<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>World<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>Let's see if we can do this.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> rootElement = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'root'</span>)

<span class="hljs-keyword">const</span> elementOne = React.createElement(<span class="hljs-string">'span'</span>, <span class="hljs-literal">null</span>, <span class="hljs-string">'Hello'</span>)
<span class="hljs-keyword">const</span> elementTwo = React.createElement(<span class="hljs-string">'span'</span>, <span class="hljs-literal">null</span>, <span class="hljs-string">'World'</span>)

ReactDOM.render(?????, rootElement)
</code></pre>
<p>Now, what should be in the place of <code>?????</code> in the last line. It can neither be <code>elementOne</code> nor <code>elementTwo</code>, because we want both of them to be rendered (not one). But <code>ReactDOM.render()</code> takes only one react element as an argument and then appends it to rootElement.</p>
<p>One way to achieve this is if we can wrap both of the elements in a new element.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> rootElement = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'root'</span>)

<span class="hljs-keyword">const</span> elementOne = React.createElement(<span class="hljs-string">'span'</span>, <span class="hljs-literal">null</span>, <span class="hljs-string">'Hello'</span>)
<span class="hljs-keyword">const</span> elementTwo = React.createElement(<span class="hljs-string">'span'</span>, <span class="hljs-literal">null</span>, <span class="hljs-string">'World'</span>)

<span class="hljs-keyword">const</span> combinedElement = React.createElement(<span class="hljs-string">'div'</span>, <span class="hljs-literal">null</span>, elementOne, elementTwo)

ReactDOM.render(combinedElement, rootElement)
</code></pre>
<p>The above code may look fine, but it produces different HTML than what we needed.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">'root'</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>Hello<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>World<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>This is the reason why you can't do something like the following in your code.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Message</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">return</span> (
        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>Hello<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>
        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>World<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>
    )
}
</code></pre>
<p>Because there is no way for babel to be able to convert this to a single React.createElement()</p>
<p>React Fragments are introduced in <code>React v16.2.0</code> exactly to solve this problem. Now you can return multiple elements by just wrapping them around with <code>React.Fragment</code>.</p>
<p>For example,</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Message</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">return</span> (
        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">React.Fragment</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>Hello<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>World<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">React.Fragment</span>&gt;</span></span>
    )
}
</code></pre>
<p>React will ignore this <code>React.Fragment</code> when rendering.</p>
<p>So the previous problem can be solved now in the following way.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> elementOne = React.createElement(<span class="hljs-string">'span'</span>, <span class="hljs-literal">null</span>, <span class="hljs-string">'Hello'</span>)
<span class="hljs-keyword">const</span> elementTwo = React.createElement(<span class="hljs-string">'span'</span>, <span class="hljs-literal">null</span>, <span class="hljs-string">'World'</span>)

<span class="hljs-keyword">const</span> combinedElement = React.createElement(React.Fragment, <span class="hljs-literal">null</span>, elementOne, elementTwo)

ReactDOM.render(combinedElement, rootElement)
</code></pre>
<p><strong>Note:</strong></p>
<ul>
<li>There is a shorthand representation for <code>React.Fragment</code>. <ul>
<li>Instead of writing <code>&lt;React.Fragment&gt;{childrent}&lt;/React.Fragment&gt;</code>, you can write something like <code>&lt;&gt;{children}&lt;/&gt;</code>. </li>
<li>Both yield absolutely the same result.</li>
</ul>
</li>
</ul>
<h3 id="heading-what-did-you-learn">What did you learn?</h3>
<p>In this article, you learned about </p>
<ul>
<li>Creating custom components.</li>
<li>The reason why the first letter of the custom component needs to be upper case.</li>
<li>Validating the props of the custom component using <code>propTypes</code></li>
<li>Using <code>prop-types</code> package to validate props</li>
<li>Rendering multiple elements at the same level using <code>React.Fragment</code></li>
</ul>
<h3 id="heading-whats-next">What's Next</h3>
<p>In the next article, we will see how to style React elements. We will also see how to handle basic forms in React.</p>
<h4 id="heading-until-next-time">Until Next Time 👋</h4>
<hr />
<p>If this was helpful to you, Please <strong>Like</strong> and <strong>Share</strong> so that it reaches others as well. To get email notifications on my latest articles, please subscribe to <a target="_blank" href="https://blog.bhanuteja.dev">my blog</a> by hitting the <strong>Subscribe</strong> button at the top of the page. You can also follow me on Twitter <a target="_blank" href="https://twitter.com/pbteja1998">@pbteja1998</a>.</p>
<p><strong>Links and References:</strong></p>
<ul>
<li><a target="_blank" href="https://epicreact.dev">EpicReact.Dev</a> - Series of workshops with video explanations by <a target="_blank" href="https://kentcdodds.com">Kent C. Dodds</a> based on which this blog post series is being written.</li>
<li><a target="_blank" href="https://github.com/kentcdodds/react-fundamentals">React Fundamentals Workshop Repo</a> - Github Repo if you want to do the self-paced workshop yourself.</li>
<li><a target="_blank" href="http://react-fundamentals.netlify.app">React Fundamentals Workshop Demo</a> - Production application of the above workshop repo.</li>
</ul>
<hr />
<p>You might also like the following articles that I wrote:</p>
<ul>
<li><a target="_blank" href="https://blog.bhanuteja.dev/i-revamped-github-jobs-website-using-design-from-frontend-mentor">I Revamped GitHub Jobs Website Using Design From Frontend Mentor</a></li>
<li><a target="_blank" href="https://blog.bhanuteja.dev/react-fundamentals-understanding-jsx">React Fundamentals: Understanding JSX</a></li>
<li><a target="_blank" href="https://blog.bhanuteja.dev/epic-react-react-fundamentals-part-1">React Fundamentals: Intro to React Raw APIs</a></li>
<li><a target="_blank" href="https://blog.bhanuteja.dev/how-i-gave-a-modern-look-for-hackernews-feed">How I Gave A Modern Look For HackerNews Feed</a></li>
<li><a target="_blank" href="https://blog.bhanuteja.dev/epic-react-javascript-you-need-to-know-for-react">Javascript You Need To Know For React</a></li>
<li><a target="_blank" href="https://blog.bhanuteja.dev/epic-react-introduction">My Review of Kent C. Dodds's EpicReact.Dev: Introduction</a></li>
<li><a target="_blank" href="https://blog.bhanuteja.dev/react-fundamentals">React Fundamentals</a></li>
<li><a target="_blank" href="https://blog.bhanuteja.dev/create-your-own-super-simple-url-shortener">Create Your Own Super Simple URL Shortener</a></li>
<li><a target="_blank" href="https://blog.bhanuteja.dev/why-you-should-start-using-hsl-color-format">Why you should start using HSL color format</a></li>
<li><a target="_blank" href="https://blog.bhanuteja.dev/embed-youtube-videos-into-your-markdown-editor">Embed Youtube Videos into Your Markdown Editor</a></li>
<li><a target="_blank" href="https://blog.bhanuteja.dev/babel-plugin-to-remove-console-logs-in-production">Babel Plugin To Remove Console Logs In Production</a></li>
<li><a target="_blank" href="https://blog.bhanuteja.dev/create-custom-markdown-parser">Create Custom Markdown Parser</a></li>
<li><a target="_blank" href="https://blog.bhanuteja.dev/add-typescript-to-your-nextjs-project">Add Typescript to your Next.js project</a></li>
</ul>
<hr />
<div class="hn-embed-widget" id="newsletter"></div>]]></content:encoded></item><item><title><![CDATA[Revamped GitHub Jobs Website Using Design From Frontend Mentor]]></title><description><![CDATA[Hello World 👋
Welcome to another project showcase. This time, I will be showing the GitHub Jobs project that I did very recently. The design is from FrontendMentor.Io. The website is available at jobs.bhanuteja.dev. 
Let's start with some visuals of...]]></description><link>https://blog.bhanuteja.dev/i-revamped-github-jobs-website-using-design-from-frontend-mentor</link><guid isPermaLink="true">https://blog.bhanuteja.dev/i-revamped-github-jobs-website-using-design-from-frontend-mentor</guid><category><![CDATA[React]]></category><category><![CDATA[Tailwind CSS]]></category><category><![CDATA[ShowHashnode]]></category><category><![CDATA[2Articles1Week]]></category><category><![CDATA[JavaScript]]></category><dc:creator><![CDATA[Bhanu Teja Pachipulusu]]></dc:creator><pubDate>Sat, 17 Oct 2020 06:22:52 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1602879230572/AtRA1AiJx.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-hello-world">Hello World 👋</h2>
<p>Welcome to another project showcase. This time, I will be showing the GitHub Jobs project that I did very recently. The design is from <a target="_blank" href="https://frontendmentor.io">FrontendMentor.Io</a>. The website is available at <a target="_blank" href="https://jobs.bhanuteja.dev">jobs.bhanuteja.dev</a>. </p>
<p>Let's start with some visuals of how the website looks like.</p>
<h3 id="heading-loading-home-page">Loading Home Page</h3>
<h4 id="heading-dark-mode">Dark Mode</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602873265135/MUxaADqq-.png" alt="Loading Home Page - Dark Mode" /></p>
<h4 id="heading-light-mode">Light Mode</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602873271367/LbfOD_4Gc.png" alt="Loading Home Page - Light Mode" /></p>
<h3 id="heading-home-page">Home Page</h3>
<h4 id="heading-desktop-dark-mode">Desktop (Dark Mode)</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602873396082/vTgrrs8m9.png" alt="Home Page - Dark Mode" /></p>
<h4 id="heading-desktop-light-mode">Desktop (Light Mode)</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602873404790/nvP5BMxO-.png" alt="Home Page - Light Mode" /></p>
<h4 id="heading-tabipad-dark-mode">Tab/iPad (Dark Mode)</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602873953189/LHgnDyQ0g.png" alt="tab-dark.png" /></p>
<h4 id="heading-tabipad-light-mode">Tab/iPad (Light Mode)</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602874022009/shdOPkvyG.png" alt="tab-light.png" /></p>
<h4 id="heading-mobile-dark-mode">Mobile (Dark Mode)</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602874106777/iLiRmKoP3.png" alt="mobile-dark.png" /></p>
<h4 id="heading-mobile-light-mode">Mobile (Light Mode)</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602874124192/9r5dShQt6.png" alt="mobile-light.png" /></p>
<h3 id="heading-job-details-page">Job Details Page</h3>
<h4 id="heading-desktop-dark-mode">Desktop (Dark Mode)</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602876131894/zoGTwdC0e.png" alt="desktop-dark-job-details.png" /></p>
<h4 id="heading-desktop-light-mode">Desktop (Light Mode)</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602876146307/3lYvtC0AB.png" alt="desktop-job-details.png" /></p>
<h3 id="heading-mobile-filters">Mobile - Filters</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602875782094/cfO7KCi1e.gif?auto=compress" alt="Mobile - Filters" /></p>
<h3 id="heading-features">Features:</h3>
<ul>
<li>Dark Mode Support</li>
<li>Filters - text, location, full time.</li>
<li>Infinite Scrolling with Skeleton Loading</li>
<li>Responsive</li>
<li>Job Details Page</li>
</ul>
<p>This website is made with <a target="_blank" href="https://nextjs.org/">Next.js</a>, <a target="_blank" href="https://tailwindcss.com/">Tailwind CSS</a> and <a target="_blank" href="http://react-query.tanstack.com/">React Query</a></p>
<h3 id="heading-dark-mode">Dark Mode</h3>
<ul>
<li>I used <a target="_blank" href="https://tailwindcss.com">Tailwind CSS</a>'s inbuilt dark mode support to achieve this. </li>
<li>Check <a target="_blank" href="https://github.com/tailwindlabs/tailwindcss/pull/2279">this pr</a> for more details.</li>
<li>I then stored the user's dark mode preference in local storage. So, if the user sets the dark mode, and closes the browser. When he reopens it again, the website will be loaded in dark mode.</li>
</ul>
<h3 id="heading-github-api">GitHub API</h3>
<ul>
<li>Recently GitHub added a strict CORS policy and we will not be able to request the resources from GitHub using a client. </li>
<li>So, I had to use a CORS proxy to fetch the data from GitHub Jobs API. </li>
<li>I tried every one of the proxies mentioned in this <a target="_blank" href="https://nordicapis.com/10-free-to-use-cors-proxies/">blog post</a>. But, the only one that worked for me then was <a target="_blank" href="https://allorigins.win/">allOrigins</a>.</li>
</ul>
<h3 id="heading-filters">Filters</h3>
<p>Implementing this one was straight-forward. GitHub API itself supports the option to pass the filters as params, it then returns the filtered data.</p>
<h3 id="heading-infinite-scrolling-with-skeleton-loading">Infinite Scrolling with Skeleton Loading</h3>
<ul>
<li>Used React Query's <code>useMutation</code> hook to do this. </li>
<li>Every time the user presses the<code>Load More</code> button, a mutation is triggered to fetch the jobs from the next page.</li>
<li>I then combined the job data fetched from the next page with the current job data to show all the jobs up until then.</li>
</ul>
<p>I used <a target="_blank" href="https://tailwindcss.com/docs/animation">Tailwind CSS animations utilities</a> to show the loading skeleton.</p>
<p>I made the source code for this project open source. You can take a look at it.</p>
<p>Tell me in the comments if you like me to dig deep into any of the things that I discussed in this article. I will be happy to do so.</p>
<p>Here is the repo 👉
<a target="_blank" href="https://github.com/pbteja1998/github-jobs-api">pbteja1998/github-jobs-api</a></p>
<h3 id="heading-whats-next">What's Next</h3>
<p>The next article will be part of the <a target="_blank" href="https://hashnode.com/series/epic-react-ckfv4gidh08efu9s1408v8tgp">My Review of Kent C. Dodds's EpicReact.Dev</a> series. It will be the fifth article in the series. To know more, go to the link below.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://hashnode.com/series/epic-react-ckfv4gidh08efu9s1408v8tgp">https://hashnode.com/series/epic-react-ckfv4gidh08efu9s1408v8tgp</a></div>
<h4 id="heading-until-next-time">Until Next Time 👋</h4>
<hr />
<p>You might also like the following articles that I wrote:</p>
<ul>
<li><a target="_blank" href="https://blog.bhanuteja.dev/react-fundamentals-understanding-jsx">React Fundamentals: Understanding JSX</a></li>
<li><a target="_blank" href="https://blog.bhanuteja.dev/epic-react-react-fundamentals-part-1">Introduction to React Raw APIs</a></li>
<li><a target="_blank" href="https://blog.bhanuteja.dev/how-i-gave-a-modern-look-for-hackernews-feed">How I Gave A Modern Look For HackerNews Feed</a></li>
<li><a target="_blank" href="https://blog.bhanuteja.dev/epic-react-javascript-you-need-to-know-for-react">Javascript You Need To Know For React</a></li>
<li><a target="_blank" href="https://blog.bhanuteja.dev/create-your-own-super-simple-url-shortener">Create Your Own Super Simple URL Shortener</a></li>
<li><a target="_blank" href="https://blog.bhanuteja.dev/why-you-should-start-using-hsl-color-format">Why you should start using HSL color format</a></li>
<li><a target="_blank" href="https://blog.bhanuteja.dev/embed-youtube-videos-into-your-markdown-editor">Embed Youtube Videos into Your Markdown Editor</a></li>
<li><a target="_blank" href="https://blog.bhanuteja.dev/babel-plugin-to-remove-console-logs-in-production">Babel Plugin To Remove Console Logs In Production</a></li>
<li><a target="_blank" href="https://blog.bhanuteja.dev/create-custom-markdown-parser">Create Custom Markdown Parser</a></li>
</ul>
<hr />
<p>If this was helpful to you, Please <strong>Like</strong> and <strong>Share</strong> so that it reaches others as well. To get email notifications on my latest articles, please subscribe to <a target="_blank" href="https://blog.bhanuteja.dev">my blog</a> by hitting the <strong>Subscribe</strong> button at the top of the page. You can also follow me on Twitter <a target="_blank" href="https://twitter.com/pbteja1998">@pbteja1998</a>.</p>
<div class="hn-embed-widget" id="newsletter"></div>]]></content:encoded></item><item><title><![CDATA[React Fundamentals: Understanding JSX]]></title><description><![CDATA[Hello World 👋
Welcome to the 4th article of the series My Review of Kent C. Dodds's EpicReact.Dev. Please note that this blog post series is just my review of the EpicReact.Dev workshop material. I am just trying to explain what I learned and unders...]]></description><link>https://blog.bhanuteja.dev/react-fundamentals-understanding-jsx</link><guid isPermaLink="true">https://blog.bhanuteja.dev/react-fundamentals-understanding-jsx</guid><category><![CDATA[React]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[JSX]]></category><category><![CDATA[2Articles1Week]]></category><dc:creator><![CDATA[Bhanu Teja Pachipulusu]]></dc:creator><pubDate>Thu, 15 Oct 2020 07:12:02 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1602547882873/uuGVzAKFO.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-hello-world">Hello World 👋</h2>
<p>Welcome to the 4th article of the series <a target="_blank" href="https://hashnode.com/series/my-review-of-kent-c-doddss-epicreactdev-ckfv4gidh08efu9s1408v8tgp">My Review of Kent C. Dodds's EpicReact.Dev</a>. Please note that this blog post series is just my review of the <a target="_blank" href="https://epicreact.dev">EpicReact.Dev</a> workshop material. I am just trying to explain what I learned and understood in my own way. This is not in any way officially associated with <a target="_blank" href="https://epicreact.dev">Kent C. Dodds</a> or <a target="_blank" href="https://epicreact.dev">EpicReact.Dev</a>. You would learn a lot more when you actually go through the <code>EpicReact.Dev</code> video explanations and workshop material yourself. The workshop material is also self-paced and open source. So, if you want to do the workshop yourself, you can go to <a target="_blank" href="https://github.com/kentcdodds/react-fundamentals">React Fundamentals Workshop Repo</a> and follow the instructions there.</p>
<p>If you haven't read the previous articles in this series, please go and read them first before you continue. I will add links to the articles below.</p>
<ol>
<li><a target="_blank" href="https://blog.bhanuteja.dev/epic-react-introduction">Introduction</a></li>
<li><a target="_blank" href="https://blog.bhanuteja.dev/epic-react-javascript-you-need-to-know-for-react">Javascript You Need To Know For React</a></li>
<li><a target="_blank" href="https://blog.bhanuteja.dev/epic-react-react-fundamentals-part-1">React Fundamentals - Intro to React Raw APIs</a></li>
</ol>
<p>In the previous article, you have learnt about React Raw APIs specifically <code>React.createElement()</code> and <code>ReactDOM.render()</code>. In this article, you will learn all about JSX.</p>
<h3 id="heading-table-of-contents">Table of Contents</h3>
<ul>
<li><a class="post-section-overview" href="#using-jsx">Using JSX</a><ul>
<li><a class="post-section-overview" href="#writing-markup-with-jsx">Writing Markup With JSX</a></li>
<li><a class="post-section-overview" href="#adding-props-to-jsx">Adding Props To JSX</a></li>
<li><a class="post-section-overview" href="#interpolation-in-jsx">Interpolation In JSX</a></li>
<li><a class="post-section-overview" href="#spreading-props">Spreading Props</a></li>
</ul>
</li>
</ul>
<h3 id="heading-using-jsx">Using JSX</h3>
<h4 id="heading-writing-markup-with-jsx">Writing Markup With JSX</h4>
<p>JSX is the HTML-like syntactic sugar that finally gets compiled into couple of <code>React.createElement()</code> function calls.</p>
<p>Let's see a <code>Hello World</code> example of how JSX looks like.</p>
<pre><code class="lang-js"><span class="hljs-comment">// JSX</span>
<span class="hljs-keyword">const</span> element = <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Hello World<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>

<span class="hljs-comment">// Above JSX compiles into following</span>
<span class="hljs-keyword">const</span> element = React.createElement(<span class="hljs-string">"div"</span>, <span class="hljs-literal">null</span>, <span class="hljs-string">"Hello World"</span>)
</code></pre>
<p>Since JSX is not a valid javascript code, you have to add a compiler that compiles this code and converts it into a normal javascript code(in this case <code>React.createElement()</code> calls).</p>
<p>We can use <a target="_blank" href="https://babeljs.io/">Babel</a> for this purpose. Babel converts our JSX code into javascript code in the browser itself. </p>
<p><strong>Note:</strong></p>
<ul>
<li>In actual production-level applications, we would not be following this method of using babel that we see here. We will see more about this in future articles.</li>
<li>While adding JSX code, Babel needs a way to find out which part of the code it needs to compile into JS. You also need to have a way to tell the browser to not evaluate any JSX code since if it does, it throws errors because JSX code is not a valid JS code. So, you need to wrap the JSX code between <code>&lt;script type="text/babel"&gt;</code> and <code>&lt;/script&gt;</code>. Any code between the script tag with type <code>text/babel</code> will be compiled by Babel and not evaluated by the browser.</li>
<li>You can also play around with <a target="_blank" href="https://babeljs.io/repl#?builtIns=App&amp;code_lz=MYewdgzgLgBArgSxgXhgHgCYIG4D40QAOAhmLgBICmANtSGgPRGm7rNkDqIATtRo-3wMseAFBA&amp;presets=react&amp;prettier=true">Babel REPL</a> to see exactly how JSX is compiled to javascript.</li>
</ul>
<p>You can add Babel to your application through CDN.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://unpkg.com/@babel/standalone@7.9.3/babel.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<p>In the previous article, we tried to create nesting elements markup using <code>React.createElement</code>.</p>
<pre><code class="lang-js"><span class="hljs-comment">// This is the code that we used to create that markup.</span>
<span class="hljs-keyword">const</span> helloElement = React.createElement(<span class="hljs-string">"span"</span>, {<span class="hljs-attr">children</span>: <span class="hljs-string">"Hello"</span>})
<span class="hljs-keyword">const</span> worldElement = React.createElement(<span class="hljs-string">"span"</span>, {<span class="hljs-attr">children</span>: <span class="hljs-string">"World"</span>})
<span class="hljs-keyword">const</span> helloWorldElement = React.createElement(<span class="hljs-string">"div"</span>, {
    <span class="hljs-attr">children</span>: [helloElement, worldElement]
})

<span class="hljs-comment">// Let's try to create the same helloWorldElement using JSX</span>
<span class="hljs-keyword">const</span> helloWorldElement = <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>Hello<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>World<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>

<span class="hljs-comment">// You can even split the JSX into multiple lines for more readability.</span>
<span class="hljs-comment">// It is recommended to add parenthesis around JSX when splitting them into multiple lines</span>
<span class="hljs-keyword">const</span> helloWorldElement = (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>Hello<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>World<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
)
</code></pre>
<p>From the above example, we can see that JSX is more intuitive to work with than directly using <code>React.createElement</code>.</p>
<h4 id="heading-adding-props-to-jsx">Adding Props to JSX</h4>
<p>consider the below element created using <code>React.createElement</code> API</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> element = React.createElement(<span class="hljs-string">"div"</span>, {<span class="hljs-attr">className</span>: <span class="hljs-string">"container"</span>}, <span class="hljs-string">"Hello World"</span>)
</code></pre>
<p>Let's try to convert this to JSX code. Here you have a prop called <code>className</code>. The way to add the React props in JSX is to add them as attributes.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> element = <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"container"</span>&gt;</span>Hello World<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
</code></pre>
<p>Let's see an example with multiple props.</p>
<pre><code class="lang-js"><span class="hljs-comment">// js</span>
<span class="hljs-keyword">const</span> element = React.createElement(<span class="hljs-string">"div"</span>, {<span class="hljs-attr">className</span>: <span class="hljs-string">"container"</span>, <span class="hljs-attr">id</span>: <span class="hljs-string">"hello"</span>}, <span class="hljs-string">"Hello World"</span>)

<span class="hljs-comment">// jsx</span>
<span class="hljs-keyword">const</span> element = <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"container"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"hello"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
</code></pre>
<p><strong>Note:</strong></p>
<ul>
<li>Notice that in JSX we write <code>className</code> instead of <code>class</code> like in HTML. It's because in the corresponding <code>React.createElement</code> API, the name of the prop for class is <code>className</code>. We are directly adding props in <code>React.createElement()</code> to JSX as attributes. </li>
</ul>
<h4 id="heading-interpolation-in-jsx">Interpolation in JSX</h4>
<p>Let's see the English meaning of interpolation first. A quick google search gave me <code>The insertion of something of a different nature into something else</code>.</p>
<p>You already saw interpolation in one of the javascript concepts that we know - Template Literals. In template literals, we are inserting javascript expressions inside strings.</p>
<p>Interpolation in JSX is inserting javascript expressions into JSX. Let's see a basic example to know what I mean.</p>
<pre><code class="lang-js"><span class="hljs-comment">// Without Interpolation</span>
<span class="hljs-keyword">const</span> element = <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"container"</span>&gt;</span>Hello World<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>

<span class="hljs-comment">// With JSX Interpolation</span>
<span class="hljs-keyword">const</span> nameOfClass = <span class="hljs-string">"container"</span>
<span class="hljs-keyword">const</span> content = <span class="hljs-string">"Hello World"</span>
<span class="hljs-keyword">const</span> element = <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">{nameOfClass}</span>&gt;</span>{content}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
</code></pre>
<p>You can see in the example above we are interpolating <code>nameOfClass</code> and <code>content</code> into JSX. The way you do that is by wrapping them around inside curly braces.</p>
<p>Let's also look at how Babel compiles this down to.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> element = React.createElement(<span class="hljs-string">"div"</span>, {<span class="hljs-attr">className</span>: nameOfClass}, content)
</code></pre>
<p>So, basically, whatever you write inside those curly braces, the babel directly assigns them to the corresponding prop without changing anything.</p>
<p>You are not just limited to interpolating strings, you can interpolate any type of javascript expression into JSX. Let's see some examples</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> element = <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>{count + 1} Blogs<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>

<span class="hljs-keyword">const</span> element = <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">{</span>`<span class="hljs-attr">blog-</span>${<span class="hljs-attr">blogId</span>}`}&gt;</span>This is a blog post with id {blogId}.<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>

<span class="hljs-keyword">const</span> element = (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">{isMobile</span> ? "<span class="hljs-attr">mobile</span>" <span class="hljs-attr">:</span> "<span class="hljs-attr">desktop</span>"}&gt;</span>
        This is {isMobile ? "Mobile" : "Desktop"} view
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
)

<span class="hljs-keyword">const</span> element = (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>{isDesktop &amp;&amp; (<span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>Hello<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>)} World<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
)
</code></pre>
<p><strong>Notes:</strong></p>
<ul>
<li>Ternary operator is also an expression, hence we are able to interpolate that in JSX</li>
<li>Conditional AND and Conditional OR operators are also expressions and can be interpolated in JSX.</li>
<li>Statements cannot be interpolated in JSX.</li>
</ul>
<p>Let's see why statements cannot be interpolated in JSX.</p>
<p>Consider the following JSX where we interpolated an if statement</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> element = <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">{if(condition)</span> <span class="hljs-attr">func</span>() }&gt;</span>Hello<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>

<span class="hljs-comment">// let's try to convert this to React.createElement()</span>
<span class="hljs-keyword">const</span> element = React.createElement(<span class="hljs-string">"div"</span>, {<span class="hljs-attr">className</span>: <span class="hljs-keyword">if</span>(condition) func()}, <span class="hljs-string">"Hello"</span>)
<span class="hljs-comment">// The above statement is not a valid javascript, a statement cannot be assigned to a variable.</span>
<span class="hljs-comment">// This is the reason why we cannot add statements inside interpolation.</span>
</code></pre>
<h4 id="heading-spreading-props">Spreading Props</h4>
<p>Consider the below example.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> props = {
    <span class="hljs-attr">id</span>: <span class="hljs-string">"hello"</span>,
    <span class="hljs-attr">className</span>: <span class="hljs-string">"container"</span>,
    <span class="hljs-attr">children</span>: <span class="hljs-string">"Hello World"</span>
}
<span class="hljs-keyword">const</span> element = React.createElement(<span class="hljs-string">"div"</span>, props)
<span class="hljs-comment">// This will render &lt;div id="hello" className="container"&gt;Hello World&lt;/div&gt;</span>

<span class="hljs-comment">// Let's slightly change how we write props.</span>
<span class="hljs-comment">// This will produce the same exact result as above</span>
<span class="hljs-keyword">const</span> element = React.createElement(<span class="hljs-string">"div"</span>, {...props})

<span class="hljs-comment">// Let's try to convert this to JSX</span>
<span class="hljs-comment">// Note that in JSX, we can use all the tags as self-closing tags.</span>
<span class="hljs-keyword">const</span> element = <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> {<span class="hljs-attr">...props</span>} /&gt;</span></span>
</code></pre>
<p>From the above example, we can see that the way to spread the props in JSX is to use <code>{...props}</code>.</p>
<p><strong>Notes:</strong></p>
<ul>
<li>In JSX, the attributes are camelCased. For example, the equivalent of HTML attribute <code>aria-label</code> in JSX is <code>ariaLabel</code> and equivalent of <code>onchange</code> is <code>onChange</code>. I will add a couple of links at the bottom to learn more about these changes.</li>
<li>In JSX, if you add an attribute, but do not assign any value to it, JSX treats it as a boolean attribute and assigns value <code>true</code> to it.<pre><code class="lang-js">  <span class="hljs-comment">// Both of these are same</span>
  <span class="hljs-keyword">const</span> element = <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">disabled</span>=<span class="hljs-string">{true}</span>&gt;</span>Button<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
  <span class="hljs-keyword">const</span> element = <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">disabled</span>&gt;</span>Button<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
</code></pre>
</li>
<li><p>When assigning props, the order is important. The attributes to the right will override the same attributes that are to the left.</p>
<pre><code class="lang-js">  <span class="hljs-keyword">const</span> element = <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"default"</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"primary"</span>&gt;</span>Hello World<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>

  <span class="hljs-comment">// when the above JSX is rendered, it will be converted to following HTML markup.</span>
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"primary"</span>&gt;</span>Hello World<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  <span class="hljs-comment">// The className attribute that is to the right will replace the className attribute that is to the left</span>
</code></pre>
</li>
</ul>
<h3 id="heading-whats-next">What's Next</h3>
<p>In this article, you learned about JSX, adding props to JSX, interpolation in JSX, spreading props in JSX, etc. In the next article, we will see how to create custom components. We will also see how to style the elements in React.</p>
<h4 id="heading-until-next-time">Until Next Time 👋</h4>
<hr />
<p>You might also like the following articles that I wrote:</p>
<ul>
<li><a target="_blank" href="https://blog.bhanuteja.dev/epic-react-react-fundamentals-part-1">Introduction to React Raw APIs</a></li>
<li><a target="_blank" href="https://blog.bhanuteja.dev/how-i-gave-a-modern-look-for-hackernews-feed">How I Gave A Modern Look For HackerNews Feed</a></li>
<li><a target="_blank" href="https://blog.bhanuteja.dev/epic-react-javascript-you-need-to-know-for-react">Javascript You Need To Know For React</a></li>
<li><a target="_blank" href="https://blog.bhanuteja.dev/epic-react-introduction">My Review of Kent C. Dodds's EpicReact.Dev: Introduction</a></li>
<li><a target="_blank" href="https://blog.bhanuteja.dev/react-fundamentals">React Fundamentals</a></li>
<li><a target="_blank" href="https://blog.bhanuteja.dev/create-your-own-super-simple-url-shortener">Create Your Own Super Simple URL Shortener</a></li>
<li><a target="_blank" href="https://blog.bhanuteja.dev/why-you-should-start-using-hsl-color-format">Why you should start using HSL color format</a></li>
<li><a target="_blank" href="https://blog.bhanuteja.dev/embed-youtube-videos-into-your-markdown-editor">Embed Youtube Videos into Your Markdown Editor</a></li>
<li><a target="_blank" href="https://blog.bhanuteja.dev/babel-plugin-to-remove-console-logs-in-production">Babel Plugin To Remove Console Logs In Production</a></li>
<li><a target="_blank" href="https://blog.bhanuteja.dev/create-custom-markdown-parser">Create Custom Markdown Parser</a></li>
<li><a target="_blank" href="https://blog.bhanuteja.dev/add-typescript-to-your-nextjs-project">Add Typescript to your Next.js project</a></li>
</ul>
<hr />
<p>If this was helpful to you, Please <strong>Like</strong> and <strong>Share</strong> so that it reaches others as well. To get email notifications on my latest articles, please subscribe to my blog by hitting the <strong>Subscribe</strong> button at the top of the page. You can also follow me on twitter <a target="_blank" href="https://twitter.com/pbteja1998">@pbteja1998</a>.</p>
<p><strong>Links and References:</strong></p>
<ul>
<li><a target="_blank" href="https://epicreact.dev">EpicReact.Dev</a> - Series of workshops with video explanations by <a target="_blank" href="https://kentcdodds.com">Kent C. Dodds</a> based on which this blog post series is being written.</li>
<li><a target="_blank" href="https://github.com/kentcdodds/react-fundamentals">React Fundamentals Workshop Repo</a> - Github Repo if you want to do the self-paced workshop yourself.</li>
<li><a target="_blank" href="http://react-fundamentals.netlify.app">React Fundamentals Workshop Demo</a> - Production application of the above workshop repo.</li>
<li><a target="_blank" href="https://reactjs.org/docs/introducing-jsx.html">Introducing JSX</a> - Official React Docs</li>
<li><a target="_blank" href="https://reactjs.org/docs/dom-elements.html">DOM Elements And Their Attributes</a> - Official React Docs</li>
</ul>
<div class="hn-embed-widget" id="newsletter"></div>]]></content:encoded></item><item><title><![CDATA[React Fundamentals: Intro to React Raw APIs]]></title><description><![CDATA[Hello World 👋
Welcome to the third article of the My Review of Kent C. Dodds's EpicReact.Dev Series which is based on the workshop material from EpicReact.Dev by Kent C. Dodds. If you haven't read the previous articles of the series yet, please go a...]]></description><link>https://blog.bhanuteja.dev/epic-react-react-fundamentals-part-1</link><guid isPermaLink="true">https://blog.bhanuteja.dev/epic-react-react-fundamentals-part-1</guid><category><![CDATA[React]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[2Articles1Week]]></category><dc:creator><![CDATA[Bhanu Teja Pachipulusu]]></dc:creator><pubDate>Mon, 12 Oct 2020 06:55:17 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1602517073891/uDJDlX2ec.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-hello-world">Hello World 👋</h2>
<p>Welcome to the third article of the <a target="_blank" href="https://hashnode.com/series/epic-react-ckfv4gidh08efu9s1408v8tgp">My Review of Kent C. Dodds's EpicReact.Dev Series</a> which is based on the workshop material from <a target="_blank" href="https://epicreact.dev">EpicReact.Dev</a> by <a target="_blank" href="https://kentcdodds.com">Kent C. Dodds</a>. If you haven't read the previous articles of the series yet, please go and read them before continuing through this article. </p>
<p>Here are the previous articles.</p>
<ol>
<li><a target="_blank" href="https://blog.bhanuteja.dev/epic-react-introduction">Epic React: Introduction</a></li>
<li><a target="_blank" href="https://blog.bhanuteja.dev/epic-react-javascript-you-need-to-know-for-react">Epic React: Javascript You Need To Know For React</a></li>
</ol>
<p>In this article, You are going to learn the very basics of React. We will just be working with basic HTML and javascript using React raw APIs. We will not even be using any JSX in this article(If you don't know what JSX is, don't worry, we will learn about it in the next article.) You will see why it is difficult to work with React raw APIs. Many people skip over these fundamentals before learning React, but it is important to know about these abstractions to understand some things in React which we will see in the next article.</p>
<p>We will follow the similar format of the workshop - meaning for every topic, we will first introduce what we are trying to achieve, then we will see how to achieve that.</p>
<h3 id="heading-table-of-contents">Table of Contents</h3>
<ul>
<li><a class="post-section-overview" href="#basic-js-hello-world">Basic JS "Hello World"</a><ul>
<li><a class="post-section-overview" href="#introduction">Introduction</a></li>
<li><a class="post-section-overview" href="#generate-dom-nodes">Generate DOM Nodes</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#intro-to-raw-react-apis">Intro to Raw React APIs</a><ul>
<li><a class="post-section-overview" href="#introduction-2">Introduction</a></li>
<li><a class="post-section-overview" href="#raw-react-apis">Raw React APIs</a></li>
<li><a class="post-section-overview" href="#nesting-elements">Nesting Elements</a></li>
</ul>
</li>
</ul>
<h3 id="heading-basic-js-hello-world">Basic JS "Hello World"</h3>
<h4 id="heading-introduction">Introduction</h4>
<p>Our goal is to render <code>Hello World</code> using basic javascript. </p>
<p>Our HTML currently has the following</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"root"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>We want our HTML to be:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"root"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container"</span>&gt;</span>Hello World<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<h4 id="heading-generate-dom-nodes">Generate DOM Nodes</h4>
<p>We can achieve the above result by making use of Javascript's <code>document</code> API.</p>
<pre><code class="lang-js"><span class="hljs-comment">// Fetches the element with id as `root` from DOM</span>
<span class="hljs-keyword">const</span> rootElement = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"root"</span>)

<span class="hljs-comment">// Creates an element with `div` tag</span>
<span class="hljs-keyword">const</span> helloWorldElement = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">"div"</span>)
helloWorldElement.textContent = <span class="hljs-string">"Hello World"</span>
helloWorldElement.className = <span class="hljs-string">"container"</span>

<span class="hljs-comment">// Appends the helloWorldElement to the rootElement</span>
rootElement.append(helloWorldElement)
</code></pre>
<p>Let's break down what we are doing here.</p>
<ol>
<li>Get the element with <code>id</code> as <code>root</code> from DOM.</li>
<li>Create a new DOM element and then set its properties.</li>
<li>Append the newly created element to the root element that we fetched from DOM.</li>
</ol>
<p>Even though the above code is very clear, I broke it down into steps, because in the following section, we will use these exact steps to achieve this, but by using React APIs.</p>
<h3 id="heading-intro-to-raw-react-apis">Intro to Raw React APIs</h3>
<h4 id="heading-introduction-2">Introduction 2</h4>
<p>React uses the same document API that we have seen before under the hood. But it abstracts it away and gives you easy to use and intuitive API to work with</p>
<p>Let's try to create the same hello world markup that we did before, this time using React. </p>
<h4 id="heading-raw-react-apis">Raw React APIs</h4>
<pre><code class="lang-js"><span class="hljs-comment">// Fetches the element with id as `root` from DOM</span>
<span class="hljs-keyword">const</span> rootElement = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"root"</span>)

<span class="hljs-comment">// Creates an element with `div` tag</span>
<span class="hljs-keyword">const</span> helloWorldElement = React.createElement(<span class="hljs-string">"div"</span>, { 
    <span class="hljs-attr">className</span>: <span class="hljs-string">"container"</span>, 
    <span class="hljs-attr">children</span>: <span class="hljs-string">"Hello World"</span> 
})

<span class="hljs-comment">// Appends the helloWorldElement to the rootElement</span>
ReactDOM.render(helloWorldElement, rootElement)
</code></pre>
<p>Before we understand this code, observe that we have used <code>React</code> and <code>ReactDOM</code>, which are not a part of basic javascript. Hence, they should be added before they become available to us.</p>
<p>Let's add them using their CDN scripts. We will be using <a target="_blank" href="https://unpkg.com/">unpkg</a>'s CDN.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://unpkg.com/react@16.7.0/umd/react.production.min.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://unpkg.com/react-dom@16.7.0/umd/react-dom.production.min.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<p>After adding this, we will be able to access <code>React</code> and <code>ReactDOM</code> from within javascript.</p>
<p>Let's try to understand the code now.</p>
<ol>
<li>Get the element with <code>id</code> as <code>root</code> from DOM.<ul>
<li>This part did not change. We are still using the <code>document</code> API to get the root element.</li>
</ul>
</li>
<li>Create a new DOM element and then set its properties.<ul>
<li>Here we are introducing the new React API called <code>React.createElement()</code>.</li>
<li>It takes two arguments<ol>
<li>HTML tag that we want to create.</li>
<li>Properties and the corresponding values that we want to set.</li>
</ol>
</li>
<li>Note that we have introduced a new property called <code>children</code>. <ul>
<li><code>children</code> is basically a replacement of what we want inside of the HTML tag that we create. </li>
<li>So, if we want to render <code>&lt;div&gt;Hello World&lt;/div&gt;</code>, we will create a React element with a <code>div</code> tag and set the children's property to <code>Hello World</code>.</li>
</ul>
</li>
</ul>
</li>
<li>Append the newly created element to the root element that we fetched from DOM.<ul>
<li>We will be using ReactDOM for rendering. The corresponding API is <code>ReactDOM.render()</code></li>
<li>It also takes two arguments.<ul>
<li>Element that we want to append.</li>
<li>Element which we want to append the above element to.</li>
</ul>
</li>
<li>So, if we want to append <code>element1</code> to <code>element2</code>. You would do <code>ReactDOM.render(element1, element2)</code>.</li>
</ul>
</li>
</ol>
<p>Can you see and appreciate how similar both the React APIs and document APIs are. With the knowledge that we have let's try to create the below markup using React.</p>
<h4 id="heading-nesting-elements">Nesting Elements</h4>
<p>Lets try to create the following markup with React.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"root"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>Hello<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>World<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>Before doing this, you need to know that the <code>children</code> property that we have seen before will also accept an array as its value.
For example, both of the following calls will produce the same HTML output.</p>
<pre><code class="lang-js"><span class="hljs-comment">// 1.</span>
React.createElement(<span class="hljs-string">"div"</span>, { <span class="hljs-attr">children</span>: <span class="hljs-string">"Hello World"</span> })

<span class="hljs-comment">// 2.</span>
React.createElement(<span class="hljs-string">"div"</span>, { <span class="hljs-attr">children</span>: [<span class="hljs-string">"Hello"</span>, <span class="hljs-string">" "</span>, <span class="hljs-string">"World"</span>] })
</code></pre>
<p>Now that we know this, let's try to create the given markup.</p>
<pre><code class="lang-js"><span class="hljs-comment">// Fetches the element with id as `root`</span>
<span class="hljs-keyword">const</span> rootElement = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"root"</span>)

<span class="hljs-comment">// Creates a `span` element with content as `Hello`</span>
<span class="hljs-keyword">const</span> helloElement = React.createElement(<span class="hljs-string">"span"</span>, {<span class="hljs-attr">children</span>: <span class="hljs-string">"Hello"</span>})

<span class="hljs-comment">// Creates a `span` element with content as `World`</span>
<span class="hljs-keyword">const</span> worldElement = React.createElement(<span class="hljs-string">"span"</span>, {<span class="hljs-attr">children</span>: <span class="hljs-string">"World"</span>})

<span class="hljs-comment">// Let's put the above two elements in to a single div</span>
<span class="hljs-keyword">const</span> helloWorldElement = React.createElement(<span class="hljs-string">"div"</span>, {
    <span class="hljs-attr">children</span>: [helloElement, worldElement]
})
</code></pre>
<p>The above code will create the HTML markup that we want.</p>
<p><strong>Note:</strong></p>
<p>React.createElement can also take more than 2 arguments.
The following two calls generate the same thing.</p>
<pre><code class="lang-js"><span class="hljs-comment">// 1.</span>
React.createElement(<span class="hljs-string">"div"</span>, {<span class="hljs-attr">children</span>: [element1, element2, element3]})

<span class="hljs-comment">// 2.</span>
React.createElement(<span class="hljs-string">"div"</span>, {}, element1, element2, element3)
</code></pre>
<p>So, you can essentially unpack the <code>children</code> array and then add them as other arguments.</p>
<p>That's it for now.</p>
<h3 id="heading-whats-next">What's Next</h3>
<p>In this article, you saw how verbose React raw APIs are. So, it becomes a little difficult to write code like this when there are a lot of elements and each element has different properties. </p>
<p>That is why React gave us a way to simplify this and write the code in a format called <code>JSX</code> which looks a bit similar to <code>HTML</code>. In the next article, we will see all about <code>JSX</code> and we will also see how to create custom components and style them with CSS.</p>
<h4 id="heading-until-next-time">Until Next Time 👋</h4>
<hr />
<p>If this was helpful to you, Please <strong>Like</strong> and <strong>Share</strong> so that it reaches others as well. To get email notifications on my latest articles, please subscribe to my blog by hitting the <strong>Subscribe</strong> button at the top of the page. You can also follow me on twitter <a target="_blank" href="https://twitter.com/pbteja1998">@pbteja1998</a>.</p>
<p><strong>Links and References:</strong></p>
<ul>
<li><a target="_blank" href="https://epicreact.dev">EpicReact.Dev</a> - Series of workshops by <a target="_blank" href="https://kentcdodds.com">Kent C. Dodds</a> based on which this blog post series is being written.</li>
<li><a target="_blank" href="https://github.com/kentcdodds/react-fundamentals">React Fundamentals Workshop Repo</a> - Github Repo if you want to do the self-paced workshop yourself.</li>
<li><a target="_blank" href="http://react-fundamentals.netlify.app">React Fundamentals Workshop Demo</a> - Production application of the above workshop repo.</li>
</ul>
<hr />
<p>The next article in this series is already live. Click on the link below👇</p>
<div class="hn-embed-widget" id="newsletter"></div>]]></content:encoded></item><item><title><![CDATA[How I Gave A Modern Look For HackerNews Feed]]></title><description><![CDATA[Hello World 👋
I made a website showing Hacker News and gave it a modern look. Before we dive into what all I used to make it, let's see some visuals of how the website looks. By the way, the website is at hn.bhanuteja.dev.
Let's get to it.
Here are ...]]></description><link>https://blog.bhanuteja.dev/how-i-gave-a-modern-look-for-hackernews-feed</link><guid isPermaLink="true">https://blog.bhanuteja.dev/how-i-gave-a-modern-look-for-hackernews-feed</guid><category><![CDATA[React]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Tailwind CSS]]></category><category><![CDATA[ShowHashnode]]></category><category><![CDATA[2Articles1Week]]></category><dc:creator><![CDATA[Bhanu Teja Pachipulusu]]></dc:creator><pubDate>Sat, 10 Oct 2020 08:00:07 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1602520502273/zxOwULGD8.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-hello-world">Hello World 👋</h2>
<p>I made a website showing Hacker News and gave it a modern look. Before we dive into what all I used to make it, let's see some visuals of how the website looks. By the way, the website is at <a target="_blank" href="https://hn.bhanuteja.dev">hn.bhanuteja.dev</a>.</p>
<p>Let's get to it.</p>
<p>Here are the screenshots of the website at various screen sizes.</p>
<h3 id="heading-loading-view">Loading View</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602013009637/UsTIjEPzw.png" alt="Screenshot 2020-10-07 at 12.50.58 AM.png" /></p>
<h3 id="heading-story-view">Story View</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602013524465/RW_JX3pis.png" alt="1-m.png" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602013531416/mZxOt2YLW.png" alt="1-t.png" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602013540648/QpoCnxD1K.png" alt="1-d.png" /></p>
<h3 id="heading-comments-view">Comments View</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602013549076/6fPz7Lor2.png" alt="2-m.png" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602013557214/oOtXlC8NI.png" alt="2-t.png" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602013566746/VBC_ywfmG.png" alt="2-d.png" /></p>
<p>Looks clean, right? I like it. If you want to play around with it, visit https://hn.bhanuteja.dev</p>
<h3 id="heading-lets-get-technical">Let's Get Technical</h3>
<p>This project is built using Next.js, Tailwind, and React Query. There are different components to this website, let's see each one of them below.</p>
<ol>
<li>Hacker News API</li>
<li>UI</li>
<li>Loading</li>
<li>Pagination</li>
<li>Filters</li>
<li>Styling The Comments.</li>
<li>Search</li>
</ol>
<p>I wanted to support the following use-cases. Anything extra is an added bonus</p>
<ul>
<li>Users can see articles from Hacker News.</li>
<li>Users can filter to only see articles about a specific topic.</li>
<li>Users can filter articles by date.</li>
<li>Pagination.</li>
</ul>
<h3 id="heading-1-hacker-news-api">1. Hacker News API</h3>
<p>We need an API that does the following things:</p>
<ul>
<li>Fetch Top Hacker News stories.</li>
<li>Fetch New Hacker News stories.</li>
<li>Fetch Show, Ask, and Job Hacker News stories.</li>
<li>Fetch the stories that matched the given search query.</li>
</ul>
<p>I ended up using the <a target="_blank" href="https://hackernews.api-docs.io/v0/overview/introduction">official API</a> which does 3 of the 4 things that I mentioned above. It doesn't have an API to fetch stories based on the search query. I decided to just implement the search functionality separately on the website itself based on the content fetched.</p>
<h3 id="heading-2ui">2.UI</h3>
<p>I used the following things for the UI.</p>
<ul>
<li><a target="_blank" href="https://tailwindcss.com/">Tailwind CSS</a></li>
<li><a target="_blank" href="https://tailwindui.com/">Tailwind UI</a></li>
<li><a target="_blank" href="https://heroicons.com/">Heroicons</a></li>
<li><a target="_blank" href="https://headlessui.dev/">Headless UI</a><ul>
<li>These are completely unstyled, fully accessible UI components. I tried this for the first time in this project. I like them very much. Will be using these a lot.</li>
</ul>
</li>
</ul>
<p>I found an amazing package called <a target="_blank" href="https://github.com/catamphetamine/javascript-time-ago">javascript-time-ago</a> which is a highly customizable relative date/time formatted. I used this to show the relative dates and times like <code>3 mins ago</code>, <code>23 hrs ago</code> etc.</p>
<h3 id="heading-3-loading">3. Loading</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602316591122/V7QVo04Pm.gif" alt="loading.gif" />
I used <a target="_blank" href="https://tailwindcss.com/docs/animation">Tailwind CSS animations utilities</a> to show the loading skeleton.</p>
<h3 id="heading-4-pagination">4. Pagination</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602314359243/yrP9Fnjcf.gif" alt="Oct-10-2020 12-47-48.gif" /></p>
<p>I implemented pagination a little unconventionally. I have added infinite scrolling with the <code>Load More</code> button. But I also added page numbers to the website. When you click on a page, the page scrolls down to the first story of that page. I added this to have easy navigation when you load a large number of stories. Check the above gif to understand better.</p>
<h3 id="heading-5-filters">5. Filters</h3>
<p>I have added three types of filters.</p>
<ol>
<li>Show Only<ul>
<li>All Time</li>
<li>Last 24 Hours</li>
<li>Past Week</li>
<li>Past Month</li>
<li>Past Year</li>
</ul>
</li>
<li>Sort By<ul>
<li>Popularity</li>
<li>Date</li>
<li>Comments</li>
</ul>
</li>
<li>Order In<ul>
<li>Ascending Order</li>
<li>Descending Order</li>
</ul>
</li>
</ol>
<h3 id="heading-6-styling-the-comments">6. Styling The Comments</h3>
<p>This is a little bit tricky. The comments that we get from API is not just pure text. We get HTML content as the comment text. To style that, I have used <a target="_blank" href="https://tailwindcss.com/docs/typography-plugin">@tailwindcss/typography</a> plugin. If you don't know what it is, you should definitely check it out.</p>
<h3 id="heading-7-search">7. Search</h3>
<p>The search functionality that is present right now is very basic. It just does substring matches and filters the results. I am planning to instead use <a target="_blank" href="https://fusejs.io/">Fuse.js</a> to do fuzzy searching(approximate string matching). Will get to this when I find the time.</p>
<h3 id="heading-challenges">Challenges</h3>
<p>The main challenge that I faced is because of API.
The API has an endpoint that gives the story ids of approximately 500 stories. Then it has another endpoint that gives the details of a single story. </p>
<p>So, if I fetch all the stories at the page load, it was taking approximately 3-4 mins to fetch everything. Until we fetch everything, the filters wouldn't work. So I have to hide the filters until everything is fetched.</p>
<p>So, I made a compromise and decided to fetch just 50 stories at the start, and added a load more button. And I decided not to show a blank page until all stories are fetched. I immediately showed a story if it is fetched and showed a loading skeleton for the stories that are still being fetched. I hid the filters and added a loading rotating ring in place of that. </p>
<p>I faced some more challenges when I actually sat down to code. Especially because I wanted to show the story on the page as soon as it is fetched, instead of waiting for other stories to be fetched. </p>
<p>I made the code for this open-source. You can take a look at it, star it, fork it, make issues, raise PRS, do whatever you want with it.</p>
<p>Tell me in the comments if you like me to dig deep into any of the things that I discussed in this article. I will be happy to do so.</p>
<p>Here is the repo 👉
<a target="_blank" href="https://github.com/pbteja1998/hacker-news-client">pbteja1998/hacker-news-client</a></p>
<h3 id="heading-whats-next">What's Next</h3>
<p>Tell me in the comments if you like to see more articles in this format.</p>
<p>The next article will be part of the <a target="_blank" href="https://hashnode.com/series/epic-react-ckfv4gidh08efu9s1408v8tgp">My Review of Kent C. Dodds's EpicReact.Dev</a> series. It will be the third article in the series. To know more, go to <a target="_blank" href="https://hashnode.com/series/epic-react-ckfv4gidh08efu9s1408v8tgp">My Review of Kent C. Dodds's EpicReact.Dev</a> series.</p>
<h4 id="heading-until-next-time">Until Next Time 👋</h4>
<hr />
<p>If this was helpful to you, Please <strong>Like</strong> and <strong>Share</strong> so that it reaches others as well. To get email notifications on my latest articles, please subscribe to my blog by hitting the <strong>Subscribe</strong> button at the top of the page. You can also follow me on Twitter <a target="_blank" href="https://twitter.com/pbteja1998">@pbteja1998</a>.</p>
<div class="hn-embed-widget" id="newsletter"></div>]]></content:encoded></item><item><title><![CDATA[Javascript You Need To Know For React]]></title><description><![CDATA[Hello World 👋
Welcome to the second article of the My Review of Kent C. Dodds's EpicReact.Dev series which is based on the workshop material from EpicReact.Dev by Kent C. Dodds. In the previous article, you looked at the different topics that are go...]]></description><link>https://blog.bhanuteja.dev/epic-react-javascript-you-need-to-know-for-react</link><guid isPermaLink="true">https://blog.bhanuteja.dev/epic-react-javascript-you-need-to-know-for-react</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[React]]></category><category><![CDATA[2Articles1Week]]></category><dc:creator><![CDATA[Bhanu Teja Pachipulusu]]></dc:creator><pubDate>Thu, 08 Oct 2020 06:55:58 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1602517196479/BzLPgC2LL.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-hello-world">Hello World 👋</h2>
<p>Welcome to the second article of the <a target="_blank" href="https://hashnode.com/series/epic-react-ckfv4gidh08efu9s1408v8tgp">My Review of Kent C. Dodds's EpicReact.Dev</a> series which is based on the workshop material from <a target="_blank" href="https://epicreact.dev">EpicReact.Dev</a> by <a target="_blank" href="https://kentcdodds.com">Kent C. Dodds</a>. In the previous article, you looked at the different topics that are going to be covered in <a target="_blank" href="https://epicreact.dev">EpicReact.Dev</a> workshop. If you haven't read the <a target="_blank" href="https://blog.bhanuteja.dev/epic-react-introduction">previous article of the series</a>, please go and read it now and come back. In this article, I am going to explain the basic javascript concepts that you need to know before you start learning React.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://blog.bhanuteja.dev/epic-react-introduction">https://blog.bhanuteja.dev/epic-react-introduction</a></div>
<p>Let's get to it.</p>
<hr />
<p>I am one of those persons who learned React before properly learning the basic concepts of javascript. Because of this, in the early days of my React journey, I didn't know which part of the code is React and which part is the vanilla js. It's important to know the basic javascript concepts to understand better which part of the puzzle is React solving.</p>
<p>In this blog post, I will be writing about different concepts of javascript that you see yourself using very often while working with React. It's better to know these before you deep dive into learning React.</p>
<p>I will be covering the following topics. Feel free to skip over the topics that you already know.</p>
<ul>
<li><a class="post-section-overview" href="#logical-and-and-and-logical-or-or-operators">Logical AND (&amp;&amp;) and Logical OR (||) Operators</a><ul>
<li><a class="post-section-overview" href="#logical-and-and-operator">Logical AND (&amp;&amp;) Operator</a></li>
<li><a class="post-section-overview" href="#logical-or-or-operator">Logical OR (||) Operator</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#template-literals">Template Literals</a></li>
<li><a class="post-section-overview" href="#ternary-operator">Ternary Operator</a></li>
<li><a class="post-section-overview" href="#shorthand-property-names">Shorthand Property Names</a></li>
<li><a class="post-section-overview" href="#object-destructuring">Object Destructuring</a></li>
<li><a class="post-section-overview" href="#array-destructuring">Array Destructuring</a></li>
<li><a class="post-section-overview" href="#default-parameters">Default Parameters</a></li>
<li><a class="post-section-overview" href="#optional-chaining">Optional Chaining</a></li>
<li><a class="post-section-overview" href="#nullish-coalescing-operator">Nullish Coalescing Operator</a></li>
<li><a class="post-section-overview" href="#spread-operator">Spread Operator</a></li>
<li><a class="post-section-overview" href="#rest-operator">Rest Operator</a></li>
<li><a class="post-section-overview" href="#arrow-functions">Arrow Functions</a></li>
<li><a class="post-section-overview" href="#array-methods">Array Methods</a><ul>
<li><a class="post-section-overview" href="#array-map-method">Array map() Method</a></li>
<li><a class="post-section-overview" href="#array-filter-method">Array filter() Method</a></li>
<li><a class="post-section-overview" href="#array-reduce-method">Array reduce() Method</a></li>
<li><a class="post-section-overview" href="#array-sort-method">Array sort() Method</a></li>
<li><a class="post-section-overview" href="#array-includes-method">Array includes() Method</a></li>
<li><a class="post-section-overview" href="#array-slice-method">Array slice() Method</a></li>
<li><a class="post-section-overview" href="#array-splice-method">Array splice() Method</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#default-exports-vs-named-exports">Default Exports vs Named Exports</a></li>
<li><a class="post-section-overview" href="#promises">Promises</a></li>
<li><a class="post-section-overview" href="#basic-dom-document-apis">Basic DOM Document APIs</a></li>
</ul>
<hr />
<h3 id="heading-logical-and-andampandamp-and-logical-or-or-operators">Logical AND (&amp;&amp;) and Logical OR (||) Operators</h3>
<h4 id="heading-logical-and-andampandamp-operator">Logical AND (&amp;&amp;) Operator</h4>
<p>Let's say we have the following expression - where <code>b</code> and <code>c</code> are <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators">expressions</a></p>
<pre><code class="lang-js">b &amp;&amp; c
</code></pre>
<p>This will be evaluated to the value of <code>c</code> only if <code>b</code> is <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Glossary/truthy">truthy</a>, otherwise, it will be evaluated to the value of <code>b</code></p>
<p><strong>Note:</strong> </p>
<ul>
<li>If <code>b</code> is <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Glossary/falsy">falsy</a>, then the expression <code>c</code> is not even going to be evaluated. </li>
<li>This is called <code>short-circuit evaluation</code>.  </li>
<li>This will be used quite a lot while using React.</li>
</ul>
<h4 id="heading-logical-or-or-operator">Logical OR (||) Operator</h4>
<p>Let's say we have the following expression - where <code>b</code> and <code>c</code> are <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators">expressions</a></p>
<pre><code class="lang-js">b || c
</code></pre>
<p>This will be evaluated to the value of <code>b</code> if b is <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Glossary/truthy">truthy</a>, otherwise, it will be evaluated to the value of <code>c</code>.</p>
<p><strong>Note:</strong> </p>
<ul>
<li>Short-circuit evaluation happens here too.</li>
<li>If <code>b</code> is <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Glossary/truthy">truthy</a>, then the expression <code>c</code> is not even going to be evaluated.</li>
<li>You will be using this also quite often while using React.</li>
</ul>
<hr />
<h3 id="heading-template-literals">Template Literals</h3>
<p>This is a new <a target="_blank" href>ES6</a> way to create strings. </p>
<p>Let's see an example.</p>
<p>Assume that you want to create the following type of strings:</p>
<ul>
<li><code>3 blog posts were written by Bhanu Teja in a span of 2 weeks.</code> </li>
</ul>
<p>You will be given <code>count</code> (number of blogs), <code>name</code> (name of the user), <code>span</code> (time span it took) as variables.</p>
<p><strong>Without using template literals</strong></p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> count = <span class="hljs-number">3</span>
<span class="hljs-keyword">const</span> user = <span class="hljs-string">'Bhanu Teja'</span>
<span class="hljs-keyword">const</span> span = <span class="hljs-number">2</span>

<span class="hljs-keyword">const</span> result = count + <span class="hljs-string">' blog posts were written by '</span> 
                     + name + <span class="hljs-string">' in a span of '</span> + span 
                     + <span class="hljs-string">' weeks.'</span>
</code></pre>
<p><strong>Using template literals</strong></p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> count = <span class="hljs-number">3</span>
<span class="hljs-keyword">const</span> name = <span class="hljs-string">'Bhanu Teja'</span>
<span class="hljs-keyword">const</span> span = <span class="hljs-number">2</span>

<span class="hljs-keyword">const</span> result = <span class="hljs-string">`<span class="hljs-subst">${count}</span> blog posts were written by <span class="hljs-subst">${name}</span> in a span of <span class="hljs-subst">${span}</span> weeks.`</span>
</code></pre>
<p>Template literals start and end with a <code>backtick(`)</code> and you can write strings of text inside them and you have to wrap the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators">javascript expressions</a> around with <code>${</code> and <code>}</code></p>
<p>Let's add another use-case to the above example.</p>
<ul>
<li>If we have just 1 blog post you have to use <code>blog post</code> instead of <code>blog posts</code> </li>
<li>If the time span is just 1 week, you have to use <code>week</code> instead of <code>weeks</code>.</li>
</ul>
<p><strong>Without using template literals</strong></p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">pluralize</span>(<span class="hljs-params">text, count</span>) </span>{
    <span class="hljs-keyword">if</span> (count === <span class="hljs-number">1</span>) {
        <span class="hljs-keyword">return</span> text
    }
    <span class="hljs-keyword">return</span> text + <span class="hljs-string">'s'</span>
}

<span class="hljs-keyword">const</span> result = count + <span class="hljs-string">' '</span> + pluralize(<span class="hljs-string">'blog post'</span>, count)  
                     + <span class="hljs-string">' were written by '</span> + name
                     + <span class="hljs-string">' in a span of '</span> + span 
                     + <span class="hljs-string">' '</span> + pluralize(<span class="hljs-string">'week'</span>, span) + <span class="hljs-string">'.'</span>
</code></pre>
<p><strong>Using template literals</strong></p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">pluralize</span>(<span class="hljs-params">text, count</span>) </span>{
    <span class="hljs-keyword">if</span> (count === <span class="hljs-number">1</span>) {
        <span class="hljs-keyword">return</span> text
    }
    <span class="hljs-keyword">return</span> text + <span class="hljs-string">'s'</span>
}

<span class="hljs-keyword">const</span> result = <span class="hljs-string">`<span class="hljs-subst">${count}</span> <span class="hljs-subst">${pluralize(<span class="hljs-string">'blog post'</span>, count)}</span> were written by <span class="hljs-subst">${name}</span> in a span of <span class="hljs-subst">${span}</span> <span class="hljs-subst">${pluralize(<span class="hljs-string">'week'</span>, span)}</span>.`</span>
</code></pre>
<hr />
<h3 id="heading-ternary-operator">Ternary Operator</h3>
<p>This is a shorthand representation of the if-else statements.</p>
<p>This is best explained using an example.</p>
<pre><code class="lang-js"><span class="hljs-keyword">if</span> (condition) {
    doSomething()
} <span class="hljs-keyword">else</span> {
    doSomethingElse()
}
</code></pre>
<p>The above example when written using ternary operator</p>
<pre><code class="lang-js">condition ? doSomething() : doSomethingElse()
</code></pre>
<h4 id="heading-syntax">Syntax</h4>
<pre><code class="lang-js">condition ? expressionIfTrue : expressionIfFalse
</code></pre>
<hr />
<h3 id="heading-shorthand-property-names">Shorthand Property Names</h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> id = <span class="hljs-number">2</span>
<span class="hljs-keyword">const</span> name = <span class="hljs-string">'Bhanu'</span>
<span class="hljs-keyword">const</span> count = <span class="hljs-number">2</span>

<span class="hljs-comment">// This is the normal way</span>
<span class="hljs-keyword">const</span> user = {
    <span class="hljs-attr">id</span>: id,
    <span class="hljs-attr">blogs</span>: count,
    <span class="hljs-attr">name</span>: name,
}

<span class="hljs-comment">// Using shorthand property names</span>
<span class="hljs-keyword">const</span> user = {
    id,
    <span class="hljs-attr">blogs</span>: count,
    name,
}
</code></pre>
<p>If the name of the <code>variable</code> and the name of the <code>property</code> of the object are same, then you can just write the variable name and omit the rest.</p>
<p>This is one of the things that I did not know when I was initially learning React, and you usually see this being used a lot in code and documentation.</p>
<hr />
<h3 id="heading-object-destructuring">Object Destructuring</h3>
<p>This is a short-hand way to get the properties of an object into variables.</p>
<pre><code class="lang-js"><span class="hljs-comment">// we have a `user` variable that looks like this</span>
<span class="hljs-keyword">const</span> user = {
    <span class="hljs-attr">name</span>: <span class="hljs-string">'Bhanu Teja'</span>,
    <span class="hljs-attr">blogs</span>: <span class="hljs-number">3</span>,
    <span class="hljs-attr">timeSpan</span>: <span class="hljs-number">2.</span>
}

<span class="hljs-comment">// without using object destructuring</span>
<span class="hljs-keyword">const</span> name = user.name
<span class="hljs-keyword">const</span> blogs = user.blogs
<span class="hljs-keyword">const</span> timeSpan = user.timeSpan

<span class="hljs-comment">// using object destructuring</span>
<span class="hljs-keyword">const</span> { name, blogs, timeSpan } = user
</code></pre>
<p><strong>Note</strong>: 
The name of the destructured variables should be same as the name of the object properties.</p>
<hr />
<h3 id="heading-array-destructuring">Array Destructuring</h3>
<p>This is a short-hand way to get the elements of an array into variables.</p>
<pre><code class="lang-js"><span class="hljs-comment">// we have a `name` variable that looks like this</span>
<span class="hljs-keyword">const</span> name = [ <span class="hljs-string">'Bhanu Teja'</span>, <span class="hljs-string">'P'</span>]

<span class="hljs-comment">// without using array destructuring</span>
<span class="hljs-keyword">const</span> firstName = name[<span class="hljs-number">0</span>]
<span class="hljs-keyword">const</span> lastName = name[<span class="hljs-number">1</span>]

<span class="hljs-comment">// using array destructuring</span>
<span class="hljs-keyword">const</span> [firstName, lastName] = name
</code></pre>
<hr />
<h3 id="heading-default-parameters">Default Parameters</h3>
<p>You often want the function parameters to take some default values if that is not passed while calling the function.</p>
<p>Let's see an example</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sum</span>(<span class="hljs-params">a = <span class="hljs-number">2</span>, b = <span class="hljs-number">5</span></span>) </span>{
    <span class="hljs-keyword">return</span> a + b
}

sum(<span class="hljs-number">5</span>, <span class="hljs-number">7</span>) <span class="hljs-comment">// a = 5, b = 7, result = 12</span>
sum(<span class="hljs-number">4</span>) <span class="hljs-comment">// a = 4, b = 5(default value of b), result = 9</span>
sum() <span class="hljs-comment">// a = 2(default a), b = 5(default b), result = 7</span>
</code></pre>
<p>So, whenever you want a parameter to take a default value, simply add a <code>=</code> sign after the parameter and add your default value there.</p>
<hr />
<h3 id="heading-optional-chaining">Optional Chaining</h3>
<p>This is a relatively new feature of javascript.</p>
<blockquote>
<p>The optional chaining operator (?.) permits reading the value of a property located deep within a chain of connected objects without having to expressly validate that each reference in the chain is valid. </p>
<ul>
<li>Taken from <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining">MDN Docs</a></li>
</ul>
</blockquote>
<p>Consider the expression <code>a?.b</code>. </p>
<p>This expression evaluates to <code>a.b</code> if <code>a</code> is <code>not null</code> and <code>not undefined</code>, otherwise, it evaluates to <code>undefined</code>.</p>
<p>You can even chain this multiple times like <code>a?.b?.c</code></p>
<ul>
<li>If <code>a</code> is <code>undefined</code> or <code>null</code>, then this expression evaluates to <code>undefined</code></li>
<li>Else if <code>b</code> is undefined or <code>null</code>, then this expression evaluates to <code>undefined</code></li>
<li>Else this evaluates to <code>a.b.c</code></li>
</ul>
<p><strong>Syntax:</strong></p>
<pre><code class="lang-js">obj.val?.prop
obj.val?.[expr]
obj.arr?.[index]
obj.func?.(args)
</code></pre>
<hr />
<h3 id="heading-nullish-coalescing-operator">Nullish Coalescing Operator</h3>
<blockquote>
<p>The nullish coalescing operator (??) is a logical operator that returns its right-hand side operand when its left-hand side operand is <code>null</code> or <code>undefined</code>, and otherwise returns its left-hand side operand.</p>
<ul>
<li>Taken from <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator">MDN Docs</a></li>
</ul>
</blockquote>
<p>Consider the expression <code>a ?? b</code>.
This evaluates to <code>b</code> if <code>a</code> is <code>null</code> or <code>undefined</code>, otherwise, it evaluates to <code>a</code></p>
<hr />
<h3 id="heading-spread-operator">Spread Operator</h3>
<p>This operator spreads the values of an iterable object.</p>
<h4 id="heading-array-spread">Array Spread</h4>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> a = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]
<span class="hljs-keyword">const</span> b = [<span class="hljs-number">5</span>, <span class="hljs-number">6</span>]

<span class="hljs-built_in">console</span>.log(...a) <span class="hljs-comment">// 1 2 3</span>

<span class="hljs-comment">// Now, if you want to have an array with values 0, 1, 2, 3, 4, 5, 6</span>
<span class="hljs-keyword">const</span> c = [<span class="hljs-number">0</span>, ...a, <span class="hljs-number">4</span>, ...b]

<span class="hljs-built_in">console</span>.log(c) <span class="hljs-comment">// 0 1 2 3 4 5 6</span>
</code></pre>
<h4 id="heading-object-spread">Object Spread</h4>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> first = {<span class="hljs-attr">a</span>: <span class="hljs-number">1</span>, <span class="hljs-attr">b</span>: <span class="hljs-number">2</span>}
<span class="hljs-keyword">const</span> second = {<span class="hljs-attr">c</span>: <span class="hljs-number">3</span>}


<span class="hljs-comment">// Now to create an object {a: 1, b: 2, c: 3, d: 4}</span>
<span class="hljs-keyword">const</span> result = {...first, ...second, <span class="hljs-attr">d</span>: <span class="hljs-number">4</span>}

<span class="hljs-built_in">console</span>.log(result) <span class="hljs-comment">// {a: 1, b: 2, c: 3, d: 4}</span>
</code></pre>
<ul>
<li>To learn more about spread operator, Check out this amazing article <a target="_blank" href="https://blog.skay.dev/es6-spread-operator">ES6 - Spread Operator</a> by <a class="user-mention" href="https://hashnode.com/@skay">Skay</a></li>
</ul>
<hr />
<h3 id="heading-rest-operator">Rest Operator</h3>
<blockquote>
<p>The rest parameter syntax allows us to represent an indefinite number of arguments as an array.</p>
<ul>
<li>Taken from <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters">MDN Docs</a></li>
</ul>
</blockquote>
<h4 id="heading-function-arguments">Function Arguments</h4>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sum</span>(<span class="hljs-params">a, b, ...rest</span>) </span>{
    <span class="hljs-comment">// ...</span>
}

sum(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>, <span class="hljs-number">6</span>) <span class="hljs-comment">// a = 1, b = 2, rest = [3, 4, 5, 6]</span>
</code></pre>
<h4 id="heading-usage-with-objects">Usage with objects</h4>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> user = {
    <span class="hljs-attr">name</span>: <span class="hljs-string">'Bhanu Teja'</span>,
    <span class="hljs-attr">blogs</span>: <span class="hljs-number">3</span>,
    <span class="hljs-attr">span</span>: <span class="hljs-number">2</span>,
}
<span class="hljs-keyword">const</span> {name, ...rest} = user
<span class="hljs-built_in">console</span>.log(name) <span class="hljs-comment">// Bhanu Teja</span>
<span class="hljs-built_in">console</span>.log(rest) <span class="hljs-comment">// { blogs: 3, span: 2}</span>
</code></pre>
<hr />
<h3 id="heading-arrow-functions">Arrow Functions</h3>
<p>This is a new ES6 way to write functions.</p>
<pre><code class="lang-js"><span class="hljs-comment">// without using arrow functions</span>
<span class="hljs-keyword">const</span> sum = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">a, b</span>) </span>{
    <span class="hljs-keyword">return</span> a + b
}

<span class="hljs-comment">// (or)</span>

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sum</span> (<span class="hljs-params">a, b</span>) </span>{
    <span class="hljs-keyword">return</span> a + b
}

<span class="hljs-comment">// Using arrow functions</span>
<span class="hljs-keyword">const</span> sum = <span class="hljs-function">(<span class="hljs-params">a, b</span>) =&gt;</span> {
    <span class="hljs-keyword">return</span> a + b
}

<span class="hljs-comment">// (or)</span>

<span class="hljs-keyword">const</span> sum = <span class="hljs-function">(<span class="hljs-params">a, b</span>) =&gt;</span> a+ b

<span class="hljs-keyword">const</span> multiplyBy2 = <span class="hljs-function">(<span class="hljs-params">a</span>) =&gt;</span> a * <span class="hljs-number">2</span>

(or)

<span class="hljs-keyword">const</span> multiplyBy2 = <span class="hljs-function"><span class="hljs-params">a</span> =&gt;</span> a * <span class="hljs-number">2</span>
</code></pre>
<p>As you can see from the above example, converting the normal function to arrow functions can be done as follows:</p>
<ul>
<li>Remove the <code>function</code> keyword.</li>
<li>Add an <code>=&gt;</code> after the parameters.</li>
</ul>
<p><strong>Note</strong></p>
<ul>
<li>If the body of the function is a simple expression you can even omit the <code>return</code> keyword and also need not wrap it between <code>{</code> and <code>}</code></li>
<li>If there is only one argument, you have the option to remove parenthesis around the arguments.</li>
<li>There are still some more differences between arrow functions and normal functions, Checkout the following amazing articles to know more.<ul>
<li><a target="_blank" href="https://lo-victoria.com/a-simple-guide-to-arrow-functions-in-javascript">A Simple Guide To Arrow Functions</a> by <a class="user-mention" href="https://hashnode.com/@victoria">Victoria Lo</a></li>
<li><a target="_blank" href="https://blog.skay.dev/es6-arrow-functions">ES6 =&gt; Arrow Functions</a> by <a class="user-mention" href="https://hashnode.com/@skay">Skay</a></li>
</ul>
</li>
</ul>
<hr />
<h3 id="heading-array-methods">Array Methods</h3>
<p>There are so many array methods, but we frequently use some of these. I will be covering the following array methods.</p>
<ul>
<li>map</li>
<li>filter</li>
<li>reduce</li>
<li>sort</li>
<li>includes</li>
<li>slice</li>
<li>splice</li>
</ul>
<h4 id="heading-array-map-method">Array map() Method</h4>
<p>This method creates a new array from an existing array by calling a function for every element of the array.</p>
<p>I always remember this as <code>mapping the values in an array to some other values</code>.</p>
<p>Let's see an example.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> names = [
    { <span class="hljs-attr">firstName</span>: <span class="hljs-string">'Bhanu Teja'</span>, <span class="hljs-attr">lastName</span>: <span class="hljs-string">'P'</span> },
    { <span class="hljs-attr">firstName</span>: <span class="hljs-string">'Florin'</span>, <span class="hljs-attr">lastName</span>: <span class="hljs-string">'Pop'</span>},
    { <span class="hljs-attr">firstName</span>: <span class="hljs-string">'Brad'</span>, <span class="hljs-attr">lastName</span>: <span class="hljs-string">'Traversy'</span>},
]

<span class="hljs-comment">// Let's say we have to create a new array with full names.</span>

<span class="hljs-comment">// First let's write a callback function which takes an array element as an argument.</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">callback</span>(<span class="hljs-params">name</span>) </span>{
    <span class="hljs-keyword">return</span> name.firstName + <span class="hljs-string">' '</span> + name.lastName
}

<span class="hljs-comment">// Now let's call .map() method on the array</span>
<span class="hljs-built_in">console</span>.log(names.map(callback)) <span class="hljs-comment">// ["Bhanu Teja P", "Florin Pop", "Brad Traversy"]</span>

<span class="hljs-comment">// You can even inline the callback function which is how most of the people write this.</span>
names.map(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">name</span>) </span>{ <span class="hljs-keyword">return</span> name.firstName + <span class="hljs-string">' '</span> + name.lastName })

<span class="hljs-comment">// Let's write the same using arrow functions and template literals that we just learned earlier</span>
names.map(<span class="hljs-function">(<span class="hljs-params">name</span>) =&gt;</span> <span class="hljs-string">`<span class="hljs-subst">${name.firstName}</span> <span class="hljs-subst">${name.lastName}</span>`</span>)

<span class="hljs-comment">// You can even omit the parenthesis around name</span>
names.map(<span class="hljs-function"><span class="hljs-params">name</span> =&gt;</span> <span class="hljs-string">`<span class="hljs-subst">${name.firstName}</span> <span class="hljs-subst">${name.lastName}</span>`</span>)

<span class="hljs-comment">// Let's use object destructuring</span>
names.map(<span class="hljs-function">(<span class="hljs-params">{firstName, lastName}</span>) =&gt;</span> <span class="hljs-string">`<span class="hljs-subst">${firstName}</span> <span class="hljs-subst">${lastName}</span>`</span>)
</code></pre>
<p><strong>Syntax:</strong></p>
<pre><code class="lang-js"><span class="hljs-comment">// callback takes a single array element as an argument.</span>
<span class="hljs-comment">// values is an array</span>
values.map(callback)
</code></pre>
<p><strong>Note:</strong></p>
<ul>
<li>Calling this method will not change the original array</li>
</ul>
<h4 id="heading-array-filter-method">Array filter() Method</h4>
<p>Now that we know the <code>Array map</code> method, it's easy to understand other array methods. They all have a similar syntax.</p>
<p>The array filter method creates a new array with elements that satisfy some given criteria.</p>
<p>I always remember this as the <code>filter</code> method filters out elements that do not satisfy the criteria.</p>
<pre><code class="lang-js"><span class="hljs-comment">// consider the following array of users</span>
<span class="hljs-keyword">const</span> users = [
    {<span class="hljs-attr">id</span>: <span class="hljs-number">1</span>, <span class="hljs-attr">posts</span>: <span class="hljs-number">2</span>},
    {<span class="hljs-attr">id</span>: <span class="hljs-number">2</span>, <span class="hljs-attr">posts</span>: <span class="hljs-number">1</span>},
    {<span class="hljs-attr">id</span>: <span class="hljs-number">3</span>, <span class="hljs-attr">posts</span>: <span class="hljs-number">5</span>},
    {<span class="hljs-attr">id</span>: <span class="hljs-number">4</span>, <span class="hljs-attr">posts</span>: <span class="hljs-number">4</span>},
    {<span class="hljs-attr">id</span>: <span class="hljs-number">5</span>, <span class="hljs-attr">posts</span>: <span class="hljs-number">3</span>},
]

<span class="hljs-comment">// Let's say we want to have all users who have at least 3 posts.</span>
users.filter(<span class="hljs-function">(<span class="hljs-params">user</span>) =&gt;</span> user.posts &gt;= <span class="hljs-number">3</span>) <span class="hljs-comment">// [{id: 3, posts: 5}, {id: 4, posts: 4}, {id: 5, posts: 3}]</span>
</code></pre>
<p><strong>Syntax:</strong></p>
<pre><code class="lang-js"><span class="hljs-comment">// callback takes a single array element as an argument.</span>
<span class="hljs-comment">// values is an array</span>
values.filter(callback)
</code></pre>
<p><strong>Note:</strong></p>
<ul>
<li>Calling this method will not change the original array</li>
</ul>
<h4 id="heading-array-reduce-method">Array reduce() method</h4>
<p>The array reduce method reduces the array of values into a single value. It executes the callback function for each value of the array.</p>
<p>Lets see the syntax of the reduce method before seeing an example.</p>
<pre><code class="lang-js">array.reduce(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">totalValue, currentValue, currentIndex, arr</span>), <span class="hljs-title">initialValue</span>)</span>
</code></pre>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> values = [<span class="hljs-number">2</span>, <span class="hljs-number">4</span>, <span class="hljs-number">6</span>, <span class="hljs-number">7</span>, <span class="hljs-number">8</span>]

<span class="hljs-comment">// Let's say that we want to have a sum of all these values.</span>
<span class="hljs-comment">// Let's see how we do it using a traditional for loop</span>
<span class="hljs-keyword">let</span> total = <span class="hljs-number">0</span>
<span class="hljs-keyword">for</span>(<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; values.length; i++) {
    <span class="hljs-keyword">const</span> value = values[i]
    total = total + value
}
<span class="hljs-built_in">console</span>.log(total)


<span class="hljs-comment">// Let's use reduce method now</span>
<span class="hljs-keyword">const</span> initialValue = <span class="hljs-number">0</span>
values.reduce(<span class="hljs-function">(<span class="hljs-params">total, currentValue</span>) =&gt;</span> total + currentValue, initialValue)
</code></pre>
<p><strong>Notes:</strong></p>
<ul>
<li><code>initialValue</code> is optional parameter.</li>
<li>Calling this method will not change the original array</li>
</ul>
<h4 id="heading-array-sort-method">Array sort() method</h4>
<p>The callback function takes two different values as arguments. Based on the return value of the callback function, the two elements' positions are decided.</p>
<ul>
<li>If the return value is negative, then the first value is considered to be before the second value.</li>
<li>If the return value is zero, then there will be no change in the order of the values.</li>
<li>If the return value is positive, then the first value is considered to be after the second value.</li>
</ul>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> values = [<span class="hljs-number">4</span>, <span class="hljs-number">10</span>, <span class="hljs-number">2</span>, <span class="hljs-number">1</span>, <span class="hljs-number">55</span>]

<span class="hljs-comment">// Let's say we want to sort this array in descending order</span>
<span class="hljs-comment">// so if a and b are given</span>
<span class="hljs-comment">// a should be before b if a &gt; b</span>
<span class="hljs-comment">// a should be after b if a &lt; b</span>
<span class="hljs-comment">// a and b can be at their own places if a === b</span>

values.sort(<span class="hljs-function">(<span class="hljs-params">a, b</span>) =&gt;</span> {
    <span class="hljs-keyword">if</span>(a &gt; b) {
        <span class="hljs-keyword">return</span> <span class="hljs-number">-1</span>
    }
    <span class="hljs-keyword">if</span>(a &lt; b) {
        <span class="hljs-keyword">return</span> <span class="hljs-number">1</span>
    }
    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>
}) <span class="hljs-comment">// [55, 10, 4, 2, 1]</span>


<span class="hljs-comment">// You can also do this as follows</span>
values.sort(<span class="hljs-function">(<span class="hljs-params">a, b</span>) =&gt;</span> b - a)
</code></pre>
<p><strong>Note:</strong></p>
<ul>
<li>The return value of the function is the sorted array</li>
<li>This changes the original array</li>
<li>If you do not pass any callback function, this sorts the values as strings and in ascending order.</li>
</ul>
<h4 id="heading-array-includes-method">Array includes() Method</h4>
<p>This returns <code>true</code> if the element is included in the array, otherwise returns false.
<strong>Syntax:</strong></p>
<pre><code class="lang-js">array.includes(element)
</code></pre>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> values = [<span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>]
values.includes(<span class="hljs-number">1</span>) <span class="hljs-comment">// false</span>
values.includes(<span class="hljs-number">2</span>) <span class="hljs-comment">// true</span>
</code></pre>
<p><strong>Note:</strong></p>
<ul>
<li>You can pass an optional parameter specifying the start index to start the search from. <code>array.includes(element, startIndex)</code></li>
</ul>
<h4 id="heading-array-slice-method">Array slice() method</h4>
<p><strong>Syntax</strong></p>
<pre><code class="lang-js">array.slice(start, end)
</code></pre>
<p>Array slice will return the elements in the given range.</p>
<ul>
<li><strong>start</strong> <ul>
<li>starting index to select the elements from</li>
<li>This is an optional parameter and by default, it takes the value of 0</li>
<li>You can even pass a negative number.</li>
<li>Negative number represents the position from the end.<ul>
<li><code>-1</code> refers to the last element of the array, <code>-2</code> refers to last but one element, and so on.</li>
</ul>
</li>
</ul>
</li>
<li><strong>end</strong><ul>
<li>ending index up to where to select the elements</li>
<li>This is an optional parameter. If this is not passed, then all elements up to the end of the array will be selected.</li>
<li>the element at <code>end</code> will not be selected</li>
<li>This also accepts a negative number as an argument and the meaning is the same as before.</li>
</ul>
</li>
</ul>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> numbers = [<span class="hljs-number">0</span>, <span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>, <span class="hljs-number">6</span>, <span class="hljs-number">7</span>]
<span class="hljs-built_in">console</span>.log(numbers.slice())  <span class="hljs-comment">// [0, 1, 2, 3, 4, 5, 6, 7]</span>
<span class="hljs-built_in">console</span>.log(numbers.slice(<span class="hljs-number">2</span>)) <span class="hljs-comment">// [2, 3, 4, 5, 6, 7]</span>
<span class="hljs-built_in">console</span>.log(numbers.slice(<span class="hljs-number">2</span>, <span class="hljs-number">6</span>)) <span class="hljs-comment">// [2, 3, 4, 5]</span>
<span class="hljs-built_in">console</span>.log(numbers.slice(<span class="hljs-number">-1</span>)) <span class="hljs-comment">// [7]</span>
<span class="hljs-built_in">console</span>.log(numbers.slice(<span class="hljs-number">-3</span>)) <span class="hljs-comment">// [5, 6, 7]</span>
<span class="hljs-built_in">console</span>.log(numbers.slice(<span class="hljs-number">-3</span>, <span class="hljs-number">-1</span>)) <span class="hljs-comment">// [5, 6]</span>
</code></pre>
<p><strong>Note:</strong></p>
<ul>
<li>This doesn't change the original array</li>
</ul>
<h4 id="heading-array-splice-method">Array splice() method</h4>
<p><strong>Syntax:</strong></p>
<pre><code class="lang-js">array.splice(index, count, item1, ....., itemX)
</code></pre>
<p>This method is used to add or remove elements in an array.</p>
<ul>
<li><strong>index</strong><ul>
<li>The index at which the elements need to be added or removed. Can be a negative value too.</li>
</ul>
</li>
<li><strong>count</strong><ul>
<li>Number of elements to remove. </li>
</ul>
</li>
<li><strong>item1, ....., itemX</strong><ul>
<li>Items that will be added at <code>index</code></li>
</ul>
</li>
</ul>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> numbers = [<span class="hljs-number">0</span>, <span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">100</span>, <span class="hljs-number">6</span>, <span class="hljs-number">7</span>]
<span class="hljs-comment">// let's say we have to convert this array to [0, 1, 2, 3, 4, 5, 6, 7]</span>
numbers.splice(<span class="hljs-number">3</span>, <span class="hljs-number">1</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>) 
<span class="hljs-built_in">console</span>.log(numbers) <span class="hljs-comment">// [0, 1, 2, 3, 4, 5, 6, 7]</span>
</code></pre>
<p><strong>Note:</strong></p>
<ul>
<li>The return value of the splice method is the array of items removed.</li>
<li>This changes the original array</li>
</ul>
<p>To know more about different array methods, check out the amazing series <a target="_blank" href="https://hashnode.com/series/javascript-array-methods-ckfqksxdi004vfjs12tkdf52b">Javascript Array Methods</a> made by @aman__tyagi</p>
<hr />
<h3 id="heading-default-exports-vs-named-exports">Default Exports vs Named Exports</h3>
<p>You often see yourself using ES Modules imports and exports while working with React. It's important to know how to import them when they are exported as default exports vs when they are exported as named exports.</p>
<p>Check out the following amazing articles to read about these.</p>
<ul>
<li><a target="_blank" href="https://blog.greenroots.info/javascript-modules-and-how-to-effectively-work-with-export-import-cka7t5z6s01irx9s16st6j51j">JavaScript Modules and how to effectively work with Export Import</a> by <a class="user-mention" href="https://hashnode.com/@atapas">Tapas Adhikary</a></li>
<li><a target="_blank" href="https://kentcdodds.com/blog/javascript-to-know-for-react#esmodules">ES Modules</a> by <a target="_blank" href="https://kentcdodds.com">Kent C. Dodds</a></li>
</ul>
<hr />
<h3 id="heading-promises">Promises</h3>
<p>You also need to have a basic knowledge of what promises are and how to work them. They will be used quite often in React.</p>
<p>Check out the following amazing articles to read about these.</p>
<ul>
<li><a target="_blank" href="https://blog.skay.dev/what-are-javascript-promises">What are JavaScript Promises?</a> by <a class="user-mention" href="https://hashnode.com/@skay">Skay</a></li>
<li><a target="_blank" href="https://kentcdodds.com/blog/javascript-to-know-for-react#promises-and-asyncawait">Promises and Async Await</a> by <a target="_blank" href="https://kentcdodds.com">Kent C. Dodds</a></li>
</ul>
<hr />
<h3 id="heading-basic-dom-document-apis">Basic DOM Document APIs</h3>
<p>It is also good to be familiar with basic Document Apis like <code>createElement</code>, <code>getElementById</code> etc. If you know these, you will appreciate the similarity and differences between React APIs and Document APIs.</p>
<p>If you are working with javascript for a while now, it is most likely that you already know basic Document APIs. </p>
<p>MDN Docs are the best place to read up on these.</p>
<ul>
<li><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Document">Document - Web APIs | MDN</a></li>
</ul>

<hr />
<p>You might already know some of the topics that I have explained in this article. Even if you didn't before, now you know. These concepts are enough for you to follow along with <a target="_blank" href="https://hashnode.com/series/epic-react-ckfv4gidh08efu9s1408v8tgp">EpicReact</a> series. If you find something that can be improved or added to this article, feel free to comment on this article. I will try to incorporate your suggestions. Subscribe to my blog if you don't want to miss the next article in this series.</p>
<h3 id="heading-whats-next">What's Next</h3>
<p>In the next article, we are actually going to start the workshop - starting with <a target="_blank" href="https://github.com/kentcdodds/react-fundamentals">React Fundamentals</a> workshop.</p>
<h4 id="heading-until-next-time">Until Next Time 👋</h4>
<hr />
<p>If this was helpful to you, Please <strong>Like</strong> and <strong>Share</strong> so that it reaches others as well. To get email notifications on my latest articles, please subscribe to my blog by hitting the <strong>Subscribe</strong> button at the top of the page. You can also follow me on twitter <a target="_blank" href="https://twitter.com/pbteja1998">@pbteja1998</a>.</p>
<hr />
<p>If you want to learn more about the topics mentioned in this article, you can go through the following articles that I found being published on <a class="user-mention" href="https://hashnode.com/@hashnode">Hashnode</a>. Will be adding more articles to this list as they come along. Different people will find different explanations better.</p>
<ul>
<li>Spread and Rest Operators<ul>
<li><a target="_blank" href="https://blog.skay.dev/es6-spread-operator">ES6 - Spread Operator</a> by <a class="user-mention" href="https://hashnode.com/@skay">Skay</a></li>
<li><a target="_blank" href="https://nemo.hashnode.dev/the-three-dots-of-javascript-rest-and-spread-operator-ckg4seylp05d2e9s1d87c0mci">The Three Dots of JavaScript: Rest and Spread Operator</a> by <a class="user-mention" href="https://hashnode.com/@nemo">Subha Chanda</a></li>
</ul>
</li>
<li>Arrow Functions<ul>
<li><a target="_blank" href="https://lo-victoria.com/a-simple-guide-to-arrow-functions-in-javascript">A Simple Guide To Arrow Functions</a> by <a class="user-mention" href="https://hashnode.com/@victoria">Victoria Lo</a></li>
<li><a target="_blank" href="https://blog.skay.dev/es6-arrow-functions">ES6 =&gt; Arrow Functions</a> by <a class="user-mention" href="https://hashnode.com/@skay">Skay</a></li>
</ul>
</li>
<li>Optional Chaining and Nullish Coalescing<ul>
<li><a target="_blank" href="https://learn-n-share.hashnode.dev/optional-chaining-is-amazing-heres-why-ckanokqle023vbbs1xzqfsu1e">Optional Chaining is amazing, here's why?</a> by <a class="user-mention" href="https://hashnode.com/@mishraaSoumya">Soumya Mishra</a></li>
<li><a target="_blank" href="https://learn-n-share.hashnode.dev/nullish-coalescing-is-not-as-scary-as-it-sounds-ckbj6swwl01iy0ns1bjze789q">Nullish Coalescing is not as scary as it sounds</a> by <a class="user-mention" href="https://hashnode.com/@mishraaSoumya">Soumya Mishra</a></li>
</ul>
</li>
<li>Destructuring<ul>
<li><a target="_blank" href="https://blog.skay.dev/es6-understanding-destructuring">ES6 - Understanding Destructuring</a> by <a class="user-mention" href="https://hashnode.com/@skay">Skay</a></li>
<li><a target="_blank" href="https://blog.sedat.dev/js-bits-destructuring-arrays-in-javascript">JS Bits - Destructuring arrays in JavaScript!</a> by <a class="user-mention" href="https://hashnode.com/@sedatcyalcin">Sedat Can Yalçın</a></li>
<li><a target="_blank" href="https://devrk.hashnode.dev/es6-destructuring">ES6: Destructuring</a> by <a class="user-mention" href="https://hashnode.com/@ip127001">Rohit Kumawat</a></li>
</ul>
</li>
<li>Array Methods<ul>
<li><a target="_blank" href="https://hashnode.com/series/javascript-array-methods-ckfqksxdi004vfjs12tkdf52b">Javascript Array Methods</a> by <a class="user-mention" href="https://hashnode.com/@aman__tyagi">Aman Tyagi</a></li>
<li><a target="_blank" href="https://festack.hashnode.dev/javascript-array-methods-in-one-picture">JavaScript Array methods in one picture</a> by <a class="user-mention" href="https://hashnode.com/@FeStack">FeStack</a></li>
<li><a target="_blank" href="https://ruedatech.com/array-methods">Array Methods Part 1</a> and <a target="_blank" href="https://ruedatech.com/array-methods-part-2">Array Methods Part 2</a> by <a class="user-mention" href="https://hashnode.com/@srueda">Sergio Rueda</a></li>
</ul>
</li>
<li>ES Modules<ul>
<li><a target="_blank" href="https://blog.greenroots.info/javascript-modules-and-how-to-effectively-work-with-export-import-cka7t5z6s01irx9s16st6j51j">JavaScript Modules and how to effectively work with Export Import</a> by <a class="user-mention" href="https://hashnode.com/@atapas">Tapas Adhikary</a></li>
</ul>
</li>
<li>Promises<ul>
<li><a target="_blank" href="https://blog.skay.dev/what-are-javascript-promises">What are JavaScript Promises?</a> by <a class="user-mention" href="https://hashnode.com/@skay">Skay</a></li>
<li><a target="_blank" href="https://hashnode.humanwhocodes.com/creating-a-javascript-promise-from-scratch-part-1-constructor">Creating a JavaScript promise from scratch, Part 1: Constructor</a> by <a class="user-mention" href="https://hashnode.com/@humanwhocodes">Nicholas Zakas</a></li>
<li><a target="_blank" href="https://hashnode.humanwhocodes.com/creating-a-javascript-promise-from-scratch-part-2-resolving-to-a-promise">Creating a JavaScript promise from scratch, Part 2: Resolving to a promise</a> by <a class="user-mention" href="https://hashnode.com/@humanwhocodes">Nicholas Zakas</a></li>
<li><a target="_blank" href="https://rbkannan1.dev/4-promise-methods-you-need-to-know">4 Promise Methods you need to know</a> by <a class="user-mention" href="https://hashnode.com/@rbkannan1">Kannan</a></li>
</ul>
</li>
</ul>
<hr />
<p>The next article in this series is already live. Click on the link below👇</p>
<div class="hn-embed-widget" id="newsletter"></div>]]></content:encoded></item><item><title><![CDATA[My Review of Kent C. Dodds's EpicReact.Dev: Introduction]]></title><description><![CDATA[Hello World 👋
Welcome to the new series that I am starting on React called My Review of Kent C. Dodds's EpicReact.Dev. This is the first article in this series and I will start it off with the introduction to what this series will be about.
This ser...]]></description><link>https://blog.bhanuteja.dev/epic-react-introduction</link><guid isPermaLink="true">https://blog.bhanuteja.dev/epic-react-introduction</guid><category><![CDATA[React]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[2Articles1Week]]></category><dc:creator><![CDATA[Bhanu Teja Pachipulusu]]></dc:creator><pubDate>Mon, 05 Oct 2020 06:55:57 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1602517390311/d-ytPvP1T.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-hello-world">Hello World 👋</h2>
<p>Welcome to the new series that I am starting on React called <code>My Review of Kent C. Dodds's EpicReact.Dev</code>. This is the first article in this series and I will start it off with the introduction to what this series will be about.</p>
<p>This series is based on the workshop content from <a target="_blank" href="https://epicreact.dev">EpicReact.Dev</a> by <a target="_blank" href="https://kentcdodds.com">Kent C. Dodds</a>. While I go through the workshops, I will write blog posts explaining what I understand from the content. Hope you are as excited as I am to be part of this <strong>epic</strong> journey.</p>
<p>In this article, I will list out all the things that will be covered in Epic React workshops. These workshops are also self-paced, and the content in it is <a target="_blank" href="https://twitter.com/kentcdodds/status/1280710694640291840?s=20">open source</a>. So, you can go through the content on your own if you like. But I highly recommend that you <a target="_blank" href="https://epicreact.dev">buy the license</a> and watch the video explanations if you are planning on going through this content by yourself. I will most probably combine multiple lessons while writing a blog post or may write multiple blog posts for some of the lessons.</p>
<h2 id="heading-workshops">Workshops</h2>
<p>Epic React is divided into 8 different workshops.</p>
<ol>
<li>React Fundamentals</li>
<li>React Hooks</li>
<li>Advanced React Hooks</li>
<li>Advanced React Patterns</li>
<li>React Performance</li>
<li>Testing React Apps</li>
<li>React Suspense</li>
<li>Building an Epic React App</li>
</ol>
<h2 id="heading-1-react-fundamentals">1. React Fundamentals</h2>
<blockquote>
<p>In this workshop, we will learn everything you need to be effective with the fundamental building blocks of React applications. When you’re finished, you’ll be prepared to create React components to build excellent experiences for your app's users. </p>
<p>➖ <strong>Summary Taken From <a target="_blank" href="https://epicreact.dev">EpicReact.Dev</a></strong></p>
</blockquote>
<ul>
<li>React Fundamentals Welcome</li>
<li>Basic JS "Hello World"</li>
<li>Intro to Raw React APIs</li>
<li>Using JSX</li>
<li>Creating Custom Components</li>
<li>Styling</li>
<li>Forms</li>
<li>Rendering Arrays</li>
<li>React Fundamentals Outro</li>
</ul>
<h4 id="heading-articles-already-published-as-a-part-of-this-section">Articles already published as a part of this section:</h4>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://blog.bhanuteja.dev/epic-react-javascript-you-need-to-know-for-react">https://blog.bhanuteja.dev/epic-react-javascript-you-need-to-know-for-react</a></div>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://blog.bhanuteja.dev/epic-react-react-fundamentals-part-1">https://blog.bhanuteja.dev/epic-react-react-fundamentals-part-1</a></div>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://blog.bhanuteja.dev/react-fundamentals-understanding-jsx">https://blog.bhanuteja.dev/react-fundamentals-understanding-jsx</a></div>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://blog.bhanuteja.dev/react-fundamentals-creating-custom-components">https://blog.bhanuteja.dev/react-fundamentals-creating-custom-components</a></div>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://blog.bhanuteja.dev/react-fundamentals-styling-and-handling-forms">https://blog.bhanuteja.dev/react-fundamentals-styling-and-handling-forms</a></div>
<h2 id="heading-2-react-hooks">2. React Hooks</h2>
<blockquote>
<p>Learn the ins and outs of React Hooks. I will take you on a deep dive into React Hooks, and show you what you need to know to start using them in your applications right away.</p>
<p>➖ <strong>Summary Taken From <a target="_blank" href="https://epicreact.dev">EpicReact.Dev</a></strong></p>
</blockquote>
<ul>
<li>React Hooks Welcome</li>
<li>useState: greeting</li>
<li>useEffect: persistent state</li>
<li>Hooks Flow</li>
<li>Lifting state</li>
<li>useState: tic tac toe</li>
<li>useRef and useEffect: DOM interaction</li>
<li>useEffect: HTTP requests</li>
<li>React Hooks Outro</li>
</ul>
<h4 id="heading-articles-already-published-as-a-part-of-this-section">Articles already published as a part of this section:</h4>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://blog.bhanuteja.dev/react-hooks-managing-state-with-usestate-hook">https://blog.bhanuteja.dev/react-hooks-managing-state-with-usestate-hook</a></div>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://blog.bhanuteja.dev/how-to-create-a-reusable-localstorage-hook">https://blog.bhanuteja.dev/how-to-create-a-reusable-localstorage-hook</a></div>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://blog.bhanuteja.dev/easily-detect-outside-click-using-useref-hook">https://blog.bhanuteja.dev/easily-detect-outside-click-using-useref-hook</a></div>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://blog.bhanuteja.dev/the-lifecycle-of-react-hooks-component">https://blog.bhanuteja.dev/the-lifecycle-of-react-hooks-component</a></div>
<h2 id="heading-3-advanced-react-hooks">3. Advanced React Hooks</h2>
<blockquote>
<p>We’ll look at some of the more advanced hooks and ways they can be used to optimize your components and custom hooks. We’ll also look at several patterns you can follow to make custom hooks that provide great APIs for developers to be productive building applications.</p>
<p>➖ <strong>Summary Taken From <a target="_blank" href="https://epicreact.dev">EpicReact.Dev</a></strong></p>
</blockquote>
<ul>
<li>Advanced React Hooks Welcome</li>
<li>useReducer: simple Counter</li>
<li>useCallback: custom hooks</li>
<li>useContext: simple counter</li>
<li>useLayoutEffect: auto-growing textarea</li>
<li>useImperativeHandle: scroll to top/bottom</li>
<li>useDebugValue: useMedia</li>
<li>Advanced React Hooks Outro</li>
</ul>
<h2 id="heading-4-advanced-react-patterns">4. Advanced React Patterns</h2>
<blockquote>
<p>Not only learn great patterns you can use but also the strengths and weaknesses of each, so you know which to reach for to provide your custom hooks and components the flexibility and power you need.</p>
<p>➖ <strong>Summary Taken From <a target="_blank" href="https://epicreact.dev">EpicReact.Dev</a></strong></p>
</blockquote>
<ul>
<li>Advanced React Patterns Welcome</li>
<li>Context Module Functions</li>
<li>Compound Components</li>
<li>Flexible Compound Components</li>
<li>Prop Collections and Getters</li>
<li>State Reducer</li>
<li>Control Props</li>
<li>Advanced React Patterns Outro</li>
</ul>
<h2 id="heading-5-react-performance">5. React Performance</h2>
<blockquote>
<p>Learn everything you need to diagnose, profile, and fix performance problems in your React application using the Browser Performance Profiler, React DevTools Profiler, and proven React optimization techniques.</p>
<p>➖ <strong>Summary Taken From <a target="_blank" href="https://epicreact.dev">EpicReact.Dev</a></strong></p>
</blockquote>
<ul>
<li>React Performace Welcome</li>
<li>Code Splitting</li>
<li>useMemo for Expensive Calculations</li>
<li>React.memo for Reducing re-renders</li>
<li>Window Large Lists with react-virtual</li>
<li>Optimize Context Value</li>
<li>Fix Perf Death by a Thousand Cuts</li>
<li>Production Performance Monitoring</li>
<li>React Performance Outro</li>
</ul>
<h2 id="heading-6-testing-react-apps">6. Testing React Apps</h2>
<blockquote>
<p>In this hands-on workshop you'll learn everything you need to test React components and applications with ease and get the knowledge you need to ship your applications with confidence.</p>
<p>➖ <strong>Summary Taken From <a target="_blank" href="https://epicreact.dev">EpicReact.Dev</a></strong></p>
</blockquote>
<ul>
<li>Testing React Apps Welcome</li>
<li>Simple Test with ReactDOM</li>
<li>Simple Test with React Testing Library</li>
<li>Avoid Implementation Details</li>
<li>Form Testing</li>
<li>Mocking HTTP Requests</li>
<li>Mocking Browser APIs and Modules</li>
<li>Context and Custom Render Method</li>
<li>Testing Custom Hooks</li>
<li>Testing React Apps Outro</li>
</ul>
<h2 id="heading-7-react-suspense">7. React Suspense</h2>
<blockquote>
<p>Learn how Suspense works under the hood, preparing you for the future of asynchronous state management.</p>
<p>➖ <strong>Summary Taken From <a target="_blank" href="https://epicreact.dev">EpicReact.Dev</a></strong></p>
</blockquote>
<ul>
<li>React Suspense Welcome</li>
<li>Concurrent Mode</li>
<li>Simple Data-Fetching</li>
<li>Render as You Fetch</li>
<li>useTransition</li>
<li>Cache Resources</li>
<li>Suspense Image</li>
<li>Suspense with a Custom Hook</li>
<li>Coordinate Suspending Components with SuspenseList</li>
<li>React Suspense Outro</li>
</ul>
<h2 id="heading-8-building-an-epic-react-app">8. Building an Epic React App</h2>
<blockquote>
<p>The React and JavaScript ecosystem is full of tools and libraries to help you build your applications. In this (huge) workshop we’ll build an application from scratch using widely supported and proven tools and techniques. We’ll cover everything about building frontend React applications, from the absolute basics to the tricky parts you'll run into building real-world React apps and how to create great abstractions.</p>
<p>➖ <strong>Summary Taken From <a target="_blank" href="https://epicreact.dev">EpicReact.Dev</a></strong></p>
</blockquote>
<ul>
<li>Build an Epic React App Welcome</li>
<li>Walkthrough of Project Setup</li>
<li>Render a React App</li>
<li>Add Styles</li>
<li>Make HTTP Requests</li>
<li>Authentication</li>
<li>Routing</li>
<li>Cache Management</li>
<li>Context</li>
<li>Compound Components</li>
<li>Performance</li>
<li>Render as You Fetch</li>
<li>Unit Testing</li>
<li>Testing Hooks and Components</li>
<li>Integration Testing</li>
<li>E2E Testing</li>
<li>Build an Epic React App Outro</li>
</ul>
<p>I previously wrote an article based on the first workshop (<a target="_blank" href="https://blog.bhanuteja.dev/react-fundamentals">React Fundaments</a>). It was received quite well. But many people were unable to go through it as it is too long. That's why I will be republishing that article too as a part of this series. I will be dividing it into multiple articles this time.</p>
<h2 id="heading-whats-next">What's Next</h2>
<p>In my next article, I will explain the javascript concepts that you need to get familiar with before you deep dive into React. Subscribe to my blog if you don't want to miss the next article in this series.</p>
<h4 id="heading-until-next-time">Until Next Time 👋</h4>
<hr />
<p>If this was helpful to you, Please <strong>Like</strong> and <strong>Share</strong> so that it reaches others as well. To get email notifications on my latest articles, please subscribe to my blog by hitting the <strong>Subscribe</strong> button at the top of the page. You can also follow me on twitter <a target="_blank" href="https://twitter.com/pbteja1998">@pbteja1998</a>.</p>
<hr />
<p>The next article in this series is already live. Click on the link below👇</p>
<div class="hn-embed-widget" id="newsletter"></div>]]></content:encoded></item><item><title><![CDATA[React Fundamentals]]></title><description><![CDATA[In this article, I will discuss very basic React fundamentals. Knowing basic javascript is good enough to follow along with the article. Even though you have been working with React for some time, you might learn some new things or justifications for...]]></description><link>https://blog.bhanuteja.dev/react-fundamentals</link><guid isPermaLink="true">https://blog.bhanuteja.dev/react-fundamentals</guid><category><![CDATA[React]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[JSX]]></category><category><![CDATA[2Articles1Week]]></category><dc:creator><![CDATA[Bhanu Teja Pachipulusu]]></dc:creator><pubDate>Wed, 02 Sep 2020 09:37:04 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1599039334808/ioAbyFP75.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this article, I will discuss very basic React fundamentals. Knowing basic javascript is good enough to follow along with the article. Even though you have been working with React for some time, you might learn some new things or justifications for certain things that you already know from this article.</p>
<blockquote>
<p>This article is HEAVILY based on <a target="_blank" href="https://github.com/kentcdodds/react-fundamentals">React Fundamentals workshop</a> by <a target="_blank" href="https://kentcdodds.com/">Kent C Dodds</a> which will also be a part of <a target="_blank" href="https://epicreact.dev/">Epic React</a> course soon to be released. If you are more like a <code>learning by doing</code> type of person similar to me, head over to the <a target="_blank" href="https://github.com/kentcdodds/react-fundamentals">React Fundamentals</a> repo and follow the instructions in the README. This article is more or less a compilation of things in that repo with my own explanations. I will add some more things to this article in the future based on feedback.</p>
</blockquote>
<p>Table of Contents</p>
<ul>
<li><a class="post-section-overview" href="#basic-javascript-rendered-hello-world">Basic JavaScript-rendered Hello World</a></li>
<li><a class="post-section-overview" href="#intro-to-raw-react-apis">Intro to raw React APIs</a><ul>
<li><a class="post-section-overview" href="#reactcreateelement">React.createElement()</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#using-jsx">Using JSX</a><ul>
<li><a class="post-section-overview" href="#interpolation-in-jsx">Interpolation in JSX</a></li>
<li><a class="post-section-overview" href="#conditionals-and-loops">Conditionals and Loops</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#creating-custom-components">Creating custom components</a><ul>
<li><a class="post-section-overview" href="#proptypes">PropTypes</a></li>
<li><a class="post-section-overview" href="#react-fragments">React Fragments</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#styling">Styling</a><ul>
<li><a class="post-section-overview" href="#inline-css">Inline CSS</a></li>
<li><a class="post-section-overview" href="#regular-css">Regular CSS</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#forms">Forms</a><ul>
<li><a class="post-section-overview" href="#using-refs">Using Refs</a></li>
</ul>
</li>
</ul>
<h2 id="heading-basic-javascript-rendered-hello-world">Basic JavaScript-rendered Hello World</h2>
<p>Let's see how to render Hello World using basic javascript.</p>
<p>My HTML contains a single <code>div</code> with <code>id</code> as <code>root</code></p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">'root'</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>Now, I want to add <code>&lt;div class='container'&gt;Hello World&lt;/div&gt;</code> to that root div.</p>
<p>We can do that using javascript's document API. Let's see how</p>
<pre><code class="lang-js"><span class="hljs-comment">// Fetching the root div element</span>
<span class="hljs-keyword">const</span> rootElement = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'root'</span>)

<span class="hljs-comment">// Creating a new div as per our requirements</span>
<span class="hljs-keyword">const</span> divElement = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'div'</span>)
divElement.textContent = <span class="hljs-string">'Hello World'</span>
divElement.className = <span class="hljs-string">'container'</span>

<span class="hljs-comment">// Appending newly created div element to the root element.</span>
rootElement.append(divElement)
</code></pre>
<p>What we are doing here is very simple.</p>
<ol>
<li>Get a reference to the actual DOM root element</li>
<li>Create a new div element using <code>document.createElement</code> and then set its class and textContent</li>
<li>Append this newly created element to the root div element.</li>
</ol>
<p>This produces the following HTML markup.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">'root'</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">'container'</span>&gt;</span>Hello World<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<h2 id="heading-intro-to-raw-react-apis">Intro to raw React APIs</h2>
<p>Now let's try to use React's raw APIs to create markup that we need instead of (vanilla) javascript.</p>
<p>We need two important APIs to achieve our task. In vanilla javascript. they are:</p>
<pre><code class="lang-js"><span class="hljs-built_in">document</span>.createElement()
rootElement.append(domElement)
</code></pre>
<p>The React's equivalent of these two APIs are:</p>
<pre><code class="lang-js">React.createElement()
ReactDOM.render(reactElement, rootElement)
</code></pre>
<p>Let's see <code>React.createElement()</code> in more detail.</p>
<h3 id="heading-reactcreateelement">React.createElement()</h3>
<p>This accepts three parameters</p>
<ol>
<li>Component or Tag to use to create the element</li>
<li>Props for the component</li>
<li>Children</li>
</ol>
<p>The API looks like <code>React.createElement(component, props, ...children)</code></p>
<p>So, to create an element like <code>&lt;div class='container'&gt;Hello World&lt;/div&gt;</code>, you would do </p>
<pre><code class="lang-js">React.createElement(<span class="hljs-string">'div'</span>, { <span class="hljs-attr">className</span>: <span class="hljs-string">'container'</span> }, <span class="hljs-string">'Hello World'</span>)
</code></pre>
<p>Our HTML will have</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"root"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>Now, to append <code>&lt;div class='container'&gt;Hello World&lt;/div&gt;</code> to the root element using React, we do:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> rootElement = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'root'</span>)

<span class="hljs-keyword">const</span> divElement = React.createElement(<span class="hljs-string">'div'</span>, {<span class="hljs-attr">className</span>: <span class="hljs-string">'container'</span>}, <span class="hljs-string">'Hello World'</span>)

ReactDOM.render(divElement, rootElement)
</code></pre>
<p>Can you see how similar the React's API is to the normal vanilla js document API? </p>
<p>Note that, you can even create nested elements using this.</p>
<p>For example, let's try to create the following markup.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">'container'</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>Hello<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>World<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>To create the above markup</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> rootElement = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'root'</span>)

<span class="hljs-keyword">const</span> helloElement = React.createElement(<span class="hljs-string">'span'</span>, <span class="hljs-literal">null</span>, <span class="hljs-string">'Hello'</span>)
<span class="hljs-keyword">const</span> worldElement = React.createElement(<span class="hljs-string">'span'</span>, <span class="hljs-literal">null</span>, <span class="hljs-string">'World'</span>)
<span class="hljs-keyword">const</span> divElement = React.createElement(<span class="hljs-string">'div'</span>, {<span class="hljs-attr">className</span>: <span class="hljs-string">'container'</span>}, helloElement, worldElement)

ReactDOM.render(divElement, rootElement)
</code></pre>
<p>You can even use a special <code>children</code> prop to add the children like the following</p>
<pre><code class="lang-js">React.createElement(<span class="hljs-string">'div'</span>, {<span class="hljs-attr">className</span>: <span class="hljs-string">'container'</span>, <span class="hljs-attr">children</span>: [helloElement, worldElement]})
</code></pre>
<p>The above code is same as the below code</p>
<pre><code>React.createElement(<span class="hljs-string">'div'</span>, {<span class="hljs-attr">className</span>: <span class="hljs-string">'container'</span>}, helloElement, worldElement)
</code></pre><h2 id="heading-using-jsx">Using JSX</h2>
<p>If you have already been using React or saw the React code any time, you most probably would not have seen <code>React.createElement</code> being used. Instead, you might have seen some code that looks similar to HTML. Let's see what it is.</p>
<p>JSX is HTML-like syntactic sugar on top of raw React APIs. </p>
<p>Let's see an example.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> divElement = <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">'container'</span>&gt;</span>Hello World<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
</code></pre>
<p>The above code is equivalent to </p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> divElement = React.createElement(<span class="hljs-string">'div'</span>, {<span class="hljs-attr">id</span>: <span class="hljs-string">'container'</span>}, <span class="hljs-string">'Hello World'</span>)
</code></pre>
<p>But JSX is not a valid javascript code, so we use a compiler called <code>Babel</code> to convert JSX code to its corresponding <code>React.createElement</code> code.</p>
<p>Now, let's see how easy it is to create the following markup using JSX.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">'container'</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>Hello<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>World<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> rootElement = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'root'</span>)

<span class="hljs-keyword">const</span> divElement = <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'container'</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>Hello<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>World<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>

ReactDOM.render(divElement, rootElement)
</code></pre>
<p>Note that there are some subtle differences between JSX and HTML. </p>
<p>For example, in HTML to add class to an element, we add it like <code>class='container'</code>, whereas in JSX, we need to write <code>className='container'</code>. </p>
<p>There are some other differences when using JSX which I will explain later in the post.</p>
<h2 id="heading-interpolation-in-jsx">Interpolation in JSX</h2>
<p>Since JSX is written in javascript itself, there are some very interesting things which you can do. One of those is using JSX interpolation. It basically gives us the ability to use javascript inside of JSX. Whenever you do interpolation, you would surround it with <code>{</code> and <code>}</code>. This tells the Babel compiler that interpolation is being used here.</p>
<p>For example, take the following code</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> divElement = <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'container'</span>&gt;</span>Hello World<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
</code></pre>
<p>Now, you want the class name and text content to be dynamic, you can do something like</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> divClassName = <span class="hljs-string">'container'</span>
<span class="hljs-keyword">const</span> divTextContent = <span class="hljs-string">'Hello World'</span>

<span class="hljs-keyword">const</span> divElement = <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">{divClassName}</span>&gt;</span>{divTextContent}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
</code></pre>
<p>Can you see the flexibility that interpolation gives us? </p>
<h3 id="heading-conditionals-and-loops">Conditionals and Loops</h3>
<p>You can even add conditionals and loops in JSX</p>
<pre><code class="lang-js">{ condition ? <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Hello World<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span> : <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Goodbye World<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span> }
</code></pre>
<p>As you can see above, to use conditionals in JSX, you would make use of the tertiary operator.</p>
<pre><code class="lang-js">{items.map(<span class="hljs-function">(<span class="hljs-params">item</span>) =&gt;</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{item.id}</span>&gt;</span>{item.title}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>)}
</code></pre>
<p>To use loops, you will use the <code>map</code> function.</p>
<p>You can even use template literals in JSX like</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> element = <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">{</span>`<span class="hljs-attr">item-</span>${<span class="hljs-attr">itemId</span>}`}&gt;</span>{itemContent}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
</code></pre>
<p>To learn more about JSX, head over to <a target="_blank" href="https://reactjs.org/docs/jsx-in-depth.html">JSX in Depth</a> - React's official docs</p>
<h2 id="heading-creating-custom-components">Creating custom components</h2>
<p>Consider the following JSX code</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'container'</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'message'</span>&gt;</span>Hello World<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'message'</span>&gt;</span>Goodbye World<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>Here you can see the code <code>&lt;div className='message'&gt;&lt;/div&gt;</code> is duplicated at two places.</p>
<p>To avoid duplication, the simplest thing we can do is to create a function and then call it instead.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">message</span>(<span class="hljs-params">text</span>) </span>{
    <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'message'</span>&gt;</span>{text}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
}
</code></pre>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'container'</span>&gt;</span>
    {message('Hello World')}
    {message('Goodbye World')}
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>Let's refactor this a bit.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">message</span>(<span class="hljs-params">{children}</span>) </span>{
    <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'message'</span>&gt;</span>{children}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
}
</code></pre>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'container'</span>&gt;</span>
    {message({children: 'Hello World'})}
    {message({children: 'Goodbye World'})}
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>Let's refactor this even more to use React.createElement</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">message</span>(<span class="hljs-params">{children}</span>) </span>{
    <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'message'</span>&gt;</span>{children}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
}
</code></pre>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'container'</span>&gt;</span>
    {React.createElement(message, null, 'Hello World')}
    {React.createElement(message, null, 'Goodbye World')}
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>Previously in all the examples that we have seen, the first argument of React.createElement() is a string like 'span' or 'div'.</p>
<p>But React.createElement also accepts a function that returns something renderable like JSX, some string, number etc.</p>
<p>That's why the above code works.</p>
<p>Now, let's convert the above code to JSX</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">message</span>(<span class="hljs-params">{children}</span>) </span>{
    <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'message'</span>&gt;</span>{children}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
}
</code></pre>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'container'</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">message</span>&gt;</span>Hello World<span class="hljs-tag">&lt;/<span class="hljs-name">message</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">message</span>&gt;</span>Goodbye World<span class="hljs-tag">&lt;/<span class="hljs-name">message</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>The above code seems to be perfect, right? Actually it's not. The above code will not work as intended. The reason being how babel compiles the JSX code to it's corresponding React.createElement() code.</p>
<p><code>&lt;message /&gt;</code> is compiled by babel to <code>React.createElement('message')</code>. But what we want is <code>React.createElement(message)</code>. In the first case, the first argument is a string, in the second case, it's a function.</p>
<p>For the babel to convert it into what we needed, we have to make the <code>message</code> function name uppercase.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Message</span>(<span class="hljs-params">{children}</span>) </span>{
    <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'message'</span>&gt;</span>{children}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
}
</code></pre>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'container'</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">Message</span>&gt;</span>Hello World<span class="hljs-tag">&lt;/<span class="hljs-name">Message</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">Message</span>&gt;</span>Goodbye World<span class="hljs-tag">&lt;/<span class="hljs-name">Message</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>Now, this <code>&lt;Message&gt;Hello World&lt;/Message&gt;</code> will be compiled to <code>React.createElement(Message, {children: 'Hello World'})</code>, which is exactly what we needed.</p>
<p>Check the below examples to see how Babel compiles each of the JSX formats.</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>JSX</td><td>React.createElement()</td></tr>
</thead>
<tbody>
<tr>
<td><code>&lt;Capitalized /&gt;</code></td><td><code>React.createElement(Capitalized)</code></td></tr>
<tr>
<td><code>&lt;property.access /&gt;</code></td><td><code>React.createElement(property.access)</code></td></tr>
<tr>
<td><code>&lt;Property.Access /&gt;</code></td><td><code>React.createElement(Property.Access)</code></td></tr>
<tr>
<td><code>&lt;Property['Access'] /&gt;</code></td><td><code>SyntaxError</code></td></tr>
<tr>
<td><code>&lt;lowercase /&gt;</code></td><td><code>React.createElement('lowercase')</code></td></tr>
<tr>
<td><code>&lt;kebab-case /&gt;</code></td><td><code>React.createElement('kebab-case')</code></td></tr>
<tr>
<td><code>&lt;Upper-Kebab-Case /&gt;</code></td><td><code>React.createElement('Upper-Kebab-Case')</code></td></tr>
<tr>
<td><code>&lt;Upper_Snake_Case /&gt;</code></td><td><code>React.createElement(Upper_Snake_Case)</code></td></tr>
<tr>
<td><code>&lt;lower_snake_case /&gt;</code></td><td><code>React.createElement('lower_snake_case')</code></td></tr>
</tbody>
</table>
</div><p>So, we can see that the component name needs to be UpperCamelCased for it to work as intended.</p>
<h3 id="heading-proptypes">PropTypes</h3>
<p>Let's slightly change the previous message component so that it accepts <code>name</code> prop.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Message</span>(<span class="hljs-params">{name}</span>) </span>{
    <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'message'</span>&gt;</span>Hi, your name is {name}.<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
}
</code></pre>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">Message</span> <span class="hljs-attr">name</span>=<span class="hljs-string">'foo'</span> /&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">Message</span> /&gt;</span>
</code></pre>
<p>This produces</p>
<pre><code>Hi, your name is foo.
Hi, your name is .
</code></pre><p>This doesn't look good. Does it? So what if there is a way we can enforce that the name needs to be passed and it needs to be a string.</p>
<p>Luckily, React gives us a way to do that using <code>PropTypes</code>.
Let's create a <code>PropType</code> to enforce the type of <code>name</code> to be <code>string</code>.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> PropTypes = {
    string(props, propName, componentName) {
        <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> props[propName] !== <span class="hljs-string">'string'</span>) {
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">`In component <span class="hljs-subst">${componentName}</span>, <span class="hljs-subst">${propName}</span> needs to be a string, but it was of type <span class="hljs-subst">${<span class="hljs-keyword">typeof</span> props[propName]}</span>`</span>)
        }
    },
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Message</span>(<span class="hljs-params">{name}</span>) </span>{
    <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'message'</span>&gt;</span>Hi, your name is {name}.<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
}

Message.propTypes = {
    <span class="hljs-attr">name</span>: PropTypes.string,
}
</code></pre>
<p>Now every time you pass anything other than <code>string</code> for <code>name</code> prop, it throws an error.</p>
<p>Since cases like these are so common, the <code>React</code> team developed a library called <a target="_blank" href="https://github.com/facebook/prop-types">prop-types</a> which you can use in a similar way - <code>PropTypes.string.isRequired</code>.  Check out the <a target="_blank" href="https://github.com/facebook/prop-types">repo</a> for more details.</p>
<p>Note that PropTypes will be disabled in a production environment for performance reasons.</p>
<h3 id="heading-react-fragments">React Fragments</h3>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">'root'</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>Let's consider the following use case.
You have to add <code>&lt;span&gt;Hello&lt;/span&gt;</code> and <code>&lt;span&gt;World&lt;/span&gt;</code> to the <code>rootElement</code> using React.</p>
<p>In the end, the markup should look like</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">'root'</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>Hello<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>World<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>Let's see if we can do this.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> rootElement = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'root'</span>)

<span class="hljs-keyword">const</span> elementOne = React.createElement(<span class="hljs-string">'span'</span>, <span class="hljs-literal">null</span>, <span class="hljs-string">'Hello'</span>)
<span class="hljs-keyword">const</span> elementTwo = React.createElement(<span class="hljs-string">'span'</span>, <span class="hljs-literal">null</span>, <span class="hljs-string">'World'</span>)

ReactDOM.render(?????, rootElement)
</code></pre>
<p>Now, what should be in the place of <code>?????</code> in the last line. It can neither be <code>elementOne</code> nor <code>elementTwo</code>, because we want both of them to be rendered (not one). But <code>ReactDOM.render()</code> takes only one react element as an argument and then appends it to rootElement.</p>
<p>One way to achieve this is if we can wrap both of the elements in a new element.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> rootElement = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'root'</span>)

<span class="hljs-keyword">const</span> elementOne = React.createElement(<span class="hljs-string">'span'</span>, <span class="hljs-literal">null</span>, <span class="hljs-string">'Hello'</span>)
<span class="hljs-keyword">const</span> elementTwo = React.createElement(<span class="hljs-string">'span'</span>, <span class="hljs-literal">null</span>, <span class="hljs-string">'World'</span>)

<span class="hljs-keyword">const</span> combinedElement = React.createElement(<span class="hljs-string">'div'</span>, <span class="hljs-literal">null</span>, elementOne, elementTwo)

ReactDOM.render(combinedElement, rootElement)
</code></pre>
<p>The above code may look fine, but it produces different HTML than what we needed.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">'root'</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>Hello<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>World<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>This is the reason why you can't do something like the following in your code.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Message</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>Hello<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span><span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>World<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>
}
</code></pre>
<p>Because there is no way for babel to be able to convert this to a single React.createElement()</p>
<p>React Fragments are introduced in <code>React v16.2.0</code> exactly to solve this problem. Now you can return multiple elements by just wrapping them around with <code>React.Fragment</code>.</p>
<p>For example,</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Message</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">return</span> (
        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">React.Fragment</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>Hello<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>World<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">React.Fragment</span>&gt;</span></span>
    )
}
</code></pre>
<p>React will ignore this <code>React.Fragment</code> when rendering.</p>
<p>So the previous problem can be solved now in the following way.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> elementOne = React.createElement(<span class="hljs-string">'span'</span>, <span class="hljs-literal">null</span>, <span class="hljs-string">'Hello'</span>)
<span class="hljs-keyword">const</span> elementTwo = React.createElement(<span class="hljs-string">'span'</span>, <span class="hljs-literal">null</span>, <span class="hljs-string">'World'</span>)

<span class="hljs-keyword">const</span> combinedElement = React.createElement(React.Fragment, <span class="hljs-literal">null</span>, elementOne, elementTwo)

ReactDOM.render(combinedElement, rootElement)
</code></pre>
<p>There is a short hand representation for <code>React.Fragment</code>. </p>
<p>Instead of writing <code>&lt;React.Fragment&gt;{childrent}&lt;/React.Fragment&gt;</code>, you can write something like <code>&lt;&gt;{children}&lt;/&gt;</code>. Both yield absolutely same result.</p>
<h2 id="heading-styling">Styling</h2>
<p>There are two general ways to style React components.</p>
<ol>
<li>Inline CSS</li>
<li>Regular CSS</li>
</ol>
<p>Let's see inline CSS first</p>
<h3 id="heading-inline-css">Inline CSS</h3>
<p>In normal HTML too, you can add inline styles to your HTML elements by adding your styles as a string to <code>style</code> attribute.</p>
<pre><code>&lt;div style=<span class="hljs-string">"color: red; font-style: italic;"</span>&gt;Red Italic Text&lt;/div&gt;
</code></pre><p>In <code>React</code> also you would add your styles to <code>style</code> prop, but instead of a <code>string</code>, <code>style</code> prop accepts an <code>object</code>.</p>
<p>For example,</p>
<pre><code><span class="hljs-keyword">const</span> elementStyle = {
    <span class="hljs-attr">color</span>: <span class="hljs-string">'red'</span>,
    <span class="hljs-attr">fontStyle</span>: <span class="hljs-string">'italic'</span>
}
</code></pre><pre><code>&lt;div style={elementStyle}&gt;Red Italic Text&lt;/div&gt;
</code></pre><p>You can even inline <code>elementStyle</code> if you like</p>
<pre><code>&lt;div style={{ <span class="hljs-attr">color</span>: <span class="hljs-string">'red'</span>, <span class="hljs-attr">fontStyle</span>: <span class="hljs-string">'italic'</span> }}&gt;
    Red Italic Text
&lt;/div&gt;
</code></pre><p>Another difference with styles in React from that of HTML is property names needs to be <code>camelCased</code> instead of <code>kebab-cased</code>. For example, in React styles, <code>background-color</code> will become <code>backgroundColor</code>, <code>font-style</code> will become <code>fontStyle</code>, etc.</p>
<p>Also the value of the style property is always <code>string</code> or <code>number</code>(since <code>style</code> needs to be a proper javascript object, things like <code>#fff</code> or <code>20px</code> are not proper javascript values). So you cannot write something like <code>fontSize: 20px</code>, instead you need to write <code>fontSize: '20px'</code>. Similarly you cannot write <code>color: #fff</code>, you need to write <code>color: '#fff'</code>.</p>
<h3 id="heading-regular-css">Regular CSS</h3>
<p>Using regular css is straight forward. You just add the classNames and ids that you need and then style your elements using those accrodingly.</p>
<h2 id="heading-forms">Forms</h2>
<p>Consider the following form</p>
<pre><code>&lt;form&gt;
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">htmlFor</span>=<span class="hljs-string">"usernameId"</span>&gt;</span>Username:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"usernameId"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"username"</span> /&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Submit<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
&lt;/form&gt;
</code></pre><p>Now handling forms in React is very similar to how we do in normal javascript. You just define a submit handler and then assign it to the onSubmit event of the form.</p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleSubmit</span>(<span class="hljs-params">event</span>) </span>{
    event.preventDefault()
    <span class="hljs-comment">// You can get the value of username in one of the following ways.</span>
    <span class="hljs-comment">// event.target.elements[0].value</span>
    <span class="hljs-comment">// event.target.elements.usernameId.value</span>
    <span class="hljs-comment">// event.target.elements.username.value</span>
   <span class="hljs-comment">// Do whatever you want with the username</span>
}
</code></pre><h3 id="heading-using-refs">Using Refs</h3>
<p>There is another way to get the reference to an element in React - using Refs.
Refs are special objects in react that stays consistent between rerenders of the component and also changing it will not cause the component to rerender.</p>
<p>You can create a Ref using <code>React.useRef()</code></p>
<pre><code><span class="hljs-keyword">const</span> myRef = React.useRef()
</code></pre><p>Refs will have a <code>current</code> property which contains the value of ref. If you assign a <code>ref</code> to a React element, <code>ref.current</code> will automatically have the reference to the object.</p>
<p>For example</p>
<pre><code>&lt;input ref={myRef} /&gt;
</code></pre><p>Now <code>myRef.current</code> will have reference to that input element.</p>
<p>Let's make use of ref to get the username in our form.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">UsernameForm</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> usernameInputRef = React.useRef()

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleSubmit</span>(<span class="hljs-params">event</span>) </span>{
    event.preventDefault()
    <span class="hljs-comment">// usernameInputRef.current.value will have the value of the input</span>
  }

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">onSubmit</span>=<span class="hljs-string">{handleSubmit}</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">htmlFor</span>=<span class="hljs-string">"usernameInput"</span>&gt;</span>Username:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"usernameInput"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">{usernameInputRef}</span> /&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Submit<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span></span>
  )
}
</code></pre>
<p>Go through <a target="_blank" href="https://reactjs.org/docs/hooks-reference.html#useref">useRef - official docs</a> to learn more about refs.</p>
<p>There is more to learn about React Forms. Go through <a target="_blank" href="https://reactjs.org/docs/forms.html">official docs</a> to learn more.</p>
<blockquote>
<p>This article is HEAVILY based on <a target="_blank" href="https://github.com/kentcdodds/react-fundamentals">React Fundamentals workshop</a> by <a target="_blank" href="https://kentcdodds.com/">Kent C Dodds</a> which will also be a part of <a target="_blank" href="https://epicreact.dev/">Epic React</a> course soon to be released. If you are more like a <code>learning by doing</code> type of person similar to me, head over to the <a target="_blank" href="https://github.com/kentcdodds/react-fundamentals">React Fundamentals</a> repo and follow the instructions in the README. This article is more or less a compilation of things in that repo with my own explanations. I will add some more things to this article in the future based on the feedback that I receive.</p>
</blockquote>
<p>Did you learn anything new from this article? Tell me in the comments.</p>
<p><strong>Links and References</strong></p>
<ul>
<li><a target="_blank" href="https://github.com/kentcdodds/react-fundamentals">React Fundamental Workshop</a> by <a target="_blank" href="https://kentcdodds.com/">Kent C Dodds</a></li>
<li><a target="_blank" href="https://epicreact.dev/">Epic React</a></li>
<li><a target="_blank" href="https://kcd.im/beginner-react">Beginner's Guide to React</a></li>
<li><a target="_blank" href="https://reactjs.org/docs/getting-started.html">React Documentation</a></li>
<li><a target="_blank" href="https://reactjs.org/docs/react-without-jsx.html">React Without JSX</a></li>
<li><a target="_blank" href="https://reactjs.org/docs/introducing-jsx.html">Introducing JSX</a></li>
<li><a target="_blank" href="https://reactjs.org/docs/jsx-in-depth.html">JSX in Depth</a></li>
<li><a target="_blank" href="https://reactjs.org/docs/typechecking-with-proptypes.html">Typechecking with PropTypes</a></li>
<li><a target="_blank" href="https://reactjs.org/docs/fragments.html">React Fragments</a></li>
<li><a target="_blank" href="https://reactjs.org/docs/dom-elements.html#style">Inline Styles</a></li>
<li><a target="_blank" href="https://reactjs.org/docs/faq-styling.html">Styling and CSS</a></li>
<li><a target="_blank" href="https://reactjs.org/docs/forms.html#gatsby-focus-wrapper">Forms</a></li>
<li><a target="_blank" href="https://reactjs.org/docs/hooks-reference.html#useref">useRef</a></li>
</ul>
<div class="hn-embed-widget" id="newsletter"></div>]]></content:encoded></item><item><title><![CDATA[Create Your Own Super Simple URL Shortener]]></title><description><![CDATA[In this article, we will see how to create a simple URL shortener. We will be using Netlify Redirects and a package called netlify-shortener.
I have always wanted to create my own URL shortener and use it to shorten all my links. But I always felt li...]]></description><link>https://blog.bhanuteja.dev/create-your-own-super-simple-url-shortener</link><guid isPermaLink="true">https://blog.bhanuteja.dev/create-your-own-super-simple-url-shortener</guid><category><![CDATA[General Programming]]></category><category><![CDATA[Netlify]]></category><category><![CDATA[programming]]></category><category><![CDATA[2Articles1Week]]></category><dc:creator><![CDATA[Bhanu Teja Pachipulusu]]></dc:creator><pubDate>Sat, 29 Aug 2020 06:17:03 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1598677336273/JnyqFHnQS.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this article, we will see how to create a simple URL shortener. We will be using <a target="_blank" href="https://docs.netlify.com/routing/redirects/">Netlify Redirects</a> and a package called <a target="_blank" href="https://github.com/kentcdodds/netlify-shortener">netlify-shortener</a>.</p>
<p>I have always wanted to create my own URL shortener and use it to shorten all my links. But I always felt like creating it would take a lot of effort, although I never actually gave much thought to it. </p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://twitter.com/kentcdodds/status/1296524239701327873?s=20">https://twitter.com/kentcdodds/status/1296524239701327873?s=20</a></div>
<p>But I came across a tweet containing a link to the video which showed how to create a simple URL shortener. This blog post is my attempt to share that approach with you.</p>
<p>Before we see how to create your own URL shortener, let's see why having a URL shortener can be useful.</p>
<p>If you are already convinced that having your own URL shortener can be useful, you can skip this section and directly jump to <a class="post-section-overview" href="#creating-your-own-url-shortener">Creating Your Own URL Shortener</a> section.</p>
<h2 id="heading-benefits-of-shortening-your-urls">Benefits of Shortening Your URLs</h2>
<h3 id="heading-it-masks-the-original-links">It masks the original links.</h3>
<p>Masking the URL has many advantages</p>
<p>For example, take this URL - <code>hashnode.com/series/how-i-made-a-markdown-editor-with-ability-to-embed-youtube-videos-codepens-etc-cke6g1y2x00afxms17vp30803</code></p>
<p>This URL is the link to the series that I am writing on <a class="user-mention" href="https://hashnode.com/@hashnode">Hashnode</a> where I am developing a full-featured Markdown editor from scratch. But, the URL is so long and difficult to read and share on platforms like twitter. </p>
<p>Instead, wouldn't it be nice to have a simple short URL like <code>pbt.im/markdown-series</code> which redirects to the above URL. It's short, crisp, readable, and also equally conveys what one can expect in that link.</p>
<h3 id="heading-sharing-affiliate-links">Sharing affiliate links.</h3>
<p>Other places where URL shortening can be useful is when you want to share or brand an ugly affiliate link, or when the domain of the link that you want to share is very long.</p>
<h3 id="heading-social-media-profiles">Social Media Profiles</h3>
<p>Take a look at some of the shortened links that I frequently use. </p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Link</td><td>Description</td></tr>
</thead>
<tbody>
<tr>
<td>pbt.im/github (or) pbt.im/gh</td><td>My GitHub Profile</td></tr>
<tr>
<td>pbt.im/linkedin (or) pbt.im/li</td><td>My LinkedIn Profile</td></tr>
<tr>
<td>pbt.im/twitter (or) pbt.im/t</td><td>My Twitter Profile</td></tr>
<tr>
<td>pbt.im/hn</td><td>My Hashnide Profile</td></tr>
<tr>
<td>pbt.im/site</td><td>My Personal Website</td></tr>
<tr>
<td>pbt.im/resume</td><td>My Resume</td></tr>
<tr>
<td>pbt.im/blog</td><td>My Personal Blog</td></tr>
<tr>
<td>pbt.im/projects</td><td>My Personal Projects</td></tr>
<tr>
<td>pbt.im/new</td><td>When I want to write a new blog</td></tr>
<tr>
<td>pbt.im/drafts</td><td>When I want to look at my drafts</td></tr>
<tr>
<td>...</td><td>....</td></tr>
</tbody>
</table>
</div><p>Sharing the above links is so easy. You don't even have to copy them. You can just type them out yourself. They are short, consistent, readable and can easily be remembered.</p>
<h3 id="heading-links-can-change">Links can change</h3>
<p>Another disadvantage of sharing normal links is that the links can potentially change in the future. </p>
<p>If they do change, you can't hunt down every post and every place where you posted or shared that link and then update it. And it might not always be feasible to redirect the old URL to a new URL. </p>
<p>Shortened links can come in very handy in this situation. The shortened link that you share need not change ever. Whereas the URL that the short link should redirect to can change as you wish.</p>
<h3 id="heading-bookmarks">Bookmarks</h3>
<p>I even started using my URL shortener to create bookmarks. I added a short URL(<code>/bookmarks</code>) that redirects to a GitHub page which contains all my other short URLs. Then whenever I want to bookmark a very useful URL, instead of bookmarking it normally, I started shortening it, which will automatically add it to my list of short URLs (which means it will also be available at <code>/bookmarks</code>)</p>
<p>Now that we saw some of the reasons of how shortened URLs can help us, let's see how to create one yourself.</p>
<h2 id="heading-creating-your-own-url-shortener">Creating Your Own URL Shortener</h2>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://twitter.com/kentcdodds/status/1296524239701327873?s=20">https://twitter.com/kentcdodds/status/1296524239701327873?s=20</a></div>
<p>This is the tweet that inspired me to explore and create a URL shortener for shortening my links. I finally ended up using the approach that Kent suggested. I will be explaining the same in this article.</p>
<h3 id="heading-netlify-redirects">Netlify Redirects</h3>
<p>Before we jump into the actual content, let's see what Netlify redirects are. Netlify gives us an easy way to handle redirects for any site that is hosted on the platform. All you have to do is create a <code>_redirects</code> file and then add the redirect rules in that file.</p>
<blockquote>
<p>In a <code>_redirects</code> file, each redirect rule must be listed on a separate line, with the original path followed by the new path or URL. Any line beginning with # will be ignored as a comment.</p>
<p>Here is an example:</p>
<pre><code># Redirects <span class="hljs-keyword">from</span> what the browser requests to what we serve
/home              /
<span class="hljs-regexp">/blog/my</span>-post.php  /blog/my-post
/news              /blog
/cuties            https:<span class="hljs-comment">//www.petsofnetlify.com</span>
</code></pre></blockquote>
<p>This is the bare minimum that you need to create your own URL shortener. </p>
<ul>
<li>Create an empty project with a single file called <code>_redirects</code>.</li>
<li>Add your short and complete URLs there.</li>
<li>Deploy that project to Netlify. </li>
</ul>
<p>You now have your own simple URL shortener. </p>
<p>Every time you want to add a new URL, you can just add it in the <code>_redirects</code> file and then deploy it. If using this workflow is good enough for you, you can stop here and use it.</p>
<p>But Kent went a step further and created a package called <a target="_blank" href="https://github.com/kentcdodds/netlify-shortener">netlify-shortener</a> which simplifies the workflow of creating short URLs even further.</p>
<p>Follow these steps to start using <code>netlify-shortener</code> and set up your own URL shortener</p>
<h4 id="heading-step-1-create-an-empty-project">Step 1: Create an empty project</h4>
<pre><code>mkdir url-shortener
cd url-shortener
</code></pre><h4 id="heading-step-2-initialize-it-as-npm-project">Step 2: Initialize it as npm project</h4>
<pre><code>npm init -y
</code></pre><h4 id="heading-step-3-create-a-redirects-file-and-add-the-following-content">Step 3: Create a <code>_redirects</code> file and add the following content.</h4>
<pre><code class="lang-sh"><span class="hljs-comment"># fallback</span>
/*       https://your-website.com
</code></pre>
<p><code>your-website.com</code> will act as a fallback when the URL doesn't match any of the available short URLs. Replace it with whatever URL you want to have as a fallback.</p>
<h4 id="heading-step-4-add-homepage-and-shorten-script-to-your-packagejson-add-your-own-short-domain-url-to-the-homepage">Step 4: Add homepage and shorten script to your package.json (Add your own short domain URL to the homepage)</h4>
<pre><code class="lang-json">{
  <span class="hljs-attr">"homepage"</span>: <span class="hljs-string">"https://pbt.im"</span>,
  <span class="hljs-attr">"scripts"</span>: {
    <span class="hljs-attr">"shorten"</span>: <span class="hljs-string">"netlify-shortener"</span>
  }
}
</code></pre>
<p>Now, you can run the following commands.</p>
<pre><code># Formats your _redirects file
npm run shorten 

# Generates a short code and adds it <span class="hljs-keyword">for</span> you
npm run shorten https:<span class="hljs-comment">//yahoo.com</span>

# Adds gh <span class="hljs-keyword">as</span> a short URL <span class="hljs-keyword">for</span> https:<span class="hljs-comment">//github.com</span>
npm run shorten https:<span class="hljs-comment">//github.com gh</span>
</code></pre><p>The <code>npm run shorten</code> command</p>
<ul>
<li>Generates a shortcode automatically if it is not provided.</li>
<li>Validates your URL.</li>
<li>Automatically check for URL collisions and throws an error if there is a collision.</li>
<li>Adds the URL to the top of the <code>_redirects</code> file and reformats the file properly.</li>
<li>Pulls the changes from remote, adds the new shortened URL, commits the code, and then pushes the commit to the remote again.</li>
<li>Automatically copies the short URL to your clipboard.</li>
</ul>
<p>You don't even have to provide <code>https://</code>, by default it assumes that the original link is <code>https://</code></p>
<p>You can even add it as a global command in your shell using <a target="_blank" href="https://github.com/kentcdodds/netlify-shortener#shell-function">these instructions</a></p>
<h3 id="heading-my-workflow-for-shortening-a-url">My workflow for shortening a URL</h3>
<p>Open the terminal and simply write <code>shorten original-URL short-slug</code>. </p>
<p>For example, to shorten the link to my Github profile, I will run the following command </p>
<pre><code>shorten github.com/pbteja1998 gh
</code></pre><h2 id="heading-tl-dr">TL; DR</h2>
<ul>
<li>Checkout <a target="_blank" href="https://github.com/kentcdodds/netlify-shortener">netlify-shortener</a></li>
<li>Checkout demo at kcd.im/shortener</li>
</ul>
<p>If you have any more questions or want to explore more about this, go to <a target="_blank" href="https://github.com/kentcdodds/netlify-shortener">netlify-shortener</a>. The instructions that are in there are very clear, There is also a youtube video explaining this process at kcd.im/shortener</p>
<p><em>Which URL do you prefer when sharing in social media or with others? Short URL or the original one? Tell me in the comments.</em></p>
<p><strong>Links and References:</strong></p>
<ul>
<li><a target="_blank" href="https://docs.netlify.com/routing/redirects/">Netlify Redirects</a></li>
<li><a target="_blank" href="https://github.com/kentcdodds/netlify-shortener">Netlify Shortener</a></li>
<li><a target="_blank" href="kcd.im/shortener">Watch a Demo</a></li>
<li><a target="_blank" href="https://github.com/kentcdodds/netlify-shortener-example">Example Repo</a></li>
</ul>
<div class="hn-embed-widget" id="newsletter"></div>]]></content:encoded></item><item><title><![CDATA[Why you should start using HSL color format]]></title><description><![CDATA[Look at the picture above and see if you can tell that they are different shades of red color? You can, right?
Now, look at their hex and RGB values below, now can you tell the same thing by looking at these values? Or can you tell if there is any re...]]></description><link>https://blog.bhanuteja.dev/why-you-should-start-using-hsl-color-format</link><guid isPermaLink="true">https://blog.bhanuteja.dev/why-you-should-start-using-hsl-color-format</guid><category><![CDATA[CSS]]></category><category><![CDATA[CSS3]]></category><category><![CDATA[2Articles1Week]]></category><dc:creator><![CDATA[Bhanu Teja Pachipulusu]]></dc:creator><pubDate>Fri, 28 Aug 2020 08:08:30 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1598601573117/-LBBlmoAP.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1598594019852/cDI1SSmy0.png" alt="red123.png" /></p>
<p>Look at the picture above and see if you can tell that they are different shades of red color? You can, right?</p>
<p>Now, look at their <code>hex</code> and <code>RGB</code> values below, now can you tell the same thing by looking at these values? Or can you tell if there is any relationship between these three colors by just looking at their hex or RGB values?</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Format</td><td>Color #1</td><td>Color #2</td><td>Color #3</td></tr>
</thead>
<tbody>
<tr>
<td>RGB</td><td>169, 4, 4</td><td>220, 91, 91</td><td>239, 169, 169</td></tr>
<tr>
<td>Hex</td><td>#a90404</td><td>#dc5b5b</td><td>#efa9a9</td></tr>
</tbody>
</table>
</div><p>This is one of the many problems that <code>HSL</code> coloring format fixes. </p>
<h2 id="heading-rgb-color-format-what-is-it">RGB Color Format - What is it?</h2>
<p><code>RGB</code> colors and <code>HEX</code> color formats are designed by keeping the computer in mind like add some x parts of red, and y parts of green and z parts of blue, the resulting color you get is the color (x, y, z). But as humans, we will not be able to tell the resultant color that we will get with (x, y, z).</p>
<h2 id="heading-hsl-system">HSL System</h2>
<p>HSL color format represents the color based on the attributes that the human eye perceives naturally - <strong>Hue</strong>, <strong>Saturation</strong>, and <strong>Lightness</strong>.</p>
<p>Let's look at each one of these below.</p>
<h3 id="heading-hue">Hue</h3>
<p>To understand what hue is, you need to know about the color wheel. Look at the picture below.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1597583116289/j1Ta94EKu.png" alt="wheel.png" /></p>
<p>Each degree in the above color wheel represents a different color. For example, 0° is red, 120° is green, 240° is blue. </p>
<p>Hue is the position of the color on this color wheel. For example, if we want a shade of red color, we will select hue as 0 which is equivalent to selecting color at 0°. </p>
<p>This is the attribute in HSL that helps us to identify that the following three colors are red even though they are different.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1598594019852/cDI1SSmy0.png" alt="red123.png" /></p>
<h3 id="heading-saturation">Saturation</h3>
<p>Saturation tells us how clear a color looks. For example, 100% saturation is the most intense color that we can get for a specific hue, whereas 0% saturation implies that the color is grey.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1598599601650/hBb3F5_Hx.png" alt="saturation-02.4f198654.png" /></p>
<p>If the saturation is 0%, then the color will not change even though the hue changes. </p>
<p>So, you can say that saturation is the attribute that gives a hue its color.</p>
<h3 id="heading-lightness">Lightness</h3>
<p>Lightness tells us how white or black a particular color is. 0% lightness indicates that the color is pure black and 100% lightness indicates that the color is pure white.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1598599612769/4-WCYdzGo.png" alt="lightness-03.dacb2988.png" /></p>
<p>So, to get the purest form of a color, you would set the saturation to 100% and lightness to 50%.</p>
<p>For example, the purest form of red, green, and blue colors is as follows.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1598600086766/PxwF57IDK.png" alt="rgb.png" /></p>
<p>Their respective hsl values are (0°, 100%, 50%), (120°, 100%, 50%) and (240°, 100%, 50%)</p>
<h2 id="heading-color-schemes">Color Schemes</h2>
<p>Now that we know what h, s, l means in HSL. Let's see how we can use this to create various color palettes.</p>
<h3 id="heading-complementary-colors">Complementary Colors</h3>
<p>Let's pick some random color first.
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1598594356238/8dE2HlCt3.png" alt="Screenshot 2020-08-28 at 11.29.08 AM.png" /></p>
<p>The HSL values of this color are 74°, 53%, 55%</p>
<p>Now, if we want to get a complementary color to this, we just pick the color that is opposite to the above color in the color wheel. It's similar to saying add 180° to the hue of above color. We get 254°, 53%, 55%</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1598594485137/VfObm8zYk.png" alt="Screenshot 2020-08-28 at 11.31.16 AM.png" /></p>
<p>Some other complementary colors that are generated in this way:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1598594780905/INler1r-6.jpeg" alt="merge_from_ofoct.jpg" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1598594776874/icXonOqJy.jpeg" alt="merge_from_ofoct (1).jpg" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1598595734761/LHFPJEVAi.png" alt="orange and cobalt blue.png" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1598595739381/ZteHi9Ija.png" alt="ps.png" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1598595746324/Vl4wY5O8R.png" alt="red and phthalo cyan.png" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1598595752180/dzJFbdUNe.png" alt="reds.png" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1598595760244/XbtXzBaUC.png" alt="yellow and ultramarine blue ( violet blue ).png" /></p>
<h3 id="heading-triadic-colors">Triadic Colors</h3>
<p>Similarly, you can even generate triadic colors in this method. Triadic colors are colors that are equidistant from each other in the color wheel. So you would just be adding 120° to the hue of the first color to generate the second color, and then you would be adding 120° to the second color to get the third color.</p>
<p>The most common example of a set of triadic colors is red, green, blue. You can generate any color using a set of triadic colors.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1598600086766/PxwF57IDK.png" alt="rgb.png" /></p>
<h3 id="heading-split-complementary-colors">Split Complementary Colors.</h3>
<p>While selecting split complementary colors, you would first fix a color, then get its complementary color. Then you select two colors that are equidistant from the complementary color.</p>
<p>For example, the following three colors are split complementary colors. Their corresponding hex values are <code>(0°, 100%, 50%)</code>, <code>(150°, 100%, 50%)</code>, and <code>(210°, 100%, 50%)</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1598596627088/aI9TqVIaH.png" alt="split.png" /></p>
<h3 id="heading-creating-different-shades-of-same-color">Creating Different Shades of Same Color</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1598597377248/iXm2QU52P.png" alt="99.png" /></p>
<p>Creating a color palette such as the above is so easy with HSL. Let's see how I made the above palette.</p>
<p>I started with a pure form of red color - (0°, 100%, 50%)</p>
<p>Now, I increased and decreased the lightness by 10%. I ended up with the following colors.</p>
<p>(0°, 100%, 10%)<br />(0°, 100%, 20%)<br />(0°, 100%, 30%)<br />(0°, 100%, 40%)<br />(0°, 100%, 50%)<br />(0°, 100%, 60%)<br />(0°, 100%, 70%)<br />(0°, 100%, 80%)<br />(0°, 100%, 90%)<br />This is exactly the color palette that is shown in the above image.</p>
<p>Just for the sake of clarity, I took the purest form of red. But you can start with any combination of hue, saturation, and lightness, and you will be able to create different shades of that color very easily.</p>
<p>You can do so much more with HSL once you understand it properly. I will leave it up to you to explore more.</p>
<h2 id="heading-tl-dr">TL; DR</h2>
<ul>
<li><strong>HSL</strong> system represents colors using the attributes that the human eye perceives naturally.</li>
<li><strong>H</strong> in <strong>HSL</strong> stands for Hue - The position(degree) of the color in <a target="_blank" href="https://cdn.hashnode.com/res/hashnode/image/upload/v1597583116289/j1Ta94EKu.png"><strong>color wheel</strong></a>.</li>
<li><strong>S</strong> in <strong>HSL</strong> stands for <strong>Saturation</strong> - Represents how intense and vivid a particular color is. It ranges from <strong>0%</strong>(grey) to <strong>100%</strong>(purest form).</li>
<li><strong>L</strong> in <strong>HSL</strong> stands for <strong>Lightness</strong> - Represents how light or dark a color is. It ranges from <strong>0%</strong>(black) to <strong>100%</strong>(white). <strong>50%</strong> is the purest form.</li>
<li>The purest form of any color at a specific hue can be found at <code>saturation of 100%</code> and a <code>lightness of 50%</code>.</li>
<li>You can get the <strong>complementary</strong> color of a given color by just <code>adding 180° to the hue</code> of the given color.</li>
<li>You can get the <strong>triadic</strong> color set by first choosing a color, then <code>adding 120°</code> to the hue of the first color to get the second color, then <code>again adding 120°</code> to the hue of the second color to get the third color.</li>
<li>You can get the <strong>split complementary</strong> colors of a given color, by first finding the complementary color of the given color, then <code>adding and subtracting an equal number of degrees</code> to the hue of complementary color to get the two split complementary colors.</li>
<li>You will be able to generate different shades of a given color by just increasing and decreasing the lightness of a color.</li>
</ul>
<p>I hope I have given you enough reasons and hopefully convinced you to ditch RGB and HEX based color formats and start using HSL based color format. </p>
<p><em>Which color format do you currently use? Would you make the switch to the HSL color format now? Tell me in the comments.</em></p>
<p><strong>Links and References</strong></p>
<ul>
<li><a target="_blank" href="https://sujansundareswaran.com/blog/why-hsl-is-better-than-hex-and-rgb">Why you should use HSL over other colour formats in your CSS</a></li>
</ul>
<div class="hn-embed-widget" id="newsletter"></div>]]></content:encoded></item></channel></rss>