<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Paul Vitalis</title>
    <description>The latest articles on Forem by Paul Vitalis (@paulstar200).</description>
    <link>https://forem.com/paulstar200</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F212720%2F65fbd75c-58d4-4fbd-85bb-b6005fe171e4.png</url>
      <title>Forem: Paul Vitalis</title>
      <link>https://forem.com/paulstar200</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/paulstar200"/>
    <language>en</language>
    <item>
      <title>Routing with React Router</title>
      <dc:creator>Paul Vitalis</dc:creator>
      <pubDate>Sun, 17 Mar 2024 01:30:19 +0000</pubDate>
      <link>https://forem.com/paulstar200/routing-with-react-router-4kj7</link>
      <guid>https://forem.com/paulstar200/routing-with-react-router-4kj7</guid>
      <description>&lt;p&gt;Navigating through pages in a React application is made possible using a library called React Router Dom.&lt;/p&gt;

&lt;p&gt;We will walk through Routing with an example.&lt;/p&gt;

&lt;p&gt;First we will use vite to quickly spin up a React project.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm create vite@latest&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Enter your project name and select all options you would prefer when prompted. &lt;/p&gt;

&lt;p&gt;Here is my preferred configuration.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1mrixi84yrl4mu9ghh49.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1mrixi84yrl4mu9ghh49.png" alt="Configuration" width="800" height="312"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Install all dependencies using &lt;code&gt;npm install&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To install react-router-dom, run the following command&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm i react-router-dom&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Run the app using &lt;code&gt;npm run dev&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Create a components folder under the &lt;code&gt;src&lt;/code&gt; directory and then  create two components: &lt;code&gt;Home&lt;/code&gt; and &lt;code&gt;About&lt;/code&gt; inside the components folder.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ROUTING&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For routing, create a folder called router under src and within it, create &lt;code&gt;index.tsx&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Our folder structure should now look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwgss33820ec669nycx0m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwgss33820ec669nycx0m.png" alt="Folder Structure" width="584" height="612"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now inside our router file, we will create routes for our Home and About pages as follows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { createBrowserRouter } from "react-router-dom";
import Home from "../components/Home";
import About from "../components/About";


const router = createBrowserRouter([
  {
    path: "/",
    element: &amp;lt;Home/&amp;gt;,
  },
  {
    path: "/about",
    element: &amp;lt;About /&amp;gt;,
  },
]);

export default router;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that we imported &lt;code&gt;createBrowserRouter&lt;/code&gt; from react-router-dom. This is the recommended router for all React Router web projects. It uses the DOM History API to update the URL and manage the history stack.&lt;/p&gt;

&lt;p&gt;We then go to our &lt;code&gt;App.tsx&lt;/code&gt; file and replace everything within it as follows.&lt;/p&gt;

&lt;p&gt;App.tsx&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import "./App.css";
import { Outlet } from "react-router-dom";

function App() {
  return (
    &amp;lt;&amp;gt;
      &amp;lt;Outlet /&amp;gt;
    &amp;lt;/&amp;gt;
  );
}

export default App;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll notice we imported &lt;code&gt;Outlet&lt;/code&gt; from react-router-dom and added it in our return statement. An Outlet should be used in parent route elements to render their child route elements. This allows nested UI to show up when child routes are rendered. If the parent route matched exactly, it will render a child index route or nothing if there is no index route. In this case, our parent route element is the &lt;code&gt;App.tsx&lt;/code&gt; file and the child routes are &lt;code&gt;Home.tsx&lt;/code&gt; and &lt;code&gt;About.tsx&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Lastly, we will update our &lt;code&gt;main.tsx&lt;/code&gt; file with RouteProvider from react-router-dom&lt;/p&gt;

&lt;p&gt;We import our router first and pass it into &lt;code&gt;RouterProvider&lt;/code&gt;. All data router objects are passed to this component to render your app and enable the rest of the data APIs.&lt;/p&gt;

&lt;p&gt;main.tsx&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import router from "./router/index.tsx";
import { RouterProvider } from "react-router-dom";

ReactDOM.createRoot(document.getElementById("root")!).render(
  &amp;lt;React.StrictMode&amp;gt;
    &amp;lt;RouterProvider router={router} /&amp;gt;
  &amp;lt;/React.StrictMode&amp;gt;
);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now if we go to the browser you can navigate routes between our two pages!&lt;/p&gt;

