<?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" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Devin Lane - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Devin Lane - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sat, 23 May 2026 16:26:52 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/author/DevinCLane/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Build a Counter Button with React, TailwindCSS, and TypeScript ]]>
                </title>
                <description>
                    <![CDATA[ How can you keep track of the number of times a user clicks a button? How are the hearts on Instagram or the likes on Facebook counted?  In this tutorial, we will build a button that tracks the number of times a button has been clicked. Along the way... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/build-a-counter-button-with-react/</link>
                <guid isPermaLink="false">66bce123d84f19f03de63fd1</guid>
                
                    <category>
                        <![CDATA[ projects ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tailwind ]]>
                    </category>
                
                    <category>
                        <![CDATA[ TypeScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Devin Lane ]]>
                </dc:creator>
                <pubDate>Wed, 10 Jul 2024 14:41:14 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/07/Build-a-counter-button-with-React-6-.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>How can you keep track of the number of times a user clicks a button? How are the hearts on Instagram or the likes on Facebook counted? </p>
<p>In this tutorial, we will build a button that tracks the number of times a button has been clicked. Along the way, you will learn some fundamental concepts in React such as components, JSX, passing props between components, and managing state with hooks. You will also get small introductions to Tailwind and TypeScript.</p>
<p>This tutorial builds upon examples and concepts outlined in the "Learn" section of the React documentation, which you can find <a target="_blank" href="https://react.dev/learn">here</a>.</p>
<h3 id="heading-prerequisites">Prerequisites</h3>
<ul>
<li>Basic familiarity with JavaScript, such as working with variables, functions, arrays, and objects. </li>
<li>Basic familiarity with CSS and HTML.</li>
<li>Basic familiarity with the command line.</li>
<li><a target="_blank" href="https://nodejs.org/en">Node</a> installed.</li>
<li>A code editor of your choice (I'll be using <a target="_blank" href="https://code.visualstudio.com/">Visual Studio Code</a> here)</li>
</ul>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ol>
<li><a class="post-section-overview" href="#heading-chapter-1-how-to-build-the-counter-button">How to Build the Counter Button</a></li>
<li><a class="post-section-overview" href="#heading-chapter-2-how-to-refactor-the-project">How to Refactor the Project</a></li>
<li><a class="post-section-overview" href="#heading-chapter-3-two-components-with-independent-and-shared-state">Two Components with Independent and Shared State</a></li>
<li><a class="post-section-overview" href="#heading-chapter-4-how-to-add-both-pairs-of-buttons-to-our-site">How to Add Both Pairs of Buttons to our Website</a></li>
<li><a class="post-section-overview" href="#heading-chapter-5-how-to-deploy-the-site-to-netlify">How to Deploy the Site to Netlify</a></li>
</ol>
<h2 id="heading-chapter-1-how-to-build-the-counter-button">Chapter 1: How to Build the Counter Button</h2>
<h3 id="heading-what-is-react">What is React?</h3>
<p>Before we dive in, let's define React. <a target="_blank" href="https://react.dev/">React</a> is a JavaScript library for creating user interfaces out of pieces called <em>components</em>. Components are JavaScript functions that can receive and display data interactively to your users.</p>
<h3 id="heading-project-setup">Project setup</h3>
<p>We're going to use <a target="_blank" href="https://nextjs.org/">Next.js</a> for our local React setup.</p>
<p>Within the directory you'd like to store this project, open your terminal and execute the following command:</p>
<pre><code class="lang-zsh">npx create-next-app@latest
</code></pre>
<p>Name your project however you like, and answer the commands as follows:</p>
<pre><code class="lang-zsh">What is your project named? react-counter-button
Would you like to use TypeScript? Yes
Would you like to use ESLint? Yes
Would you like to use Tailwind CSS? Yes
Would you like to use `src/` directory? No
Would you like to use App Router? (recommended) Yes
Would you like to customize the default import <span class="hljs-built_in">alias</span> (@/*)? No
</code></pre>
<p>Now let's <code>cd</code> into our project directory</p>
<pre><code class="lang-zsh"><span class="hljs-built_in">cd</span> react-counter-button
</code></pre>
<p>And run the project in Visual Studio Code:</p>
<pre><code class="lang-zsh">code .
</code></pre>
<p>Note: if you don't have the <code>code</code> command in your PATH, you can press ⇧⌘P (Ctrl+Shift+P on Windows/Linux) and type in 'Shell Command: Install 'code' command in PATH'. Alternatively, you can drag the folder onto the Visual Studio Code icon in MacOS. Or, within Visual Studio Code, you can select File -&gt; Open, and find "react-counter-button", or the name of your project. </p>
<p>In your terminal run:</p>
<pre><code class="lang-zsh">npm run dev
</code></pre>
<p>Open your browser to <code>localhost:3000</code> and you should see the following page:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/Screenshot-2023-10-14-at-7.10.35-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Next.js boilerplate</em></p>
<p>We now have the project up and running. Back over in our code editor, we can begin the work.</p>
<h3 id="heading-remove-boilerplate">Remove boilerplate</h3>
<p>In <code>app/page.tsx</code>, let's delete most of the boilerplate code except the two <code>main</code> tags. Then let's add a title for our project in an <code>h1</code> tag in between the <code>main</code> tags. Our code should look like this:</p>
<pre><code class="lang-js"><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">main</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex min-h-screen flex-col items-center justify-between p-24"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>React Counter Button<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</span></span>
    );
}
</code></pre>
<p>Here's what we should now see:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/Screenshot-2023-10-16-at-8.22.30-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Initial state of our project</em></p>
<h3 id="heading-writing-our-first-component">Writing our first component</h3>
<p>Let's create our first component. A React component is a function that returns markup. Below and outside of the scope of our <code>Home</code> function, let's write the following:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Button</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">button</span>&gt;</span>I have been clicked X times<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>;
}
</code></pre>
<p>Here we have a function <code>Button</code> that returns some markup in JSX. JSX looks a lot like HTML, but it can display dynamic content, and has stricter rules than HTML. You can learn more about JSX in the React docs <a target="_blank" href="https://react.dev/learn/writing-markup-with-jsx">here</a>.</p>
<p>The <code>Button</code> function must be uppercase to be recognized as a valid React component. This contrasts it with an HTML tag, which is lower case.</p>
<p>You'll notice that we still see no change on our webpage – we need to render this component in order to see it on the screen. </p>
<p>We can use our <code>Button</code> component as if it were an HTML tag we created. If we nest the <code>Button</code> component within the <code>Home</code> component, we should see it on the screen:</p>
<pre><code class="lang-js"><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">main</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex min-h-screen flex-col items-center justify-between p-24"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>React Counter Button<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">Button</span> /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</span></span>
    );
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Button</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">button</span>&gt;</span>I have been clicked X times<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>;
}
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/Screenshot-2023-10-20-at-6.37.57-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Rendering the <code>Button</code> component (with less than ideal CSS)</em></p>
<h3 id="heading-styling-our-first-component-with-tailwind">Styling our first component with Tailwind</h3>
<p>You'll notice the button is on the bottom of the screen. This is because the styles on <code>main</code> include <code>justify-between</code> in the <code>flex-col</code> direction. If we remove <code>justify-between</code> we should see this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/Screenshot-2023-10-20-at-6.36.57-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Improving the CSS of the initial state of our application</em></p>
<p>You can read more about aligning items in a flexbox from MDN <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Aligning_Items_in_a_Flex_Container">here</a>.</p>
<p>You'll also notice that the button is un-styled. This is because <a target="_blank" href="https://tailwindcss.com/">Tailwind</a> removes default styling on buttons as a part of their "preflight" styles. If you're curious to see where these styles come from, you can open <code>node_modules/tailwindcss/src/css/preflight.css</code> and check out ~line 193 (permalink on GitHub <a target="_blank" href="https://github.com/tailwindlabs/tailwindcss/blob/332347ed834a3078547923ccfddc1c22035011b6/packages/tailwindcss/preflight.css#L182">here</a>):</p>
<pre><code class="lang-css"><span class="hljs-comment">/*
1. Correct the inability to style clickable types in iOS and Safari.
2. Remove default button styles.
*/</span>

<span class="hljs-selector-tag">button</span>,
<span class="hljs-selector-attr">[type=<span class="hljs-string">'button'</span>]</span>,
<span class="hljs-selector-attr">[type=<span class="hljs-string">'reset'</span>]</span>,
<span class="hljs-selector-attr">[type=<span class="hljs-string">'submit'</span>]</span> {
  <span class="hljs-attribute">-webkit-appearance</span>: button; <span class="hljs-comment">/* 1 */</span>
  <span class="hljs-attribute">background-color</span>: transparent; <span class="hljs-comment">/* 2 */</span>
  <span class="hljs-attribute">background-image</span>: none; <span class="hljs-comment">/* 2 */</span>
}
</code></pre>
<p>We're not going to change the styles within <code>node_modules</code> – instead we'll add our own styling to the Button component. One of the benefits of Tailwind is that our CSS is co-located with our JavaScript, making quick changes to styles easier than opening a separate stylesheet file. </p>
<p>Let's make the following changes:</p>
<pre><code class="lang-js"><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">main</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex min-h-screen flex-col items-center p-24 gap-4"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>React Counter Button<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">Button</span> /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</span></span>
    );
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Button</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">button</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"bg-blue-500 hover:bg-blue-700 rounded text-white font-bold px-4 py-2"</span>&gt;</span>
            I have been clicked X times
        <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
    );
}
</code></pre>
<p>We've added styles to our button, and we've also added a <code>gap-4</code> to our <code>main</code> parent flex box to provide a space between the <code>h1</code> and the <code>button</code>. (You can read more about the CSS property "gap" in the MDN <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/gap">here</a>.) We should now see this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/Screenshot-2023-10-20-at-6.49.22-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Viewing our styled <code>Button</code> component</em></p>
<h3 id="heading-wait-but-what-is-tailwind">Wait, but what is Tailwind?</h3>
<p>Now that we've styled our button component and spaced the items out, let's reflect on what Tailwind is, and what it provided for us. <a target="_blank" href="https://tailwindcss.com/">Tailwind</a> is a CSS framework that provides a set of "utility" classes that we can use to style each element. </p>
<p>But what is a utility class? You'll see that to style our button, we added classes such as <code>bg-blue-500</code> – which corresponds to setting the CSS <code>background-color</code> property to blue, and <code>rounded</code> – which corresponds to <code>border-radius: 0.25rem</code>. </p>
<p>Each class is defined according to its <em>utility:</em> changing the background color, the border radius, and so on. Through adding these utility classes to our elements, we arrive at our desired styles. </p>
<p>Tailwind sits in contrast to other frameworks, such as Bootstrap, that provide predefined classes for elements such as buttons. In Bootstrap, we would add a class of <code>btn</code> to achieve a styled button. And of course, with standard CSS we would likely add a custom class (perhaps called <code>button</code>) to our element and create CSS rulesets in a separate stylesheet. </p>
<p>Returning to our project, so far we've set up a React project using Next.js, created our first React component, and styled our button using Tailwind. How do we introduce the counter functionality?</p>
<h3 id="heading-how-to-add-state">How to add state</h3>
<p>In order to display the number of times a button has been clicked, we need to use an event handler, and we need a way to manage <em>state.</em> </p>
<p><a target="_blank" href="https://react.dev/learn/state-a-components-memory">State</a> is component-specific memory. In our example, this is how the button will remember how many times it has been clicked. Using a special React function "<a target="_blank" href="https://react.dev/reference/react/hooks">hook</a>", we trigger a re-render and retain the data across renders – the <code>[useState](https://react.dev/reference/react/useState)</code> hook is provided by React for this purpose. </p>
<p>At the top of our <code>page.tsx</code>, let's import <code>useState</code>: </p>
<p><code>import { useState } from "react"</code></p>
<p>and within our <code>Button</code> component, let's add the following:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Button</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">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">"bg-blue-500 hover:bg-blue-700 rounded py-2 px-4 text-white font-bold"</span>&gt;</span>
            I have been clicked X times
        <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
    );
}
</code></pre>
<p>Let's unpack what we have here: </p>
<ul>
<li>We're using the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment">destructuring assignment</a> to get the values of <code>count</code> and the function <code>setCount</code> from <code>useState</code>. The convention is to name these two values <code>something</code> and <code>setSomething</code>, though we could name them anything. </li>
<li>The argument to <code>useState</code> is the initial value of our state variable. Here we've set it to 0.</li>
<li><code>count</code> is our current state.</li>
<li><code>setCount</code> is the function that updates our state and triggers a re-render. </li>
</ul>
<p>However, if you click save you'll see the following error in your terminal and in your browser:</p>
<pre><code class="lang-zsh">You<span class="hljs-string">'re importing a component that needs useState. It only works in a Client Component but none of its parents are marked with "use client", so they'</span>re Server Components by default.
Learn more: https://nextjs.org/docs/getting-started/react-essentials

   ╭─[/[...your project path]/src/app/page.tsx:1:1]
 1 │ import { useState } from <span class="hljs-string">"react"</span>;
   ·          ────────
 2 │ 
 3 │ <span class="hljs-built_in">export</span> default <span class="hljs-keyword">function</span> <span class="hljs-function"><span class="hljs-title">Home</span></span>() {
 4 │     <span class="hljs-built_in">return</span> (
   ╰────

Maybe one of these should be marked as a client entry with <span class="hljs-string">"use client"</span>:
  ./src/app/page.tsx
</code></pre>
<p>This is due to Next.js's use of <a target="_blank" href="https://www.joshwcomeau.com/react/server-components/">React Server Components</a>, which you can learn more about <a target="_blank" href="https://nextjs.org/docs/app/building-your-application/rendering">here</a>. React Server Components is a large topic, but the bottom line is that, by default, components are Server Components in Next.js and <code>useState</code> only works in a Client Component. If we write the  <code>"use client"</code> directive at the top of our <code>page.tsx</code>, we resolve the error.</p>
<h3 id="heading-how-to-evaluate-javascript-within-jsx">How to Evaluate JavaScript within JSX</h3>
<p>If we click the button, we still don't see the numbers update. This is because we need a way to <em><a target="_blank" href="https://react.dev/learn/javascript-in-jsx-with-curly-braces">interpolate</a></em> (or evaluate) JavaScript within our JSX markup. Enter the curly braces: <code>{}</code>.</p>
<p>We can use curly braces to "escape" into JavaScript from within JSX markup. This way we can evaluate JavaScript expressions (such as adding to a counter) and dynamically display data in our components. Here's what we'll do:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MyButton</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">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">"bg-blue-500 hover:bg-blue-700 rounded py-2 px-4 text-white font-bold"</span>&gt;</span>
            I have been clicked {count} times
        <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
    );
}
</code></pre>
<p>We have added <code>{count}</code> to evaluate the value of <code>count</code> from <code>useState</code> within our button. We should see the following:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Screenshot-2023-11-26-at-4.46.56-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Displaying data in JSX with curly braces {}</em></p>
<p>We see a 0 – this comes from the <code>count</code> variable that we destructured from our <code>useState</code> hook, which we initially set to 0. We've successfully interpolated the JavaScript within our JSX markup!</p>
<h3 id="heading-event-handling">Event handling</h3>
<p>You'll notice that if we click the button, still nothing happens. How do we get the number to increment when we click it? </p>
<p>For this, we'll make use of an <a target="_blank" href="https://react.dev/learn/responding-to-events#adding-event-handlers">event handler function</a> as well as the setter function (which we named <code>setCount</code>) that we get from <code>useState</code>:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MyButton</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">handleClick</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">className</span>=<span class="hljs-string">"bg-blue-500 hover:bg-blue-700 rounded py-2 px-4 text-white font-bold"</span>&gt;</span>
            I have been clicked {count} times
        <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
    );
}
</code></pre>
<p>What we've done here is add a function <code>handleClick</code> to update the state of the <code>count</code> variable. The convention is to name event handler functions <code>handle</code> followed by the name of your event (for example, <code>handleClick</code>). </p>
<p><code>[setCount](https://react.dev/reference/react/useState#setstate)</code> is a special <code>set</code> function returned by <code>useState</code> that will update the state of the <code>count</code> variable to whatever we pass in as an argument. For example, we could call <code>setCount(2)</code>, and it would update <code>count</code> to 2. <code>setCount(7)</code> would set it to 7, and so on. </p>
<p>We are calling <code>setCount(count + 1)</code>, which evaluates to <code>setCount(0 + 1)</code>, because the initial value of <code>count</code> is 0. Upon the next click, <code>count</code> will be 1, so we'd be calling <code>setCount(1 + 1)</code>, and the next click would call <code>setCount(2 + 1)</code> and so on. </p>
<p>This allows us to update the counter with every click. But, if you click, you'll notice that <em>still</em> nothing happens – why? Perhaps take a moment to try to figure this out for yourself before reading on to help the concept stick even better.</p>
<h3 id="heading-how-to-pass-an-event-handler-as-a-prop-to-your-jsx">How to Pass an Event Handler as a Prop to Your JSX</h3>
<p>Looking at our code, there is no relationship between the user clicking the button, and the <code>handleClick</code> function. We need to pass the <code>handleClick</code> event handler to the <code>onClick</code> property on the button! Let's add that here:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MyButton</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">handleClick</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">{handleClick}</span>
            <span class="hljs-attr">className</span>=<span class="hljs-string">"bg-blue-500 hover:bg-blue-700 rounded py-2 px-4 text-white font-bold"</span>
        &gt;</span>
            I have been clicked {count} times
        <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
    );
}
</code></pre>
<p>Notice how we haven't said <code>onClick={handleClick()}</code>. We aren't calling the function ourselves here – we are instead passing it down. This is an important distinction, as React calls the function for us when the user clicks the button, instead of it firing immediately. </p>
<p>You can learn more about passing props to components in the React docs <a target="_blank" href="https://react.dev/learn/passing-props-to-a-component">here</a>.</p>
<h3 id="heading-our-working-project">Our working project</h3>
<p>Try it out now, the button works! </p>
<p>You now have a button that updates its count when you click it. This shows usage of interpolating JavaScript within JSX using curly braces, creating your own component and nesting it within other components, using state and hooks within React, as well as working with Next.js and Tailwind. Congratulations! </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/react-counter-button.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Our working project</em></p>
<p>Here would be a good point to <em>commit</em> our changes using Git. You can close the current terminal process by pressing <code>ctrl + c</code>, and then type in <code>git add .</code>, followed by <code>git commit -m "counter button"</code> or some other message that is meaningful.</p>
<h2 id="heading-chapter-2-how-to-refactor-the-project">Chapter 2: How to Refactor the Project</h2>
<h3 id="heading-moving-our-component-to-another-file">Moving our component to another file</h3>
<p>As our project sits, all the code is within <code>app/page.tsx</code>. What if we wanted to add another component, or several? Over time, our <code>page.tsx</code> would get large and difficult to read. </p>
<p>Instead, we can break our components up into their own files to help with readability as well as modularity (reusing the component in multiple different places).</p>
<p>Let's start by creating a folder <code>components</code> at the root of our project to store our components. Inside <code>components</code>, create a file called <code>button.tsx</code>. Then, within <code>app/page.tsx</code> cut (copy and then delete) the entire <code>Button</code> function component and paste it within <code>components/button.tsx</code>. </p>
<p><code>components/button.tsx</code> should look like this:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Button</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">handleClick</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">{handleClick}</span>
            <span class="hljs-attr">className</span>=<span class="hljs-string">"bg-blue-500 hover:bg-blue-700 rounded text-white font-bold px-4 py-2"</span>
        &gt;</span>
            I have been clicked {count} times
        <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
    );
}
</code></pre>
<h3 id="heading-fix-the-usestate-import-error">Fix the <code>useState</code> import error</h3>
<p>You'll likely notice in your code editor that <code>useState(0)</code> has red squiggly lines underneath it. In Visual Studio Code, if you hover over it, you will see an error that says:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/Screenshot-2024-06-07-at-6.10.44-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Error: cannot find name 'useState'</em></p>
<p>Why is this? We are using <code>useState</code> but we have not imported the module from React. Adding <code>import { useState } from "react";</code> to the top of our <code>button.tsx</code> file will fix this error.</p>
<p>If you look at the beginning of the function, you'll see that <code>Button()</code> is underlined with white lines in Visual Studio Code. Hovering over it will show this error. Reflect on why this might be the case – we'll address this later. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/Screenshot-2024-06-07-at-6.13.45-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Error: 'Button' is declared but its value is never read</em></p>
<h3 id="heading-importing-and-exporting-components">Importing and Exporting Components</h3>
<p>Let's return to <code>app/page.tsx</code> . You'll see two errors here: one on <code>import { useState } from "react";</code> and another on <code>&lt;Button /&gt;</code>. </p>
<p>Let's address the <code>useState</code> error first. We used <code>useState</code> within our <code>Button</code> component, but now that we've moved that component to its own file, we no longer it. Deleting it will solve our error. You can use <code>cmd (ctrl on Windows) + shift + k</code> to delete the entire line in Visual Studio Code.</p>
<p>If you've saved your <code>app/page.tsx</code> you will see this error in the console:</p>
<pre><code class="lang-zsh"> ⨯ app/page.tsx (7:14) @ Button
 ⨯ ReferenceError: Button is not defined
    at Home (./app/page.tsx:19:89)
digest: <span class="hljs-string">"2129895745"</span>
   5 |         &lt;main className=<span class="hljs-string">"flex min-h-screen flex-col items-center p-24 gap-4"</span>&gt;
   6 |             &lt;h1&gt;React Counter Button&lt;/h1&gt;
&gt;  7 |             &lt;Button /&gt;
     |              ^
   8 |         &lt;/main&gt;
   9 |     );
  10 | }
 GET / 500 <span class="hljs-keyword">in</span> 87ms
</code></pre>
<p>Why wouldn't <code>Button</code> be defined? The issue is that within our <code>app/page.tsx</code> we have no way to access the <code>Button</code> component over in <code>components/button.tsx</code>. We solve this by exporting and importing the appropriate module.</p>
<p>Within <code>components/button.tsx</code>, at the beginning of our function declaration, let's add the keywords <code>export default</code>. The file will look like this now:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { useState } <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">Button</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">handleClick</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">{handleClick}</span>
            <span class="hljs-attr">className</span>=<span class="hljs-string">"bg-blue-500 hover:bg-blue-700 rounded text-white font-bold px-4 py-2"</span>
        &gt;</span>
            I have been clicked {count} times
        <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
    );
}
</code></pre>
<p>You'll notice that our earlier error of <code>'Button' is declared but its value is never read</code> has gone away, because now the value is being read as a default export. </p>
<p>But what have we done here? What is an export, or a default export? <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export">Exporting</a> and importing allows us to modularize JavaScript components into their own sections and use them in others. </p>
<p>There are two types: <em>default</em> exports<em>,</em> and <em>named</em> exports. Each file can have multiple <em>named</em> exports but only one <em>default</em> export. You can read more about importing and exporting components the React documentation <a target="_blank" href="https://react.dev/learn/importing-and-exporting-components">here</a>.</p>
<p>Now that we have exported the component from <code>components/button.tsx</code>, we have to import it within <code>app/page.tsx</code>. Visual Studio Code can help with "<a target="_blank" href="https://code.visualstudio.com/docs/editor/intellisense">intellisense</a>" suggestions: at the top of your file if you start typing "Button", it will suggest the correct import with the correct filepath:</p>
<p><code>import Button from "@/components/button";</code></p>
<p>Within Next.js we can use this <code>@/</code> syntax to reference the root of the project. This is a convenience added in case our import is several file layers deep. You can read the examples of the <code>@/</code> syntax in the Next.js documentation <a target="_blank" href="https://nextjs.org/docs/app/building-your-application/configuring/absolute-imports-and-module-aliases">here</a>. </p>
<p>You'll see that our errors have disappeared and the project still works! We haven't added any new features but we have successfully refactored our code to make it more modular, readable, and maintainable.</p>
<p>Here let's follow the same steps to commit our changes, adding a message such as <code>refactor: move button to its own file</code>.</p>
<h2 id="heading-chapter-3-two-components-with-independent-and-shared-state">Chapter 3: Two Components with Independent and Shared State</h2>
<h3 id="heading-two-components-with-independent-state">Two Components with Independent State</h3>
<p>What if we wanted to have two buttons that can count independently of each other? This will showcase the beauty of React and component-based development implementation will be simpler than building the button from scratch entirely again.</p>
<p>Within <code>app/page.tsx</code> we can simply add another <code>&lt;Button /&gt;</code>. You can focus your cursor on <code>&lt;Button /&gt;</code> and press <code>option + shift + ↓</code> to create another <code>&lt;Button /&gt;</code>:</p>
<pre><code class="lang-js"><span class="hljs-string">"use client"</span>;

