Step-by-Step Implementation of The Poll App in React
Step-by-Step Implementation of The Poll App in React
In this module, we will build the Poll App step by step. By the end, you’ll have a working poll system where users can vote on options, see live results update instantly, and reset polls if needed. We’ll cover environment setup, directory structure, main rendering logic, state handling for polls, displaying results dynamically, and styling for a clean UI.
1) Set up the Environment
We’ll use Vite to scaffold our React project, since it’s fast and lightweight.
Open your terminal and run:
npm create vite@latest poll-app
Choose the following options:
- Project name: poll-app
- Framework: React
- Variant: JavaScript
Then install dependencies:
cd poll-app
npm install
Start the development server:
npm run dev
You’ll get a local URL like http://localhost:5173/. Open it in the browser and you should see the default Vite + React page.
2) Create Application Structure (Directory Layout)
After setup, your project looks like this:
poll-app/
├── index.html
├── package.json
├── vite.config.js
├── public/
└── src/
├── App.jsx
├── App.css
├── index.css
└── main.jsx
- index.html: Contains <div id="root"></div> — where React mounts the app.
- src/main.jsx: Entry point that renders the <App /> component.
- src/App.jsx: Main component where we’ll build the poll logic.
- src/App.css and src/index.css: Styling files for layout and components.
3) Rendering App in main.jsx
Open src/main.jsx. It mounts our App into the root div:
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 means everything we build in App.jsx will appear in the browser.
4) Building the Poll Logic in App.jsx
Now let’s open App.jsx and implement our poll system step by step.
Step 1: Import React hooks and CSS
import { useState } from "react";
import "./App.css";
We’ll use useState to manage poll options, votes, and results.
Step 2: Define Poll State
const [question, setQuestion] = useState("Which is your favorite programming language?");
const [options, setOptions] = useState([
{ text: "JavaScript", votes: 0 },
{ text: "Python", votes: 0 },
{ text: "Java", votes: 0 },
{ text: "C++", votes: 0 }
]);
const [voted, setVoted] = useState(false);
- question: The poll’s main question.
- options: Array of choices, each with text and a vote count.
- voted: Tracks whether the user has already voted (to prevent multiple votes).
Step 3: Handle Voting
const handleVote = (index) => {
if (voted) return; // prevent multiple votes
const updatedOptions = [...options];
updatedOptions[index].votes += 1;
setOptions(updatedOptions);
setVoted(true);
};
This function updates the selected option’s votes and locks further voting.
Step 4: Calculate Results in Percentages
const totalVotes = options.reduce((sum, option) => sum + option.votes, 0);
This helps us show how popular each option is, relative to the total.
Step 5: Reset Poll
const resetPoll = () => {
const resetOptions = options.map(opt => ({ ...opt, votes: 0 }));
setOptions(resetOptions);
setVoted(false);
};
This clears all votes and allows users to vote again.
Step 6: Return the UI
return (
<div className="app">
<h1>Poll App</h1>
<h2>{question}</h2>
<div className="options">
{options.map((option, index) => (
<button
key={index}
onClick={() => handleVote(index)}
disabled={voted}
{option.text}
</button>
))}
</div>
<div className="results">
<h3>Results</h3>
{options.map((option, index) => {
const percentage = totalVotes > 0 ? ((option.votes / totalVotes) * 100).toFixed(1) : 0;
return (
<div key={index} className="result-bar">
<span>{option.text} - {option.votes} votes ({percentage}%)</span>
<div className="bar">
<div className="fill" style={{ width: `${percentage}%` }}></div>
</div>
</div>
);
})}
</div>
<button onClick={resetPoll} className="reset-btn">Reset Poll</button>
<footer>
Built by Jaishree Tomar for{" "}
<a href="https://www.guvi.in" target="_blank" rel="noreferrer">
GUVI
</a>
</footer>
</div>
);
This renders:
- The poll question
- Options as clickable buttons
- Live-updating results with percentage bars
- Reset button to start fresh
- Footer with credit
5) Styling with CSS
In App.css, we add styles for a clean and modern UI:
body {
margin: 0;
font-family: "Poppins", sans-serif;
background: linear-gradient(135deg, #0f2027, #203a43, #2c5364);
color: #f1f1f1;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
.app {
background: rgba(30, 30, 30, 0.9);
padding: 2rem;
border-radius: 1.5rem;
box-shadow: 0 0 20px rgba(0, 255, 255, 0.2);
text-align: center;
width: 90%;
max-width: 600px;
}
h1 {
color: #00ffff;
text-shadow: 0 0 8px #00ffffaa;
}
.options button {
margin: 0.5rem;
padding: 0.8rem 1.2rem;
background: #111;
color: #00ffff;
border: 1px solid #00ffff;
border-radius: 8px;
cursor: pointer;
transition: 0.2s;
}
.options button:hover:not(:disabled) {
background: #00ffff;
color: #111;
}
.options button:disabled {
opacity: 0.6;
cursor: not-allowed;
}
.results {
margin-top: 1.5rem;
text-align: left;
}
.result-bar {
margin: 0.6rem 0;
}
.bar {
background: #333;
border-radius: 6px;
overflow: hidden;
height: 12px;
margin-top: 0.3rem;
}
.fill {
background: #00ffff;
height: 100%;
transition: width 0.4s ease;
}
.reset-btn {
margin-top: 1.5rem;
padding: 0.7rem 1.2rem;
border: none;
background: #ff4d4d;
color: white;
border-radius: 10px;
cursor: pointer;
transition: 0.3s;
}
.reset-btn:hover {
background: #cc0000;
}
footer {
margin-top: 2rem;
font-size: 0.9rem;
color: #aaa;
}
footer a {
color: #00ffff;
text-decoration: none;
}
Key highlights:
- Gradient background for a modern look
- Buttons styled with neon blue glow effect
- Results shown as percentage bars
- Smooth animations when voting updates the bar
- Red reset button for emphasis
6) Final Touches
- Test the app: Vote once and watch the results update instantly.
- Try the reset button — all votes should clear.
- Style adjustments can be made in App.css to match your preferences.
Now your Poll App is fully functional. It lets users vote, shows real-time percentages, and provides a reset option — all built with React hooks and Vite.











