React Basics Explained — Complete Beginner's Guide to Components & JSX
React components are reusable JavaScript functions that return UI elements, letting you build complex interfaces by composing small, self-contained pieces together.
What You’ll Learn
- What React is and why it uses a declarative approach
- How JSX combines HTML-like syntax with JavaScript
- How to build components and pass data with props
- How to manage state with
useStateand handle events - How to render lists, conditionals, and forms
Why React Basics Matters
React powers thousands of applications — from social media feeds to antivirus management consoles. At DodaTech, we use React for the Durga Antivirus Pro dashboard (real-time threat graphs, scan history) and the Doda Browser extension popup UI (bookmark manager, ad-block toggles). Without React, you’d write tedious DOM manipulation code that’s hard to maintain as your app grows.
Your Learning Path
flowchart LR
A[JavaScript<br/>Fundamentals] --> B[React Basics]
B --> C[React Hooks]
C --> D[React Advanced]
C --> E[React Reference]
B --> F[Next.js]
style B fill:#3b82f6,color:#fff,stroke:#2563eb,stroke-width:3px
What Is React?
React is a JavaScript library for building user interfaces. It was created by Facebook (now Meta) in 2013 to solve a big problem: keeping the UI in sync with data as it changes.
Imagine you’re building a house. Instead of cutting every piece of wood from scratch, you use pre-built Lego blocks. React components are those Lego blocks — small, self-contained pieces of code that describe a part of your UI. A button is a component. A search bar is a component. An entire dashboard is a composition of many components working together.
Declarative vs Imperative
Before React, you wrote imperative code: “Get this element, change its text, add a class, then listen for a click.” You told the browser how to do everything step by step.
React flips this to declarative: “Here’s what the UI should look like when the state is X. When the state changes to Y, here’s what it should look like.” React figures out the how.
Analogy: Imperative is giving turn-by-turn driving directions. Declarative is handing someone a map with the destination marked.
The Virtual DOM
React keeps a lightweight JavaScript copy of the real DOM called the Virtual DOM — think of it as a blueprint. When state changes, React:
- Creates a new Virtual DOM tree
- Compares it with the previous one (diffing)
- Calculates the minimal set of changes
- Applies only those changes to the real DOM
This avoids expensive direct DOM manipulation, keeping your UI fast.
Your First Component
A component is a JavaScript function that returns JSX:
function App() {
return (
<div>
<h1>Hello, React!</h1>
<p>Welcome to your first app.</p>
</div>
);
}
export default App;Line by line:
function App() {— Component names must start with a capital letter. This tells React: “This is a component, not a regular HTML tag.”return (...)— The component returns what should be rendered on screen<div>...</div>— This is JSX, not HTML. It gets compiled intoReact.createElement()callsexport default App;— Makes this component available for other files to import
You might be wondering: why return only one element? React needs one root element to build the component tree. Use a Fragment (<>...</>) to group elements without adding an extra <div>.
JSX — JavaScript XML
JSX is a syntax extension that lets you write HTML-like code inside JavaScript:
const element = <h1>Hello, World!</h1>;
// Compiles to:
const element = React.createElement("h1", null, "Hello, World!");Embedding JavaScript with {}
Use curly braces to embed any JavaScript expression inside JSX:
const name = "Alice";
const greeting = <h1>Hello, {name}!</h1>; // Variables
const sum = <p>2 + 2 = {2 + 2}</p>; // Expressions
const msg = <p>{isLoggedIn ? "Hi" : "Sign in"}</p>; // TernaryWhat doesn’t work inside {}: Statements like if, for, or switch — those go outside JSX.
JSX vs HTML: Key Differences
| JSX | HTML | Why? |
|---|---|---|
className="box" | class="box" | class is a reserved word in JavaScript |
htmlFor="email" | for="email" | for is also reserved |
onClick={handler} | onclick="handler()" | camelCase is JavaScript convention |
style={{ color: "red" }} | style="color: red" | JSX styles are JavaScript objects |
Components & Props
Props (short for “properties”) are like function arguments for components. They let you pass data from a parent to a child. Think of props as configuration knobs — you turn them to customize a component.
function Greeting({ name, age }) { // Destructured props
return (
<div>
<h2>Hello, {name}!</h2>
<p>You are {age} years old.</p>
</div>
);
}
// Using the component
function App() {
return (
<div>
<Greeting name="Alice" age={25} />
<Greeting name="Bob" age={30} />
</div>
);
}Line by line:
function Greeting({ name, age })— Destructuring the props object gives us direct access tonameandage<Greeting name="Alice" age={25} />— Strings use quotes, numbers use{}- React reuses the same
Greetingfunction with different props each time — like calling a function with different arguments
The Children Prop
Every component receives a special prop called children — whatever is nested between the tags:
function Card({ children, title }) {
return (
<div className="card">
<h3>{title}</h3>
{children}
</div>
);
}
<Card title="Notice"><p>This is the content.</p></Card>State with useState
State is a component’s memory. Without state, a component always renders the same thing. With state, it can remember data between renders and update when that data changes.
Think of state like a whiteboard: you write a number, and when you erase and write a new one, everyone sees the updated value.
import { useState } from "react";
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>+1</button>
<button onClick={() => setCount(count - 1)}>-1</button>
<button onClick={() => setCount(0)}>Reset</button>
</div>
);
}Line by line:
import { useState } from "react";— Imports the hook. You must import it to use it.const [count, setCount] = useState(0);— Array destructuring.useState(0)returns[currentValue, setterFunction]. We name themcountandsetCount.{count}— Displays the current count in JSXonClick={() => setCount(count + 1)}— When clicked,setCounttriggers a re-render: React callsCounteragain, anduseStatereturns the updated value
State vs Props
| Feature | Props | State |
|---|---|---|
| Who owns it? | Parent component | The component itself |
| Mutable? | No (read-only) | Yes (via setter) |
| Change triggers re-render? | Yes (in the child) | Yes |
| Analogy | Configuration knobs | Component’s memory |
Events & Forms
React events use camelCase and you pass a function reference (not a string):
function Button() {
const handleClick = () => alert("Button clicked!");
return <button onClick={handleClick}>Click Me</button>;
}Note: onClick={handleClick} — no parentheses. onClick={handleClick()} would call the function immediately on render, not on click.
Controlled Forms
Form elements like <input> can be controlled — their value is driven by state:
function LoginForm() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const handleSubmit = (e) => {
e.preventDefault();
console.log("Login:", { email, password });
};
return (
<form onSubmit={handleSubmit}>
<input type="email" placeholder="Email" value={email}
onChange={(e) => setEmail(e.target.value)} />
<input type="password" placeholder="Password" value={password}
onChange={(e) => setPassword(e.target.value)} />
<button type="submit">Login</button>
</form>
);
}Line by line:
value={email}— The input’s displayed value comes from state, not the DOMonChange={(e) => setEmail(e.target.value)}— Every keystroke updates state.eis the synthetic evente.preventDefault()— Stops the browser from reloading on form submit- This is called a controlled component — React controls the input’s value, not the DOM
Conditional Rendering & Lists
Use regular JavaScript control flow inside JSX:
// Ternary for if/else
function Greeting({ isLoggedIn }) {
return <h1>{isLoggedIn ? "Welcome back!" : "Please sign in"}</h1>;
}
// Logical AND for "if only"
function UserStatus({ user }) {
return <div>{user && <p>Logged in as {user.name}</p>}</div>;
}
// Lists with map()
function TodoList() {
const todos = [
{ id: 1, text: "Learn React" },
{ id: 2, text: "Build a project" },
];
return (
<ul>
{todos.map(todo => <li key={todo.id}>{todo.text}</li>)}
</ul>
);
}Why keys? Keys help React identify which items changed, moved, or were removed — like license plates for cars. Always use a stable, unique ID from your data. Never use the array index unless the list is static.
React vs Vanilla JavaScript
| Task | Vanilla JS | React |
|---|---|---|
| Update text on click | document.getElementById("x").textContent = "hi" | setText("hi") |
| Create a reusable button | Write a function returning HTML string | Write a component returning JSX |
| Handle form input | addEventListener("input", fn) and read .value | value={state} + onChange handler |
| Re-render on data change | Manually find and update DOM nodes | Automatic via state setters |
Common Mistakes
1. Mutating state directly
items.push(4); // Wrong! React can't detect this
setItems([...items, 4]); // Correct — new array referenceReact detects changes by reference comparison. If you mutate an existing array, the reference stays the same — React thinks nothing changed.
2. Forgetting e.preventDefault()
Forms reload the page by default. In a Single Page Application, this kills your app state.
3. Setting state in the component body
function Bad() {
const [count, setCount] = useState(0);
setCount(count + 1); // re-render → setCount → infinite loop
return <p>{count}</p>;
}State updates belong in event handlers or effects, never directly in the component body.
4. Using array index as key
Index-as-key works until items are reordered. React then reuses the wrong component instances.
5. Confusing props with state
Props come from parents (read-only). State is internal (mutable). If data comes from outside, it’s a prop. If the component creates it, it’s state.
6. Forgetting to import hooks
useState must be imported: import { useState } from "react".
Practice Questions
What is the difference between the Virtual DOM and the real DOM?
The Virtual DOM is a lightweight JavaScript object mirroring the real DOM. React uses it to calculate minimal updates (diffing) before applying changes to the real DOM, avoiding expensive direct manipulation.
Why must component names start with a capital letter?
React treats lowercase tags as HTML elements (
<div>) and capitalized tags as components (<Greeting />). Without capitalization,<greeting>would be treated as an unknown HTML element.What does
useState(0)return?It returns an array of two elements: the current state value (
0initially) and a setter function. We destructure them:const [count, setCount] = useState(0).Why do we use
classNameinstead ofclassin JSX?classis a reserved keyword in JavaScript. Since JSX is JavaScript, React usesclassNameto avoid conflicts.What happens when
setCountis called?React schedules a re-render: it calls the component function again,
useStatereturns the updated value, and React diffs the new Virtual DOM to apply minimal DOM updates.
Challenge
Build a temperature converter with two inputs (Celsius and Fahrenheit). When the user types in either field, the other auto-updates. Formulas: C = (F - 32) * 5/9, F = C * 9/5 + 32.
FAQ
Try It Yourself
Here’s a complete interactive React sandbox. Edit the code and see results live — no installation needed:
What’s Next
Now that you understand React basics, level up with hooks:
| Lesson | Description |
|---|---|
| https://tutorials.dodatech.com/frameworks/react/react-hooks/ | Master useEffect, useContext, useRef, and custom hooks |
| https://tutorials.dodatech.com/frameworks/react/react-advanced/ | Error boundaries, portals, code splitting |
| TypeScript for React | Adding types to your components |
| Node.js Backend for React | Build APIs your React frontend consumes |
Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.
What’s Next
Congratulations on completing this React Basics tutorial! Here’s where to go from here:
- Practice daily — Consistency is more important than long study sessions
- Build a project — Apply what you learned by building something real
- Explore related topics — Check out other tutorials in the same category
- Join the community — Discuss with other learners and share your progress
Remember: every expert was once a beginner. Keep coding!
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro