<?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[Umaru S. Biango]]></title><description><![CDATA[Am mostly hiding behind my keyboard either making websites, playing with tech or ranting in the wide wise west.]]></description><link>https://blog.umarubiango.com</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1704627243116/Gu4CicqZi.png</url><title>Umaru S. Biango</title><link>https://blog.umarubiango.com</link></image><generator>RSS for Node</generator><lastBuildDate>Wed, 20 May 2026 23:07:26 GMT</lastBuildDate><atom:link href="https://blog.umarubiango.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Accordion App With React]]></title><description><![CDATA[Let's get started.
As always, I first of all design my projects in Figma before I move to development. This way, I do not get confused. I know exactly how to structure the UI as that thinking has already been done and it's in front of me.
Here is wha...]]></description><link>https://blog.umarubiango.com/accordion-app-with-react</link><guid isPermaLink="true">https://blog.umarubiango.com/accordion-app-with-react</guid><category><![CDATA[React]]></category><dc:creator><![CDATA[Umaru Sahr Biango]]></dc:creator><pubDate>Sun, 11 Feb 2024 20:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1707850766171/a1584e68-edba-4d79-b1c7-c2f4c2b1a423.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Let's get started.</p>
<p>As always, I first of all design my projects in Figma before I move to development. This way, I do not get confused. I know exactly how to structure the UI as that thinking has already been done and it's in front of me.</p>
<p>Here is what we are going to build.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1707881507272/aa284577-9d24-4815-8de8-d248114b9c5e.png" alt class="image--center mx-auto" /></p>
<p>If you look at the screenshot of the finished product above, you will see that we have the <strong>header</strong> and the <strong>accordions</strong>. In the accordion components, we have the <strong>topic</strong>, the <strong>question</strong> underneath it and the <strong>answer</strong> (what will be shown when the accordion is expanded).</p>
<p>Every one of these pieces is a separate component. I then returned the parent component (<code>accordion</code>) in the <code>App.js</code> to render the app.</p>
<p>I started by creating a file <code>Accordion.jsx</code> in my <code>src</code> directory. This is the file that has all the code for the project.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1707881012091/5e151e28-efcf-4639-9068-352ad2995205.png" alt class="image--center mx-auto" /></p>
<p>So let's start with each component in the UI.</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Accordion</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">div</span>&gt;</span></span>
    )
}
</code></pre>
<p>For now, we are simply returning an empty div element.</p>
<h3 id="heading-the-accordionitem-component">The <code>AccordionItem</code> component.</h3>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">AccordionItem</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> <span class="hljs-attr">className</span>=<span class="hljs-string">"container"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">AccordionQuestion</span>/&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">AccordionAnswer</span>/&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
    )
}
</code></pre>
<p>Now let's create the two components we are returning here.</p>
<h3 id="heading-the-accordionquestion-component">The <code>AccordionQuestion</code> component</h3>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">AccordionQuestion</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> <span class="hljs-attr">className</span>=<span class="hljs-string">"header"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Lorem ipsum dolor sit amet.<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"question"</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Nam itaque cumque et consectetur magni<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
                <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>
            <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>
<h3 id="heading-the-accordionanswer-component">The <code>AccordionAnswer</code> component</h3>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">AccordionAnswer</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">p</span>&gt;</span>Lorem ipsum dolor sit amet consectetur adipisicing elit. 
        Doloribus soluta molestias accusantium ut eveniet architecto 
        vero repellendus. Officiis, cupiditate necessitatibus.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>
    )
}
</code></pre>
<p>It is always clean and neat for you to write your data in a separate file like JSON or even just a simple object and import it into your app. We have been typing the accordion content manually but that is not the optimal way to do it if we are going to have multiple components.</p>
<p>Let's create a utilities file and write our data in it instead.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1707966840407/7128ad7d-55c8-42fe-8c49-5d73e6c671ab.png" alt class="image--center mx-auto" /></p>
<p>We write the following object in the file.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> accordionData = [
    {
        <span class="hljs-attr">subject</span>: <span class="hljs-string">'Lorem ipsum dolor sit amet.'</span>,
        <span class="hljs-attr">question</span>: <span class="hljs-string">'Nam itaque cumque et consectetur magni?'</span>,
        <span class="hljs-attr">answer</span>: <span class="hljs-string">`Lorem ipsum dolor sit amet, consectetur adipisicing elit. 
        Nobis perspiciatis recusandae placeat qui, accusamus molestias 
        voluptates cupiditate culpa quo? Magnam atque vero nemo 
        molestiae tenetur. Placeat vel quas quisquam amet doloremque 
        perferendis numquam ut. Hic aut qui alias molestiae at. 
        Aspernatur quam doloremque dolores blanditiis itaque veniam 
        perferendis voluptate repellendus.`</span>
    },

    {
        <span class="hljs-attr">subject</span>: <span class="hljs-string">'Lorem ipsum dolor sit amet.'</span>,
        <span class="hljs-attr">question</span>: <span class="hljs-string">'Nam itaque cumque et consectetur magni?'</span>,
        <span class="hljs-attr">answer</span>: <span class="hljs-string">`Lorem ipsum dolor sit amet, consectetur adipisicing elit. 
        Nobis perspiciatis recusandae placeat qui, accusamus molestias 
        voluptates cupiditate culpa quo? Magnam atque vero nemo 
        molestiae tenetur. Placeat vel quas quisquam amet doloremque 
        perferendis numquam ut. Hic aut qui alias molestiae at. 
        Aspernatur quam doloremque dolores blanditiis itaque veniam 
        perferendis voluptate repellendus.`</span>
    }
]
</code></pre>
<p>All we need to do now is to import the parent component (<code>accordion</code>) and the utilities file in the <code>App</code> component to render our static accordion.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> Accordion <span class="hljs-keyword">from</span> <span class="hljs-string">"./Accordion"</span>;
<span class="hljs-keyword">import</span> { accordionData } <span class="hljs-keyword">from</span> <span class="hljs-string">"./Utilities"</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">'./Style.css'</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> items = accordionData;

  <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">Accordion</span> 
        <span class="hljs-attr">items</span>=<span class="hljs-string">{items}</span>
      /&gt;</span>
   <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<p>As you can see. Here we created an <code>items</code> variable that points to the accordion data and passed it down to <code>&lt;Accordion /&gt;</code></p>
