Building Components
A well-structured React app is made of many small components, each responsible for one thing. The challenge is deciding where to draw the lines — what should be its own component versus what should stay inline.
One responsibility per component
Section titled “One responsibility per component”Each component should do one thing clearly. A CategoryCard renders a single budget category. A TransactionList renders a list of transactions. An IncomeRow renders a single income source. These are easy to test, easy to read, and easy to reuse.
A component doing too much — rendering a form, managing a list, and handling navigation all at once — becomes hard to follow and hard to change. When a component function grows beyond ~80 lines, it is usually doing too much.
Building IncomeSection
Section titled “Building IncomeSection”In ZeroBudget, the income section shows a list of income sources and a form to add new ones. Here is a minimal version:
export default function IncomeSection() { return ( <section className="income-section"> <h2>Income</h2> <ul> <li>Paycheck — $3,500</li> <li>Freelance — $800</li> </ul> </section> );}This renders static data. It has one job: display the income section. The data is hardcoded for now — props will make it dynamic in the next lesson.
Exporting components
Section titled “Exporting components”Every component file exports one component as the default export:
export default function IncomeSection() { ... }Or equivalently:
function IncomeSection() { ... }export default IncomeSection;Use the first form — it is shorter and keeps the name visible at the top of the file. Named exports (export function) are reserved for files that export utilities or multiple small helpers.
Importing components
Section titled “Importing components”To use a component in another file, import it:
import IncomeSection from './components/IncomeSection/IncomeSection';
function App() { return ( <main> <IncomeSection /> </main> );}The import path does not need the .jsx extension — Vite resolves it automatically. Use relative paths from the importing file.
Building multiple components
Section titled “Building multiple components”Start sketching ZeroBudget’s component tree. The app needs:
App— root, holds layoutMonthNav— month navigation barIncomeSection— income list + add formLeftToAssign— the hero number showing unassigned moneyCategoryCard— one card per spending categoryTransactionForm— global form to add a transactionTransactionList— list of transactions inside a category card
Build each as an empty placeholder first so the structure is visible before the logic arrives:
export default function LeftToAssign() { return <div className="left-to-assign">$0.00 Left to Assign</div>;}Exercise
Section titled “Exercise”- Create
src/components/IncomeSection/IncomeSection.jsxwith a component that renders a<section>containing an<h2>Income</h2>and a hardcoded<ul>with two income items. - Create
src/components/LeftToAssign/LeftToAssign.jsxwith a placeholder that renders a<div>showing$0.00 Left to Assign. - Import and render both components in
App.jsx. - Confirm both appear in the browser.
- Each component should have one clearly defined responsibility.
- Files use PascalCase names and a default export matching the component name.
- Import components with relative paths — Vite resolves the
.jsxextension automatically. - Build placeholder components first to establish structure before adding logic.