<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>ReactJS on Techformist</title>
    <link>https://techformist.com/tags/reactjs/</link>
    <description>Recent content in ReactJS on Techformist</description>
    <image>
      <url>https://techformist.com/logo.svg</url>
      <link>https://techformist.com/logo.svg</link>
    </image>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Thu, 02 Oct 2025 06:30:00 +0000</lastBuildDate><atom:link href="https://techformist.com/tags/reactjs/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>TimeMomo - A Shared Timer App</title>
      <link>https://techformist.com/shared-timer-app-free-self-hosted/</link>
      <pubDate>Thu, 02 Oct 2025 06:30:00 +0000</pubDate>
      
      <guid>https://techformist.com/shared-timer-app-free-self-hosted/</guid>
      <description>&lt;p&gt;As someone who&amp;rsquo;s never been a huge fan of React, I found myself diving headfirst into building &lt;strong&gt;TimeMomo&lt;/strong&gt; - a real-time collaborative timer platform. This project was born out of a desire to learn more about modern web development stacks while creating something genuinely useful (for me, if no one else!).&lt;/p&gt;
&lt;p&gt;TimeMomo is designed for presenters, streamers, and event managers who need to share timers with audiences in real-time, without the complexity of traditional WebSocket implementations.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>As someone who&rsquo;s never been a huge fan of React, I found myself diving headfirst into building <strong>TimeMomo</strong> - a real-time collaborative timer platform. This project was born out of a desire to learn more about modern web development stacks while creating something genuinely useful (for me, if no one else!).</p>
<p>TimeMomo is designed for presenters, streamers, and event managers who need to share timers with audiences in real-time, without the complexity of traditional WebSocket implementations.</p>
<h2 id="what-is-timemomo">What is TimeMomo?</h2>
<p>TimeMomo is a collaborative timer application that allows users to create &ldquo;rooms&rdquo; where timers can be started, paused, and synchronized across all participants in real-time. Think of it as a professional timer platform for:</p>
<ul>
<li><strong>Presenters</strong> who need to manage speaking time during conferences</li>
<li><strong>Streamers</strong> who want to share countdowns with their audience</li>
<li><strong>Event managers</strong> coordinating multiple sessions</li>
<li><strong>Meeting facilitators</strong> keeping discussions on track</li>
</ul>
<p>The app features a clean, intuitive interface with room management, user authentication, and responsive design that works seamlessly on both desktop and mobile devices.</p>
<p>Using TimeMomo is simple.</p>
<p>Register &gt; Create a room &gt; Share the room URL with audience and presenters to see a common timer.</p>
<p><img loading="lazy" src="/2025/timemomo-timer.png" type="" alt="timemomo-timer"  /></p>
<p>It is an alternative to apps like stagetimer.io, but let&rsquo;s face it - there are many great apps and it&rsquo;s not a great alternative. TimeMomo happens to be the app I built.</p>
<p>Use it for free (well, limited to 3 concurrent rooms and ~100 participants).
<a href="http://timemomo.techformist.com/">http://timemomo.techformist.com/</a></p>
<p>Or, make the project your own! TimeMomo is open source and available on <a href="https://github.com/techformist/timemomo">GitHub</a>.</p>
<p>Try it out and let me know what you think!</p>
<h2 id="why-i-built-this">Why I Built This</h2>
<p>My motivation was twofold: <strong>learning</strong> and <strong>solving a real problem</strong>. Despite my reservations about React (I&rsquo;ve always preferred Vue/Nuxt), I wanted to challenge myself with Next.js to understand what all the hype was about. At the same time, I kept encountering situations where I needed a reliable timer that could be shared across devices without the hassle of screen sharing or manual coordination.</p>
<p>The idea crystallized when I realized how many professional settings could benefit from a real-time timer platform - from agile ceremonies to public speaking events. And since I&rsquo;m a big fan of keeping things simple, I wanted to build something that didn&rsquo;t require complex infrastructure.</p>
<h2 id="technology-choices-keeping-it-simple-and-powerful">Technology Choices: Keeping It Simple and Powerful</h2>
<h3 id="nextjs-facing-my-react-fears">Next.js: Facing My React Fears</h3>
<p>Choosing Next.js was a deliberate step outside my comfort zone. As someone who&rsquo;s struggled with React&rsquo;s verbosity and component lifecycle complexities, I approached this with skepticism. However, Next.js 15&rsquo;s improvements, combined with TypeScript, made the experience surprisingly smooth. The App Router and server components felt more intuitive than I expected, and the built-in optimization features handled performance concerns automatically.</p>
<h3 id="pocketbase-real-time-magic">PocketBase: Real-Time Magic</h3>
<p>This is where the project really shines. <strong>PocketBase is absolutely incredible</strong> for real-time applications. While I always appreciated the one-file philosophy for entire backend, I was blown away by how it handles live synchronization without needing to set up WebSocket servers or manage connection states. The real-time subscriptions API is so clean and reliable that I could focus on building features rather than infrastructure.</p>
<p>The decision to use PocketBase instead of traditional WebSockets was a game-changer. It simplified the architecture dramatically:</p>
<ul>
<li>No need for separate WebSocket servers</li>
<li>Built-in authentication and authorization</li>
<li>SQLite backend that&rsquo;s easy to deploy</li>
<li>Automatic real-time updates across all connected clients</li>
</ul>
<h3 id="shadcnui-the-ui-i-always-wanted">Shadcn/UI: The UI I Always Wanted</h3>
<p>If PocketBase is the backend hero, Shadcn is definitely the frontend star. The developer experience is exceptional - copy-paste components that just work, with full TypeScript support and excellent documentation.</p>
<h3 id="dokploy-deployment-adventures">Dokploy: Deployment Adventures</h3>
<p>Using Dokploy for the first time was an interesting experience. I always wanted the Vercel / Netlify experience at budget and this is certainly it. The ability to deploy both the Next.js frontend and PocketBase backend as containers with automated CI/CD made the whole process much smoother than traditional hosting setups.</p>
<h2 id="travails-and-turbulences-the-learning-curve">Travails and Turbulences: The Learning Curve</h2>
<p>Building TimeMomo wasn&rsquo;t without its challenges. As someone new to React/Next.js, I hit several roadblocks:</p>
<h3 id="react-learning-pains">React Learning Pains</h3>
<ul>
<li>Understanding React&rsquo;s component lifecycle and hooks took time</li>
<li>State management across real-time updates required careful planning</li>
<li>TypeScript integration had a learning curve, especially with complex types</li>
</ul>
<p>I am still not a fan.</p>
<h3 id="real-time-synchronization-headaches">Real-Time Synchronization Headaches</h3>
<ul>
<li>Love the real-time capabilities</li>
<li>Debugging hooks - not so much</li>
</ul>
<h3 id="deployment-drama">Deployment Drama</h3>
<ul>
<li>Dokploy&rsquo;s initial setup was trickier than expected</li>
<li>Docker networking between Next.js and PocketBase containers</li>
</ul>
<h2 id="and-finally-addressing-the-ai-in-the-room">And finally.. addressing the AI in the room</h2>
<p>AI tools were incredibly helpful throughout this project. I started out with Bolt, and switched to VSCode. Throughout the cycle, AI assistance was a game-changer for Next.js and Shadcn specifically. I was never very successful getting clean first versions out with Nuxt in the past, but with React I could certainly iterate much faster.</p>
<ul>
<li>Fast conversion of design ideas into working React components</li>
<li>Query issues during development</li>
<li>Get contextual answers for deployment issues</li>
</ul>
<h2 id="in-conclusion">In Conclusion</h2>
<p>This project taught me that sometimes stepping outside your comfort zone pays off. While I&rsquo;m still not a React convert, I now understand its strengths and can appreciate why it&rsquo;s so popular. The combination of Next.js + PocketBase + Shadcn proved to be incredibly productive.</p>
<p>Looking ahead, I&rsquo;m excited about the potential improvements:</p>
<ul>
<li>Nuxt 4 with Nuxt UI and Shadcn-Vue MCP (that AI-assisted Vue development I keep hearing about)</li>
<li>Laravel with Laravel Boost!</li>
</ul>
<p>My plans for this app? Well, not much - unless I see people really interested.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>NextJS 13 is a good step forward</title>
      <link>https://techformist.com/nextjs-13-good-step-forward/</link>
      <pubDate>Wed, 02 Nov 2022 06:30:00 +0000</pubDate>
      
      <guid>https://techformist.com/nextjs-13-good-step-forward/</guid>
      <description>&lt;p&gt;I am quite excited about the possibilities offered by NextJS 13. Announced in Oct &amp;lsquo;22, the most popular JavaScript framework has set fantastic standards for rest of the world.&lt;/p&gt;