&lt;p&gt;Home Page&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frw09t9ccgq889he4x7qu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frw09t9ccgq889he4x7qu.png" alt="Home Page" width="800" height="478"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;About Page&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6n0as6e9qxjeb6ozwq5h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6n0as6e9qxjeb6ozwq5h.png" alt="About Page" width="800" height="477"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's all you need! Or is it? &lt;/p&gt;

&lt;p&gt;Suppose you tried accessing a route like &lt;code&gt;/home&lt;/code&gt;, what do you think will happen? Let's see.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0oap8z7uthz3505pylqs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0oap8z7uthz3505pylqs.png" alt="Error" width="800" height="479"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yikes! We had not specified a route for &lt;code&gt;/home&lt;/code&gt;. We only put two routes: &lt;code&gt;/&lt;/code&gt; and &lt;code&gt;/about&lt;/code&gt;. To fix this, we can add a route to handle non-existent routes.&lt;/p&gt;

&lt;p&gt;Firstly, create a component that will render whenever a user accesses a non existent route.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";

const Error = () =&amp;gt; {
  return &amp;lt;div&amp;gt;This is the error page&amp;lt;/div&amp;gt;;
};

export default Error;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we go to our router file, import the Error component we just created, and add a path to handle non-existent routes as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; {
    path: "*",
    element: &amp;lt;Error /&amp;gt;,
  },
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And this is our result if we go to a non-existent route:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F166pv4zp4lev6414eapm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F166pv4zp4lev6414eapm.png" alt="Non existent" width="800" height="475"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This tutorial is just a tip of the iceberg when it comes to React Router. I would encourage you to explore more and see what React router has to offer you. The full documentation of react-router can be found at: &lt;a href="https://reactrouter.com/en/main"&gt;https://reactrouter.com/en/main&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Follow me on:&lt;br&gt;
LinkedIn: Paul Otieno&lt;br&gt;
Twitter: me_huchoma&lt;br&gt;
Instagram: paul_dreamer_&lt;/p&gt;

&lt;p&gt;Happy Coding! 🥂&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>routing</category>
    </item>
    <item>
      <title>Implementing search in a React app</title>
      <dc:creator>Paul Vitalis</dc:creator>
      <pubDate>Mon, 19 Feb 2024 12:36:42 +0000</pubDate>
      <link>https://forem.com/paulstar200/implementing-search-in-a-react-app-10cm</link>
      <guid>https://forem.com/paulstar200/implementing-search-in-a-react-app-10cm</guid>
      <description>&lt;p&gt;In this article, we will look at implementing a search box in a React app.&lt;/p&gt;

&lt;p&gt;The application is a quiz application that lists quizes.&lt;/p&gt;

&lt;p&gt;A link to the working demo is here: &lt;a href="https://quiz-react-ochre.vercel.app/"&gt;https://quiz-react-ochre.vercel.app/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also access the stackblitz project here: &lt;a href="https://stackblitz.com/~/github.com/Paulvitalis200/quiz-react"&gt;Stackblitz&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Source Code: &lt;a href="https://github.com/Paulvitalis200/quiz-react"&gt;https://github.com/Paulvitalis200/quiz-react&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We would like to filter a specific quiz by searching for it using the search box.&lt;/p&gt;

&lt;p&gt;Here is how the app looks:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fptxkszw6mt16w051zfg9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fptxkszw6mt16w051zfg9.png" alt="Quiz app" width="800" height="478"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The code for this is in the &lt;strong&gt;App.tsx&lt;/strong&gt; file,&lt;/p&gt;

&lt;p&gt;Firstly, we import our quizes from the quizes.json file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import data from "./data/quizes.json";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First, we create an array for setting up our quizes and initialize the state with the quizes we've imported.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const [quizes, setQuizes] = useState&amp;lt;QuizInterface[] | null&amp;gt;(data);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We then create our search box&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Search placeholder="Search" onChange={searchQuiz}&amp;gt;&amp;lt;/Search&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see that we have a search input box. We also have an &lt;strong&gt;onChange&lt;/strong&gt; event handler tied to it. To read about how to use onChange and more about it, you can read about it in my other article here - &lt;a href="https://dev.to/paulstar200/tracking-changes-on-inputs-and-textareas-react-3cpp"&gt;onChange article&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We also have the function &lt;strong&gt;searchQuiz&lt;/strong&gt; that's tied to onChange.&lt;/p&gt;