<span class="hljs-keyword">import</span> Button <span class="hljs-keyword">from</span> <span class="hljs-string">"@/components/button"</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">main</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex min-h-screen flex-col items-center p-24 gap-4"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>React Counter Button<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">Button</span> /&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">Button</span> /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</span></span>
    );
}
</code></pre>
<p>You should now see two button counters with their own independent state:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/Screenshot-2024-06-07-at-6.40.47-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Two buttons with independent state</em></p>
<p>Component-based design with React makes re-using parts of your application easy. Easy win.</p>
<h3 id="heading-two-components-with-shared-state">Two Components with Shared State</h3>
<p>What if we wanted the buttons to share their state and update together? You'll notice that as we click each button, they separately increment. </p>
<p>In order for the buttons to share their state, we will need to move their state from each individual components "upward" to their common parent component (in this case, the <code>Home</code> function in <code>app/page.tsx</code>). You'll also hear this referred to as "<a target="_blank" href="https://react.dev/learn#sharing-data-between-components">lifting state up</a><em>".</em></p>
<p>Cut the counting logic from <code>components/button.tsx</code> and paste it into <code>app/page.tsx</code> within the body of the <code>Home</code> function. We will also need our <code>useState</code> import at the top of the file:</p>
<pre><code class="lang-js"><span class="hljs-string">"use client"</span>;