<p>We are done writing the UI. At this point, we have a static accordion component. It is best to always write the UI first before logic and event handlers.</p>
<h3 id="heading-create-logic-and-event-handlers">Create logic and event handlers</h3>
<p>We go back to our <code>Accordion</code> and create the state using <code>useState</code> hook and the event handler.</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Accordion</span>(<span class="hljs-params">{ items }</span>) </span>{
    <span class="hljs-keyword">const</span> [activeIndex, setActiveIndex] = useState(<span class="hljs-literal">null</span>)

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleClick</span>(<span class="hljs-params">index</span>) </span>{
        setActiveIndex(activeIndex === index ? <span class="hljs-literal">null</span> : index)
    }

    <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">Heading</span> /&gt;</span>

            {items.map((item, index) =&gt; (
                <span class="hljs-tag">&lt;<span class="hljs-name">AccordionItem</span> 
                    <span class="hljs-attr">key</span>=<span class="hljs-string">{index}</span>
                    <span class="hljs-attr">item</span>=<span class="hljs-string">{item}</span>
                    <span class="hljs-attr">isActive</span>=<span class="hljs-string">{index</span> === <span class="hljs-string">activeIndex}</span>
                    <span class="hljs-attr">onToggle</span>=<span class="hljs-string">{()</span> =&gt;</span> handleClick(index)}
                /&gt;
            ))}
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
    )
}
</code></pre>
<p>I created the state variables <code>[activeIndex, setActiveIndex]</code> and the handleClick function to toggle the <code>activeIndex</code> that expands or collapses the accordion. If the clicked item is the currently active one, it sets <code>activeIndex</code> to null (collapsing the item), otherwise, it sets <code>activeIndex</code> to the index of the clicked item.</p>
<p>In the return statement, we are returning the <code>&lt;Heading /&gt;</code> of the app and we are also mapping over the array of <code>AccordionItem</code> components. Each <code>AccordionItem</code> receives the following props: <strong>key</strong>, <strong>item</strong>, <strong>isActive</strong> and <strong>onToggle</strong>.</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">AccordionItem</span>(<span class="hljs-params">{ item, isActive, onToggle}</span>) </span>{
    <span class="hljs-keyword">const</span> {subject, question, answer} = item

    <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">"container"</span>&gt;</span>
             <span class="hljs-tag">&lt;<span class="hljs-name">AccordionQuestion</span>
                 <span class="hljs-attr">subject</span>=<span class="hljs-string">{subject}</span>
                 <span class="hljs-attr">question</span>=<span class="hljs-string">{question}</span>
                 <span class="hljs-attr">onToggle</span>=<span class="hljs-string">{onToggle}</span>
                 <span class="hljs-attr">isActive</span>=<span class="hljs-string">{isActive}</span>
             /&gt;</span>
             <span class="hljs-tag">&lt;<span class="hljs-name">AccordionAnswer</span>
                 <span class="hljs-attr">answer</span>=<span class="hljs-string">{answer}</span>
                 <span class="hljs-attr">isActive</span>=<span class="hljs-string">{isActive}</span>
             /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>

    )
}
</code></pre>
<p>I used a destructuring assignment to get our subject, question and answer properties from the array of objects.</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">AccordionItem</span>(<span class="hljs-params">{ item, isActive, onToggle}</span>) </span>{
    <span class="hljs-keyword">const</span> {subject, question, answer} = item