&lt;p&gt;It's defined here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  const searchQuiz = (event: any) =&amp;gt; {
    const filteredQuizes = data.filter((quiz: QuizInterface) =&amp;gt;
      quiz.name.toLowerCase().includes(event.target.value.trim().toLowerCase())
    );
    setQuizes(filteredQuizes);
  };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We use the &lt;strong&gt;.filter()&lt;/strong&gt; method which is an in-built javascript method that filters an array to match a specific criteria and returns the array of items that matches the criteria.&lt;/p&gt;

&lt;p&gt;The criteria we want to match is that the quiz's name includes the input value that the user types in. We get the value that the user types in using &lt;strong&gt;event.target.value&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;We use &lt;strong&gt;.includes()&lt;/strong&gt; which is also an in-built javascript method that determines whether an array includes a certain value among its entries, returning true or false as appropriate.&lt;/p&gt;

&lt;p&gt;We use &lt;strong&gt;.toLowerCase()&lt;/strong&gt; on the strings to convert all the text to lowercase before doing the comparison.&lt;/p&gt;

&lt;p&gt;To ensure that the user does not enter spaces only, we use &lt;strong&gt;.trim()&lt;/strong&gt; on the input text to remove any whitespace before they input an alphanumeric character and to ensure we do not filter when they only input spaces as the search parameter.&lt;/p&gt;

&lt;p&gt;Finally, we set the value of our quizes state to be the &lt;strong&gt;filteredQuizes&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; setQuizes(filteredQuizes);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Important Note:&lt;/strong&gt; We perform the filter on the original array of quizes that we imported &lt;strong&gt;(data)&lt;/strong&gt; and not on the quizes array that we defined using useState. This is important because we will always be updating the quizes state and if we filter on this state array, we will reach a point where we may get erroneous data since we filtered out the original array items 😬.&lt;/p&gt;

&lt;p&gt;And that's it! &lt;/p&gt;

&lt;p&gt;Happy Coding 🥂&lt;/p&gt;

&lt;p&gt;Follow me on:&lt;br&gt;
LinkedIn: &lt;a href="https://stackblitz.com/~/github.com/Paulvitalis200/Notes-app-react"&gt;Paul Otieno&lt;/a&gt;&lt;br&gt;
Twitter: &lt;a href="https://twitter.com/me_huchoma"&gt;me_huchoma&lt;/a&gt;&lt;br&gt;
Instagram: &lt;a href="https://www.instagram.com/paul_dreamer_"&gt;paul_dreamer_&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>html</category>
    </item>
    <item>
      <title>Tracking changes on inputs and textareas in React</title>
      <dc:creator>Paul Vitalis</dc:creator>
      <pubDate>Sat, 17 Feb 2024 12:05:11 +0000</pubDate>
      <link>https://forem.com/paulstar200/tracking-changes-on-inputs-and-textareas-react-3cpp</link>
      <guid>https://forem.com/paulstar200/tracking-changes-on-inputs-and-textareas-react-3cpp</guid>
      <description>&lt;p&gt;This post will cover how to track changes from an input field or text area. You can either follow along and write the code following the steps I will explain or just access the project on Stackblitz using the link I've provided and skip to the explanation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://stackblitz.com/~/github.com/Paulvitalis200/Notes-app-react" rel="noopener noreferrer"&gt;Stackblitz project&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Writing the code&lt;/strong&gt;&lt;br&gt;
We'll begin by creating a react app using vite&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm create vite@latest&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Install all dependencies using:&lt;br&gt;
&lt;code&gt;npm install&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now in &lt;strong&gt;App.tsx&lt;/strong&gt;, replace all the code with the following block of code&lt;/p&gt;

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

import { useState } from "react";
import "./App.css";

interface Note {
  id: number;
  text: string;
  backgroundColor: string;
  date: string;
}

