Step-by-Step Implementation of Our Form Validation App

Step-by-Step Implementation of Our Form Validation App

In this module, we’ll actually build the Form Validation app. We’ll set up the project with Vite, organize the structure, add the form with validation, connect it to the hobby dataset, and style it neatly.

1) Set up the environment

We’ll use Vite for a fast React environment.

Open your terminal and run:

npm create vite@latest form-validation-app

Choose the following options:

  • Project name: form-validation-app
  • Framework: React
  • Variant: JavaScript

Next, install dependencies:

cd form-validation-app

npm install

Start the development server:

npm run dev

You’ll see a local URL like http://localhost:5173/. Open it in your browser. The Vite + React starter page will appear.

2) Create Application Structure (Directory Structure)

After running Vite, you’ll get this structure:

form-validation-app/

├── index.html

├── package.json

├── vite.config.js

├── public/

│   └── hobbies.json

└── src/

├── App.jsx

├── App.css

├── index.css

└── main.jsx

  • index.html: contains <div id="root"></div>. React injects our app here.
  • src/main.jsx: entry point that renders <App />.
  • src/App.jsx: main component where we build the form logic.
  • src/App.css and src/index.css: styling files.
  • public/hobbies.json: dataset of hobbies and tags we’ll use to generate suggestions.

3) Rendering App in main.jsx

Open src/main.jsx. By default, it looks like this:

import { StrictMode } from 'react'

import { createRoot } from 'react-dom/client'

import './index.css'

import App from './App.jsx'

createRoot(document.getElementById('root')).render(

<StrictMode>

<App />

</StrictMode>,

)

This code finds the root div in index.html and renders the <App /> component into it.

4) Building the Form in App.jsx

Now open src/App.jsx and replace it with our form logic.

Step 1: Import React and CSS

import React, { useState, useEffect } from "react";

import "./App.css";

Step 2: Define state

We’ll store:

  • formData: user’s name and interests
  • dataset: hobbies loaded from hobbies.json
  • suggestions: suggested hobbies after form submission

const [formData, setFormData] = useState({ name: "", interests: "" });

const [dataset, setDataset] = useState([]);

const [suggestions, setSuggestions] = useState([]);

Step 3: Load hobbies.json

When the app starts, we fetch the hobby dataset from the public folder:

useEffect(() => {

fetch("/hobbies.json")

.then((res) => res.json())

.then((data) => setDataset(data));

}, []);

Step 4: Handle input changes

function handleChange(e) {

const { name, value } = e.target;

setFormData(prev => ({ ...prev, [name]: value }));

}

Step 5: Handle form submission

On submit, we split the user’s interests, match them with the dataset, and generate suggestions.

function handleSubmit(e) {

e.preventDefault();

const interestsArray = formData.interests

.split(",")

.map(i => i.trim().toLowerCase());

const suggested = generateSuggestions(interestsArray, dataset);

setSuggestions(suggested);

}

Step 6: Suggestion logic

We give each hobby a score based on matched tags, then return the top 10 results.

function generateSuggestions(interests, dataset) {

let scoredHobbies = {};

dataset.forEach(item => {

let score = 0;

item.tags.forEach(tag => {

interests.forEach(interest => {

if (tag.toLowerCase().includes(interest)) score += 1;

});

});

if (score > 0) scoredHobbies[item.hobby] = score;

});

let sortedHobbies = Object.entries(scoredHobbies)

.sort((a, b) => b[1] - a[1])

.map(entry => entry[0]);

return sortedHobbies.length

? sortedHobbies.slice(0, 10)

: ["Try exploring new hobbies like reading, coding, music, or fitness!"];

}

Step 7: Return the UI

return (

<div className="app">

<main className="main">

<h1>Hobby Suggestion Form</h1>

<form onSubmit={handleSubmit} className="form-container">

<input

type="text"

name="name"

value={formData.name}

onChange={handleChange}

placeholder="Your Name"

required

/>

<input

type="text"

name="interests"

value={formData.interests}

onChange={handleChange}

placeholder="Your Interests (comma-separated)"

required

/>

<button type="submit">Suggest Hobbies</button>

</form>

{suggestions.length > 0 && (

<div className="suggestions-container">

<h3>Suggested Hobbies:</h3>

<ul>

{suggestions.map((s, i) => (

<li key={i}>{s}</li>

))}

</ul>

</div>

)}

</main>

<footer>

Made by <strong>Your Name</strong>

</footer>

</div>

);

5) Styling with CSS

We use App.css to style the form and suggestion list.

  • The page has a dark gradient background.
  • The form is styled like a card with shadows and rounded corners.
  • Inputs glow when focused.
  • The suggestion list fades in smoothly with animation.

Example:

.form-container {

display: flex;

flex-direction: column;

gap: 16px;

background: #1f1f2e;

padding: 30px 25px;

border-radius: 16px;

max-width: 500px;

margin: 0 auto;

}

6) Final Touches and Deployment

  1. Add a footer with your name or link.
  2. Test by entering your name and some interests (like "coding, music").
    The app will suggest hobbies such as "Build a React App" or "Play Guitar".

To deploy, build the app:

npm run build

  1. This creates a dist/ folder with optimized files.

You can host it easily on Netlify or Vercel by dragging and dropping the dist/ folder. Now the app is complete. It takes user input, validates it, matches it against the dataset, and shows personalized hobby suggestions in a clean UI.