</code></pre>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">AccordionAnswer</span>(<span class="hljs-params">{ answer, isActive }</span>) </span>{
    <span class="hljs-keyword">return</span> (
        <span class="xml"><span class="hljs-tag">&lt;&gt;</span>
            {isActive &amp;&amp; <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{answer}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>}
        <span class="hljs-tag">&lt;/&gt;</span></span>
    )
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">AccordionQuestion</span>(<span class="hljs-params">{ subject, question, onToggle, isActive}</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">"header"</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>{subject}<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"subtitle"</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{onToggle}</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{question}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>{ isActive ? '-' : '+'}<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></span>
    )
}
</code></pre>
<p>In the <code>AccordionAnswer</code> we pass in the <strong>answer</strong> and <strong>isActive</strong> props. It conditionally renders the answer only if the item is active (isActive is true).</p>
<p>The <code>AccordionQuestion</code> renders the question and toggle button of an accordion item.</p>
<h3 id="heading-the-complete-code">The complete code</h3>
<p>The Accordion component</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { 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">AccordionAnswer</span>(<span class="hljs-params">{ answer, isActive }</span>) </span>{
    <span class="hljs-keyword">return</span> (
        <span class="xml"><span class="hljs-tag">&lt;&gt;</span>
            {isActive &amp;&amp; <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{answer}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>}
        <span class="hljs-tag">&lt;/&gt;</span></span>
    )
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">AccordionQuestion</span>(<span class="hljs-params">{ subject, question, onToggle, isActive}</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">"header"</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>{subject}<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"subtitle"</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{onToggle}</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{question}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>{ isActive ? '-' : '+'}<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></span>
    )
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Heading</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">h1</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"heading"</span>&gt;</span>Accordion<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span></span>
    )
  }

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">AccordionItem</span>(<span class="hljs-params">{ item, isActive, onToggle}</span>) </span>{

    <span class="hljs-keyword">const</span> {subject, question, answer} = item

    <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">"container"</span>&gt;</span>
             <span class="hljs-tag">&lt;<span class="hljs-name">AccordionQuestion</span>
                 <span class="hljs-attr">subject</span>=<span class="hljs-string">{subject}</span>
                 <span class="hljs-attr">question</span>=<span class="hljs-string">{question}</span>
                 <span class="hljs-attr">onToggle</span>=<span class="hljs-string">{onToggle}</span>
                 <span class="hljs-attr">isActive</span>=<span class="hljs-string">{isActive}</span>
             /&gt;</span>
             <span class="hljs-tag">&lt;<span class="hljs-name">AccordionAnswer</span>
                 <span class="hljs-attr">answer</span>=<span class="hljs-string">{answer}</span>
                 <span class="hljs-attr">isActive</span>=<span class="hljs-string">{isActive}</span>
             /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>

    )
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Accordion</span>(<span class="hljs-params">{ items }</span>) </span>{
    <span class="hljs-keyword">const</span> [activeIndex, setActiveIndex] = useState(<span class="hljs-literal">null</span>)

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleClick</span>(<span class="hljs-params">index</span>) </span>{
        setActiveIndex(activeIndex === index ? <span class="hljs-literal">null</span> : index)
    }

    <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">Heading</span> /&gt;</span>

            {items.map((item, index) =&gt; (
                <span class="hljs-tag">&lt;<span class="hljs-name">AccordionItem</span> 
                    <span class="hljs-attr">key</span>=<span class="hljs-string">{index}</span>
                    <span class="hljs-attr">item</span>=<span class="hljs-string">{item}</span>
                    <span class="hljs-attr">isActive</span>=<span class="hljs-string">{index</span> === <span class="hljs-string">activeIndex}</span>
                    <span class="hljs-attr">onToggle</span>=<span class="hljs-string">{()</span> =&gt;</span> handleClick(index)}
                /&gt;
            ))}
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
    )
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Accordion
</code></pre>
<p>The App component</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> Accordion <span class="hljs-keyword">from</span> <span class="hljs-string">"./Accordion"</span>;
<span class="hljs-keyword">import</span> { accordionData } <span class="hljs-keyword">from</span> <span class="hljs-string">"./Utilities"</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">'./Style.css'</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> items = accordionData;

  <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">Accordion</span> 
        <span class="hljs-attr">items</span>=<span class="hljs-string">{items}</span>
      /&gt;</span>
   <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<p>And we are done.</p>
]]></content:encoded></item><item><title><![CDATA[Todo List App With React]]></title><description><![CDATA[A few weeks ago I started learning ReactJs. I first watched a crash course to get a brief understanding of what it is all about.
Then I went to the official docs to start fiddling with it. After reading a fair bit of it, I decided to start building s...]]></description><link>https://blog.umarubiango.com/todo-list-app-with-react</link><guid isPermaLink="true">https://blog.umarubiango.com/todo-list-app-with-react</guid><category><![CDATA[React]]></category><dc:creator><![CDATA[Umaru Sahr Biango]]></dc:creator><pubDate>Thu, 25 Jan 2024 20:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1705760412655/6bcfd62a-9554-4977-aec8-a05dd808aec2.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>A few weeks ago I started learning ReactJs. I first watched a crash course to get a brief understanding of what it is all about.</p>
<p>Then I went to the official <a target="_blank" href="https://react.dev/learn">docs</a> to start fiddling with it. After reading a fair bit of it, I decided to start building small projects and this is one of them.</p>
<p>Let's get started.</p>
<h2 id="heading-the-features">The features</h2>
<ul>
<li><p>Alerts the user to enter a task if an empty task is submitted</p>
</li>
<li><p>Clicking the checkbox against the task marks it as done by crossing a grey line through</p>
</li>
<li><p>The <strong>clear completed</strong> button clears all tasks that are marked as done</p>
</li>
<li><p>The <strong>clear all tasks</strong> button clears all tasks in the list whether completed or not</p>
</li>
</ul>
<p>Here is the <a target="_blank" href="https://tada-list.netlify.app/">demo</a> of the app. And here is the project on <a target="_blank" href="https://github.com/SUBiango/todo-list-react">github</a>.</p>
<p>The complete <a target="_blank" href="https://github.com/SUBiango/todo-list-react/blob/main/src/Style.css">CSS file.</a></p>
<h3 id="heading-import-statements">Import Statements</h3>
<pre><code class="lang-javascript"><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> <span class="hljs-string">'./Style.css'</span>;
</code></pre>
<p>In React, you can either build “top-down” by starting with building the components higher up in the hierarchy or “bottom-up” by working from components lower down.</p>
<p>So I started writing the components using the bottom-up approach.</p>
<h3 id="heading-the-app-component">The app component</h3>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ToDoApp</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">ToDoContainer</span> /&gt;</span></span>
  );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> ToDoApp;