<span class="hljs-keyword">import</span> { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-keyword">import</span> Button <span class="hljs-keyword">from</span> <span class="hljs-string">"@/components/button"</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> [count, setCount] = useState(<span class="hljs-number">0</span>);

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleClick</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">main</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex min-h-screen flex-col items-center p-24 gap-4"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>React Counter Button<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">Button</span> /&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">Button</span> /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</span></span>
    );
}
</code></pre>
<h3 id="heading-passing-props-down-to-a-component">Passing Props Down to a Component</h3>
<p>Now that we have our state in the parent component of each button (<code>Home</code>), we can pass this state down via <em><a target="_blank" href="https://react.dev/learn/passing-props-to-a-component">props</a></em> to the <code>Button</code> component. We will want to pass down both the event handler <code>handleClick</code> as well as the <code>count</code> variable we wish to display:</p>
<pre><code class="lang-js"><span class="hljs-string">"use client"</span>;

<span class="hljs-keyword">import</span> { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-keyword">import</span> Button <span class="hljs-keyword">from</span> <span class="hljs-string">"@/components/button"</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> [count, setCount] = useState(<span class="hljs-number">0</span>);

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleClick</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">main</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex min-h-screen flex-col items-center p-24 gap-4"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>React Counter Button<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">Button</span> <span class="hljs-attr">count</span>=<span class="hljs-string">{count}</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{handleClick}</span> /&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">Button</span> <span class="hljs-attr">count</span>=<span class="hljs-string">{count}</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{handleClick}</span> /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</span></span>
    );
}
</code></pre>
<p>The <code>count</code> from <code>useState</code> is passed to the <code>count</code> prop, and the function <code>handleClick</code> is passed to the <code>onClick</code> prop, both on the <code>Button</code> component. In JSX, we can define our own props (which might remind you of HTML attributes) so that we can pass data from one component to another. </p>
<p>You might see some errors related to TypeScript at this point – we will come back to these later.</p>
<h3 id="heading-read-props-in-your-child-component">Read Props in Your Child Component</h3>
<p>Now that we have passed the data as props to our component, we need to adjust our <code>Button</code> component to <em>read</em> the props from its parent component. Within <code>components/button.tsx</code>:</p>
<pre><code class="lang-js"><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">Button</span>(<span class="hljs-params">{ count, onClick }</span>) </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">{onClick}</span>
            <span class="hljs-attr">className</span>=<span class="hljs-string">"bg-blue-500 hover:bg-blue-700 rounded text-white font-bold px-4 py-2"</span>
        &gt;</span>
            I have been clicked {count} times
        <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
    );
}
</code></pre>
<p>React function components accept a single <code>props</code> object as an argument. Here we destructure the props that we want to pass into our <code>Button</code> component. In other words, we are taking <code>count</code>, and <code>onClick</code> from the <code>props</code> object directly, as an argument to <code>Button</code>.</p>
<p>If you save your file you'll see that this now works: you have two buttons with shared state:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/Screen-Recording-2024-06-14-at-12.07.37-PM.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Two buttons with shared state</em></p>
<p>But why did we pass <code>onClick</code> and not <code>handleClick</code> to the <code>Button</code> component? Isn't <code>handleClick</code> what we want to run when we click the button?</p>
<p>Within the <code>Home</code> component in <code>app/page.tsx</code>, we define <code>handleClick</code> and pass it down as a prop to the <code>Button</code> component. Within the <code>Button</code> component's body in <code>components/button.tsx</code> we read the <em>prop</em> <code>onClick</code>, not the event handler <code>handleClick</code> itself. So when the <code>Button</code> component fires, it calls the <code>onClick</code> prop, which sits "up" the component tree inside <code>Home</code>, where it then calls <code>handleClick</code>, updates the count, and then passes that state back down to both <code>Button</code> components.</p>
<h3 id="heading-tiny-crash-course-in-typescript">Tiny Crash Course in TypeScript</h3>
<p>If you check <code>components/button.tsx</code> you will see the following errors for both the <code>count</code> and <code>onClick</code> props you are reading into <code>Button</code>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/Screenshot-2024-06-14-at-2.49.55-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Binding element 'count' implicitly has an 'any' type.</em></p>
<p>(You can get these "pretty" TypeScript syntax-highlighted errors with the Visual Studio Code extension <a target="_blank" href="https://marketplace.visualstudio.com/items?itemName=yoavbls.pretty-ts-errors">here</a>).</p>
<p>What do these errors mean, and what is TypeScript? TypeScript is a superset of JavaScript that adds <em>types</em> to JavaScript. These can help ensure that our program works as we intend. Examples of types are <code>number</code>, <code>boolean</code>, and <code>string</code>. This error is telling us that we haven't defined a type for the props <code>count</code> or <code>onClick</code>. </p>
<p>So what will the type of <code>count</code> be? If we consider the result of count, the answers could be <code>1</code>, <code>2</code>, <code>3</code>, and so on. These are all numbers, so we will assign the type <code>number</code> to <code>count</code>.</p>
<p>The <code>onClick</code> prop is a function that doesn't take any arguments or return any value – we use it for its side effect of updating <code>setCount</code>. So we assign it the type <code>() =&gt; void</code>. </p>
<p>We create an <em><a target="_blank" href="https://www.typescriptlang.org/docs/handbook/interfaces.html">interface</a></em> where we define the types for our <code>ButtonProps</code>, and then read this interface into our component:</p>
<pre><code class="lang-js">interface ButtonProps {
    <span class="hljs-attr">count</span>: number;
    onClick: <span class="hljs-function">() =&gt;</span> <span class="hljs-keyword">void</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">Button</span>(<span class="hljs-params">{ count, onClick }: ButtonProps</span>) </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">{onClick}</span>
            <span class="hljs-attr">className</span>=<span class="hljs-string">"bg-blue-500 hover:bg-blue-700 rounded text-white font-bold px-4 py-2"</span>
        &gt;</span>
            I have been clicked {count} times
        <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
    );
}
</code></pre>
<p>The errors are gone and there you have it: a tiny intro to TypeScript!</p>
<p>Here let's make another commit with a message such as <code>buttons with shared state</code>.</p>
<h2 id="heading-chapter-4-how-to-add-both-pairs-of-buttons-to-our-site">Chapter 4: How to Add Both Pairs of Buttons to Our Site</h2>
<p>Let's showcase both our buttons with shared and independent state, and deploy the application.</p>
<p>Let's rename our <code>button.tsx</code> to <code>button-shared-state.tsx</code>. Let's also rename the function, the interface, the import within <code>app/page.tsx</code>, as well as the component in <code>app/page.tsx</code>. And let's switch these to <em>named</em> exports using a function expression using <code>const</code> instead of a function declaration:</p>
<pre><code class="lang-js">interface ButtonSharedStateProps {
    <span class="hljs-attr">count</span>: number;
    onClick: <span class="hljs-function">() =&gt;</span> <span class="hljs-keyword">void</span>;
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> ButtonSharedState = <span class="hljs-function">(<span class="hljs-params">{
    count,
    onClick,
}: ButtonSharedStateProps</span>) =&gt;</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">{onClick}</span>
            <span class="hljs-attr">className</span>=<span class="hljs-string">"bg-blue-500 hover:bg-blue-700 rounded text-white font-bold px-4 py-2"</span>
        &gt;</span>
            I have been clicked {count} times
        <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
    );
};
</code></pre>
<pre><code class="lang-js"><span class="hljs-string">"use client"</span>;

