React Tutorial
Build user interfaces from components. Hooks, routing, data fetching, testing and deployment.
- Topics
- 42
- Full lessons
- 42
- Est. hours
- ~8
- Interview Qs
- 29
Overview
React is a JavaScript library for building user interfaces from small, reusable components. You describe what the UI should look like for a given state, and React updates the DOM to match.
The track uses function components and hooks with Vite. It also explains when you do not need an effect — one of the most common sources of React bugs.
What you will learn
- Build components with JSX, props and state
- Use hooks correctly: useState, useEffect, useRef, useContext, useReducer
- Fetch data with proper loading and error states
- Add routing, authentication and deploy to Hostinger
Prerequisites
You will get the most from this track if you already know:
Learning path
The recommended sequence, from beginner to advanced. Each stage builds on the one before.
- 1Getting Started · 7 topics · BeginnerIntroduction to React · JavaScript Prerequisites · React Setup with Vite · JSX · Components · Functional Components · Props
- 2State & Events · 6 topics · Beginner → IntermediateState · Event Handling · Conditional Rendering · Lists and Keys · Forms · Controlled Components
- 3Hooks · 7 topics · IntermediateuseState · useEffect · useRef · useContext · useReducer · Custom Hooks · Component Lifecycle Concepts
- 4Routing & Data · 5 topics · IntermediateReact Router · API Integration · Fetch and Axios · Loading and Error States · Form Validation
- 5State at Scale · 6 topics · Intermediate → AdvancedContext API · State Management · Performance Optimization · Memoization · Lazy Loading · Error Boundaries
- 6Auth & Quality · 5 topics · AdvancedAuthentication · Protected Routes · TypeScript with React · React Testing · Accessibility
- 7Shipping · 6 topics · AdvancedProduction Build · Deployment to Hostinger · React with Node.js API · React with ASP.NET Core Web API · Complete CRUD Project · React Interview Questions
Complete topic list
42 topicsGetting Started
7 topics- Introduction to ReactBeginner5m
- JavaScript PrerequisitesBeginner6m
- React Setup with ViteBeginner5m
- JSXBeginner5m
- ComponentsBeginner5m
- Functional ComponentsBeginner5m
- PropsBeginner5m
State & Events
6 topics- StateBeginner6m
- Event HandlingBeginner5m
- Conditional RenderingBeginner5m
- Lists and KeysBeginner6m
- FormsIntermediate5m
- Controlled ComponentsIntermediate5m
Hooks
7 topics- useStateIntermediate5m
- useEffectIntermediate6m
- useRefIntermediate5m
- useContextIntermediate6m
- useReducerIntermediate6m
- Custom HooksIntermediate6m
- Component Lifecycle ConceptsIntermediate5m
Routing & Data
5 topics- React RouterIntermediate6m
- API IntegrationIntermediate6m
- Fetch and AxiosIntermediate6m
- Loading and Error StatesIntermediate6m
- Form ValidationIntermediate6m
State at Scale
6 topics- Context APIIntermediate6m
- State ManagementIntermediate6m
- Performance OptimizationIntermediate6m
- MemoizationIntermediate6m
- Lazy LoadingAdvanced5m
- Error BoundariesAdvanced6m
Auth & Quality
5 topics- AuthenticationAdvanced7m
- Protected RoutesAdvanced6m
- TypeScript with ReactAdvanced6m
- React TestingAdvanced6m
- AccessibilityAdvanced6m
Shipping
6 topics- Production BuildAdvanced6m
- Deployment to HostingerAdvanced5m
- React with Node.js APIAdvanced7m
- React with ASP.NET Core Web APIAdvanced6m
- Complete CRUD ProjectAdvanced8m
- React Interview QuestionsAdvanced15m
Visual guides
1 diagramCode example
A taste of the track, from JavaScript Prerequisites.
const products = [
{ id: 1, name: 'Pen', price: 20, stock: 0 },
{ id: 2, name: 'Notebook', price: 60, stock: 12 },
{ id: 3, name: 'Bag', price: 650, stock: 3 },
];
// 1. Arrow functions
const withTax = price => Math.round(price * 1.18);
// 2. Destructuring
const { name, price } = products[1];
console.log(name, withTax(price));
// 3. Spread: copy and change (never mutate state)
const updated = { ...products[0], stock: 5 };
console.log(products[0].stock, updated.stock);
// 4. map: data → display strings (in React: → JSX)
console.log(products.map(p => `${p.name}: ₹${p.price}`));
// 5. filter
const inStock = products.filter(p => p.stock > 0);
console.log(inStock.length);
// 6. Spread to add to a list
const more = [...products, { id: 4, name: 'Ruler', price: 15, stock: 9 }];
console.log(more.length, products.length);
// 7. Ternary and &&
const label = p => (p.stock > 0 ? 'In stock' : 'Sold out');
console.log(label(products[0]), products[2].stock < 5 && 'Hurry!');
// 8. Optional chaining and ??
const user = { name: 'Asha' };
console.log(user.address?.city ?? 'No city');
Notebook 71 0 5 [ 'Pen: ₹20', 'Notebook: ₹60', 'Bag: ₹650' ] 2 4 3 Sold out Hurry! No city
Practice exercises
Write a component ProfileCard that receives name and city props and renders them in an <article> with an <h2> and a <p>.
Given todos = [{ id: 1, text: "Learn JS", done: true }, { id: 2, text: "Learn React", done: false }], create a new array where todo 2 is done, without changing the original, and log the texts of unfinished todos from the original.
Create a Vite React app called todo-app, change App.jsx to show "My Todos", and build it for production.
Write a component Badge that shows "Admin" in red bold text when isAdmin is true, and "Member" in grey otherwise, using one <span> and a style object.
Split this into components: a page with a <SearchBar /> (an input and a button) and a <ResultsCount count={3} /> that shows "3 results".
Convert this class component to a function component: class Hello extends Component { render() { return <p>Hello {this.props.name}</p>; } }
Show all 41 exercises
Create an Alert component with a type prop ("success" or "error", default "success") and children. Success shows a green border, error a red one.
Two components, TemperatureInput (Celsius) and FahrenheitDisplay, must stay in sync. Lift the Celsius state into a parent and show both.
Build a LikeButton that shows "♡ Like" and becomes "♥ Liked" when clicked, toggling back on the next click.
Write a Greeting component: if user is null show a "Log in" button; if user.isAdmin show "Welcome back, admin <name>"; otherwise "Welcome back, <name>".
Render a list of contacts grouped by first letter: show an <h4> for each letter followed by the names starting with it.
Write an uncontrolled contact form (name, email, message) that, on submit, reads the values with FormData and shows "Thanks, <name>!".
Create a controlled amount input that accepts only digits and at most one decimal point, and shows the amount with ₹ below it.
Build a toggle button that shows “Show details” / “Hide details” and conditionally renders a paragraph.
Write a component that shows the window width and updates it on resize. Make sure the listener is removed on unmount.
Build a "Copy code" box: a readonly input with a coupon code and a button that selects the input’s text using a ref and shows "Copied!".
Create a LanguageContext ("en" or "hi") with a provider in App, a toggle button, and a Greeting component that shows "Hello" or "नमस्ते".
Write a counterReducer supporting "incremented", "decremented" (not below 0) and "reset", and use it in a Counter component.
Write useOnlineStatus() that returns true/false and updates when the browser fires "online" or "offline" events. Show "Online" or "Offline" in a component.
Write a ProfileEditor that resets its internal state whenever the userId prop changes, without an effect.
Add a route /orders/:orderId that shows "Order #<orderId>" and a link back to /orders.
Write a component that loads https://jsonplaceholder.typicode.com/users once and lists the names, with loading and error states.
Add a getTodo(id) function to fetchApi and a component that loads todo 1 and shows its title.
Create a reusable <AsyncView status data onRetry render /> component that shows a loading text, an error with retry, an empty message, or calls render(data).
Add a phone field to validate(): required, exactly 10 digits. Write the rule and test it with "98765" and "9876543210".
Write an AuthProvider with user (null by default), login(name) and logout(), plus a useAuth hook. Show "Hi, Asha" with a Logout button, or a Login button.
Classify each: (1) whether a tooltip is visible, (2) the logged-in user, (3) the list of products from the API, (4) the current page number of a search, (5) the text in a comment box.
A Layout component holds a "menuOpen" state and renders an expensive <ProductGrid />. Restructure it so toggling the menu does not re-render ProductGrid, without memo.
A component computes the total of a 10,000-item cart on every render, even when only a "notes" text field changes. Cache the total with useMemo.
Lazy-load a Settings page in React Router: use lazy() for the component and wrap the router outlet in Suspense.
Write a Profile component that throws if user.name is missing, and wrap it in an ErrorBoundary with fallback text "Profile unavailable". Render it with a user that has no name.
Write a RoleGate component that renders its children only if useAuth().user.roles includes a given role, otherwise "You do not have access".
Write a GuestOnly route that redirects signed-in users away from /login and /register to /account.
Type a Button component with props label (string), onClick (no arguments, returns nothing), optional disabled (boolean) and variant ("primary" | "danger", default "primary").
Write a test for a Counter with a "+1" button and text "Count: 0" that checks the count becomes 2 after two clicks.
Fix this component: <div onClick={toggle}>☰</div><input placeholder="Search">. Make the menu toggle a real button with an accessible name and state, and give the input a label.
Create .env.development and .env.production files with different VITE_API_URL values and show how a component reads it.
Your app lives in public_html/shop/. Adapt the fallback rule and say which two settings in the React project must also change.
Write the vite.config.js server.proxy setting that forwards /api to http://localhost:4000 and explain why it avoids CORS.
Write the vite.config.js proxy for an ASP.NET Core API running at https://localhost:7001 with the development certificate.
Extend the project: add a "Sort by price" checkbox that sorts the visible products from cheapest to most expensive.
Common interview questions
- Why does calling setCount(count + 1) twice only add one?
- Why do list items need keys, and why not use the array index?
- What is JSX?
- Props vs state?
- What is a controlled component?
- What is React, and what problem does it solve?
- What is a component, and what rules must it follow?
- How do you pass data from a child to a parent?
- How do you render something conditionally?
- How do event handlers differ in React?
- When should you use useEffect, and when not?
- What is the virtual DOM and reconciliation?
- When would you use useRef?
- useContext — what problem does it solve, and what are its drawbacks?
- useState vs useReducer?
- What is a custom hook?
- What does the cleanup function in useEffect do?
- How do you map class lifecycle methods to hooks?
- How does React Router handle URLs and parameters?
- How do you handle loading and error states when fetching data?
- What is prop drilling, and how do you avoid it?
- How do you validate forms in React?
- What are React.memo, useMemo and useCallback for?
- What are error boundaries?
- How do you implement protected routes?
- How do you code-split a React app?
- How do you test React components?
- How do you store and send an authentication token in a React app?
- How do you make a React app accessible?