React is an open-source JavaScript library for building user interfaces, especially single-page applications.
Created by Facebook, it allows developers to create reusable UI components.
JSX stands for JavaScript XML.
It is a syntax extension that allows you to write HTML-like code inside JavaScript.
Browser doesn’t understand JSX → Babel transpiles it to React.createElement() calls.
<div>)Example:
// Element
const title = <h1>Hello</h1>;
// Component
function Title() {
return <h1>Hello</h1>;
}
Most common ways (2025):
npx create-react-app my-app (classic)npx create-vite@latest my-app -- --template react (faster & modern)npx create-next-app@latest (with Next.js)A component is an independent, reusable piece of UI.
Two types:
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
// or arrow function (very common)
const Welcome = ({ name }) => <h1>Hello, {name}</h1>;
Props (properties) are read-only data passed from parent to child component.
Like function arguments.
<Welcome name="Sara" />
State is a built-in object that holds data that can change over time.
When state changes → component re-renders.
In functional components we use useState hook.
| Props | State | |
|---|---|---|
| Mutable? | No (read-only) | Yes |
| Who owns? | Parent component | Component itself |
| Can be passed? | Yes, to children | No (but can pass via props) |
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>+1</button>
</>
);
}
Direct mutation doesn’t trigger re-render.
React compares previous & new state → only re-renders when using setter function.
Functions that respond to user actions (click, change, submit, etc.).
Use camelCase: onClick, onChange, onSubmit
Pass a callback function as prop from parent to child.
// Parent
function Parent() {
const [name, setName] = useState("");
return <Child setName={setName} />;
}
// Child
function Child({ setName }) {
return <input onChange={e => setName(e.target.value)} />;
}
{isLoggedIn ? <Dashboard /> : <Login />}{isLoading && <Spinner />}if (!user) return <Login />;const users = ["Alice", "Bob", "Charlie"];
return (
<ul>
{users.map((user, index) => (
<li key={index}>{user}</li>
))}
</ul>
);
Keys help React identify which items have changed, added, or removed.
Without keys → unnecessary re-renders or lost state.
Best: use unique ID from data, not array index.
Allows grouping multiple elements without adding extra DOM node.
return (
<>
<h1>Title</h1>
<p>Content</p>
</>
);
Older way to write components using ES6 classes.
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
Today mostly replaced by functional components + hooks.
It is the only required method in class component.
Returns the JSX (or null) that describes what should appear on screen.
React wraps native browser events into cross-browser compatible synthetic events.
Ensures consistent behavior across browsers.
<form onSubmit={(e) => {
e.preventDefault();
// handle form
}}>
Data flows only from parent → child via props.
Children cannot directly modify parent state → must use callback functions.
Makes debugging easier and predictable.
index.js or main.jsx
import ReactDOM from 'react-dom/client';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
It is the bridge between React and the browser DOM.
Methods like createRoot, render, hydrateRoot.
Yes — using <></> (Fragment) or React.Fragment.
React shows warning in console.
May cause performance issues, wrong UI updates, or lost component state.
setCount(prev => prev + 1);
Safer when multiple updates happen in same event loop.
Special prop that contains everything passed between opening & closing tags.
<Card>
<h2>Title</h2>
Content here
</Card>
<User
name="John"
age={28}
isActive={true}
address={{ city: "Mumbai", pin: 400001 }}
/>
It’s allowed but not recommended.
Better to use state initializer:
state = { count: 0 };
style={{ color: 'red' }}className="btn"class is a reserved word in JavaScript → use className instead.
const [value, setValue] = useState("");
<input
value={value}
onChange={(e) => setValue(e.target.value)}
/>
Form elements whose value is controlled by React state.
Most common and recommended way.
Form elements that maintain their own state in the DOM.
Use defaultValue and refs to access value.
Less common today.
const inputRef = useRef(null);
<input ref={inputRef} />
// later
inputRef.current.focus();
Moving shared state to the closest common parent component.
Allows sibling components to share and sync data.
Passing props through many levels even when intermediate components don’t use them.
Solution: Context API, Zustand, etc.
No — initializer must be synchronous.
Use useEffect for async operations.
Spread operator — passes all remaining props to child.
function Button({ children, ...rest }) {
return <button {...rest}>{children}</button>;
}
function User({ name, age, city }) {
return <p>{name} is {age} from {city}</p>;
}
Nothing is rendered (component is skipped).
Useful for conditional rendering.
No — violates Rules of Hooks.
Hooks must be called in the same order on every render.
Forcing remount when key changes.
{tab === 'home' ? <Home key="home" /> : <Profile key="profile" />}
{/* This is a comment */}
Inside curly braces because it’s JavaScript.
Low-level method that JSX compiles to.
React.createElement("div", { className: "box" }, "Hello")
Yes — using React.createElement directly.
Less readable, so JSX is preferred.
<React.StrictMode> enables extra checks in development:
Best practice: extract reusable logic into custom hooks or utility functions.
Keeps components clean and focused on UI.