The React app with Vite for managing a grocery list is set up! Follow these steps:
Project Initialization: Use the Vite template for React and install Bootstrap for styling.
Component Structure: The app is modular, with separate components for each feature.
Implementation Details: Each component handles specific functionality, ensuring maintainable code.
Integration: All components come together in AppGrocery.jsx, the parent component, using state management.
Run npm run dev to see your grocery list application in action!
Step 1. Initialize the project
Run the following commands in your terminal to create a Vite React project and install Bootstrap for styling.
// Step 1:
// Run the following commands in your terminal
npm create vite@latest react-grocery-app --template react
cd grocery-list-app
npm install
npm install bootstrap bootstrap-icons
Step 2. Structure the src folder
Create the necessary folder structure for organizing the application components.
// Create the following structure:
// src/
// AppGrocery.jsx
// components/
// HeaderNav.jsx
// GroceryInputForm.jsx
// GroceryList.jsx
// Footer.jsx
Step 3. Implement HeaderNav.jsx
This component displays the application header with a title.
Create HeaderNav.jsx file in src/components folder
This component contains an input field and a button to add new grocery items.
Create GroceryInputForm.jsx file in src/components folder
// Step 4: Implement GroceryInputForm.jsx
import React, { useState } from 'react';
const GroceryInputForm = ({ onAddItem }) => {
const [itemName, setItemName] = useState(""); // State to keep track of the input value.
const handleAddItem = () => {
if (itemName.trim()) { // Ensures the input is not empty.
onAddItem(itemName); // Calls the parent function to add the item.
setItemName(""); // Resets the input field.
}
};
return (
<div className="my-3 d-flex justify-content-center">
<input
type="text"
className="form-control w-50"
placeholder="Enter item name"
value={itemName} // Binds the input value to the state.
onChange={(e) => setItemName(e.target.value)} // Updates state on input change.
/>
<button className="btn btn-success ms-2" onClick={handleAddItem}>
Add Item // Triggers adding a new item.
</button>
</div>
);
};
export default GroceryInputForm;
Step 5. Implement GroceryList.jsx
This component displays a list of grocery items with toggle and delete functionalities.
Create GroceryList.jsx file in src/components folder
use icon style for delete button. For this, the delete button has been updated to use a Bootstrap icon (bi bi-trash) for a more polished and modern look. You need to install bootstrap-icons at terminal if not installed.
npm install bootstrap-icons
// Step 5: Implement GroceryList.jsx
import React from 'react';
const GroceryList = ({ items, onToggleBought, onDeleteItem }) => {
return (
<ul className="list-group">
{items.map((item, index) => (
<li
key={index} // Provides a unique key for each list item.
className="list-group-item d-flex justify-content-between align-items-center"
>
<span
style={{ textDecoration: item.bought ? "line-through" : "none" }} // Strikes through if bought.
onClick={() => onToggleBought(index)} // Toggles the bought state when clicked.
className="cursor-pointer"
>
{item.name}
</span>
<div>
<button
className="btn btn-danger btn-sm"
onClick={() => onDeleteItem(index)} // Removes the item when clicked.
>
<i className="bi bi-trash"></i> // use "bi bi-trash" instead of "Delete" text
</button>
</div>
</li>
))}
</ul>
);
};
export default GroceryList;
Step 6. Implement Footer.jsx
This component displays a summary of total items and the number bought.
Step 7. Implement the parent component AppGrocery.jsx
This is the main component that integrates all child components and manages the application state.
Create AppGrocery.jsx in src folder
import Ass.css style
// Step 7: Implement AppGrocery.jsx
import React, { useState } from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
import HeaderNav from './components/HeaderNav';
import GroceryInputForm from './components/GroceryInputForm';
import GroceryList from './components/GroceryList';
import Footer from './components/Footer';
const AppGrocery = () => {
const [items, setItems] = useState([]); // Manages the list of grocery items.
const handleAddItem = (name) => {
setItems([...items, { id: Date.now(), name:name, bought: false }]); // Adds a new item with a default bought state.
};
const handleToggleBought = (index) => {
setItems(
items.map((item, i) =>
i === index ? { ...item, bought: !item.bought } : item // Toggles the bought state of the item.
)
);
};
const handleDeleteItem = (index) => {
setItems(items.filter((_, i) => i !== index)); // Removes the item from the list.
};
return (
<div>
<HeaderNav /> // Renders the header.
<div className="container my-4">
<GroceryInputForm onAddItem={handleAddItem} /> // Passes the add item handler.
<GroceryList
items={items} // Passes the current items to the list.
onToggleBought={handleToggleBought} // Passes the toggle handler.
onDeleteItem={handleDeleteItem} // Passes the delete handler.
/>
</div>
<Footer
totalItems={items.length} // Total number of items.
totalBoughtItems={items.filter((item) => item.bought).length} // Total bought items.
/>
</div>
);
};
export default AppGrocery;
Step 8. Update main.jsx to render AppGrocery
This step ensures the main application component is rendered to the DOM.
// Step 8: Update main.jsx to render AppGrocery
// Replace the contents of src/main.jsx with:
import React from 'react';
import ReactDOM from 'react-dom/client';
import AppGrocery from './AppGrocery';
ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<AppGrocery /> // Mounts the main component.
</React.StrictMode>
);
//Step 9. Run the application
Use the following command to start the development server and view the app in the browser.
Run npm run dev to see your grocery list application in action!