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.
1. Writing the code
We'll begin by creating a react app using vite
npm create vite@latest
Install all dependencies using:
npm install
Now in App.tsx, replace all the code with the following block of code
import { useState } from "react";
import "./App.css";
interface Note {
id: number;
text: string;
backgroundColor: string;
date: string;
}
function App() {
const getRandomColor = (): string => {
return "hsl(" + Math.random() * 360 + ", 100%, 75%)";
};
const [notes, setNotes] = useState<Note[]>([]);
const [note, setNote] = useState<string>("");
const [showModal, setShowModal] = useState<boolean>(false);
const [showError, setShowError] = useState<boolean>(false);
const addNote = () => {
if (note.trim().length < 10) {
setShowError(true);
return;
}
setNotes([
...notes,
{
id: Math.random(),
text: note.trim(),
date: new Date().toLocaleDateString(),
backgroundColor: getRandomColor(),
},
]);
toggleModal();
};
const handleChange = (event: any) => {
setNote(event.target.value);
};
const resetForm = () => {
setNote("");
setShowError(false);
};
const toggleModal = () => {
resetForm();
setShowModal(!showModal);
};
return (
<>
{showModal && (
<div className="modal">
<div className="modal-content">
<textarea
className="text"
onChange={handleChange}
value={note}
></textarea>
{showError && (
<p className="error">Minimum characters allowed is 10</p>
)}
<div className="buttons">
<button className="add-btn" onClick={addNote}>
Add Note
</button>
<button className="close-btn" onClick={toggleModal}>
Close
</button>
</div>
</div>
</div>
)}
<main>
<div className="header">
<h2 className="header-title">Notes</h2>
<button className="add-note-btn" onClick={toggleModal}>
+
</button>
</div>
<div className="notes-container">
{notes.map((note) => {
return (
<div
key={note.id}
className="note"
style={{ backgroundColor: note.backgroundColor }}
>
<p className="note-text">{note.text}</p>
<p className="note-date">{note.date}</p>
</div>
);
})}
</div>
</main>
</>
);
}
export default App;
Update the App.css to be as follows
.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 */
}
}
Finally, Update the index.css file too
: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;
}
}
Save all the changes and run your app with the following command:
npm run dev
Your application should now look as follows:
Our application is a notes app that allows us to add notes.
On clicking the + icon, we get a modal as follows:
2. Explanation.
The textarea field has an initial value set to the **note **variable that we created:
<textarea
className="text"
onChange={handleChange}
value={note}
></textarea>
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.
The handleChange function used on the onChange event handler was defined as follows:
const handleChange = (event: any) => {
console.log(event.target.value)
setNote(event.target.value);
console.log("Note: ", note)
};
You can check the console and see the value that is logged out and also the value of the note as you type.
The handleChange function simply sets the note variable to be whatever text the user inputs as they type.
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.
For the source code, you can access it at this link: Source code
Follow me on:
LinkedIn: Paul Otieno
Twitter: me_huchoma
Instagram: paul_dreamer_
Happy Coding! 🥂
Top comments (0)