function App() {
  const getRandomColor = (): string =&amp;gt; {
    return "hsl(" + Math.random() * 360 + ", 100%, 75%)";
  };

  const [notes, setNotes] = useState&amp;lt;Note[]&amp;gt;([]);

  const [note, setNote] = useState&amp;lt;string&amp;gt;("");

  const [showModal, setShowModal] = useState&amp;lt;boolean&amp;gt;(false);
  const [showError, setShowError] = useState&amp;lt;boolean&amp;gt;(false);
  const addNote = () =&amp;gt; {
    if (note.trim().length &amp;lt; 10) {
      setShowError(true);
      return;
    }

    setNotes([
      ...notes,
      {
        id: Math.random(),
        text: note.trim(),
        date: new Date().toLocaleDateString(),
        backgroundColor: getRandomColor(),
      },
    ]);

    toggleModal();
  };

  const handleChange = (event: any) =&amp;gt; {
    setNote(event.target.value);
  };

  const resetForm = () =&amp;gt; {
    setNote("");
    setShowError(false);
  };

  const toggleModal = () =&amp;gt; {
    resetForm();
    setShowModal(!showModal);
  };

  return (
    &amp;lt;&amp;gt;
      {showModal &amp;amp;&amp;amp; (
        &amp;lt;div className="modal"&amp;gt;
          &amp;lt;div className="modal-content"&amp;gt;
            &amp;lt;textarea
              className="text"
              onChange={handleChange}
              value={note}
            &amp;gt;&amp;lt;/textarea&amp;gt;
            {showError &amp;amp;&amp;amp; (
              &amp;lt;p className="error"&amp;gt;Minimum characters allowed is 10&amp;lt;/p&amp;gt;
            )}
            &amp;lt;div className="buttons"&amp;gt;
              &amp;lt;button className="add-btn" onClick={addNote}&amp;gt;
                Add Note
              &amp;lt;/button&amp;gt;
              &amp;lt;button className="close-btn" onClick={toggleModal}&amp;gt;
                Close
              &amp;lt;/button&amp;gt;
            &amp;lt;/div&amp;gt;
          &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
      )}

      &amp;lt;main&amp;gt;
        &amp;lt;div className="header"&amp;gt;
          &amp;lt;h2 className="header-title"&amp;gt;Notes&amp;lt;/h2&amp;gt;
          &amp;lt;button className="add-note-btn" onClick={toggleModal}&amp;gt;
            +
          &amp;lt;/button&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;div className="notes-container"&amp;gt;
          {notes.map((note) =&amp;gt; {
            return (
              &amp;lt;div
                key={note.id}
                className="note"
                style={{ backgroundColor: note.backgroundColor }}
              &amp;gt;
                &amp;lt;p className="note-text"&amp;gt;{note.text}&amp;lt;/p&amp;gt;
                &amp;lt;p className="note-date"&amp;gt;{note.date}&amp;lt;/p&amp;gt;
              &amp;lt;/div&amp;gt;
            );
          })}
        &amp;lt;/div&amp;gt;
      &amp;lt;/main&amp;gt;
    &amp;lt;/&amp;gt;
  );
}

export default App;



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Update the &lt;strong&gt;App.css&lt;/strong&gt; to be as follows&lt;/p&gt;

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

.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.add-note-btn {
  border: None;
  background-color: black;
  color: white;
  border-radius: 50%;
  padding: 10px 13px;
}

.add-note-btn:hover {
  cursor: pointer;
  box-shadow: rgba(100, 100, 111, 0.2) 0px 7px 29px 0px;
}


main {
  width: 80%;
  margin: 0 auto;
}

.notes-container {
  display: flex;
  flex-wrap: wrap;
}