</code></pre>
<p>Here, I created the ToDoApp function that returns the component that contains all the components of the entire app, <strong>ToDoContainer</strong>.</p>
<h3 id="heading-the-todo-container">The Todo Container</h3>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ToDoContainer</span>(<span class="hljs-params"></span>) </span>{
   <span class="hljs-comment">// the rest of the code </span>
}
</code></pre>
<p>I put all the states and the functions for the entire app in this component and then I passed them down through props to the child components. But more on that later.</p>
<p>For now, let's write the entire UI (user interface) first as it requires just a little effort of thinking before adding interactivity.</p>
<h3 id="heading-the-rest-of-the-components">The rest of the components</h3>
<p>The <code>Header</code> component.</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Header</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">h1</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'header'</span>&gt;</span>Ta-Da List App<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span></span>
  )
}
</code></pre>
<p>The <code>AddTask</code> component.</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">AddTask</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">form</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'add-task'</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span>  <span class="hljs-attr">type</span>=<span class="hljs-string">'text'</span>/&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'add-task-button'</span>&gt;</span>Add Task<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>Here we are returning a simple form with an input box and a button to add a task to the list.</p>
<p>The <code>TaskList</code> component</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">TaskList</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">ul</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'task-list-ul'</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'task-list-li'</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span></span>
    )
}
</code></pre>
<p>The <code>TodoControls</code> component returns the <strong>clear completed</strong> and <strong>clear all task</strong> buttons.</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">TodoControls</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> <span class="hljs-attr">className</span>=<span class="hljs-string">'tada-wrapper'</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'btn'</span>&gt;</span>Clear all task<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">className</span>=<span class="hljs-string">'btn'</span>&gt;</span>Clear completed<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  )
}
</code></pre>
<p>The UI is done.</p>
<p>As I mentioned earlier, I used the bottom-up approach to write the UI. That means the first component (<code>ToDoContainer</code>) we created at the top is in fact at the very bottom of the app and the last one is at the top.</p>
<p>I then added all of the above components in the <code>ToDoContainer</code> to display the static app.</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ToDoContainer</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> <span class="hljs-attr">className</span>=<span class="hljs-string">'container'</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Header</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">AddTask</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">TaskList</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">TodoControls</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  )
}
</code></pre>
<p>This is the result so far.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1707738475988/0d0ed87d-5bed-4788-b402-beca2db4b0c5.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-add-interactivity">Add interactivity</h2>
<p>I created three state variables for the <strong>tasks</strong>, the <strong>input value</strong> and the <strong>checkbox</strong> in the <code>ToDoContainer</code>. These are the three pieces of the app that change based on user interaction.</p>
<p>Thereafter I added</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ToDoContainer</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [tasks, setTasks] = useState([])
  <span class="hljs-keyword">const</span> [inputValue, setInputValue] = useState(<span class="hljs-string">''</span>)
  <span class="hljs-keyword">const</span> [checkedTask, setCheckedTask] = useState([])
    <span class="hljs-comment">// the rest of the code</span>
}
</code></pre>
<h3 id="heading-let-us-wire-the-handler-functions">Let us wire the handler functions</h3>
<p>I first created the <code>handleChange</code> function that will trigger when clicked in the input.</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleChange</span>(<span class="hljs-params">e</span>) </span>{
    setInputValue(e.target.value)
}
</code></pre>
<p>Let's create the handler function that will add the input value to the task list.</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleSubmit</span>(<span class="hljs-params">e</span>) </span>{
    e.preventDefault()

    <span class="hljs-keyword">if</span> (inputValue.trim() !== <span class="hljs-string">''</span>) {
      setTasks([...tasks, {<span class="hljs-attr">text</span>: inputValue, <span class="hljs-attr">completed</span>: <span class="hljs-literal">false</span>}])
      setInputValue(<span class="hljs-string">''</span>)
    } <span class="hljs-keyword">else</span> {
      alert(<span class="hljs-string">'Please enter task'</span>)
    }
}
</code></pre>
<p>This <code>handleSubmit</code> function ensures that a new task is added to the To-Do list only if the user has entered a non-empty task. If the input is empty, it displays an alert prompting the user to enter a task.</p>
<p>Let's create the <code>handleToggleTask</code> function that is responsible for toggling the completion status of a task.</p>
<pre><code class="lang-javascript"> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleToggleTask</span>(<span class="hljs-params">index</span>) </span>{
    <span class="hljs-keyword">const</span> updatedTasks = tasks.map(<span class="hljs-function">(<span class="hljs-params">task, i</span>) =&gt;</span> 
      i === index ? {...task, <span class="hljs-attr">completed</span>: !task.completed} : task
    )
    setTasks(updatedTasks)

    <span class="hljs-keyword">if</span> (checkedTask.includes(index)) {
      setCheckedTask(checkedTask.filter(<span class="hljs-function">(<span class="hljs-params">i</span>) =&gt;</span> i !== index))
    } <span class="hljs-keyword">else</span> {
      setCheckedTask(checkedTask.concat(index))
    }
  }
</code></pre>
<p>This function toggles the completion status of a task, updates the tasks array with the modified task(s), and updates the <code>checkedTask</code> array to keep track of completed tasks.</p>
<pre><code class="lang-javascript"> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleClearCompletedTask</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">let</span> completedTask = tasks.filter(<span class="hljs-function">(<span class="hljs-params">_, index</span>) =&gt;</span> !checkedTask.includes(index))
    setTasks(completedTask)
    setCheckedTask([])
  }

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleClearAllTask</span>(<span class="hljs-params"></span>) </span>{
    tasks.splice(<span class="hljs-number">0</span>, tasks.length)
    setTasks([])
  }
