Full-Stack Development · Tutorial 1 of 5
React Components and Props, explained with one small app
By the FUTEAC Team · 24 October 2026 · 10 min read · Beginner
In short
A React component is a reusable piece of UI written as a JavaScript function that returns JSX — HTML-like markup you write inside JavaScript. Props are the inputs you pass to a component, like arguments to a function: one InfoCard component can render three different cards because each use passes different title and text props.
- A component is a function that returns UI.
function InfoCard() { return <div>…</div>; }is a complete component. - Props are read-only inputs. The parent passes them down; the component uses them but never changes them.
- One component, many uses. Reuse is the entire point — write
InfoCardonce, render it three times with different props. - Component names start with a capital letter.
<InfoCard />is a component;<infocard>is treated as an unknown HTML tag. - This tutorial feeds the React from Scratch course (/course/react-from-scratch) and the React skill (/skill/react).
Before you start
What is a component, exactly?
A component is a JavaScript function whose return value describes what should appear on screen:
function Greeting() {
return <h1>Hello from my first component</h1>;
}That is the whole idea. React takes the returned JSX, turns it into real DOM elements, and puts them on the page. Three rules make this work:
- The function name starts with a capital letter. React uses the capital letter to tell your components apart from built-in HTML tags.
- It returns exactly one root element. Wrap siblings in a
<div>or a fragment<>…</>. - You use it like an HTML tag:
<Greeting />renders the component wherever you place it.
A real app is just components inside components: App renders Header, ProductList and Footer; ProductList renders many ProductCards. The small app below shows exactly this pattern with two components.
What are props — and why not just use variables?
Props are how data flows *into* a component. The parent decides the values; the component receives them as one object argument:
function InfoCard({ title, text }) {
return (
<div className="card">
<h2>{title}</h2>
<p>{text}</p>
</div>
);
}{ title, text } is destructuring — it pulls the two props out of the props object so you can use them directly. Curly braces inside JSX mean "evaluate this JavaScript": {title} inserts the value of title.
Why not just hard-code variables inside the component? Because then the component can only ever show one thing. Props make it reusable:
<InfoCard title="Components" text="A component is a reusable piece of UI." />
<InfoCard title="Props" text="Props are the inputs a component receives." />Same component, different output — decided by the parent at each use. That is the core React pattern: parents own the data, children receive it through props.
Two non-negotiable rules about props:
- Props are read-only. A component must never reassign its props (
title = "other"is a bug). If data needs to change over time, that is *state* — covered in the next tutorial, React Hooks for Beginners (/tutorials/full-stack/react-hooks-usestate-useeffect). - Data flows one way: down. A child cannot pass props back up to its parent. Parents pass down; children render.
The worked example: one small app, step by step
We will build an app that renders three info cards from one InfoCard component. Follow each step in order — the expected result of each is stated.
Step 1 — Scaffold the project. In your terminal:
npm create vite@latest react-cards -- --template react
cd react-cards
npm installExpected output: Vite creates the react-cards folder and prints "Done. Now run…"; npm install finishes with no errors. This is the standard setup the React from Scratch course uses ("Why React? Setting Up Your First Project").
Step 2 — Start the dev server:
npm run devExpected output: the terminal prints Local: http://localhost:5173/ (the port may differ if 5173 is taken — use whichever URL it prints). Open that URL in Chrome: you see the default Vite + React starter page. Leave the server running; it reloads automatically when you save files.
Step 3 — Create the component. Create the file src/components/InfoCard.jsx with exactly this content:
function InfoCard({ title, text }) {
return (
<div className="card">
<h2>{title}</h2>
<p>{text}</p>
</div>
);
}
export default InfoCard;Step 4 — Use it in App. Replace the contents of src/App.jsx with:
import InfoCard from "./components/InfoCard";
function App() {
return (
<main>
<h1>My first React app</h1>
<InfoCard title="Components" text="A component is a reusable piece of UI." />
<InfoCard title="Props" text="Props are the inputs a component receives." />
<InfoCard title="Reuse" text="One component, used three times, with different props." />
</main>
);
}
export default App;Check: the import path is correct (App.jsx sits in src/, the component in src/components/); all three <InfoCard /> tags are self-closed with />; everything is wrapped in one <main> root. You do not need to touch src/main.jsx — the Vite template already renders <App /> into the page.
Step 5 — Add a little styling. Append this to src/index.css:
.card {
border: 1px solid #ddd;
border-radius: 8px;
padding: 1rem;
margin-bottom: 1rem;
max-width: 420px;
}Save everything. The dev server reloads on its own.
What does the finished app look like, and how do you check it?
Expected result: the page shows "My first React app" as a heading, followed by three bordered cards — "Components", "Props" and "Reuse" — each with its own paragraph. Three cards, one component definition: that is props doing their job.
Verify it properly in Chrome DevTools (F12 → Elements): expand the DOM and confirm you see a <main> containing an <h1> and three <div class="card"> blocks, each with its <h2> and <p> in the right order. If a card is missing, the usual cause is an unclosed tag in App.jsx — the terminal running npm run dev will show a compile error pointing at the line.
Try it yourself
Extend the app: add a third prop called emoji to InfoCard and render it before the title (<h2>{emoji} {title}</h2>). Then add a fourth card with your own title, text and emoji. When it works, test yourself in the Module Quiz: React Fundamentals on the React from Scratch course page (/course/react-from-scratch).
Common mistakes
- Writing
classinstead ofclassName. In JSX,classis a reserved word, so React usesclassName. Usingclassproduces a warning and the styles silently do not apply — the single most common beginner error in this tutorial. - Forgetting to export or import. If the browser shows a blank page and the console says
InfoCard is not defined, you forgotexport default InfoCardin the component file or theimportline inApp.jsx. Check the import path character by character:./components/InfoCard. - Trying to change props inside the component. Props are read-only —
title = "new"will not work the way you expect and React will warn you. Data that changes over time belongs in *state*, not props (that is the next tutorial in this series). - Lowercase component names.
<infoCard />or<infocard />is treated as a plain HTML tag and renders nothing useful. Components must start with a capital letter:<InfoCard />. - Returning two root elements. A component's return must have one root.
return (<h2>..</h2><p>..</p>)fails to compile; wrap them in a<div>or a fragment<>…</>.
Frequently asked questions
Is React a programming language?
No — it is a JavaScript library. Everything in this tutorial is JavaScript (functions, objects, destructuring) plus JSX, which is a syntax extension for writing markup inside JavaScript. Your JavaScript knowledge transfers directly.
Do I need TypeScript to learn React?
No. This tutorial and the React from Scratch course use plain JavaScript. TypeScript adds type checking on top later; learn components and props first, then add TypeScript when the JavaScript feels comfortable.
What is the difference between props and state?
Props are the inputs; state is the memory. You will meet state in React Hooks for Beginners (/tutorials/full-stack/react-hooks-usestate-useeffect). Who sets it: Props — The parent component, when using the child; State — The component itself. Can it change: Props — No — read-only inside the component; State — Yes — with a setter like setCount. Direction: Props — Flows down, parent → child; State — Lives inside one component.
Why is my page blank with no error?
The three usual causes, in order: the dev server is not running (npm run dev again); the import path is wrong (./components/InfoCard — check the folder name); or main.jsx still imports the old starter App.css that you deleted. Read the terminal output — Vite's error messages name the file and line.
Can a prop be an object or a list, not just text?
Yes. Props can be any JavaScript value: strings, numbers, arrays, objects, even functions. <InfoCard title="Hi" text="…" /> passes strings; you could equally pass items={["a", "b"]} — the curly braces mean "this is JavaScript, not text". Rendering lists from array props is covered in the course lesson "Rendering Lists and Conditional UI". ---
Follow the Full-Stack Developer Roadmap
Build complete web applications — frontend, backend APIs, databases and deployment. Free, step by step, at your pace.
View the Roadmap