.note {
  width: 200px;
  height: 200px;
  border-radius: 10px;
  margin-right: 15px;
  margin-bottom: 20px;
  padding: 10px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

.note-text {
  height: 80%;
  overflow: scroll;
  -ms-overflow-style: none;  /* IE and Edge */
  scrollbar-width: none;  /* Firefox */
  word-wrap: break-word;
}

/* Hide scrollbar for Chrome, Safari and Opera */.note-text::-webkit-scrollbar {
  display: none;
}

.modal {
  position: fixed; /* Stay in place */
  z-index: 1; /* Sit on top */
  left: 0;
  top: 0;
  width: 100%; /* Full width */
  height: 100%; /* Full height */
  overflow: auto; /* Enable scroll if needed */
  background-color: rgb(0,0,0); /* Fallback color */
  background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
}

/* Modal Content/Box */
.modal-content {
  background-color: #fefefe;
  margin: 15% auto; /* 15% from the top and centered */
  padding: 20px;
  border: 1px solid #888;
  width: 40%; /* Could be more or less, depending on screen size */
  border-radius: 10px;
}

/* The Close Button */
.close {
  color: #aaa;
  float: right;
  font-size: 28px;
  font-weight: bold;
}

.close:hover,
.close:focus {
  color: black;
  text-decoration: none;
  cursor: pointer;
}

.buttons {
  display: flex;
  flex-direction: column;
}

.buttons button {
  margin-top: 8px;
  color: #fff;
  border: none;
  padding: 5px 0;
  font-size: 18px;
  border-radius: 4px;
}

.buttons button:hover {
  cursor: pointer;
}

textarea {
  width: 100%;
  min-height: 100px;
  font-size: 18px;
}

.add-btn {
  background-color: purple;
}

.close-btn {
  background-color: rgb(133, 34, 34);
}

.error {
  color: red;
}

@media only screen and (max-width: 500px) {
  .modal-content {
    width: 80%; /* Could be more or less, depending on screen size */

  }
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Finally, Update the &lt;strong&gt;index.css&lt;/strong&gt; file too&lt;/p&gt;

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

:root {
  font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
  /* line-height: 1.5; */
  font-weight: 400;

  color-scheme: light dark;
  color: rgba(255, 255, 255, 0.87);
  background-color: #242424;

  font-synthesis: none;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

a:hover {
  color: #535bf2;
}

body {
  margin: 0;
  place-items: center;
  min-width: 320px;
  min-height: 100vh;
}


@media (prefers-color-scheme: light) {
  :root {
    color: #213547;
    background-color: #ffffff;
  }
  a:hover {
    color: #747bff;
  }
  button {
    background-color: #f9f9f9;
  }
}



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Save all the changes and run your app with the following command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm run dev&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Your application should now look as follows:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffsxhnjwk536yqj5t6ku5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffsxhnjwk536yqj5t6ku5.png" alt="Initial application view"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our application is a notes app that allows us to add notes.&lt;/p&gt;

&lt;p&gt;On clicking the &lt;strong&gt;+&lt;/strong&gt; icon, we get a modal as follows:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv5uurojka53xahgsuy0d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv5uurojka53xahgsuy0d.png" alt="Modal"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Explanation.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The textarea field has an initial value set to the **note **variable that we created:&lt;/p&gt;

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

&amp;lt;textarea
              className="text"
              onChange={handleChange}
              value={note}
            &amp;gt;&amp;lt;/textarea&amp;gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;JavaScript allows us to listen to an input’s change in value by providing the attribute ** onchange**. React’s version of the onchange event handler is the same but camel-cased.&lt;/p&gt;

&lt;p&gt;The handleChange function used on the onChange event handler was defined as follows:&lt;/p&gt;

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

 const handleChange = (event: any) =&amp;gt; {
    console.log(event.target.value)
    setNote(event.target.value);
    console.log("Note: ", note)
  };



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You can check the console and see the value that is logged out and also the value of the note as you type.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faju6if0ioli3gz5kc9ez.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faju6if0ioli3gz5kc9ez.png" alt="Console output"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The handleChange function simply sets the note variable to be whatever text the user inputs as they type.&lt;/p&gt;

&lt;p&gt;And that's it. On change is a very useful event handler and will simplify your work relating to user input on your React journey.&lt;/p&gt;

&lt;p&gt;For the source code, you can access it at this link: &lt;a href="https://github.com/Paulvitalis200/Notes-app-react" rel="noopener noreferrer"&gt;Source code&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Follow me on:&lt;br&gt;
LinkedIn: &lt;a href="https://stackblitz.com/~/github.com/Paulvitalis200/Notes-app-react" rel="noopener noreferrer"&gt;Paul Otieno&lt;/a&gt;&lt;br&gt;
Twitter: &lt;a href="https://twitter.com/me_huchoma" rel="noopener noreferrer"&gt;me_huchoma&lt;/a&gt;&lt;br&gt;
Instagram: &lt;a href="https://www.instagram.com/paul_dreamer_" rel="noopener noreferrer"&gt;paul_dreamer_&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Happy Coding!&lt;/em&gt; 🥂&lt;/p&gt;

</description>
      <category>react</category>
      <category>input</category>
      <category>html</category>
    </item>
  </channel>
</rss>