</code></pre>
<p>The <code>handleClearCompletedTask</code> removes completed tasks by filtering the tasks array based on the indices stored in <code>checkedTask</code>.</p>
<p>And the <code>handleClearAllTask</code> removes or clears all the tasks from the to-do list.</p>
<h3 id="heading-pass-the-functions-as-props">Pass the functions as props</h3>
<p>Let us go back to the <code>AddTask</code> component and add the state and the handle functions as props.</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">AddTask</span>(<span class="hljs-params">props</span>) </span>{

  <span class="hljs-keyword">const</span> {inputValue, handleChange, handleSubmit} = props

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'add-task'</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
        <span class="hljs-attr">type</span>=<span class="hljs-string">'text'</span>
        <span class="hljs-attr">value</span>=<span class="hljs-string">{inputValue}</span>
        <span class="hljs-attr">onChange</span>=<span class="hljs-string">{handleChange}</span>
        <span class="hljs-attr">placeholder</span>=<span class="hljs-string">'Enter task...'</span>
        <span class="hljs-attr">className</span>=<span class="hljs-string">'add-task-input'</span>
      /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> 
        <span class="hljs-attr">onClick</span>=<span class="hljs-string">{handleSubmit}</span>
        <span class="hljs-attr">className</span>=<span class="hljs-string">'add-task-button'</span>&gt;</span>Add Task
      <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>We are using <strong>"destructuring assignment"</strong> to destructure the <code>inputValue</code>, <code>handleChange</code> and <code>handleSubmit</code> properties from the props object.</p>
<p>Now, let's go back to our task list and fill out what was missing for the functionality.</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">TaskList</span>(<span class="hljs-params">{tasks, onToggleTask}</span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">ul</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'task-list-ul'</span>&gt;</span>
      {tasks.map((task, index) =&gt; (
        <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{index}</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'task-list-li'</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">id</span>=<span class="hljs-string">{</span>`<span class="hljs-attr">task-checkbox-</span>${<span class="hljs-attr">index</span>}`}
              <span class="hljs-attr">className</span>=<span class="hljs-string">'task-checkbox'</span>
              <span class="hljs-attr">checked</span>=<span class="hljs-string">{task.completed}</span>
              <span class="hljs-attr">onChange</span>=<span class="hljs-string">{()</span> =&gt;</span> onToggleTask(index)}
            /&gt; 
          <span class="hljs-tag">&lt;<span class="hljs-name">label</span> 
              <span class="hljs-attr">htmlFor</span>=<span class="hljs-string">{</span>`<span class="hljs-attr">task-checkbox-</span>${<span class="hljs-attr">index</span>}`} 
              <span class="hljs-attr">className</span>=<span class="hljs-string">'task-checkbox-label'</span>&gt;</span>
           {' '} {task.text}
          <span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
      ))}
    <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span></span>
  )
}
</code></pre>
<p>Now our <code>TaskList</code> component renders the list of tasks. It maps over the <code>tasks</code> array, creating a list item for each task with a checkbox input and a corresponding label. The checkbox's state is determined by the <code>completed</code> property of each task. The <code>onToggleTask</code> function is called when a checkbox is clicked, passing the index of the task.</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">TodoControls</span>(<span class="hljs-params">{onClearCompletedTask, onClearAllTask}</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">'tada-wrapper'</span>&gt;</span>
      <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">{onClearAllTask}</span>
        &gt;</span>Clear all task
        <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">className</span>=<span class="hljs-string">'btn'</span> 
        <span class="hljs-attr">onClick</span>=<span class="hljs-string">{onClearCompletedTask}</span>&gt;</span>
      Clear completed
      <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  )
}
</code></pre>
<p>In this component, we are receiving the functions to clear tasks as props.</p>
<h2 id="heading-the-complete-code">The complete code</h2>
<pre><code class="lang-javascript"><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> <span class="hljs-string">'./Style.css'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">TodoControls</span>(<span class="hljs-params">{onClearCompletedTask, onClearAllTask}</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">'tada-wrapper'</span>&gt;</span>
      <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">{onClearAllTask}</span>&gt;</span>Clear all task<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">className</span>=<span class="hljs-string">'btn'</span> 
        <span class="hljs-attr">onClick</span>=<span class="hljs-string">{onClearCompletedTask}</span>&gt;</span>
      Clear completed
      <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  )
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">TaskList</span>(<span class="hljs-params">{tasks, onToggleTask}</span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">ul</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'task-list-ul'</span>&gt;</span>
      {tasks.map((task, index) =&gt; (
        <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{index}</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'task-list-li'</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">id</span>=<span class="hljs-string">{</span>`<span class="hljs-attr">task-checkbox-</span>${<span class="hljs-attr">index</span>}`}
              <span class="hljs-attr">className</span>=<span class="hljs-string">'task-checkbox'</span>
              <span class="hljs-attr">checked</span>=<span class="hljs-string">{task.completed}</span>
              <span class="hljs-attr">onChange</span>=<span class="hljs-string">{()</span> =&gt;</span> onToggleTask(index)}
            /&gt; 
          <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">htmlFor</span>=<span class="hljs-string">{</span>`<span class="hljs-attr">task-checkbox-</span>${<span class="hljs-attr">index</span>}`} 
            <span class="hljs-attr">className</span>=<span class="hljs-string">'task-checkbox-label'</span>&gt;</span>
           {' '} {task.text}
          <span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
      ))}
    <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span></span>
  )
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">AddTask</span>(<span class="hljs-params">props</span>) </span>{

  <span class="hljs-keyword">const</span> {inputValue, handleChange, handleSubmit} = props

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'add-task'</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
        <span class="hljs-attr">type</span>=<span class="hljs-string">'text'</span>
        <span class="hljs-attr">value</span>=<span class="hljs-string">{inputValue}</span>
        <span class="hljs-attr">onChange</span>=<span class="hljs-string">{handleChange}</span>
        <span class="hljs-attr">placeholder</span>=<span class="hljs-string">'Enter task...'</span>
        <span class="hljs-attr">className</span>=<span class="hljs-string">'add-task-input'</span>
      /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> 
        <span class="hljs-attr">onClick</span>=<span class="hljs-string">{handleSubmit}</span>
        <span class="hljs-attr">className</span>=<span class="hljs-string">'add-task-button'</span>&gt;</span>Add Task
      <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>
  )
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Header</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">h1</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'header'</span>&gt;</span>Ta-Da List App<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span></span>
  )
}