<span class="hljs-keyword">import</span> { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-keyword">import</span> { ButtonSharedState } <span class="hljs-keyword">from</span> <span class="hljs-string">"@/components/button-shared-state"</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> [count, setCount] = useState(<span class="hljs-number">0</span>);

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleClick</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">main</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex min-h-screen flex-col items-center p-24 gap-4"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>React Counter Button<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">ButtonSharedState</span> <span class="hljs-attr">count</span>=<span class="hljs-string">{count}</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{handleClick}</span> /&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">ButtonSharedState</span> <span class="hljs-attr">count</span>=<span class="hljs-string">{count}</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{handleClick}</span> /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</span></span>
    );
}
</code></pre>
<p>Now let's create a file <code>components/button-independent-state.tsx</code>:</p>
<pre><code class="lang-js"><span class="hljs-string">"use client"</span>;
<span class="hljs-keyword">import</span> { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> ButtonIndependentState = <span class="hljs-function">() =&gt;</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">handleClick</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">className</span>=<span class="hljs-string">"bg-blue-500 hover:bg-blue-700 rounded text-white font-bold py-2 px-4"</span>
            <span class="hljs-attr">onClick</span>=<span class="hljs-string">{handleClick}</span>
        &gt;</span>
            I have been clicked {count} times
        <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
    );
};
</code></pre>
<p>What we've done here is similar to our logic in the beginning of this guide: we've located the state within the button component itself, so that each implementation of the button component creates and tracks its own independent state.</p>
<p>Let's import <code>ButtonIndependentState</code> into <code>app/page.tsx</code>:</p>
<pre><code class="lang-js"><span class="hljs-string">"use client"</span>;