&lt;p&gt;I particularly liked the below features -&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;React Server Components that makes life simpler, but the coding process is much more efficient&lt;/li&gt;
&lt;li&gt;The new directory structure that simplifies routes. Layouts are intuitive and simple&lt;/li&gt;
&lt;li&gt;Love the new links (yes, I had to say this)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;What lays hidden in the first statement is all the power hidden in React Server Component itself and that of streaming SSR. Combined with the new way of writing pages, I think this came closest for me to reconsider coding in React.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I am quite excited about the possibilities offered by NextJS 13. Announced in Oct &lsquo;22, the most popular JavaScript framework has set fantastic standards for rest of the world.</p>
<p>I particularly liked the below features -</p>
<ul>
<li>React Server Components that makes life simpler, but the coding process is much more efficient</li>
<li>The new directory structure that simplifies routes. Layouts are intuitive and simple</li>
<li>Love the new links (yes, I had to say this)</li>
</ul>
<p>What lays hidden in the first statement is all the power hidden in React Server Component itself and that of streaming SSR. Combined with the new way of writing pages, I think this came closest for me to reconsider coding in React.</p>
<ul>
<li>Write server and client code in context of a component</li>
<li>Do not worry about writing an entire backend infrastructure</li>
<li>Smaller JS download sizes</li>
<li>Execute faster with streaming SSR - UI that loads instantly and maintains performance for all the magical stuff in your app</li>
</ul>
<p>With easy deployment options and the ability to serve many things from edge, NextJS is compelling for any new apps in the React world.</p>
<h2 id="time-for-a-to-do-app">Time for a To-do app</h2>
<p>Let us try out the new features with a simple to-do app written with -</p>
<ol>
<li>NextJS</li>
<li>Pico CSS for styling</li>
<li>PocketBase for backend</li>
</ol>
<h3 id="setup">Setup</h3>
<p>Create the NextJS app.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cmd" data-lang="cmd"><span class="line"><span class="cl"><span class="k">cd</span> c:\dev\myprojects
</span></span><span class="line"><span class="cl">pnpm create next-app todo-next13 --experimental-app
</span></span></code></pre></div><p>You may not want the experimental flag once the &ldquo;app&rdquo; directory and associated functions are main stream.</p>
<h5 id="install-pico-css">Install Pico CSS</h5>
<p>You can just CDN into Pico CSS, a lightweight, easy-to-use CSS library that is perfect for experimental projects.</p>
<p>I just installed it for later use..</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cmd" data-lang="cmd"><span class="line"><span class="cl">pnpm install pico-css
</span></span></code></pre></div><h5 id="setup-pocketbase">Setup PocketBase</h5>
<p>PocketBase is turning out to be a God send for me to quickly try out applications with a robust backend. PocketBase is written in Go, is extensible since it can also act as a framework, and has a good database (uses SQLite).</p>
<p>As the first step, <a href="https://pocketbase.io/docs/">download PocketBase executable</a>. Store the exe in <code>&lt;_root-folder_ &gt; db</code>.</p>
<p>You can serve PocketBase with -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cmd" data-lang="cmd"><span class="line"><span class="cl">./pocketbase serve
</span></span></code></pre></div><p>You can access the database using automatic REST APIs, or use the <a href="https://github.com/pocketbase/js-sdk">JS SDK</a>. We will use the SDK since we never know when our To do app will blow up.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cmd" data-lang="cmd"><span class="line"><span class="cl">pnpm install pocketbase
</span></span></code></pre></div><h3 id="define-data-model-in-pocketbase">Define data model in PocketBase</h3>
<p>Once installed, you should be able to access the admin UI to create tables and enter dummy records in the database before you take your next gulp of your favourite drink.</p>
<p>Point your browser to <code>http://127.0.0.1:8090/_/</code>.</p>
<p>Click on them shiny buttons to create a table and a few columns.</p>
<h3 id="code-the-todo-app">Code the Todo app</h3>
<p>It is time to write some magic.</p>
<h5 id="create-layout-and-home-page">Create layout and home page</h5>
<p>In the <code>_root-folder_ &gt; app</code> directory create a new file called &rsquo;layout.tsx&rsquo;.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ts" data-lang="ts"><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">Link</span> <span class="kr">from</span> <span class="s2">&#34;next/link&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="s2">&#34;@picocss/pico/css/pico.min.css&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="s2">&#34;../app/css/custom.css&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="kd">function</span> <span class="nx">RootLayout</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">children</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">children</span>: <span class="kt">React.ReactNode</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">})</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">html</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">head</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      
</span></span><span class="line"><span class="cl">      <span class="p">&lt;/</span><span class="nt">head</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">body</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="nt">main</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;container&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="nt">nav</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">          <span class="p">&lt;</span><span class="nt">Link</span> <span class="na">href</span><span class="o">=</span><span class="s">&#34;/&#34;</span><span class="p">&gt;</span><span class="nx">Home</span><span class="p">&lt;/</span><span class="nt">Link</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">          <span class="p">&lt;</span><span class="nt">Link</span> <span class="na">href</span><span class="o">=</span><span class="s">&#34;/todos&#34;</span><span class="p">&gt;</span><span class="nx">Todo</span><span class="p">&lt;/</span><span class="nt">Link</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;/</span><span class="nt">nav</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span><span class="nx">children</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;/</span><span class="nt">main</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      
</span></span><span class="line"><span class="cl">      
</span></span><span class="line"><span class="cl">        <span class="p">&lt;/</span><span class="nt">body</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;/</span><span class="nt">html</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p><code>layout.tsx</code> will serve as our home page container. You can code in-</p>
<ol>
<li>All the elements that are common across components - e.g. Nav, etc.</li>
<li>Include CSS - Pico CSS and any custom CSS that you fancy</li>
</ol>
<p>Don&rsquo;t forget to create <code>custom.css</code> in <code>css</code> directory if you have included a custom CSS statement.</p>
<p>Create another file called <code>page.tsx</code>, which will serve as the root page of your app.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ts" data-lang="ts"><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">Link</span> <span class="kr">from</span> <span class="s2">&#34;next/link&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="kd">function</span> <span class="nx">HomePage() {</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">h1</span><span class="p">&gt;</span><span class="nx">Home</span><span class="p">&lt;/</span><span class="nt">h1</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span><span class="nx">Awesome</span> <span class="nx">Next</span> <span class="nx">Todo</span><span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">div</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;padding-top: 3em&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="nt">Link</span> <span class="na">href</span><span class="o">=</span><span class="s">&#34;/todos&#34;</span><span class="p">&gt;</span><span class="nx">View</span> <span class="nx">Todos</span><span class="p">&lt;/</span><span class="nt">Link</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Execute your Next app if you are have not already done so and see your beautiful app..</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cmd" data-lang="cmd"><span class="line"><span class="cl">pnpm run dev
</span></span></code></pre></div><p><img loading="lazy" src="/2022/todo-app-nextjs13-pico-css-pocketbase.png" type="" alt="todo-app-nextjs13-pico-css-pocketbase"  /></p>
<p>You are now ready to add the core functionality.</p>
<h5></h5>
<p>Create a folder called <code>todos</code> in <code>_root-folder</code>.</p>
<p>Add a new files called <code>page.tsx</code>..</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ts" data-lang="ts"><span class="line"><span class="cl"><span class="kr">export</span> <span class="kr">const</span> <span class="nx">fetchCache</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">Link</span> <span class="kr">from</span> <span class="s2">&#34;next/link&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">PocketBase</span> <span class="kr">from</span> <span class="s2">&#34;pocketbase&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">CreateTodo</span> <span class="kr">from</span> <span class="s2">&#34;./CreateTodo&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">client</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">PocketBase</span><span class="p">(</span><span class="s2">&#34;http://127.0.0.1:8090&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">async</span> <span class="kd">function</span> <span class="nx">getTodos</span><span class="p">(</span><span class="nx">fromRec</span>: <span class="kt">number</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span> <span class="nx">filter</span> <span class="o">=</span> <span class="s2">&#34;&#34;</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="nx">res</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">client</span><span class="p">.</span><span class="nx">records</span><span class="p">.</span><span class="nx">getList</span><span class="p">(</span><span class="s2">&#34;todos&#34;</span><span class="p">,</span> <span class="nx">fromRec</span><span class="p">,</span> <span class="mi">20</span><span class="p">,</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">filter</span>: <span class="kt">filter</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="p">});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="nx">res</span><span class="o">?</span><span class="p">.</span><span class="nx">items</span> <span class="kr">as</span> <span class="kt">any</span><span class="p">[];</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="kr">async</span> <span class="kd">function</span> <span class="nx">TodosPage() {</span>
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="nx">todos</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">getTodos</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">h1</span><span class="p">&gt;</span><span class="nx">Todos</span><span class="p">&lt;/</span><span class="nt">h1</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">      <span class="p">{</span><span class="nx">todos</span><span class="o">?</span><span class="p">.</span><span class="nx">map</span><span class="p">((</span><span class="nx">todo</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="nt">Todo</span> <span class="na">key</span><span class="o">=</span><span class="p">{</span><span class="nx">todo</span><span class="p">.</span><span class="nx">id</span><span class="p">}</span> <span class="na">todo</span><span class="o">=</span><span class="p">{</span><span class="nx">todo</span><span class="p">}&gt;&lt;/</span><span class="nt">Todo</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">))}</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">div</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;padding-top: 1em;padding-bottom: 1em;&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="nt">CreateTodo</span><span class="p">&gt;&lt;/</span><span class="nt">CreateTodo</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">Todo</span><span class="p">({</span> <span class="nx">todo</span> <span class="p">}</span><span class="o">:</span> <span class="kt">any</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">Link</span> <span class="na">href</span><span class="o">=</span><span class="p">{</span><span class="sb">`/todos/</span><span class="si">${</span><span class="nx">todo</span><span class="p">.</span><span class="nx">id</span><span class="si">}</span><span class="sb">`</span><span class="p">}&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">div</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;grid&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="nt">div</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;todo-status&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">          <span class="p">&lt;</span><span class="nt">input</span>
</span></span><span class="line"><span class="cl">            <span class="na">type</span><span class="o">=</span><span class="s">&#34;checkbox&#34;</span>
</span></span><span class="line"><span class="cl">            <span class="na">name</span><span class="o">=</span><span class="s">&#34;status&#34;</span>
</span></span><span class="line"><span class="cl">            <span class="na">id</span><span class="o">=</span><span class="s">&#34;status&#34;</span>
</span></span><span class="line"><span class="cl">            <span class="na">checked</span><span class="o">=</span><span class="p">{</span><span class="nx">todo</span><span class="p">.</span><span class="nx">status</span> <span class="o">==</span> <span class="s2">&#34;Complete&#34;</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">            <span class="na">value</span><span class="o">=</span><span class="s">&#34;Complete&#34;</span>
</span></span><span class="line"><span class="cl">          <span class="p">/&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="nt">div</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;todo-desc&#34;</span><span class="p">&gt;{</span><span class="nx">todo</span><span class="p">.</span><span class="nx">description</span><span class="p">}</span> <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="nt">div</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;todo-date&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">          <span class="p">&lt;</span><span class="nt">input</span>
</span></span><span class="line"><span class="cl">            <span class="na">name</span><span class="o">=</span><span class="s">&#34;todo-date&#34;</span>
</span></span><span class="line"><span class="cl">            <span class="na">id</span><span class="o">=</span><span class="s">&#34;todo-date&#34;</span>
</span></span><span class="line"><span class="cl">            <span class="na">className</span><span class="o">=</span><span class="s">&#34;todo-date-input&#34;</span>
</span></span><span class="line"><span class="cl">            <span class="na">value</span><span class="o">=</span><span class="p">{</span><span class="nx">todo</span><span class="p">.</span><span class="nx">planned_date</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">            <span class="na">readOnly</span><span class="o">=</span><span class="p">{</span><span class="nx">todo</span><span class="p">.</span><span class="nx">status</span> <span class="o">==</span> <span class="s2">&#34;Complete&#34;</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">          <span class="p">/&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;/</span><span class="nt">Link</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p><code>page.tsx</code> is the root page when you navigate to <code>localhost:3000/todos</code>. There is simple code here to -</p>
<ol>
<li>Query todos from database</li>
<li>Display the todos</li>
<li>Enable creation of new todo through the <code>CreateTodo</code> component (which we will create next)</li>
</ol>
<p>Create another file called <code>CreateTodo.tsx</code> in the same folder -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ts" data-lang="ts"><span class="line"><span class="cl"><span class="s2">&#34;use client&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">Link</span> <span class="kr">from</span> <span class="s2">&#34;next/link&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">useState</span> <span class="p">}</span> <span class="kr">from</span> <span class="s2">&#34;react&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">PocketBase</span> <span class="kr">from</span> <span class="s2">&#34;pocketbase&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">useRouter</span> <span class="p">}</span> <span class="kr">from</span> <span class="s2">&#34;next/navigation&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">client</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">PocketBase</span><span class="p">(</span><span class="s2">&#34;http://127.0.0.1:8090&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="kd">function</span> <span class="nx">CreateNote() {</span>
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="p">[</span><span class="nx">desc</span><span class="p">,</span> <span class="nx">setDesc</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">(</span><span class="s2">&#34;&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="p">[</span><span class="nx">status</span><span class="p">,</span> <span class="nx">setStatus</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">(</span><span class="s2">&#34;&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="p">[</span><span class="nx">plannedDate</span><span class="p">,</span> <span class="nx">setPlannedDate</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">(</span><span class="s2">&#34;&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="nx">router</span> <span class="o">=</span> <span class="nx">useRouter</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="nx">createTodo</span> <span class="o">=</span> <span class="kr">async</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">await</span> <span class="nx">client</span><span class="p">.</span><span class="nx">records</span><span class="p">.</span><span class="nx">create</span><span class="p">(</span><span class="s2">&#34;todos&#34;</span><span class="p">,</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">description</span>: <span class="kt">desc</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nx">status</span>: <span class="kt">status</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="p">});</span>
</span></span><span class="line"><span class="cl">    <span class="nx">setStatus</span><span class="p">(</span><span class="s2">&#34;&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nx">setDesc</span><span class="p">(</span><span class="s2">&#34;&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nx">router</span><span class="p">.</span><span class="nx">refresh</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">  <span class="p">};</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">form</span> <span class="na">onSubmit</span><span class="o">=</span><span class="p">{</span><span class="nx">createTodo</span><span class="p">}&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">          <span class="p">&lt;</span><span class="nt">i</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;margin-bottom: 1em;&#34;</span><span class="p">&gt;</span><span class="nx">Create</span> <span class="nx">New</span> <span class="nx">Todo</span><span class="p">..&lt;/</span><span class="nt">i</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">          <span class="p">&lt;</span><span class="nt">label</span> <span class="na">htmlFor</span><span class="o">=</span><span class="s">&#34;desc&#34;</span><span class="p">&gt;</span><span class="nx">Description</span><span class="p">&lt;/</span><span class="nt">label</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">          <span class="p">&lt;</span><span class="nt">input</span>
</span></span><span class="line"><span class="cl">            <span class="na">name</span><span class="o">=</span><span class="s">&#34;desc&#34;</span>
</span></span><span class="line"><span class="cl">            <span class="na">value</span><span class="o">=</span><span class="p">{</span><span class="nx">desc</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">            <span class="na">onChange</span><span class="o">=</span><span class="p">{(</span><span class="nx">e</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">setDesc</span><span class="p">(</span><span class="nx">e</span><span class="p">.</span><span class="nx">target</span><span class="p">.</span><span class="nx">value</span><span class="p">)}&gt;&lt;/</span><span class="nt">input</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">          <span class="p">&lt;</span><span class="nt">label</span> <span class="na">htmlFor</span><span class="o">=</span><span class="s">&#34;status&#34;</span><span class="p">&gt;</span><span class="nx">Status</span><span class="p">&lt;/</span><span class="nt">label</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">          <span class="p">&lt;</span><span class="nt">input</span>
</span></span><span class="line"><span class="cl">            <span class="na">name</span><span class="o">=</span><span class="s">&#34;status&#34;</span>
</span></span><span class="line"><span class="cl">            <span class="na">value</span><span class="o">=</span><span class="p">{</span><span class="nx">status</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">            <span class="na">onChange</span><span class="o">=</span><span class="p">{(</span><span class="nx">e</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">setStatus</span><span class="p">(</span><span class="nx">e</span><span class="p">.</span><span class="nx">target</span><span class="p">.</span><span class="nx">value</span><span class="p">)}&gt;&lt;/</span><span class="nt">input</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">          <span class="p">&lt;</span><span class="nt">button</span> <span class="na">type</span><span class="o">=</span><span class="s">&#34;submit&#34;</span><span class="p">&gt;</span><span class="nx">Create</span> <span class="nx">Todo</span><span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;/</span><span class="nt">form</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p><code>use client</code> denotes that the <code>CreateTodo</code> component needs to be interactive on the client. All the earlier components can execute code on server and send the results to the client, while <code>CreateTodo</code> has to be pushed as Javascript to client and the form needs to accept user inputs.</p>
<p>Other than the client interaction, <code>CreateTodo</code> is &lsquo;more or less&rsquo; standard React.</p>
<p>The code described so far should be good enough to complete all the things that the app needs to do. However, let us add a dynamic route just because we can. (Also, this will eliminate the errors if you have copied the code as is).</p>
<p>Create a directory <code>[id]</code> under <code>todos</code> directory. Create a new file <code>page.tsx</code> -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ts" data-lang="ts"><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">Link</span> <span class="kr">from</span> <span class="s2">&#34;next/link&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">PocketBase</span> <span class="kr">from</span> <span class="s2">&#34;pocketbase&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">client</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">PocketBase</span><span class="p">(</span><span class="s2">&#34;http://127.0.0.1:8090&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">async</span> <span class="kd">function</span> <span class="nx">getTodo</span><span class="p">(</span><span class="nx">todoId</span>: <span class="kt">string</span> <span class="o">=</span> <span class="s2">&#34;&#34;</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="nx">res</span> <span class="o">=</span> <span class="nx">todoId</span>
</span></span><span class="line"><span class="cl">    <span class="o">?</span> <span class="k">await</span> <span class="nx">client</span><span class="p">.</span><span class="nx">records</span><span class="p">.</span><span class="nx">getOne</span><span class="p">(</span><span class="s2">&#34;todos&#34;</span><span class="p">,</span> <span class="nx">todoId</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">:</span> <span class="p">{</span> <span class="nx">id</span><span class="o">:</span> <span class="s2">&#34;&#34;</span><span class="p">,</span> <span class="nx">description</span><span class="o">:</span> <span class="s2">&#34;&#34;</span><span class="p">,</span> <span class="nx">status</span><span class="o">:</span> <span class="s2">&#34;&#34;</span> <span class="p">};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="nx">res</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="kr">async</span> <span class="kd">function</span> <span class="nx">TodoPage</span><span class="p">({</span> <span class="nx">params</span> <span class="p">}</span><span class="o">:</span> <span class="kt">any</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="nx">todo</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">getTodo</span><span class="p">(</span><span class="nx">params</span><span class="p">.</span><span class="nx">id</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">h1</span><span class="p">&gt;</span><span class="nx">Todo</span><span class="p">&lt;/</span><span class="nt">h1</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">div</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;padding-bottom: 1em;&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="nt">Link</span> <span class="na">href</span><span class="o">=</span><span class="s">&#34;/todos&#34;</span><span class="p">&gt;</span><span class="nx">Back</span> <span class="nx">to</span> <span class="nx">todos</span><span class="p">&lt;/</span><span class="nt">Link</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">label</span> <span class="na">htmlFor</span><span class="o">=</span><span class="s">&#34;id&#34;</span><span class="p">&gt;</span><span class="nx">Id</span><span class="p">&lt;/</span><span class="nt">label</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">input</span> <span class="na">name</span><span class="o">=</span><span class="s">&#34;id&#34;</span> <span class="na">value</span><span class="o">=</span><span class="p">{</span><span class="nx">todo</span><span class="p">.</span><span class="nx">id</span><span class="p">}&gt;&lt;/</span><span class="nt">input</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">label</span> <span class="na">htmlFor</span><span class="o">=</span><span class="s">&#34;desc&#34;</span><span class="p">&gt;</span><span class="nx">Description</span><span class="p">&lt;/</span><span class="nt">label</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">input</span> <span class="na">name</span><span class="o">=</span><span class="s">&#34;desc&#34;</span> <span class="na">value</span><span class="o">=</span><span class="p">{</span><span class="nx">todo</span><span class="p">.</span><span class="nx">description</span><span class="p">}&gt;&lt;/</span><span class="nt">input</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">label</span> <span class="na">htmlFor</span><span class="o">=</span><span class="s">&#34;status&#34;</span><span class="p">&gt;</span><span class="nx">Status</span><span class="p">&lt;/</span><span class="nt">label</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">input</span> <span class="na">name</span><span class="o">=</span><span class="s">&#34;status&#34;</span> <span class="na">value</span><span class="o">=</span><span class="p">{</span><span class="nx">todo</span><span class="p">.</span><span class="nx">status</span><span class="p">}&gt;&lt;/</span><span class="nt">input</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>You would have probably logged out by now, or know the drill..</p>
<ol>
<li><code>page.tsx</code> is the root page</li>
<li>The component accepts a parameter from the caller to query for a particular todo record</li>
<li>Display the todo</li>
</ol>
<p>What is different is the <code>[id]</code> tag that indicates that the component is dynamic (spare me the suprise look).</p>
<p>Lo &amp; behold, you now have a to do app that can make the next million dollar SaaS app.</p>
<p>See complete code for this incomplete app on <a href="https://github.com/prashanth1k/todo-next13">GitHub</a>.</p>
<h2 id="why-i-will-not-switch-to-nextjs">Why I will not switch to NextJS</h2>
<p>I really like where NextJS is going. I see compelling reasons for using Next - the tooling, ease of deployment, and the massive community that tells me how my code is completely wrong and how I should be thinking about solving world hunger.</p>
<p>But again, ReactJS is not exactly my favourite way to write apps (yes, that&rsquo;s me being stupid). Also -</p>
<ul>
<li>I still think ReactJS is a lot of boilerplate</li>
<li>I don&rsquo;t quite enjoy writing a lot of code to maintain state, render a list or do the thousand things that every web app has to do</li>
<li>I don&rsquo;t have to answer to anyone or collaborate with 100 people for my side projects</li>
<li>I don&rsquo;t have a massive library of UI components built out in React that can help me speed up the development process</li>
</ul>
<p>Till I can check at least three of the above boxes, I will continue to code in either Vue or Svelte.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Create a Task Management App with ReactJS in 2021</title>
      <link>https://techformist.com/task-management-app-reactjs-2021/</link>
      <pubDate>Wed, 13 Jan 2021 06:30:00 +0000</pubDate>
      
      <guid>https://techformist.com/task-management-app-reactjs-2021/</guid>
      <description>&lt;p&gt;In this post let us see how we can easily build a task management app (which is totally &amp;amp; completely different from a todo app) using ReactJS. We will be using React Hooks, Chota CSS for styling and a lot of ES6+. We will not look at any centralised state management, or deal with a backend to store the tasks in this post.&lt;/p&gt;
&lt;h2 id=&#34;get-started&#34;&gt;Get Started&lt;/h2&gt;
&lt;p&gt;Use &lt;code&gt;create-react-app&lt;/code&gt; to structure your project like any sane person would do -&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>In this post let us see how we can easily build a task management app (which is totally &amp; completely different from a todo app) using ReactJS. We will be using React Hooks, Chota CSS for styling and a lot of ES6+. We will not look at any centralised state management, or deal with a backend to store the tasks in this post.</p>
<h2 id="get-started">Get Started</h2>
<p>Use <code>create-react-app</code> to structure your project like any sane person would do -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cmd" data-lang="cmd"><span class="line"><span class="cl">npx create-react-app tasker-react-sample-app
</span></span></code></pre></div><p>Proceed to have a dozen cups of coffee while your app gets initialised. Open the project root folder in VSCode to see this beautiful structure.</p>
<p><img loading="lazy" src="/2021/create-react-app-structure.jpg" type="" alt="create-react-app-structure"  /></p>
<p>Start your app..</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cmd" data-lang="cmd"><span class="line"><span class="cl">npm run start
</span></span></code></pre></div><p>Navigate to <code>http://localhost:3000</code> in your browser to see the app.</p>
<p>While the create-react-app seems to do a lot of things (it does), you only need to care about a few things at this time -</p>
<ul>
<li>The app gets anchored with one HTML file <code>public/index.html</code> and in a single node <code>&lt;div id=&quot;root&quot;&gt;&lt;/div&gt;</code> (for the most part, bear with me). The file itself will not have direct reference to the javascript - that will be done through a build step</li>
<li><code>src/index.js</code> refers to the <code>root</code> element
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">ReactDOM</span><span class="p">.</span><span class="nx">render</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">  <span class="o">&lt;</span><span class="nx">React</span><span class="p">.</span><span class="nx">StrictMode</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="o">&lt;</span><span class="nx">App</span> <span class="o">/&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="o">&lt;</span><span class="err">/React.StrictMode&gt;,</span>
</span></span><span class="line"><span class="cl">  <span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="s2">&#34;root&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">);</span>
</span></span></code></pre></div></li>
<li><code>App</code> in <code>index.js</code> is where you will start coding React magic. You shall use JSX in the React components to do all that magic, or you shall perish -
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-jsx" data-lang="jsx"><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">App</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">div</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;App&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">header</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;App-header&#34;</span><span class="p">&gt;&lt;/</span><span class="nt">header</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div></li>
</ul>
<p>Read more about JSX <a href="https://reactjs.org/docs/introducing-jsx.html">here</a>, or just follow along by keeping mind two things -</p>
<ul>
<li>You can code all the HTML you want within JSX</li>
<li>Use <code>className</code> instead of <code>class</code> to reference css classes</li>
<li>Use <code>{ }</code> notation within JSX for expressions, variables etc.</li>
</ul>
<p>Let&rsquo;s do a quick take on how the components work. Create a new file <code>src/components/HelloWorld.js</code> -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-jsx" data-lang="jsx"><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="kd">function</span> <span class="nx">HelloWorld</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">h3</span><span class="p">&gt;</span><span class="nx">Hello</span> <span class="nx">World</span><span class="p">&lt;/</span><span class="nt">h3</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;/&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>JSX can have only one root - <code>&lt;&gt;&lt;/&gt;</code> tags take care of that. Rest is just plain HTML.</p>
<p>Include <code>HelloWorld</code> in <code>App.js</code> -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-jsx" data-lang="jsx"><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">logo</span> <span class="nx">from</span> <span class="s2">&#34;./logo.svg&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="s2">&#34;./App.css&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">HelloWorld</span> <span class="nx">from</span> <span class="s2">&#34;./components/HelloWorld&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// ...
</span></span></span><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">App</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">div</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;App&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">header</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;App-header&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span><span class="cm">/* - existing code goes here - */</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;/</span><span class="nt">header</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">HelloWorld</span> <span class="p">/&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="nx">App</span><span class="p">;</span>
</span></span></code></pre></div><p>You can see the bold words in your app almost immediately.</p>
<p>Before we proceed, install a few things to make your React development easier -</p>
<ol>
<li>Install <a href="https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en">React Developer Tools</a>. This will add a couple of tabs in your Chrome Developer Tools to view components. By default you should see <code>Components</code> and <code>Profiler</code></li>
<li>Install VSCode extension <a href="https://marketplace.visualstudio.com/itemdetails?itemName=dsznajder.es7-react-js-snippets">ES7 React/Redux/GraphQL/React-Native snippets</a> that will give you a bunch of useful snippets</li>
</ol>
<p>You can use Emmet scripts to quickly create boilerplate and scripts - for e.g. create a new file and type in <code>rfce</code> and tab to see it in action.</p>
<p>Let us also include some styles, because well, we&rsquo;re not cave-men.</p>
<p>Include the below line in your <code>index.html</code> to include a small, class-light library called <code>chota.css</code> -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">link</span> <span class="na">rel</span><span class="o">=</span><span class="s">&#34;stylesheet&#34;</span> <span class="na">href</span><span class="o">=</span><span class="s">&#34;https://unpkg.com/chota@latest&#34;</span> <span class="p">/&gt;</span>
</span></span></code></pre></div><p>Create a new file <code>src/assets/styles.css</code> and leave it blank for now. We will use it for custom styling. Include the file in <code>App.js</code> -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">import</span> <span class="s2">&#34;./assets/styles.css&#34;</span><span class="p">;</span>
</span></span></code></pre></div><p>I will not really touch upon this topic again - but you can see the CSS code in the Github repo.</p>
<h2 id="creating-structure-for-your-app">Creating Structure for your App</h2>
<p>Let us create the basic elements for our app. First, the header - create a new file called <code>src/components/Header.js</code>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-jsx" data-lang="jsx"><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">Header</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">nav</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;nav&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="nt">div</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;nav-left&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">          <span class="p">&lt;</span><span class="nt">a</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;brand&#34;</span> <span class="na">href</span><span class="o">=</span><span class="s">&#34;#&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">            <span class="nx">Tasker</span>
</span></span><span class="line"><span class="cl">          <span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="nt">div</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;nav-right&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">          <span class="p">&lt;</span><span class="nt">div</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;tabs&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">            <span class="p">&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">&#34;https://techformist.com&#34;</span><span class="p">&gt;</span><span class="nx">Techformist</span><span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">          <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;/</span><span class="nt">nav</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="nx">Header</span><span class="p">;</span>
</span></span></code></pre></div><p>We have seen this earlier - JSX and stuff. The only difference is the CSS classes. Let&rsquo;s include this <code>Header</code> in <code>App.js</code>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-jsx" data-lang="jsx"><span class="line"><span class="cl"><span class="c1">// ...
</span></span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">Header</span> <span class="nx">from</span> <span class="s2">&#34;./components/Header&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="c1">// ... other code
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">App</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// ...
</span></span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">div</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;App&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span><span class="cm">/* .. */</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">Header</span><span class="p">&gt;&lt;/</span><span class="nt">Header</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span><span class="cm">/* .. */</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>The above changes should give you a good idea about where we are going. We create a <code>Header</code> component, and include it in the main <code>App</code> so that it&rsquo;s available everywhere in the app.</p>
<p>We can now include the main content just below <code>Header</code>.</p>
<h2 id="create-tasks-component">Create Tasks Component</h2>
<p>The simplest way to create a task component is familiar to us by now. Create a new file <code>src/components/Tasks.js</code> -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-jsx" data-lang="jsx"><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">Tasks</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">div</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;row&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">div</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;col-12&#34;</span><span class="p">&gt;</span><span class="nx">Learn</span> <span class="nx">React</span><span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">div</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;col-12&#34;</span><span class="p">&gt;</span><span class="nx">Profit</span><span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="nx">Tasks</span><span class="p">;</span>
</span></span></code></pre></div><p>Include <code>Tasks</code> in <code>App</code>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-jsx" data-lang="jsx"><span class="line"><span class="cl"><span class="c1">// ...
</span></span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">Tasks</span> <span class="nx">from</span> <span class="s2">&#34;./components/Tasks&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="c1">// ... other code
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">App</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// ...
</span></span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">div</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;App&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span><span class="cm">/* .. */</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">Header</span><span class="p">&gt;&lt;/</span><span class="nt">Header</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">button</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;button&#34;</span><span class="p">&gt;</span><span class="nx">New</span><span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">Tasks</span><span class="p">&gt;&lt;/</span><span class="nt">Tasks</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span><span class="cm">/* .. */</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>You should now be able to see the tasks and a button &ldquo;New&rdquo; that doesn&rsquo;t do anything.</p>
<p>Let&rsquo;s level up. We will create a state variable <code>tasks</code> that will store tasks and can be accessible from different components. We could eventually use this variable to store tasks retrieved from a database or a file.</p>
<p>In the simplest design we could create <code>tasks</code> in <code>Tasks</code> component, but that would make it difficult to access in a different component. For example, we need <code>tasks</code> in both <code>Tasks</code>, which is a list of tasks, and <code>TaskDetail</code>, which shows the detail task and allows user to edit tasks. So, let&rsquo;s create <code>tasks</code> in <code>App.js</code> for now.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-jsx" data-lang="jsx"><span class="line"><span class="cl"><span class="kr">import</span> <span class="s2">&#34;./App.css&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="s2">&#34;./assets/styles.css&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">Header</span> <span class="nx">from</span> <span class="s2">&#34;./components/Header&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">Tasks</span> <span class="nx">from</span> <span class="s2">&#34;./components/Tasks&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">useState</span> <span class="p">}</span> <span class="nx">from</span> <span class="s2">&#34;react&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">App</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="p">[</span><span class="nx">tasks</span><span class="p">,</span> <span class="nx">setTasks</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">([</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span> <span class="nx">desc</span><span class="o">:</span> <span class="s2">&#34;Learn React&#34;</span><span class="p">,</span> <span class="nx">id</span><span class="o">:</span> <span class="mi">1</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span> <span class="nx">desc</span><span class="o">:</span> <span class="s2">&#34;Profit&#34;</span><span class="p">,</span> <span class="nx">id</span><span class="o">:</span> <span class="mi">2</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">]);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">div</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;App&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">Header</span><span class="p">&gt;&lt;/</span><span class="nt">Header</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">div</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;container&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="nt">Tasks</span> <span class="na">tasks</span><span class="o">=</span><span class="p">{</span><span class="nx">tasks</span><span class="p">}&gt;&lt;/</span><span class="nt">Tasks</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="nx">App</span><span class="p">;</span>
</span></span></code></pre></div><p>We have done a couple of cool things here -</p>
<ol>
<li>Import <code>useState</code> from React</li>
<li>Create <code>tasks</code> and initialize it. <code>tasks</code> is the variable name and <code>setTasks</code> is used to set this variable with a value. We will not be using <code>setTasks</code> right now, but directly provide the initial value as a param to <code>useState</code>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">const</span> <span class="p">[</span><span class="nx">tasks</span><span class="p">,</span> <span class="nx">setTasks</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">([</span>
</span></span><span class="line"><span class="cl">  <span class="p">{</span> <span class="nx">desc</span><span class="o">:</span> <span class="s2">&#34;Learn React&#34;</span><span class="p">,</span> <span class="nx">id</span><span class="o">:</span> <span class="mi">1</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">{</span> <span class="nx">desc</span><span class="o">:</span> <span class="s2">&#34;Profit&#34;</span><span class="p">,</span> <span class="nx">id</span><span class="o">:</span> <span class="mi">2</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">]);</span>
</span></span></code></pre></div></li>
<li>Pass <code>tasks</code> as props to the <code>Tasks</code> component</li>
</ol>
<p>Let us receive <code>tasks</code> prop in our <code>Tasks</code> component.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-jsx" data-lang="jsx"><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">Tasks</span><span class="p">({</span> <span class="nx">tasks</span> <span class="p">})</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">div</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;row&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">div</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;col-12 text-right&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="nt">button</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;button primary&#34;</span><span class="p">&gt;</span><span class="nx">New</span><span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span><span class="nx">tasks</span><span class="p">.</span><span class="nx">map</span><span class="p">((</span><span class="nx">task</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">          <span class="p">&lt;</span><span class="nt">div</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;col-12 text-left&#34;</span> <span class="na">key</span><span class="o">=</span><span class="p">{</span><span class="nx">task</span><span class="p">.</span><span class="nx">id</span><span class="p">}&gt;</span>
</span></span><span class="line"><span class="cl">            <span class="p">&lt;</span><span class="nt">h4</span><span class="p">&gt;{</span><span class="nx">task</span><span class="p">.</span><span class="nx">desc</span><span class="p">}&lt;/</span><span class="nt">h4</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">          <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">);</span>
</span></span><span class="line"><span class="cl">      <span class="p">})}</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="nx">Tasks</span><span class="p">;</span>
</span></span></code></pre></div><p>As you can see -</p>
<ol>
<li>We receive a destructured <code>tasks</code> prop in the function. You could also define param as simply <code>props</code> (no brackets, no destructuring), and refer to tasks as <code>props.tasks</code></li>
<li>We cycle through <code>tasks</code> and display individual task using <code>h3</code> element. The brackets contain the overall expression in JSX
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-jsx" data-lang="jsx"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">tasks</span><span class="p">.</span><span class="nx">map</span><span class="p">((</span><span class="nx">task</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">div</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;col-12 text-left&#34;</span> <span class="na">key</span><span class="o">=</span><span class="p">{</span><span class="nx">task</span><span class="p">.</span><span class="nx">id</span><span class="p">}&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="nt">h4</span><span class="p">&gt;{</span><span class="nx">task</span><span class="p">.</span><span class="nx">desc</span><span class="p">}&lt;/</span><span class="nt">h4</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">});</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div></li>
</ol>
<p>You should now see..</p>
<h2 id="create-task-component">Create Task Component</h2>
<p><code>Tasks</code> component is doing too many things -</p>
<ol>
<li>List tasks</li>
<li>Show task</li>
<li>er.. that&rsquo;s about it, but it has the potential to much more</li>
</ol>
<p>Let&rsquo;s break the component so that display of a task becomes concern of a different component.</p>
<p>Create a new file <code>src/components/Task.js</code> -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-jsx" data-lang="jsx"><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">Task</span><span class="p">({</span> <span class="nx">task</span> <span class="p">})</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">div</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;col-12 text-left&#34;</span> <span class="na">key</span><span class="o">=</span><span class="p">{</span><span class="nx">task</span><span class="p">.</span><span class="nx">id</span><span class="p">}&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">h4</span><span class="p">&gt;{</span><span class="nx">task</span><span class="p">.</span><span class="nx">desc</span><span class="p">}&lt;/</span><span class="nt">h4</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="nx">Task</span><span class="p">;</span>
</span></span></code></pre></div><p>The code is a direct copy of the fragment responsible to display a specific task in <code>Tasks</code> component.</p>
<p>Include <code>Task</code> in <code>Tasks</code> -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-jsx" data-lang="jsx"><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">Task</span> <span class="nx">from</span> <span class="s2">&#34;./Task&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">Tasks</span><span class="p">({</span> <span class="nx">tasks</span> <span class="p">})</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">div</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;row&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">div</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;col-12 text-right&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="nt">button</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;button primary&#34;</span><span class="p">&gt;</span><span class="nx">New</span><span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span><span class="nx">tasks</span><span class="p">.</span><span class="nx">map</span><span class="p">((</span><span class="nx">task</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="nt">Task</span> <span class="na">task</span><span class="o">=</span><span class="p">{</span><span class="nx">task</span><span class="p">}</span> <span class="na">key</span><span class="o">=</span><span class="p">{</span><span class="nx">task</span><span class="p">.</span><span class="nx">id</span><span class="p">}</span> <span class="p">/&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">))}</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">div</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;col-12&#34;</span><span class="p">&gt;&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="nx">Tasks</span><span class="p">;</span>
</span></span></code></pre></div><p>This is very similar to last time when we included one component in another. We are just using an additional attribute called <code>key</code>, which denotes the unique identifier of each element in the array (and that will be <code>task.id</code> in our case).</p>
<p>The added advantage of segregating task display is that we can use this <code>Task</code> component to display individual task anywhere in the application.</p>
<p>Fantastic.</p>
<p>Let us add more attributes to the task and beautify this a bit. Afterall, a task is not simply about the description.</p>
<p>Add more attributes to the task in <code>App</code>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">const</span> <span class="p">[</span><span class="nx">tasks</span><span class="p">,</span> <span class="nx">setTasks</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">([</span>
</span></span><span class="line"><span class="cl">  <span class="p">{</span> <span class="nx">desc</span><span class="o">:</span> <span class="s2">&#34;Learn React&#34;</span><span class="p">,</span> <span class="nx">id</span><span class="o">:</span> <span class="mi">1</span><span class="p">,</span> <span class="nx">date</span><span class="o">:</span> <span class="s2">&#34;2021-01-03 10:00&#34;</span><span class="p">,</span> <span class="nx">status</span><span class="o">:</span> <span class="s2">&#34;Complete&#34;</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">{</span> <span class="nx">desc</span><span class="o">:</span> <span class="s2">&#34;Profit&#34;</span><span class="p">,</span> <span class="nx">id</span><span class="o">:</span> <span class="mi">2</span><span class="p">,</span> <span class="nx">date</span><span class="o">:</span> <span class="s2">&#34;2021-01-05 15:00&#34;</span><span class="p">,</span> <span class="nx">status</span><span class="o">:</span> <span class="s2">&#34;Open&#34;</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">]);</span>
</span></span></code></pre></div><p>Change <code>Task.js</code> to make tasks come alive -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-jsx" data-lang="jsx"><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">Task</span><span class="p">({</span> <span class="nx">task</span> <span class="p">})</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">div</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;card text-left&#34;</span> <span class="na">key</span><span class="o">=</span><span class="p">{</span><span class="nx">task</span><span class="p">.</span><span class="nx">id</span><span class="p">}&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">div</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;row&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="nt">div</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;col-10&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">          <span class="p">&lt;</span><span class="nt">h4</span><span class="p">&gt;{</span><span class="nx">task</span><span class="p">.</span><span class="nx">desc</span><span class="p">}&lt;/</span><span class="nt">h4</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">          <span class="p">&lt;</span><span class="nt">div</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;task-meta&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">            <span class="p">&lt;</span><span class="nt">img</span>
</span></span><span class="line"><span class="cl">              <span class="na">src</span><span class="o">=</span><span class="s">&#34;https://icongr.am/feather/calendar.svg?size=12&amp;color=b5b5b5&#34;</span>
</span></span><span class="line"><span class="cl">              <span class="na">alt</span><span class="o">=</span><span class="s">&#34;calendar&#34;</span>
</span></span><span class="line"><span class="cl">            <span class="p">/&gt;</span>
</span></span><span class="line"><span class="cl">            <span class="p">{</span><span class="nx">task</span><span class="p">.</span><span class="nx">date</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">          <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="nt">div</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;col-2 is-center&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">          <span class="p">&lt;</span><span class="nt">button</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;button icon-only clear&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">            <span class="p">&lt;</span><span class="nt">img</span>
</span></span><span class="line"><span class="cl">              <span class="na">src</span><span class="o">=</span><span class="s">&#34;https://icongr.am/feather/check-circle.svg?size=24&amp;color=11d054&#34;</span>
</span></span><span class="line"><span class="cl">              <span class="na">alt</span><span class="o">=</span><span class="s">&#34;Open&#34;</span>
</span></span><span class="line"><span class="cl">            <span class="p">/&gt;</span>
</span></span><span class="line"><span class="cl">          <span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="nt">div</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;col-12&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">          <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;{</span><span class="nx">task</span><span class="p">.</span><span class="nx">remarks</span><span class="p">}&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="nx">Task</span><span class="p">;</span>
</span></span></code></pre></div><p>And, voila..</p>
<p><img loading="lazy" src="/2021/tasker-task-lists-simple.jpg" type="" alt="tasker-task-lists-simple"  /></p>
<h2 id="add-functionality-complete-task">Add Functionality: Complete Task</h2>
<p>We have successfully displayed a task so far, but we don&rsquo;t have any functionality enabled on the task. We will change that by inserting a button to toggle the task status.</p>
<p>Add a function that can get called to change status. If we had a global state (e.g. Redux), we would have more independence to decide where this function has to reside. Since we are using a simple state at <code>App</code> level, we will introduce the function to change that state also within <code>App</code>. Create a new function -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">onTglStatus</span> <span class="o">=</span> <span class="p">(</span><span class="nx">task</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&#34;completing task&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span></code></pre></div><p>The child component (<code>Tasks</code> in our case) does not know about this method. We have to pass the function to the inner-most component that will call it for some greater good.</p>
<p>Change <code>App.js</code> to pass <code>onTglStatus</code> as a prop -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-jsx" data-lang="jsx"><span class="line"><span class="cl"><span class="c1">// ...
</span></span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">Tasks</span> <span class="na">tasks</span><span class="o">=</span><span class="p">{</span><span class="nx">tasks</span><span class="p">}</span> <span class="na">onTglStatus</span><span class="o">=</span><span class="p">{</span><span class="nx">onTglStatus</span><span class="p">}&gt;&lt;/</span><span class="nt">Tasks</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="c1">//  ...
</span></span></span></code></pre></div><p>Repeat the above code in <code>Tasks.js</code> -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-jsx" data-lang="jsx"><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">Tasks</span><span class="p">({</span> <span class="nx">tasks</span><span class="p">,</span> <span class="nx">onTglStatus</span> <span class="p">})</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="c1">// ...
</span></span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">Task</span> <span class="na">task</span><span class="o">=</span><span class="p">{</span><span class="nx">task</span><span class="p">}</span> <span class="na">onTglStatus</span><span class="o">=</span><span class="p">{</span><span class="nx">onTglStatus</span><span class="p">}</span> <span class="p">/&gt;;</span>
</span></span><span class="line"><span class="cl">  <span class="c1">// ...
</span></span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Call the function in <code>Task.js</code> -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-jsx" data-lang="jsx"><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">Task</span><span class="p">({</span> <span class="nx">task</span><span class="p">,</span> <span class="nx">onTglStatus</span> <span class="p">})</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="c1">// ...
</span></span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">button</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;button icon-only clear&#34;</span> <span class="na">onClick</span><span class="o">=</span><span class="p">{()</span> <span class="p">=&gt;</span> <span class="nx">onTglStatus</span><span class="p">(</span><span class="nx">task</span><span class="p">)}&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="o">&gt;</span> <span class="s2">&#34;⬜&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;;</span>
</span></span><span class="line"><span class="cl">  <span class="c1">// ...
</span></span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Click the button to see the debug statement in developer console.</p>
<p>We have moved props including variables(state) and functions that act on the state down the chain, and events get surfaced up the component chain!</p>
<p>Add the function to do something beyond just a debug statement in <code>App.js</code> -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">onTglStatus</span> <span class="o">=</span> <span class="p">(</span><span class="nx">task</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&#34;completing task&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="nx">setTasks</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="nx">tasks</span><span class="p">.</span><span class="nx">map</span><span class="p">((</span><span class="nx">chkTask</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">chkTask</span><span class="p">.</span><span class="nx">complete</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">        <span class="nx">task</span><span class="p">.</span><span class="nx">id</span> <span class="o">===</span> <span class="nx">chkTask</span><span class="p">.</span><span class="nx">id</span> <span class="o">?</span> <span class="o">!</span><span class="nx">chkTask</span><span class="p">.</span><span class="nx">complete</span> <span class="o">:</span> <span class="nx">chkTask</span><span class="p">.</span><span class="nx">complete</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">      <span class="k">return</span> <span class="nx">chkTask</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">})</span>
</span></span><span class="line"><span class="cl">  <span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span></code></pre></div><p>In the above code we use <code>Array.map</code> function to change status for the matching record. The matching record (<code>task</code>) is supplied by the function called by button click event.</p>
<p>Let us change the checkbox/button in indicate completed tasks in <code>Task.js</code>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-jsx" data-lang="jsx"><span class="line"><span class="cl"><span class="c1">// ...
</span></span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">button</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;button icon-only clear&#34;</span> <span class="na">onClick</span><span class="o">=</span><span class="p">{()</span> <span class="p">=&gt;</span> <span class="nx">onTglStatus</span><span class="p">(</span><span class="nx">task</span><span class="p">)}&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">{</span><span class="nx">task</span><span class="p">.</span><span class="nx">complete</span> <span class="o">&amp;&amp;</span> <span class="s2">&#34;✅&#34;</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">{</span><span class="o">!</span><span class="nx">task</span><span class="p">.</span><span class="nx">complete</span> <span class="o">&amp;&amp;</span> <span class="s2">&#34;⬜&#34;</span><span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="c1">// ...
</span></span></span></code></pre></div><p>We use one of the old Javascript tricks to display <code>✅</code> when task is complete.</p>
<ul>
<li><code>{task.complete &amp;&amp; &quot;✅&quot;}</code> evaluates to <code>✅</code> when <code>task.complete</code> is true. Else this returns nothing</li>
<li>The next expression <code>{!task.complete &amp;&amp; &quot;⬜&quot;}</code> returns <code>⬜</code> when <code>task.complete</code> is false</li>
</ul>
<p>Since our application is reactive to changes and the button label gets driven by data, we see the below behaviour.</p>
<p><img loading="lazy" src="/2021/reactive-buttons-data-react.gif" type="" alt="reactive-buttons-data-react"  /></p>
<h2 id="add-functionality-add-task">Add Functionality: Add Task</h2>
<p>We need to get task data from user and save new tasks. To that end, add the function to save tasks <code>onSaveTask</code> in <code>App.js</code> -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">onSaveTask</span> <span class="o">=</span> <span class="p">({</span> <span class="nx">desc</span><span class="p">,</span> <span class="nx">date</span> <span class="p">})</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&#34;saving tasks&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="nx">setTasks</span><span class="p">([</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span> <span class="nx">desc</span><span class="o">:</span> <span class="nx">desc</span><span class="p">,</span> <span class="nx">date</span><span class="o">:</span> <span class="nx">date</span><span class="p">,</span> <span class="nx">id</span><span class="o">:</span> <span class="nb">Date</span><span class="p">.</span><span class="nx">now</span><span class="p">(),</span> <span class="nx">complete</span><span class="o">:</span> <span class="kc">false</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">...</span><span class="nx">tasks</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="p">]);</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span></code></pre></div><p>We are using <code>setTasks</code> like before, but this time we are adding a new element to the array. Again, we don&rsquo;t add the element directly to array since the state variable is immutable. We rather do this -</p>
<ol>
<li>create a new variable</li>
<li>Add <code>{ desc: desc, date: date, id: Date.now(), complete: false },</code> as the first element. <code>desc</code> and <code>date</code> are passed along by the form used to create new tasks. <code>Date.now()</code> is a simple way to make the id unique</li>
<li>Add the existing array elements to the new array variable <code>...tasks</code></li>
</ol>
<p>Next, add a new form to collect data. Let&rsquo;s create a new component <code>src/components/TaskEdit.js</code>. This component will receive the function <code>onSaveTask</code> as props and call it on button click.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-jsx" data-lang="jsx"><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">useState</span> <span class="p">}</span> <span class="nx">from</span> <span class="s2">&#34;react&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">TaskEdit</span><span class="p">({</span> <span class="nx">task</span><span class="p">,</span> <span class="nx">onSaveTask</span> <span class="p">})</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="p">[</span><span class="nx">desc</span><span class="p">,</span> <span class="nx">setDesc</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">(</span><span class="s2">&#34;&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="p">[</span><span class="nx">date</span><span class="p">,</span> <span class="nx">setDate</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">(</span><span class="s2">&#34;&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="nx">saveTask</span> <span class="o">=</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">e</span><span class="p">.</span><span class="nx">preventDefault</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="nx">onSaveTask</span><span class="p">({</span> <span class="nx">desc</span><span class="o">:</span> <span class="nx">desc</span><span class="p">,</span> <span class="nx">date</span><span class="o">:</span> <span class="nx">date</span> <span class="p">});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nx">setDesc</span><span class="p">(</span><span class="s2">&#34;&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nx">setDate</span><span class="p">(</span><span class="s2">&#34;&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">};</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">div</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;card&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">h3</span><span class="p">&gt;</span><span class="nx">Add</span> <span class="nx">Task</span><span class="p">&lt;/</span><span class="nt">h3</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">form</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="nt">label</span> <span class="na">htmlFor</span><span class="o">=</span><span class="s">&#34;desc&#34;</span><span class="p">&gt;</span><span class="nx">Description</span><span class="p">&lt;/</span><span class="nt">label</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="nt">input</span>
</span></span><span class="line"><span class="cl">          <span class="na">type</span><span class="o">=</span><span class="s">&#34;text&#34;</span>
</span></span><span class="line"><span class="cl">          <span class="na">name</span><span class="o">=</span><span class="s">&#34;desc&#34;</span>
</span></span><span class="line"><span class="cl">          <span class="na">id</span><span class="o">=</span><span class="s">&#34;desc&#34;</span>
</span></span><span class="line"><span class="cl">          <span class="na">value</span><span class="o">=</span><span class="p">{</span><span class="nx">desc</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">          <span class="na">onChange</span><span class="o">=</span><span class="p">{(</span><span class="nx">e</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="nx">setDesc</span><span class="p">(</span><span class="nx">e</span><span class="p">.</span><span class="nx">target</span><span class="p">.</span><span class="nx">value</span><span class="p">)}</span>
</span></span><span class="line"><span class="cl">        <span class="p">/&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="nt">label</span> <span class="na">htmlFor</span><span class="o">=</span><span class="s">&#34;date&#34;</span><span class="p">&gt;</span><span class="nb">Date</span><span class="p">&lt;/</span><span class="nt">label</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="nt">input</span>
</span></span><span class="line"><span class="cl">          <span class="na">type</span><span class="o">=</span><span class="s">&#34;text&#34;</span>
</span></span><span class="line"><span class="cl">          <span class="na">name</span><span class="o">=</span><span class="s">&#34;date&#34;</span>
</span></span><span class="line"><span class="cl">          <span class="na">id</span><span class="o">=</span><span class="s">&#34;date&#34;</span>
</span></span><span class="line"><span class="cl">          <span class="na">value</span><span class="o">=</span><span class="p">{</span><span class="nx">date</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">          <span class="na">onChange</span><span class="o">=</span><span class="p">{(</span><span class="nx">e</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="nx">setDate</span><span class="p">(</span><span class="nx">e</span><span class="p">.</span><span class="nx">target</span><span class="p">.</span><span class="nx">value</span><span class="p">)}</span>
</span></span><span class="line"><span class="cl">        <span class="p">/&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="nt">div</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;text-right&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">          <span class="p">&lt;</span><span class="nt">button</span> <span class="na">className</span><span class="o">=</span><span class="s">&#34;button dark&#34;</span> <span class="na">onClick</span><span class="o">=</span><span class="p">{</span><span class="nx">saveTask</span><span class="p">}&gt;</span>
</span></span><span class="line"><span class="cl">            <span class="nx">Save</span>
</span></span><span class="line"><span class="cl">          <span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;/</span><span class="nt">form</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="nx">TaskEdit</span><span class="p">;</span>
</span></span></code></pre></div><p>We have gone through some of the functions implemented here, while rest are mostly HTML -</p>
<ol>
<li><code>const [desc, setDesc] = useState(&quot;&quot;);</code> creates a new state variale local to <code>TaskEdit</code> and initiates it to <code>&quot;&quot;</code></li>
<li>a standard HTML form displays a couple of text boxes to collect <code>desc</code> and <code>date</code></li>
<li><code>Save</code> button calls a local method <code>saveTask</code>, which will call the <code>onSaveTask</code> function in <code>App.js</code> and resets form</li>
</ol>
<p>Add functionality to <code>New</code> button so that it displays the <code>TaskEdit</code> component and associated form (and can also toggle to hide the form).</p>
<p>In <code>App.js</code> -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-jsx" data-lang="jsx"><span class="line"><span class="cl"><span class="c1">// ...
</span></span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="p">[</span><span class="nx">showTaskEdit</span><span class="p">,</span> <span class="nx">setShowTaskEdit</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="c1">// ...
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">button</span>
</span></span><span class="line"><span class="cl">  <span class="na">className</span><span class="o">=</span><span class="s">&#34;button outline&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="na">onClick</span><span class="o">=</span><span class="p">{()</span> <span class="p">=&gt;</span> <span class="nx">setShowTaskEdit</span><span class="p">(</span><span class="o">!</span><span class="nx">showTaskEdit</span><span class="p">)}&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">{</span><span class="o">!</span><span class="nx">showTaskEdit</span> <span class="o">&amp;&amp;</span> <span class="s2">&#34;New&#34;</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">{</span><span class="nx">showTaskEdit</span> <span class="o">&amp;&amp;</span> <span class="s2">&#34;➖&#34;</span><span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// ...
</span></span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">showTaskEdit</span> <span class="o">&amp;&amp;</span> <span class="p">&lt;</span><span class="nt">TaskEdit</span> <span class="na">task</span><span class="o">=</span><span class="p">{{}}</span> <span class="na">onSaveTask</span><span class="o">=</span><span class="p">{</span><span class="nx">onSaveTask</span><span class="p">}</span> <span class="p">/&gt;;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="c1">//  ...
</span></span></span></code></pre></div><p>We conditionally show <code>TaskEdit</code> only if <code>showTaskEdit</code> is <code>true</code>.</p>
<p>Time to see the complete application in action -</p>
<p><img loading="lazy" src="/2021/react-task-manager--simple-app-demo.gif" type="" alt="react-task-manager&ndash;simple-app-demo"  /></p>
<h2 id="next-steps">Next Steps</h2>
<ul>
<li>Enable user to edit tasks to change description and dates</li>
<li>Add a backend for your task manager</li>
</ul>
<p>Code for this project is available in the <a href="https://github.com/prashanth1k/tasker-react-sample-app">Github repo</a>.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Get Started on NextJS</title>
      <link>https://techformist.com/get-started-nextjs/</link>
      <pubDate>Wed, 06 Jan 2021 06:30:00 +0000</pubDate>
      
      <guid>https://techformist.com/get-started-nextjs/</guid>
      <description>&lt;p&gt;Welcome to 2021. For me this will be an exciting year when I embrace ReactJS and Svelte as friends. And, what better way to start with React than NextJS..? In this post, we will see why and how we can get started on NextJS, and a few good learning resources.&lt;/p&gt;
&lt;h2 id=&#34;but-why&#34;&gt;But, why?&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;React continues to be a leader with ~50% market share. It enjoys a lot of developer confidence, community contribution and widespread adoption&lt;/li&gt;
&lt;li&gt;More users have meant more support for the smallest of issues&lt;/li&gt;
&lt;li&gt;React and associated frameworks have been at the forefront of new developments - that may be in the way pages interact with data (Hooks, Suspense), in how front-end gets/updates data (React Server Components), or how the latest technologies can speed up development and enable you to use hybrid frameworks to get things done (Next)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Vue will not be completely replaced in my toolbox - not unless I find a shiny new thing that can completely replace it. In today&amp;rsquo;s world everyone learns from each other and adapts rather quickly - so that scenario is not likely to play out.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Welcome to 2021. For me this will be an exciting year when I embrace ReactJS and Svelte as friends. And, what better way to start with React than NextJS..? In this post, we will see why and how we can get started on NextJS, and a few good learning resources.</p>
<h2 id="but-why">But, why?</h2>
<ol>
<li>React continues to be a leader with ~50% market share. It enjoys a lot of developer confidence, community contribution and widespread adoption</li>
<li>More users have meant more support for the smallest of issues</li>
<li>React and associated frameworks have been at the forefront of new developments - that may be in the way pages interact with data (Hooks, Suspense), in how front-end gets/updates data (React Server Components), or how the latest technologies can speed up development and enable you to use hybrid frameworks to get things done (Next)</li>
</ol>
<p>Vue will not be completely replaced in my toolbox - not unless I find a shiny new thing that can completely replace it. In today&rsquo;s world everyone learns from each other and adapts rather quickly - so that scenario is not likely to play out.</p>
<h2 id="why-next">Why Next?</h2>
<ul>
<li>Next is a hybrid framework. From the same code base you can -
<ul>
<li>fetch content and generate pages on the server-side at runtime. Rapidly changing sites incl. eCommerce sites.</li>
<li>enable client-side data fetching for classic single page applications</li>
<li>generate static sites. Just fetch data and create final HTML pages at build time. Useful for Blogs, documentation sites. Oor, go rogue with incremental static files that can generate pages and hold on to them for specified time (I love this!)</li>
</ul>
</li>
<li>Built-in router that needs you to just create pages to enable routing. Not really a problem in the Vue world (Vue router becomes second nature), but I see React as more fragmented. Router in Next is easy to understand and scale</li>
<li>Many features that optimize applications incl. code splitting, ability to use HTML or JSON to deliver pages, and so on</li>
<li>Many, many features that make development of large apps easier</li>
<li>Super active development and large community.</li>
</ul>
<h2 id="how-to-get-started">How to get started?</h2>
<p>Here&rsquo;s the complicated ceremonty to initiate a Next project.</p>
<ol>
<li>Install NodeJS</li>
<li>Enter command <code>npx create-next-app do-awesome</code></li>
</ol>
<p>Run your app with <code>npm run dev</code> to meet this screen.</p>
<p><img loading="lazy" src="/2021/create-next-app-starting-page.jpg" type="" alt="create-next-app-starting-page"  /></p>
<p>You have the standard SPA development experience - change page content to see the changes reflected immediately.</p>
<ol>
<li>Add new page <code>pages/todo.js</code></li>
<li>Enter below code -
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="kd">function</span> <span class="nx">Todo</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="o">&lt;</span><span class="nx">h3</span><span class="o">&gt;</span><span class="nx">Todo</span> <span class="nx">Awesome</span><span class="o">&lt;</span><span class="err">/h3&gt;;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div></li>
</ol>
<p>Navigate to <code>http://localhost:3000/todo</code> to see the new page.</p>
<p>Let&rsquo;s write some simple code in <code>todos</code>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">Todo</span><span class="p">({</span> <span class="nx">todos</span> <span class="p">})</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="o">&lt;</span><span class="nx">div</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="o">&lt;</span><span class="nx">h2</span><span class="o">&gt;</span><span class="nx">Todo</span> <span class="nx">Awesome</span><span class="o">&lt;</span><span class="err">/h2&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span><span class="nx">todos</span><span class="p">.</span><span class="nx">map</span><span class="p">((</span><span class="nx">todo</span><span class="p">,</span> <span class="nx">index</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="o">&lt;</span><span class="nx">li</span> <span class="nx">key</span><span class="o">=</span><span class="p">{</span><span class="nx">index</span><span class="p">}</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">          <span class="p">{</span><span class="nx">todo</span><span class="p">.</span><span class="nx">description</span><span class="p">}</span><span class="o">&amp;</span><span class="nx">emsp</span><span class="p">;</span><span class="err">⇋</span> <span class="p">{</span><span class="nx">todo</span><span class="p">.</span><span class="nx">status</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="o">&lt;</span><span class="err">/li&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">))}</span>
</span></span><span class="line"><span class="cl">    <span class="o">&lt;</span><span class="err">/div&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="kd">function</span> <span class="nx">getServerSideProps</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="nx">todos</span> <span class="o">=</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span> <span class="nx">description</span><span class="o">:</span> <span class="s2">&#34;Write blog post&#34;</span><span class="p">,</span> <span class="nx">status</span><span class="o">:</span> <span class="s2">&#34;Open&#34;</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span> <span class="nx">description</span><span class="o">:</span> <span class="s2">&#34;Learn magic trick&#34;</span><span class="p">,</span> <span class="nx">status</span><span class="o">:</span> <span class="s2">&#34;Open&#34;</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span> <span class="nx">description</span><span class="o">:</span> <span class="s2">&#34;Profit from blog&#34;</span><span class="p">,</span> <span class="nx">status</span><span class="o">:</span> <span class="s2">&#34;Cancelled&#34;</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">];</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">props</span><span class="o">:</span> <span class="p">{</span> <span class="nx">todos</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">};</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="nx">Todo</span><span class="p">;</span>
</span></span></code></pre></div><p>We did good in a few lines of code -</p>
<ol>
<li>Created some static data in <code>todos</code> as part of <code>getServerSideProps</code> and returned that as <code>props</code></li>
<li><code>getServerSideProps</code> gets executed for every function call, i.e., everytime we visit the route <code>/todos</code>. Rendering function <code>Todo</code> gets the data passed in as props</li>
<li><code>Todo</code> takes care of rendering the todos</li>
</ol>
<p>Rather simple and elegant.</p>
<p><img loading="lazy" src="/2021/next-page-basic-todo.jpg" type="" alt="next-page-basic-todo"  /></p>
<h2 id="add-styles">Add Styles</h2>
<p>There is more than one way to do things in Next, just like in React - unfortunately.
I follow three distinct patterns.</p>
<h4 id="global-or-module-level-styles">Global or Module Level Styles</h4>
<p>Include CSS in <code>styles &gt; global.css</code> for all styles applicable globally. Similarly, <code>&lt;your-page&gt;.module.css</code> gets applied to <code>&lt;your-page&gt;</code>.</p>
<p>There&rsquo;s nothing preventing you from going old school and simple do -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">import</span> <span class="s2">&#34;../styles.css&#34;</span><span class="p">;</span>
</span></span></code></pre></div><p>.. in any component, but the previous pattern is simpler to use.</p>
<h4 id="global-or-module-level-css-with-cdn">Global or Module Level CSS with CDN</h4>
<p>Use the Next <code>&lt;Head&gt;&lt;/Head&gt;</code> tag anywhere - in <code>_app</code> for global styles or in any modules. Introduce CSS within the <code>HEAD</code> component.</p>
<p>Let us go ahead and do this for our app. Change <code>_app.js</code> to-</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">import</span> <span class="s2">&#34;../styles/globals.css&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">Head</span> <span class="nx">from</span> <span class="s2">&#34;next/head&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">MyApp</span><span class="p">({</span> <span class="nx">Component</span><span class="p">,</span> <span class="nx">pageProps</span> <span class="p">})</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="o">&lt;</span><span class="nx">div</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="o">&lt;</span><span class="nx">Head</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="o">&lt;</span><span class="nx">link</span> <span class="nx">rel</span><span class="o">=</span><span class="s2">&#34;stylesheet&#34;</span> <span class="nx">href</span><span class="o">=</span><span class="s2">&#34;https://unpkg.com/chota&#34;</span> <span class="o">/&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="o">&lt;</span><span class="err">/Head&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="o">&lt;</span><span class="nx">div</span> <span class="nx">className</span><span class="o">=</span><span class="s2">&#34;row&#34;</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="o">&lt;</span><span class="nx">div</span> <span class="nx">className</span><span class="o">=</span><span class="s2">&#34;col-1&#34;</span><span class="o">&gt;&lt;</span><span class="err">/div&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="o">&lt;</span><span class="nx">div</span> <span class="nx">className</span><span class="o">=</span><span class="s2">&#34;col-10&#34;</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">          <span class="o">&lt;</span><span class="nx">Component</span> <span class="p">{...</span><span class="nx">pageProps</span><span class="p">}</span> <span class="o">/&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="o">&lt;</span><span class="err">/div&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="o">&lt;</span><span class="nx">div</span> <span class="nx">className</span><span class="o">=</span><span class="s2">&#34;col-1&#34;</span><span class="o">&gt;&lt;</span><span class="err">/div&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="o">&lt;</span><span class="err">/div&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="o">&lt;</span><span class="err">/div&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="nx">MyApp</span><span class="p">;</span>
</span></span></code></pre></div><p><code>chota</code> is a small CSS framework that provides you some cool things like class-less styling, grids, out-of-the-box icons - good enough for our small project.</p>
<p>Remember that we are dealing with JSX, so we use <code>className</code> instead of <code>class</code> in normal HTML.</p>
<h4 id="style-libraries-from-npm">Style Libraries from NPM</h4>
<p>Install any CSS library through NPM. You can now include the library in <code>_app.js</code> for global styles.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">import</span> <span class="s2">&#34;bootstrap/dist/css/bootstrap.css&#34;</span><span class="p">;</span>
</span></span></code></pre></div><h2 id="add-a-db">Add a DB!</h2>
<p>Our <code>todo</code> page is static and shows the same data each time. Let us change that.</p>
<p>First, let us add prisma to our project to make database access a breeze.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cmd" data-lang="cmd"><span class="line"><span class="cl">npm i -D @prisma/cli
</span></span><span class="line"><span class="cl">npm i @prisma/client
</span></span></code></pre></div><p>Create a new folder <code>data</code> under project root.</p>
<p>Initialize prisma -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cmd" data-lang="cmd"><span class="line"><span class="cl">npx prisma init
</span></span></code></pre></div><p>Prisma CLI creates a few files including -</p>
<ul>
<li><code>.env</code> file (if it doesn&rsquo;t exist) with a database URL</li>
<li><code>prisma/schema.prisma</code> contains the database connection parameters and DB models</li>
</ul>
<p>Open <code>prisma/schema.prisma</code> and replace its contents with the below code -</p>
<pre tabindex="0"><code>datasource db {
  provider = &#34;sqlite&#34;
  url      = &#34;file:../data/data.db&#34;
}

generator client {
  provider = &#34;prisma-client-js&#34;
}

model todo {
  id Int @id @default(autoincrement())
  description String
  status String
}
</code></pre><p>Run the below command to create migration and sync model to database.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cmd" data-lang="cmd"><span class="line"><span class="cl">npx prisma migrate dev --preview-feature
</span></span></code></pre></div><p><code>preview-feature</code> flag may not be required in later versions of prisma. You can provide any name for the migration.</p>
<p>Finally, run the <code>generate</code> command to generate client that can be used in your application.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cmd" data-lang="cmd"><span class="line"><span class="cl">npx prisma generate
</span></span></code></pre></div><p>You can connect to the SQLite database using a client like <a href="https://www.heidisql.com/">HeidiSQL</a> and verify whether all your changes are applied to the table.</p>
<p><img loading="lazy" src="/2021/heidi-sql-sqlite.jpg" type="" alt="heidi-sql-sqlite"  /></p>
<p>Or, you could simply do -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cmd" data-lang="cmd"><span class="line"><span class="cl">npx prisma studio
</span></span></code></pre></div><p>.. to open the database with a simple UI.</p>
<p><img loading="lazy" src="/2021/prisma-studio.jpg" type="" alt="prisma-studio"  /></p>
<p>You are all set to work with the SQLite database from Next using Prisma!</p>
<h2 id="get-todos">Get Todos</h2>
<p>Change <code>pages/todos.js</code> -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">PrismaClient</span> <span class="p">}</span> <span class="nx">from</span> <span class="s2">&#34;@prisma/client&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">prisma</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">PrismaClient</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">Todo</span><span class="p">({</span> <span class="nx">todos</span> <span class="p">})</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="o">&lt;</span><span class="nx">div</span> <span class="nx">className</span><span class="o">=</span><span class="s2">&#34;row&#34;</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="o">&lt;</span><span class="nx">h2</span> <span class="nx">className</span><span class="o">=</span><span class="s2">&#34;col-12 list-title is-center&#34;</span><span class="o">&gt;</span><span class="nx">My</span> <span class="nx">Todos</span><span class="o">&lt;</span><span class="err">/h2&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">      <span class="o">&lt;</span><span class="nx">div</span> <span class="nx">className</span><span class="o">=</span><span class="s2">&#34;col-12&#34;</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span><span class="nx">todoArr</span><span class="p">.</span><span class="nx">map</span><span class="p">((</span><span class="nx">todo</span><span class="p">,</span> <span class="nx">index</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">          <span class="o">&lt;</span><span class="nx">div</span> <span class="nx">className</span><span class="o">=</span><span class="s2">&#34;row&#34;</span> <span class="nx">key</span><span class="o">=</span><span class="p">{</span><span class="nx">index</span><span class="p">}</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">            <span class="o">&lt;</span><span class="nx">div</span> <span class="nx">className</span><span class="o">=</span><span class="s2">&#34;col-1 list-desc&#34;</span> <span class="nx">name</span><span class="o">=</span><span class="s2">&#34;id&#34;</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">              <span class="p">{</span><span class="nx">todo</span><span class="p">.</span><span class="nx">id</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">            <span class="o">&lt;</span><span class="err">/div&gt;</span>
</span></span><span class="line"><span class="cl">            <span class="o">&lt;</span><span class="nx">div</span> <span class="nx">className</span><span class="o">=</span><span class="s2">&#34;col-5 list-desc&#34;</span> <span class="nx">name</span><span class="o">=</span><span class="s2">&#34;description&#34;</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">              <span class="p">{</span><span class="nx">todo</span><span class="p">.</span><span class="nx">description</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">            <span class="o">&lt;</span><span class="err">/div&gt;</span>
</span></span><span class="line"><span class="cl">            <span class="o">&lt;</span><span class="nx">div</span> <span class="nx">className</span><span class="o">=</span><span class="s2">&#34;col-4&#34;</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">              <span class="o">&lt;</span><span class="nx">select</span>
</span></span><span class="line"><span class="cl">                <span class="nx">name</span><span class="o">=</span><span class="s2">&#34;status&#34;</span>
</span></span><span class="line"><span class="cl">                <span class="nx">id</span><span class="o">=</span><span class="s2">&#34;&#34;</span>
</span></span><span class="line"><span class="cl">                <span class="nx">value</span><span class="o">=</span><span class="p">{</span><span class="nx">todo</span><span class="p">.</span><span class="nx">status</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">                <span class="nx">onChange</span><span class="o">=</span><span class="p">{</span><span class="nx">handleStatusChange</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">                <span class="nx">onBlur</span><span class="o">=</span><span class="p">{</span><span class="nx">handleSubmit</span><span class="p">}</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">                <span class="o">&lt;</span><span class="nx">option</span> <span class="nx">value</span><span class="o">=</span><span class="s2">&#34;Open&#34;</span><span class="o">&gt;</span><span class="nx">Open</span><span class="o">&lt;</span><span class="err">/option&gt;</span>
</span></span><span class="line"><span class="cl">                <span class="o">&lt;</span><span class="nx">option</span> <span class="nx">value</span><span class="o">=</span><span class="s2">&#34;In Progress&#34;</span><span class="o">&gt;</span><span class="nx">In</span> <span class="nx">Progress</span><span class="o">&lt;</span><span class="err">/option&gt;</span>
</span></span><span class="line"><span class="cl">                <span class="o">&lt;</span><span class="nx">option</span> <span class="nx">value</span><span class="o">=</span><span class="s2">&#34;Cancelled&#34;</span><span class="o">&gt;</span><span class="nx">Cancelled</span><span class="o">&lt;</span><span class="err">/option&gt;</span>
</span></span><span class="line"><span class="cl">              <span class="o">&lt;</span><span class="err">/select&gt;</span>
</span></span><span class="line"><span class="cl">            <span class="o">&lt;</span><span class="err">/div&gt;</span>
</span></span><span class="line"><span class="cl">          <span class="o">&lt;</span><span class="err">/div&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">))}</span>
</span></span><span class="line"><span class="cl">      <span class="o">&lt;</span><span class="err">/div&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="o">&lt;</span><span class="err">/div&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="kr">async</span> <span class="kd">function</span> <span class="nx">getServerSideProps</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="nx">todos</span> <span class="o">=</span> <span class="kr">await</span> <span class="nx">prisma</span><span class="p">.</span><span class="nx">todo</span><span class="p">.</span><span class="nx">findMany</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">    <span class="nx">orderBy</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">id</span><span class="o">:</span> <span class="s2">&#34;desc&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">});</span>
</span></span><span class="line"><span class="cl">  <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&#34;todos: &#34;</span><span class="p">,</span> <span class="nx">todos</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">props</span><span class="o">:</span> <span class="p">{</span> <span class="nx">todos</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">};</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="nx">Todo</span><span class="p">;</span>
</span></span></code></pre></div><p>The above code is straight-forward -</p>
<ul>
<li><code>getServerSideProps</code> includes logic that executes on the server side when a request is made to <code>http://localhost:3000/todos</code> (remember that the file is at <code>pages/todos.js</code>)</li>
<li>Next passes the data from <code>getServerSideProps</code> to render function <code>function Todo({ todos })</code></li>
<li>We display the <code>todos</code> data using JSX</li>
</ul>
<h2 id="createedit-todos">Create/Edit Todos</h2>
<p>We need Prisma (i.e., any DB operations) to run on the server. Next makes an easy task of creating backend APIs - no separate server needed (you could have your custom server though).</p>
<h3 id="create-apis">Create APIs</h3>
<h4 id="api-new-todo">API: New Todo</h4>
<p>Create new file <code>pages/api/todos/index.js</code> with below code -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">PrismaClient</span> <span class="p">}</span> <span class="nx">from</span> <span class="s2">&#34;@prisma/client&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">prisma</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">PrismaClient</span><span class="p">();</span>
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="kr">async</span> <span class="kd">function</span> <span class="nx">handle</span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&#34;Processing todo request..&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="nx">id</span> <span class="o">=</span> <span class="nx">req</span><span class="p">.</span><span class="nx">query</span><span class="p">.</span><span class="nx">id</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="k">if</span> <span class="p">(</span><span class="nx">req</span><span class="p">.</span><span class="nx">method</span> <span class="o">==</span> <span class="s2">&#34;GET&#34;</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">res</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="s2">&#34;hello&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">req</span><span class="p">.</span><span class="nx">method</span> <span class="o">==</span> <span class="s2">&#34;POST&#34;</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kr">const</span> <span class="nx">newTodo</span> <span class="o">=</span> <span class="kr">await</span> <span class="nx">prisma</span><span class="p">.</span><span class="nx">todo</span><span class="p">.</span><span class="nx">create</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">      <span class="nx">data</span><span class="o">:</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">req</span><span class="p">.</span><span class="nx">body</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">    <span class="p">});</span>
</span></span><span class="line"><span class="cl">    <span class="nx">res</span><span class="p">.</span><span class="nx">json</span><span class="p">(</span><span class="nx">newTodo</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Open the Developer Console in Chrome (<code>Ctrl+Shift+i</code>) and enter -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">await</span> <span class="nx">fetch</span> <span class="p">(</span><span class="s1">&#39;http://localhost:3000/api/todos&#39;</span><span class="p">)</span><span class="sb">`
</span></span></span></code></pre></div><p>.. to see &ldquo;hello&rdquo; returned. And oh.. we added the actual method to accept data from frontend and create a new record using Prisma. All it took was a couple of lines of code.</p>
<h4 id="api-updatedelete-todo">API: Update/Delete Todo</h4>
<p>While we are here, we will also handle -</p>
<ol>
<li>Record-specific deletes (<code>DELETE</code> method that will use <code>/api/todos/1</code> to delete record with <code>id</code>=1)</li>
<li>Record-specific updates (<code>PATCH</code> method to <code>/api/todos/2</code> to update record with <code>id</code>=2)</li>
</ol>
<p>The depicted URLs are standard REST resource URLs - nothing fancy here.</p>
<p>Create new file <code>pages/api/todos/index.js</code>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">PrismaClient</span> <span class="p">}</span> <span class="nx">from</span> <span class="s2">&#34;@prisma/client&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">prisma</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">PrismaClient</span><span class="p">();</span>
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="kr">async</span> <span class="kd">function</span> <span class="nx">handle</span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="nx">id</span> <span class="o">=</span> <span class="nx">req</span><span class="p">.</span><span class="nx">query</span><span class="p">.</span><span class="nx">id</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="k">if</span> <span class="p">(</span><span class="nx">req</span><span class="p">.</span><span class="nx">method</span> <span class="o">==</span> <span class="s2">&#34;DELETE&#34;</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&#34;Processing todo delete..&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="kr">const</span> <span class="nx">todo</span> <span class="o">=</span> <span class="kr">await</span> <span class="nx">prisma</span><span class="p">.</span><span class="nx">todo</span><span class="p">.</span><span class="k">delete</span><span class="p">({</span> <span class="nx">where</span><span class="o">:</span> <span class="p">{</span> <span class="nx">id</span><span class="o">:</span> <span class="nb">Number</span><span class="p">(</span><span class="nx">id</span><span class="p">)</span> <span class="p">}</span> <span class="p">});</span>
</span></span><span class="line"><span class="cl">    <span class="nx">res</span><span class="p">.</span><span class="nx">json</span><span class="p">(</span><span class="nx">todo</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">req</span><span class="p">.</span><span class="nx">method</span> <span class="o">==</span> <span class="s2">&#34;PATCH&#34;</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&#34;Processing todo update..&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="kr">const</span> <span class="nx">newTodo</span> <span class="o">=</span> <span class="kr">await</span> <span class="nx">prisma</span><span class="p">.</span><span class="nx">todo</span><span class="p">.</span><span class="nx">update</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">      <span class="nx">data</span><span class="o">:</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">req</span><span class="p">.</span><span class="nx">body</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">    <span class="p">});</span>
</span></span><span class="line"><span class="cl">    <span class="nx">res</span><span class="p">.</span><span class="nx">json</span><span class="p">(</span><span class="nx">newTodo</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>You might have noticed one key difference between the <code>GET</code> and <code>POST/DELETE/PATCH</code>. While we coded <code>GET</code> within the page itself, we used <code>api</code> folder to house update operations.</p>
<ul>
<li>While <code>prisma</code> was used in the <code>todos.js</code> page, <code>getServerSideProps</code> executes on server. So, we did not have any issues placing backend-specific logic there</li>
<li>Updates are not tied to backend in such fashion. Instead we create APIs in the <code>api</code> folder and call them using <code>fetch</code></li>
</ul>
<h3 id="change-ui-to-call-apis">Change UI to Call APIs</h3>
<p>Before we go ahead with UI changes, you would have noticed a problem with our file structure. While APIs had <code>index</code> and <code>[id]</code> files grouped under a parent <code>todos</code>, we do not have this structure in the frontend yet. Let&rsquo;s change that.</p>
<p>Create a new folder <code>pages/todos</code> - this will house all functions for <code>todos</code>. Move <code>pages/todos.js</code> to <code>pages/todos/</code> and rename it to <code>index.js</code>.</p>
<h4 id="todo-list">Todo List</h4>
<p>Replace current code in <code>pages/todos/index.js</code> with -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">useState</span> <span class="p">}</span> <span class="nx">from</span> <span class="s2">&#34;react&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">PrismaClient</span> <span class="p">}</span> <span class="nx">from</span> <span class="s2">&#34;@prisma/client&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">Link</span> <span class="nx">from</span> <span class="s2">&#34;next/link&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">prisma</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">PrismaClient</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">Todo</span><span class="p">({</span> <span class="nx">todos</span> <span class="p">})</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="p">[</span><span class="nx">todoIn</span><span class="p">,</span> <span class="nx">setTodoIn</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">(</span><span class="s2">&#34;&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="p">[</span><span class="nx">todoArr</span><span class="p">,</span> <span class="nx">setTodoArr</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">(</span><span class="nx">todos</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="nx">handleNewTodoChange</span> <span class="o">=</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">e</span><span class="p">.</span><span class="nx">preventDefault</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="nx">setTodoIn</span><span class="p">(</span><span class="nx">e</span><span class="p">.</span><span class="nx">target</span><span class="p">.</span><span class="nx">value</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="nx">handleSubmit</span> <span class="o">=</span> <span class="kr">async</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">e</span><span class="p">.</span><span class="nx">preventDefault</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="kr">const</span> <span class="nx">res</span> <span class="o">=</span> <span class="kr">await</span> <span class="nx">fetch</span><span class="p">(</span><span class="s2">&#34;/api/todos&#34;</span><span class="p">,</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">method</span><span class="o">:</span> <span class="s2">&#34;POST&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nx">body</span><span class="o">:</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">({</span> <span class="nx">description</span><span class="o">:</span> <span class="nx">todoIn</span><span class="p">,</span> <span class="nx">status</span><span class="o">:</span> <span class="s2">&#34;Open&#34;</span> <span class="p">}),</span>
</span></span><span class="line"><span class="cl">    <span class="p">});</span>
</span></span><span class="line"><span class="cl">    <span class="kr">const</span> <span class="nx">newTodo</span> <span class="o">=</span> <span class="kr">await</span> <span class="nx">res</span><span class="p">.</span><span class="nx">json</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="nx">setTodoArr</span><span class="p">([</span><span class="nx">newTodo</span><span class="p">,</span> <span class="p">...</span><span class="nx">todoArr</span><span class="p">]);</span>
</span></span><span class="line"><span class="cl">    <span class="nx">setTodoIn</span><span class="p">(</span><span class="s2">&#34;&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="nx">handleStatusChange</span> <span class="o">=</span> <span class="kr">async</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">e</span><span class="p">.</span><span class="nx">preventDefault</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&#34;target&#34;</span><span class="p">,</span> <span class="nx">e</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kr">const</span> <span class="nx">res</span> <span class="o">=</span> <span class="kr">await</span> <span class="nx">fetch</span><span class="p">(</span><span class="s2">&#34;/api/todos&#34;</span><span class="p">,</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">method</span><span class="o">:</span> <span class="s2">&#34;POST&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nx">body</span><span class="o">:</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">({</span> <span class="nx">description</span><span class="o">:</span> <span class="nx">todoIn</span><span class="p">,</span> <span class="nx">status</span><span class="o">:</span> <span class="s2">&#34;Open&#34;</span> <span class="p">}),</span>
</span></span><span class="line"><span class="cl">    <span class="p">});</span>
</span></span><span class="line"><span class="cl">    <span class="kr">const</span> <span class="nx">newTodo</span> <span class="o">=</span> <span class="kr">await</span> <span class="nx">res</span><span class="p">.</span><span class="nx">json</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="nx">setTodoArr</span><span class="p">([</span><span class="nx">newTodo</span><span class="p">,</span> <span class="p">...</span><span class="nx">todoArr</span><span class="p">]);</span>
</span></span><span class="line"><span class="cl">  <span class="p">};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="nx">deleteTodo</span> <span class="o">=</span> <span class="p">(</span><span class="nx">todo</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="kr">async</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">e</span><span class="p">.</span><span class="nx">preventDefault</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="kr">const</span> <span class="nx">res</span> <span class="o">=</span> <span class="kr">await</span> <span class="nx">fetch</span><span class="p">(</span><span class="sb">`/api/todos/</span><span class="si">${</span><span class="nx">todo</span><span class="p">.</span><span class="nx">id</span><span class="si">}</span><span class="sb">`</span><span class="p">,</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">method</span><span class="o">:</span> <span class="s2">&#34;DELETE&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="p">});</span>
</span></span><span class="line"><span class="cl">    <span class="kr">const</span> <span class="nx">index</span> <span class="o">=</span> <span class="nx">todoArr</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">todo</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nx">setTodoArr</span><span class="p">([</span>
</span></span><span class="line"><span class="cl">      <span class="p">...</span><span class="nx">todoArr</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="nx">index</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">      <span class="p">...</span><span class="nx">todoArr</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="nx">index</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="nx">todoArr</span><span class="p">.</span><span class="nx">length</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">    <span class="p">]);</span>
</span></span><span class="line"><span class="cl">  <span class="p">};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="o">&lt;</span><span class="nx">div</span> <span class="nx">className</span><span class="o">=</span><span class="s2">&#34;row&#34;</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="o">&lt;</span><span class="nx">h2</span> <span class="nx">className</span><span class="o">=</span><span class="s2">&#34;col-12 list-title is-center&#34;</span><span class="o">&gt;</span><span class="nx">My</span> <span class="nx">Todos</span><span class="o">&lt;</span><span class="err">/h2&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">      <span class="o">&lt;</span><span class="nx">form</span> <span class="nx">className</span><span class="o">=</span><span class="s2">&#34;col-12&#34;</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="o">&lt;</span><span class="nx">div</span> <span class="nx">className</span><span class="o">=</span><span class="s2">&#34;row&#34;</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">          <span class="o">&lt;</span><span class="nx">span</span> <span class="nx">className</span><span class="o">=</span><span class="s2">&#34;col-1 list-desc&#34;</span><span class="o">&gt;</span><span class="nx">Add</span><span class="o">&lt;</span><span class="err">/span&gt;</span>
</span></span><span class="line"><span class="cl">          <span class="o">&lt;</span><span class="nx">input</span>
</span></span><span class="line"><span class="cl">            <span class="nx">type</span><span class="o">=</span><span class="s2">&#34;text&#34;</span>
</span></span><span class="line"><span class="cl">            <span class="nx">onBlur</span><span class="o">=</span><span class="p">{</span><span class="nx">handleNewTodoChange</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">            <span class="nx">className</span><span class="o">=</span><span class="s2">&#34;col-5&#34;</span>
</span></span><span class="line"><span class="cl">            <span class="nx">onChange</span><span class="o">=</span><span class="p">{</span><span class="nx">handleNewTodoChange</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">            <span class="nx">value</span><span class="o">=</span><span class="p">{</span><span class="nx">todoIn</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">          <span class="o">/&gt;</span>
</span></span><span class="line"><span class="cl">          <span class="o">&lt;</span><span class="nx">button</span> <span class="nx">className</span><span class="o">=</span><span class="s2">&#34;button col-2&#34;</span> <span class="nx">onClick</span><span class="o">=</span><span class="p">{</span><span class="nx">handleSubmit</span><span class="p">}</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">            <span class="nx">Save</span>
</span></span><span class="line"><span class="cl">          <span class="o">&lt;</span><span class="err">/button&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="o">&lt;</span><span class="err">/div&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="o">&lt;</span><span class="err">/form&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">      <span class="o">&lt;</span><span class="nx">div</span> <span class="nx">className</span><span class="o">=</span><span class="s2">&#34;col-12&#34;</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span><span class="nx">todoArr</span><span class="p">.</span><span class="nx">map</span><span class="p">((</span><span class="nx">todo</span><span class="p">,</span> <span class="nx">index</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">          <span class="o">&lt;</span><span class="nx">div</span> <span class="nx">className</span><span class="o">=</span><span class="s2">&#34;row&#34;</span> <span class="nx">key</span><span class="o">=</span><span class="p">{</span><span class="nx">index</span><span class="p">}</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">            <span class="o">&lt;</span><span class="nx">div</span> <span class="nx">className</span><span class="o">=</span><span class="s2">&#34;col-1 list-desc&#34;</span> <span class="nx">name</span><span class="o">=</span><span class="s2">&#34;id&#34;</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">              <span class="p">{</span><span class="nx">todo</span><span class="p">.</span><span class="nx">id</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">            <span class="o">&lt;</span><span class="err">/div&gt;</span>
</span></span><span class="line"><span class="cl">            <span class="o">&lt;</span><span class="nx">div</span> <span class="nx">className</span><span class="o">=</span><span class="s2">&#34;col-5 list-desc&#34;</span> <span class="nx">name</span><span class="o">=</span><span class="s2">&#34;description&#34;</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">              <span class="p">{</span><span class="nx">todo</span><span class="p">.</span><span class="nx">description</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">            <span class="o">&lt;</span><span class="err">/div&gt;</span>
</span></span><span class="line"><span class="cl">            <span class="o">&lt;</span><span class="nx">div</span> <span class="nx">className</span><span class="o">=</span><span class="s2">&#34;col-4&#34;</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">              <span class="o">&lt;</span><span class="nx">select</span>
</span></span><span class="line"><span class="cl">                <span class="nx">name</span><span class="o">=</span><span class="s2">&#34;status&#34;</span>
</span></span><span class="line"><span class="cl">                <span class="nx">id</span><span class="o">=</span><span class="s2">&#34;&#34;</span>
</span></span><span class="line"><span class="cl">                <span class="nx">value</span><span class="o">=</span><span class="p">{</span><span class="nx">todo</span><span class="p">.</span><span class="nx">status</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">                <span class="nx">onChange</span><span class="o">=</span><span class="p">{</span><span class="nx">handleStatusChange</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">                <span class="nx">onBlur</span><span class="o">=</span><span class="p">{</span><span class="nx">handleSubmit</span><span class="p">}</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">                <span class="o">&lt;</span><span class="nx">option</span> <span class="nx">value</span><span class="o">=</span><span class="s2">&#34;Open&#34;</span><span class="o">&gt;</span><span class="nx">Open</span><span class="o">&lt;</span><span class="err">/option&gt;</span>
</span></span><span class="line"><span class="cl">                <span class="o">&lt;</span><span class="nx">option</span> <span class="nx">value</span><span class="o">=</span><span class="s2">&#34;In Progress&#34;</span><span class="o">&gt;</span><span class="nx">In</span> <span class="nx">Progress</span><span class="o">&lt;</span><span class="err">/option&gt;</span>
</span></span><span class="line"><span class="cl">                <span class="o">&lt;</span><span class="nx">option</span> <span class="nx">value</span><span class="o">=</span><span class="s2">&#34;Cancelled&#34;</span><span class="o">&gt;</span><span class="nx">Cancelled</span><span class="o">&lt;</span><span class="err">/option&gt;</span>
</span></span><span class="line"><span class="cl">              <span class="o">&lt;</span><span class="err">/select&gt;</span>
</span></span><span class="line"><span class="cl">            <span class="o">&lt;</span><span class="err">/div&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">            <span class="o">&lt;</span><span class="nx">div</span> <span class="nx">className</span><span class="o">=</span><span class="s2">&#34;col-2 icon&#34;</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">              <span class="o">&lt;</span><span class="nx">button</span> <span class="nx">className</span><span class="o">=</span><span class="s2">&#34;button icon-only&#34;</span> <span class="nx">onClick</span><span class="o">=</span><span class="p">{</span><span class="nx">deleteTodo</span><span class="p">(</span><span class="nx">todo</span><span class="p">)}</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">                <span class="o">&lt;</span><span class="nx">img</span>
</span></span><span class="line"><span class="cl">                  <span class="nx">src</span><span class="o">=</span><span class="s2">&#34;https://icongr.am/feather/delete.svg?size=16&amp;color=93939a&#34;</span>
</span></span><span class="line"><span class="cl">                  <span class="nx">alt</span><span class="o">=</span><span class="s2">&#34;delete&#34;</span>
</span></span><span class="line"><span class="cl">                <span class="o">/&gt;</span>
</span></span><span class="line"><span class="cl">              <span class="o">&lt;</span><span class="err">/button&gt;</span>
</span></span><span class="line"><span class="cl">              <span class="o">&lt;</span><span class="nx">Link</span> <span class="nx">href</span><span class="o">=</span><span class="p">{</span><span class="sb">`/todos/</span><span class="si">${</span><span class="nx">todo</span><span class="p">.</span><span class="nx">id</span><span class="si">}</span><span class="sb">`</span><span class="p">}</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">                <span class="o">&lt;</span><span class="nx">button</span> <span class="nx">className</span><span class="o">=</span><span class="s2">&#34;button icon-only&#34;</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">                  <span class="o">&lt;</span><span class="nx">img</span>
</span></span><span class="line"><span class="cl">                    <span class="nx">src</span><span class="o">=</span><span class="s2">&#34;https://icongr.am/feather/edit-2.svg?size=16&amp;color=93939a&#34;</span>
</span></span><span class="line"><span class="cl">                    <span class="nx">alt</span><span class="o">=</span><span class="s2">&#34;edit&#34;</span>
</span></span><span class="line"><span class="cl">                  <span class="o">/&gt;</span>
</span></span><span class="line"><span class="cl">                <span class="o">&lt;</span><span class="err">/button&gt;</span>
</span></span><span class="line"><span class="cl">              <span class="o">&lt;</span><span class="err">/Link&gt;</span>
</span></span><span class="line"><span class="cl">            <span class="o">&lt;</span><span class="err">/div&gt;</span>
</span></span><span class="line"><span class="cl">          <span class="o">&lt;</span><span class="err">/div&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">))}</span>
</span></span><span class="line"><span class="cl">      <span class="o">&lt;</span><span class="err">/div&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="o">&lt;</span><span class="err">/div&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="kr">async</span> <span class="kd">function</span> <span class="nx">getServerSideProps</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="nx">todos</span> <span class="o">=</span> <span class="kr">await</span> <span class="nx">prisma</span><span class="p">.</span><span class="nx">todo</span><span class="p">.</span><span class="nx">findMany</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">    <span class="nx">orderBy</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">id</span><span class="o">:</span> <span class="s2">&#34;desc&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">});</span>
</span></span><span class="line"><span class="cl">  <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&#34;todos: &#34;</span><span class="p">,</span> <span class="nx">todos</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">props</span><span class="o">:</span> <span class="p">{</span> <span class="nx">todos</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">};</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="nx">Todo</span><span class="p">;</span>
</span></span></code></pre></div><p>We have added below features -</p>
<ul>
<li>Add an input box and a button to add a new <code>todo</code> record. Add functions to handle changes to input and to respond to the click event</li>
<li>Add functions to handle changes to call backend APIs for inserts and deletes, and make corresponding changes on the UI</li>
<li>Create a button to delete a <code>todo</code> and call API DELETE method</li>
<li>Create a button to navigate to a detail page upon clicking on any todo (the detail page is implemented in the next section)</li>
</ul>
<h4 id="todo-detail">Todo Detail</h4>
<p>With a couple of functions you have created an app to query ( &amp; display), create and delete todos!</p>
<p>Create a new page <code>pages/todos/[id].js</code> and input below code -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">useRouter</span> <span class="p">}</span> <span class="nx">from</span> <span class="s2">&#34;next/router&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">PrismaClient</span> <span class="p">}</span> <span class="nx">from</span> <span class="s2">&#34;@prisma/client&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">prisma</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">PrismaClient</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="kd">function</span> <span class="nx">Todo</span><span class="p">({</span> <span class="nx">todo</span> <span class="p">})</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="nx">router</span> <span class="o">=</span> <span class="nx">useRouter</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="p">{</span> <span class="nx">id</span> <span class="p">}</span> <span class="o">=</span> <span class="nx">router</span><span class="p">.</span><span class="nx">query</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="o">&lt;</span><span class="nx">div</span> <span class="nx">className</span><span class="o">=</span><span class="s2">&#34;text-center&#34;</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="o">&lt;</span><span class="nx">h3</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="o">&lt;</span><span class="nx">strong</span><span class="o">&gt;</span><span class="p">{</span><span class="o">!!</span><span class="nx">todo</span> <span class="o">&amp;&amp;</span> <span class="nx">todo</span><span class="p">.</span><span class="nx">description</span><span class="p">}</span><span class="o">&lt;</span><span class="err">/strong&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="o">&lt;</span><span class="err">/h3&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="o">&lt;</span><span class="nx">p</span><span class="o">&gt;</span><span class="p">{</span><span class="o">!</span><span class="nx">todo</span> <span class="o">&amp;&amp;</span> <span class="s2">&#34;This todo has migrated to the next universe.&#34;</span><span class="p">}</span><span class="o">&lt;</span><span class="err">/p&gt;</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">      <span class="o">&lt;</span><span class="nx">p</span><span class="o">&gt;&lt;</span><span class="err">/p&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="o">&lt;</span><span class="err">/div&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="kr">async</span> <span class="kd">function</span> <span class="nx">getServerSideProps</span><span class="p">({</span> <span class="nx">params</span> <span class="p">})</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="nx">todo</span> <span class="o">=</span> <span class="kr">await</span> <span class="nx">prisma</span><span class="p">.</span><span class="nx">todo</span><span class="p">.</span><span class="nx">findFirst</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">    <span class="nx">where</span><span class="o">:</span> <span class="p">{</span> <span class="nx">id</span><span class="o">:</span> <span class="nb">Number</span><span class="p">(</span><span class="nx">params</span><span class="p">.</span><span class="nx">id</span><span class="p">)</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">});</span>
</span></span><span class="line"><span class="cl">  <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&#34;todo: &#34;</span><span class="p">,</span> <span class="nx">todo</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">props</span><span class="o">:</span> <span class="p">{</span> <span class="nx">todo</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">};</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>This page just demonstrates how we could display a single <code>todo</code> on the frontend. We have not added any functionality to it.</p>
<h2 id="what-next">What Next?</h2>
<p>Find the app code at this <a href="https://github.com/prashanth1k/do-awesome-nextjs-sample-app">Github repo</a>.</p>
<p>You could extend the current app by -</p>
<ol>
<li>Introducing update function - status changes should call <code>PATCH</code> method and change UI elements</li>
<li>Enable user to capture thoughts, ideas and other BS against each <code>todo</code>. Doing this would require you to provide functionality to add <code>comments</code> against any specific <code>todo</code> (utilising the <code>Detail page</code>)</li>
</ol>
<h2 id="learning-resources">Learning Resources</h2>
<p>See more of Next and keep rocking.</p>
<ul>
<li><a href="https://nextjs.org/learn/basics/create-nextjs-app">Learn NextJS</a> by Vercel, creator of NextJS</li>
<li><a href="https://www.youtube.com/watch?v=tt3PUvhOVzo">NextJS in 2 hours</a></li>
<li><a href="https://www.youtube.com/watch?v=1GpbdX8aJCU">Create a Snippet Manager in Next</a></li>
</ul>
]]></content:encoded>
    </item>
    
  </channel>
</rss>