<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ToDoContainer</span>(<span class="hljs-params"></span>) </span>{

  <span class="hljs-keyword">const</span> [tasks, setTasks] = useState([])
  <span class="hljs-keyword">const</span> [inputValue, setInputValue] = useState(<span class="hljs-string">''</span>)
  <span class="hljs-keyword">const</span> [checkedTask, setCheckedTask] = useState([])

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleChange</span>(<span class="hljs-params">e</span>) </span>{
    setInputValue(e.target.value)
  }

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleSubmit</span>(<span class="hljs-params">e</span>) </span>{
    e.preventDefault()

    <span class="hljs-keyword">if</span> (inputValue.trim() !== <span class="hljs-string">''</span>) {
      setTasks([...tasks, {<span class="hljs-attr">text</span>: inputValue, <span class="hljs-attr">completed</span>: <span class="hljs-literal">false</span>}])
      setInputValue(<span class="hljs-string">''</span>)
    } <span class="hljs-keyword">else</span> {
      alert(<span class="hljs-string">'Please enter task'</span>)
    }
  }

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleToggleTask</span>(<span class="hljs-params">index</span>) </span>{
    <span class="hljs-keyword">const</span> updatedTasks = tasks.map(<span class="hljs-function">(<span class="hljs-params">task, i</span>) =&gt;</span> 
      i === index ? {...task, <span class="hljs-attr">completed</span>: !task.completed} : task
    )
    setTasks(updatedTasks)

    <span class="hljs-keyword">if</span> (checkedTask.includes(index)) {
      setCheckedTask(checkedTask.filter(<span class="hljs-function">(<span class="hljs-params">i</span>) =&gt;</span> i !== index))
    } <span class="hljs-keyword">else</span> {
      setCheckedTask(checkedTask.concat(index))
    }
  }

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleClearCompletedTask</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">let</span> completedTask = tasks.filter(<span class="hljs-function">(<span class="hljs-params">_, index</span>) =&gt;</span> !checkedTask.includes(index))
    setTasks(completedTask)
    setCheckedTask([])
  }

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleClearAllTask</span>(<span class="hljs-params"></span>) </span>{
    tasks.splice(<span class="hljs-number">0</span>, tasks.length)
    setTasks([])
  }


  <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">'container'</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Header</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">AddTask</span> 
        <span class="hljs-attr">inputValue</span>=<span class="hljs-string">{inputValue}</span>
        <span class="hljs-attr">handleChange</span>=<span class="hljs-string">{handleChange}</span>
        <span class="hljs-attr">handleSubmit</span>=<span class="hljs-string">{handleSubmit}</span>
      /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">TaskList</span>
        <span class="hljs-attr">tasks</span>=<span class="hljs-string">{tasks}</span>
        <span class="hljs-attr">onToggleTask</span>=<span class="hljs-string">{handleToggleTask}</span>
      /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">TodoControls</span>
        <span class="hljs-attr">onClearCompletedTask</span>=<span class="hljs-string">{handleClearCompletedTask}</span>
        <span class="hljs-attr">onClearAllTask</span>=<span class="hljs-string">{handleClearAllTask}</span>
      /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  )
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ToDoApp</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">ToDoContainer</span> /&gt;</span></span>
  );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> ToDoApp;