<span class="hljs-keyword">import</span> { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-keyword">import</span> { ButtonSharedState } <span class="hljs-keyword">from</span> <span class="hljs-string">"@/components/button-shared-state"</span>;
<span class="hljs-keyword">import</span> { ButtonIndependentState } <span class="hljs-keyword">from</span> <span class="hljs-string">"@/components/button-independent-state"</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> [count, setCount] = useState(<span class="hljs-number">0</span>);

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleClick</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">main</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex min-h-screen flex-col items-center p-24 gap-4"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-3xl font-bold"</span>&gt;</span>React Counter Buttons<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">h2</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-xl"</span>&gt;</span>Buttons with shared state<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">ButtonSharedState</span> <span class="hljs-attr">count</span>=<span class="hljs-string">{count}</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{handleClick}</span> /&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">ButtonSharedState</span> <span class="hljs-attr">count</span>=<span class="hljs-string">{count}</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{handleClick}</span> /&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">h2</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-xl"</span>&gt;</span>Buttons with independent state<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">ButtonIndependentState</span> /&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">ButtonIndependentState</span> /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</span></span>
    );
}
</code></pre>
<p>We have now showcased a set of buttons that have independent state, as well as buttons that have shared state. We added a tiny bit of CSS to make things look nicer as well.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/Screen-Recording-2024-06-21-at-12.25.22-PM.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Our finished project</em></p>
<p>Here let's add another commit with a message such as <code>buttons with both shared and independent state</code>.</p>
<h2 id="heading-chapter-5-how-to-deploy-the-site-to-netlify">Chapter 5: How to Deploy the Site to Netlify</h2>
<h3 id="heading-publish-to-github">Publish to GitHub</h3>
<p>Let's deploy our application to the world to show it off. We are going to push our code to GitHub, and then deploy it to Netlify.</p>
<p>The first step is push our code to GitHub. If you don't have a GitHub account, create one first. In Visual Studio Code, you can push to GitHub from the command palette: open up the command palette by pressing <code>⇧⌘P</code> , then type in <code>publish to GitHub</code>, and select <code>publish to public GitHub repository</code>. </p>
<p>Open your GitHub account and verify that the project has successfully been uploaded.</p>
<h3 id="heading-deploy-to-netlify">Deploy to Netlify</h3>
<p>Once you've uploaded your project to GitHub, you can now deploy it to Netlify. Open up the <a target="_blank" href="https://www.netlify.com/">Netlify website</a>, and log in (or create an account if you don't have one).</p>
<p>Click <code>add new site</code>, and then <code>import an existing project</code>. When asked <code>Let’s deploy your project with…</code>, select <code>GitHub</code>. </p>
<p>Select the name of your repository from the list, then give the site a name under <code>site name</code>. You can leave the rest of the settings at their defaults and then click <code>deploy [your site name]</code>.</p>
<p>If the project builds successfully, you will have a live link of your work!</p>
<h2 id="heading-concluding-thoughts-and-next-steps">Concluding Thoughts and Next Steps</h2>
<p>In this project, you have learned fundamental concepts in React such as creating a functional component, importing and exporting modules, interpolating JavaScript within JSX using curly braces, working with state, and using React hooks. </p>
<p>You've also seen an introduction to using utility-based CSS techniques with Tailwind CSS, and you've gotten a tiny introduction into adding types to your JavaScript with TypeScript. Finally, you learned how to deploy your project to Netlify via GitHub.</p>
<p>Where can you go from here? One idea for expanding the project could be to create a "ticker": a counter that could be incremented and decremented (you would have one button that increases the number of the counter, and one that decreases it). </p>
<p>In the name of learning, one effective method for solidifying the concepts you've learned here would be to start a project completely fresh, and see if you can build everything in this tutorial without checking the tutorial. As you need to check in, you will identify which concepts benefit from further study and practice.</p>
<p>If you'd like to stay in touch, you can:</p>
<ul>
<li>Follow me on <a target="_blank" href="https://twitter.com/DevinCLane">Twitter</a> </li>
<li>Follow me on <a target="_blank" href="https://www.linkedin.com/in/devinlane/">LinkedIn</a></li>
</ul>
<p>Please post about what you've made along with any questions or feedback you might have.</p>
<p>Happy coding!</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