</code></pre>
<p>We are finally done.</p>
<p>I may have not done a good job with this but I will keep it going to get better at it.</p>
<p>Thanks for reading.</p>
]]></content:encoded></item><item><title><![CDATA[The Term Brand Is Not What You Think It Is]]></title><description><![CDATA[I have been a student of branding and brand strategy for a few months now, so I want to share with you what I have learned so far. My best teacher about branding who shaped my concept is Marty Neumeier, (author of The Brand Gap). So in this post, I w...]]></description><link>https://blog.umarubiango.com/the-term-brand-is-not-what-you-think-it-is</link><guid isPermaLink="true">https://blog.umarubiango.com/the-term-brand-is-not-what-you-think-it-is</guid><category><![CDATA[brand, branding]]></category><dc:creator><![CDATA[Umaru Sahr Biango]]></dc:creator><pubDate>Mon, 08 Jan 2024 04:22:57 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1704685757139/0fb8d927-88a9-4936-a5e1-29178941e42b.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I have been a student of branding and brand strategy for a few months now, so I want to share with you what I have learned so far. My best teacher about branding who shaped my concept is Marty Neumeier, (author of The Brand Gap). So in this post, I want to explain from that concept, what the term brand means in simple terms.</p>
<p>But first.</p>
<h2 id="heading-what-a-brand-is-not">What a brand is not</h2>
<p>Let's start with what he says a brand isn't. In his book, The Brand Gap, Marty Neumeier states that the term brand is not a logo, an identity, or even a product.</p>
<p>Many people think when they design a logo, boom! That is it! They now have a brand. But Logos, identities, illustrations, and all those little prints are visual elements (or visual identities) of a company or product. They are the elements you see and sometimes touch.</p>
<h2 id="heading-what-brand-is">What brand is</h2>
<p>"A brand is a person's gut feeling about a product, service, or organization," says Marty Neumeier. The gut feeling here is the reputation a company or an organization has out there in the world.</p>
<p>With that definition, a brand is not what you or anyone in your business or organization says it is. You don't describe it. It is what happens inside the heads of other people. It's not visual, but emotional.</p>
<p>What do people who use your product or service say about you? What is the feeling they get when they come in contact with the product you offer? What is the first thing that comes to their minds when they see it?</p>
<p>Answers to these questions define your brand.</p>
<p>All of that stems from everything that companies or organizations do. The product design, brand messaging, and interactions with customers/clients all affect the lives of people out there. What is the impression all of that creates on people?</p>
<h2 id="heading-apple-as-an-example">Apple as an example</h2>
<p>Why is Apple such an irresistible brand out there? They take their designs extremely seriously. They do not just want to design, they want the design to invoke a certain feeling when you experience it.</p>
<p>And when I say design I'm not just talking about the visual elements but their messaging, consistent use of colours, design patterns like the rounded corners on their product, smooth user interface, etc.</p>
<p>When you hold their product in your hand, you get a feeling. That gut feeling is the brand.</p>
<p>You don't tell people what your brand is. People have to tell you what it is. They feel your brand in their soul.</p>
<p>All that you are thinking about yourself or your business as your brand is a false mental picture. What people are thinking and saying is the real picture.</p>
<p>That is it.</p>
<p>Share the post for others to benefit if you have got value from it.</p>
]]></content:encoded></item><item><title><![CDATA[My Web Design Process]]></title><description><![CDATA[Introduction
Designing and developing a website from scratch is a complex process.
There's a lot that goes into it. With new web design tools being exploded in the industry now and then, it's difficult to map out an efficient web design workflow proc...]]></description><link>https://blog.umarubiango.com/my-web-design-process</link><guid isPermaLink="true">https://blog.umarubiango.com/my-web-design-process</guid><category><![CDATA[my Journey]]></category><dc:creator><![CDATA[Umaru Sahr Biango]]></dc:creator><pubDate>Sat, 28 Jan 2023 19:36:24 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1674934182477/2285c6de-ef02-4bd5-a986-ff986f5ef78e.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<hr />
<h2 id="heading-introduction">Introduction</h2>
<p>Designing and developing a website from scratch is a complex process.</p>
<p>There's a lot that goes into it. With new web design tools being exploded in the industry now and then, it's difficult to map out an efficient web design workflow process.</p>
<p>From the information gathering to the launch of the website involves a lot of processes.</p>
<p>Web design workflow is different from designer to designer. Ask any web designer, they will tell you something different. After all, our goal is just to design a website that our clients will love.</p>
<p>In this article, I will show you the design process that I find effective and efficient.</p>
<p><strong>Note:</strong> I'll not be going through every detail of how I come up with my design solutions, just the main points (or at least what I find relevant to share).</p>
<h2 id="heading-planning">Planning</h2>
<p>I use pen and paper to do quick site maps. I want to make sure I capture the main navigation and the home page.</p>
<p>After discussing some ideas about the main navigation with my client, I will then proceed to my mind mapping software to plan the pages and the structure.</p>
<p>That is the information hierarchy of the pages. My goal here is to structure the entire site's information architecture.</p>
<p>Wireframe. I use pen and paper here again first before any software. I try to use my imagination as best as possible to come up with something.</p>
<p>At this stage, I don't go into details. My sight is on the layout. I scribble down ideas. Therefore, I use a pen most of the time because I don't want to erase any initial concepts as I would be tempted to do if I were to use a pencil.</p>
<p>It's now time to clean things up and make them a bit tidy. My go-to software for basic wireframes is Balsamiq. Here, I experiment with my sketches and refine the ideas I want to go with.</p>
<p>I'm not worried about the content or anything else, even though I make use of Lorem Ipsum (dummy text).</p>
<p>I make sure all the sections and call to action are captured. After the wireframe is done, I'll then present (not just show) it to my client for approval. After my client has approved, I move to the next stage.</p>
<h2 id="heading-design">Design</h2>
<p>I use Adobe XD for design. The design part is the fun and best part of the process, or at least for me.</p>
<p>This is the time I consider everything aesthetics. Once my design files are ready, I use the brand guide to capture all the brand elements (colour, typography, icons, logo etc.)</p>
<p>The finished product here should look very much like the result of the real website. My client should see almost exactly what to expect.</p>
<h2 id="heading-coding">Coding</h2>
<p>I set up my development environment in the sublime text (code editor). All design files are ready. I primarily use HTML, CSS and JavaScript for front-end development. Back-end development is not yet my thing.</p>
<p>I love UI (User Interface) design so much, maybe because I am coming from a design background.</p>
<p>So, as a freelancer, I have the freedom to choose projects that I feel I'm comfortable working on.</p>
<p>For Content Management Systems, I use WordPress, it's popular, and it has many plugins for all kinds of things one can imagine. it is very easy for my clients to update their sites without no coding knowledge.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>As I said earlier, every designer has his/her way of doing things.</p>
<p>there are many tools out there for designers to use to their advantage. A lot of other designers use Sketch and Figma these days.</p>
<p>It is trending in the design industry. It is just a matter of preference sometimes or experience with the tools that determine which one to stick with.</p>
<p>This is not the best or recommended process out there. It is just <em>my</em> process. As I advance in my freelance career, I will be constantly refining this process according to my needs.</p>
<p>Join the discussion below and tell me about your process. I'd love to read them.</p>
]]></content:encoded></item><item><title><![CDATA[Three ways I'm using chatGPT to learn JavaScript faster]]></title><description><![CDATA[“The question of whether a computer can think is no more interesting than the question of whether a submarine can swim.” 
~ Edsger W. Dijkstra

Last month, as I was scrolling through TikTok, I came across chatGPT as the new AI tool that will erupt in...]]></description><link>https://blog.umarubiango.com/three-ways-im-using-chatgpt-to-learn-javascript-faster</link><guid isPermaLink="true">https://blog.umarubiango.com/three-ways-im-using-chatgpt-to-learn-javascript-faster</guid><category><![CDATA[Learning Journey]]></category><dc:creator><![CDATA[Umaru Sahr Biango]]></dc:creator><pubDate>Wed, 11 Jan 2023 18:55:38 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1673463007542/dc3c332a-0372-4f9d-890d-27db61636ebc.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote>
<p>“The question of whether a computer can think is no more interesting than the question of whether a submarine can swim.” </p>
<p>~ Edsger W. Dijkstra</p>
</blockquote>
<p>Last month, as I was scrolling through TikTok, I came across chatGPT as the new AI tool that will erupt in many industries including web development.</p>
<p>I became curious at this point to take a look.</p>
<p>I started giving it basic text prompts at first to see the type of responses it would generate. And to my greatest surprise, the responses it generated were mind-blowing.  </p>
<p>By then I was going through freeCodeCamp's basic algorithms challenges. I gave it simple JavaScript prompts and not only did it give me clear and concise explanations, but it also gave me coding examples. I was blown away. That was my first time seeing its output code on the chat. </p>
<p>Since then I have been figuring out various ways for it to help me understand JavaScript concepts. </p>
<p>The following are the three ways I'm using it so far:</p>
<h3 id="heading-i-use-it-to-explain-to-me-specific-javascript-concepts">I use it to explain to me specific JavaScript concepts.</h3>
<p>Before chatGPT, I would use google or YouTube. I would have to search through the articles that come up in google and click the response that's exactly what I am asking or very close. Even then, I would have to skim through the article to get to the point quickly. It's almost the same for YouTube. </p>
<p>ChatGPT goes straight to the point and explains the prompt I give it. And the cool thing is that it will rephrase the prompt, thereby putting it better or yet still asking me to clarify what I mean.</p>
<h3 id="heading-simplify-unclear-or-complicated-explanations">Simplify unclear or complicated explanations</h3>
<p>Whether I'm following a YouTube tutorial or reading an article/book, I usually come across something that the author or instructor did not explain very well, at least to my understanding.         </p>
<p>I will type out the code in chatGPT and ask it to explain what's going on in the code in a simple way. It will explain the code to me line-by-line and even give me some other examples to reinforce my understanding. </p>
<h3 id="heading-debug-my-code">Debug my code</h3>
<p>I spend less time trying to figure out where I'm going wrong. I simply copy my code in the chat and ask it to debug the code. It will not only find the bug and point out where I went wrong, but it will also rewrite it for me. </p>
<p>In summary, it's my personal assistant. I ask it any question (no matter how dumb it is), and it will always give me the answer without getting mad—unlike a person.</p>
<p>All the above is true for me and I like it, but I also acknowledge that it has limitations. It can generate completely useless responses. </p>
<p>I use it with caution and I always try to check other sources if I think it's missing its way with a response.   </p>
<p>Thanks for reading.</p>
<p>See you soon</p>
<p><em>~Umaru.</em></p>
]]></content:encoded></item><item><title><![CDATA[Why I Created This Blog]]></title><description><![CDATA[I have been messing around the web for quite some time now with no significant progress in becoming a developer.
Last month I decided to take things to a different level this year, 2023.
My dream has always been to become a professional web developer...]]></description><link>https://blog.umarubiango.com/why-i-created-this-blog</link><guid isPermaLink="true">https://blog.umarubiango.com/why-i-created-this-blog</guid><category><![CDATA[Learning Journey]]></category><dc:creator><![CDATA[Umaru Sahr Biango]]></dc:creator><pubDate>Sun, 01 Jan 2023 19:38:56 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1672600997283/eda7223c-534e-4c7f-9a15-9a6b6ae77543.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I have been messing around the web for quite some time now with no significant progress in becoming a developer.</p>
<p>Last month I decided to take things to a different level this year, 2023.</p>
<p>My dream has always been to become a professional web developer. But the journey has been very rough.</p>
<p>Lack of focus, inconsistency in learning, lack of time and a boatload of other distractions.</p>
<p>Programming and creating stuff for the web have always fascinated me. I like solving problems. And I want to be able to use code to do just that.</p>
<p>As I was writing down my plans, I came across a video that emphasized building projects and documenting the learning journey as keys to success in programming.</p>
<p>That is exactly the reason why I created this blog. In addition to consistent practice and building projects, I want to write about the things am learning in this blog.</p>
<p>I hope this helps deepen my understanding and solidify the concepts I will be learning.</p>
<p>As I write, I know the basics of HTML, CSS and a little bit of JavaScript.</p>
<p>I am excited about what I will be doing here over the next couple of months.</p>
<blockquote>
<p><em>“Everybody should learn to program a computer, because it teaches you how to think.”</em></p>
<p>~ <strong>Steve Jobs</strong></p>
</blockquote>
]]></content:encoded></item></channel></rss>