COMPLETE REACT COURSE  •  PART 2 of 5

Making Apps Interactive

Clicks, typing, state, lists, forms and sharing data between components: the skills that turn pages into apps.

4modules
40practice examples
~17hclass time
100%live code
Keys: → next   ← back   M menu   L Code Lab   F fullscreen
M5
Events & State (useState)
Clicks, typing, the render cycle
M6
Conditional Rendering & Lists
Show/hide, map, keys, filter, sort
M7
Forms in React
Controlled inputs, validation, wizards
M8
Sharing State & Thinking in React
Lifting state, data flow, app planning
BrainBit Infotech, Ranchi  |  Trainer: Nandan Kumar
05
MODULE 5  •  PART 2

Events & State (useState)

Until now our pages were frozen pictures. Events let users click and type; state lets components remember things and update the screen.

  • Handling clicks and typing (events)
  • The event object
  • Why normal variables do not update the UI
  • useState: anatomy of the hook
  • The render cycle (animated)
  • Updater functions: setCount(c => c + 1)
  • Objects & arrays in state (immutability)
  • Rules of hooks
YOU WILL BUILD:Like buttonPassword toggleDark modeImage sliderFAQ accordionShopping cartTic-Tac-Toe
🖱
App.jsx
const [likes, setLikes] = useState(0);

<button onClick={() =>
  setLikes(likes + 1)}>
  ❤ {likes}
</button>
10examples
● 5 Easy
● 3 Medium
● 2 Hard
each with live code
Complete React Course  |  BrainBit Infotech, Ranchi
M5Real-world use

Where is this used in real apps?

photo-share.in
brainbit_ranchi☾ Dark
‹photo 2 of 5›
❤️ 128 💬 12 Qty: − 2 +
Write a comment... 23/150

Everything you click or type

Like buttons, sliders, quantity +/-, dark-mode toggles, comment boxes: each orange box here is an event that changes state.

State = memory of a component

How many likes? Which photo is showing? Is dark mode on? React stores these in state and redraws when they change.

The heart of React

If you understand useState well, you understand 50% of React. Take this module slowly!
Complete React Course  |  Part 2  |  Events & State (useState)
M5Live demo

Handling events: onClick

Pass a function to onClick. React calls it when the user clicks. You can pass a named function or write an arrow function inline. To send a value, wrap it: onClick={() => greet('Aman')}.
App.jsx
Common mistakeonClick={handleClick()} with brackets runs the function immediately while rendering, not on click! Pass the function, do not call it.
LIVELive Preview
Console
✍ Try it Click each button and watch the console. Add a button that logs your own name.
Complete React Course  |  Part 2  |  Events & State (useState)
M5Live demo

The event object

React passes an event object (usually called e) to your handler. It tells you what happened: e.target.value is the text typed, e.key is the key pressed, e.preventDefault() stops the browser's default action.
App.jsx
LIVELive Preview
Console
✍ Try it Type "Ranchi" and press Enter. Then click the link: it does not open!
Complete React Course  |  Part 2  |  Events & State (useState)
M5Live demo

Why a normal variable does NOT work

Left: a normal let variable. The value changes (see console) but the screen stays 0, because React does not know it should redraw.
Right: useState. Calling the setter tells React "data changed, draw again".
App.jsx
LIVELive Preview
Console
✍ Try it Click both buttons 3 times. The left one prints 1, 2, 3 in the console but never updates the screen.
Complete React Course  |  Part 2  |  Events & State (useState)
M5Animated explainer

useState: anatomy of a hook

const [ count, setCount ] = useState( 0 );

count

The current value. Read it in JSX: {count}. Name it anything: likes, isOpen, cart...

setCount

The setter function. Call it with a new value to update and re-render. Convention: set + Name.

useState

A Hook (special React function, starts with "use"). Import it: import { useState } from 'react'

0

The initial value, used only on the first render. Can be a number, text, true/false, array or object.
Complete React Course  |  Part 2  |  Events & State (useState)
M5Animated explainer

The render cycle: what happens on every click

App.jsx
function LikeButton() {
  const [likes, setLikes] = useState(0);
  console.log('rendering, likes =', likes);
  return (
    <button onClick={() => setLikes(likes + 1)}>
      ❤ {likes}
    </button>
  );
}
🖱 User clicksonClick fires
setLikes(0+1)new value saved by React
React re-runs LikeButton()likes is now 0
Screen shows ❤ 0only the button text changes
RENDER
CYCLE
🔄
Complete React Course  |  Part 2  |  Events & State (useState)
M5Live demo

State is a snapshot: use updater functions

Inside one click, count is a fixed snapshot. Calling setCount(count + 1) three times sets it to 0+1 three times = 1. The updater form setCount(c => c + 1) gets the latest value each time = +3.
App.jsx
LIVELive Preview
Console
✍ Try it Press each +3 button and compare. Rule: when the new value depends on the old one, use c => c + 1.
Complete React Course  |  Part 2  |  Events & State (useState)
M5Animated explainer

Objects & arrays in state: always make a copy

App.jsx
const [cart, setCart] = useState(['Pen']);

// WRONG: changes the same array
cart.push('Book');
setCart(cart);   // React: "same array, nothing changed"

// RIGHT: make a NEW array
setCart([...cart, 'Book']);
TaskImmutable way
Add item[...arr, item]
Remove itemarr.filter(x => x.id !== id)
Change itemarr.map(x => x.id === id ? {...x, qty: 2} : x)
Change object field{ ...user, city: 'Ranchi' }
Old array['Pen'] at box #1
→
push('Book')still box #1
React compares box #1 === box #1, sees "no change" and may NOT re-render.
Old array['Pen'] at box #1
→
[...cart, 'Book']NEW box #2
box #1 !== box #2, so React knows it changed and re-renders. Never modify state directly; always create a copy.
Complete React Course  |  Part 2  |  Events & State (useState)
M5Live demo

Objects & arrays in state (live)

An object in state is updated with spread: {...profile, city: 'Dhanbad'} copies everything and replaces one field. An array uses [...items, newItem] to add and filter to remove.
App.jsx
LIVELive Preview
Console
✍ Try it Click "Add skill" twice, then click a skill chip to remove it.
Complete React Course  |  Part 2  |  Events & State (useState)
M5Rules

Rules of Hooks (very important)

1

Only call hooks at the TOP of a component

Not inside if, loops or nested functions. React remembers hooks by their order.
2

Only call hooks inside React components

or inside your own custom hooks (Module 12). Not in normal JS functions.
3

Hook names start with "use"

useState, useEffect, useRef... this is how React and ESLint recognise them.
4

Many states are OK

Use separate useState calls for separate things: name, age, isOpen.
Wrong.jsx
function Profile({ isAdmin }) {
  if (isAdmin) {
    const [x, setX] = useState(0); // WRONG: inside if
  }
}
Right.jsx
function Profile({ isAdmin }) {
  const [x, setX] = useState(0);  // top level
  const [name, setName] = useState('');
  if (!isAdmin) return <p>No access</p>;
  // ... use x and name
}
Complete React Course  |  Part 2  |  Events & State (useState)
M5Practice 1 of 10  •  Easy

Example 1: Like Button

● Easy💼 Real project: Social media posts (Instagram, YouTube)
One state for the count and one for whether I liked it. Clicking toggles liked and adds or removes 1. The heart colour comes from state.
App.jsx
LIVELive Preview
Console
✍ Try it yourself Add a small text under the button: "You and 127 others" when liked, "Be the first of your friends" when not.
Use a ternary: {liked ? 'You and ' + (likes - 1) + ' others' : '...'}
Complete React Course  |  Part 2  |  Events & State (useState)
M5Practice 2 of 10  •  Easy

Example 2: Show / Hide Password

● Easy💼 Real project: Every login form
A boolean state show switches the input type between "password" and "text". The eye button flips it with setShow(!show).
App.jsx
LIVELive Preview
Console
✍ Try it yourself Add a second button "Copy" that logs the text "Copied!" in the console when clicked.
<button onClick={() => console.log('Copied!')}>Copy</button>
Complete React Course  |  Part 2  |  Events & State (useState)
M5Practice 3 of 10  •  Easy

Example 3: Dark Mode Toggle

● Easy💼 Real project: Apps & websites with themes
A dark boolean changes the whole page colours. We pick a style object from state. (Module 13 shows how to share this across many components with Context.)
App.jsx
LIVELive Preview
Console
✍ Try it yourself Add a third theme "blue" and a button that cycles light → dark → blue → light.
Store the theme NAME in state: useState('light') and use themes[name].
Complete React Course  |  Part 2  |  Events & State (useState)
M5Practice 4 of 10  •  Easy

Example 4: Quantity Stepper (1 to 10)

● Easy💼 Real project: Shopping cart quantity
Two buttons change the quantity. We stop at the limits by disabling the buttons, and calculate the price from the quantity (no extra state needed).
App.jsx
LIVELive Preview
Console
✍ Try it yourself Show "Free delivery!" in green when the total is Rs 1,000 or more.
{qty * price >= 1000 && <p style={{color:'green'}}>Free delivery!</p>}
Complete React Course  |  Part 2  |  Events & State (useState)
M5Practice 5 of 10  •  Easy

Example 5: Feedback Character Counter

● Easy💼 Real project: Tweets, reviews, comment boxes
The textarea updates text state on every key (e.target.value). The counter, colour and button state are all calculated from text.length.
App.jsx
LIVELive Preview
Console
✍ Try it yourself Also show the number of words typed.
text.trim() === '' ? 0 : text.trim().split(/\s+/).length
Complete React Course  |  Part 2  |  Events & State (useState)
M5Practice 6 of 10  •  Medium

Example 6: Image Slider (Carousel)

●● Medium💼 Real project: Homepage banners, product photos
State stores the current index. Next/Prev change it, and the % (remainder) operator wraps around: after the last slide comes the first. Dots let you jump to any slide.
App.jsxApp.css
LIVELive Preview
Console
✍ Try it yourself Show "Slide 2 / 4" text in the corner of the slider.
{index + 1} / {slides.length} in an absolutely positioned span.
Complete React Course  |  Part 2  |  Events & State (useState)
M5Practice 7 of 10  •  Medium

Example 7: Course Details Tabs

●● Medium💼 Real project: Product pages, settings screens
State remembers the active tab name. Tab buttons set it; the content area shows only the matching content using an object lookup.
App.jsxApp.css
LIVELive Preview
Console
✍ Try it yourself Add a "Batches" tab with timing details. You only need to add one line to the tabs object.
Batches: 'Mon-Fri 9 AM, Sat-Sun 4 PM'
Complete React Course  |  Part 2  |  Events & State (useState)
M5Practice 8 of 10  •  Medium

Example 8: FAQ Accordion

●● Medium💼 Real project: Help pages, institute websites
Each FAQ item has its own open state, so we put the state inside the FaqItem component. Every item remembers itself independently.
App.jsx
LIVELive Preview
Console
✍ Try it yourself Open two answers at once. Notice each item is independent. (Module 8 shows how to allow only ONE open at a time.)
This works because every FaqItem has its own useState.
Complete React Course  |  Part 2  |  Events & State (useState)
M5Practice 9 of 10  •  Hard

Example 9: Shopping Cart with Totals

●●● Hard💼 Real project: E-commerce checkout
The cart is an array of objects in state. We add items (or increase qty if already there), change quantity with map, remove with filter, and calculate totals with reduce. All immutable!
App.jsx
LIVELive Preview
Console
✍ Try it yourself Add an "Empty cart" button that clears everything, visible only when the cart has items.
{cart.length > 0 && <button onClick={() => setCart([])}>Empty cart</button>}
Complete React Course  |  Part 2  |  Events & State (useState)
M5Practice 10 of 10  •  Hard

Example 10: Tic-Tac-Toe with Winner Detection

●●● Hard💼 Real project: Games (the official React tutorial project!)
The board is an array of 9 squares in state, plus whose turn it is. Clicking copies the array, fills a square and switches the player. getWinner() checks all 8 winning lines on every render.
App.jsxApp.css
LIVELive Preview
Console
✍ Try it yourself Keep a score: count wins for X and O in a new state and show "X: 2 | O: 1" above the board.
Use useState({ X: 0, O: 0 }) and update it in play() when the move creates a winner (check with getWinner(next)).
Complete React Course  |  Part 2  |  Events & State (useState)
M5Check your understanding

Quick Quiz

Click an answer. Wrong answers shake, the right one turns green and explains why.

Q1. What is wrong with onClick={save()}?
✔ Pass the function itself (onClick={save}) or an arrow function.
Q2. After setCount(count + 1), what does React do?
✔ Setting state schedules a re-render; the new value appears in the next render.
Q3. How do you add an item to an array in state?
✔ Always create a new array; never mutate state.
🎯
Your score: 0 / 3 (first try counts)
Answer all 3 questions. Discuss any wrong answer with your partner before moving on.
Complete React Course  |  Part 2  |  Events & State (useState)
M5Module summary

Recap: What you learned

  • ✔Events: onClick={fn}, onChange, onKeyDown; handler gets the event object e.
  • ✔Normal variables do not update the screen. useState does.
  • ✔const [value, setValue] = useState(initial)
  • ✔State change → component re-runs → React updates only what changed.
  • ✔Use updater form setX(x => x + 1) when the new value depends on the old.
  • ✔Copy objects/arrays: {...obj}, [...arr], map, filter.
🏆

Module 5 complete!

Finish all 10 examples and the "Try it yourself" tasks before moving on.

Practice folder: D:\react-practice\m05

➡ Next up

Module 6: Conditional Rendering & Lists. Show different UI for different situations and render lists like a pro.
Complete React Course  |  Part 2  |  Events & State (useState)
06
MODULE 6  •  PART 2

Conditional Rendering & Lists

Real apps show different things in different situations (logged in or not, loading or ready) and display long lists of data. Master both here.

  • if / else with early return
  • Ternary ? : inside JSX
  • && and the famous 0 trap
  • Lookup objects instead of long if chains
  • Rendering lists with map (animated)
  • Why keys matter (live bug demo)
  • Filter & sort before rendering
  • Empty states
YOU WILL BUILD:Login navbarNotification badgeCity searchSortable productsTodo appPaginated table
📋
App.jsx
{students.length === 0
  ? <p>No students yet</p>
  : students.map(s =>
      <Row key={s.id} {...s} />)}
10examples
● 5 Easy
● 3 Medium
● 2 Hard
each with live code
Complete React Course  |  BrainBit Infotech, Ranchi
M6Real-world use

Where is this used in real apps?

myshop.in/orders
My Orders 3 new
AllDeliveredSort: Price ▼
Dokra HorseDelivered
Tussar SareeShipped
Jute BagCancelled
‹ 1 2 3 ›

Conditional rendering

The "3 new" badge appears only if there are new orders; each status shows a different colour.

Lists

The order rows are ONE component repeated using map over an array from the server.

Filter, sort, paginate

Tabs filter the list, the dropdown sorts it, and page numbers show 10 at a time. You will build all of these.
Complete React Course  |  Part 2  |  Conditional Rendering & Lists
M6Live demo

if / else and early return

Normal JavaScript if works great before the return. A common pattern is the early return: handle special cases first (loading, error, not logged in) and return early.
App.jsx
LIVELive Preview
Console
✍ Try it Add a 4th case: if user.tasks === 0, return "All done! 🎉".
Complete React Course  |  Part 2  |  Conditional Rendering & Lists
M6Live demo

Ternary, && and the 0 trap

cond ? A : B picks one of two. cond && A shows A or nothing.
Trap: if cond is the number 0, React prints 0 on the screen! Use count > 0 && ... instead.
App.jsx
LIVELive Preview
Console
✍ Try it See the stray "0" in the wrong line? Change unread to 5 and both lines show the badge.
Complete React Course  |  Part 2  |  Conditional Rendering & Lists
M6Live demo

Lookup objects & returning null

Instead of long if / else if chains, keep options in an object and look them up: config[status]. Return null to render nothing at all.
App.jsx
LIVELive Preview
Console
✍ Try it Add a "cancelled" status with ❌ and red colour, and use it.
Complete React Course  |  Part 2  |  Conditional Rendering & Lists
M6Animated explainer

Rendering lists with map()

App.jsx
const students = [
  { id: 1, name: 'Aman', city: 'Ranchi' },
  { id: 2, name: 'Priya', city: 'Dhanbad' },
  { id: 3, name: 'Rohit', city: 'Bokaro' },
];

<ul>
  {students.map((s) => (
    <li key={s.id}>
      {s.name} - {s.city}
    </li>
  ))}
</ul>
ARRAY (data)
{ id:1, 'Aman' }
{ id:2, 'Priya' }
{ id:3, 'Rohit' }
→
.map()
JSX (screen)
<li> 👤 Aman - Ranchi </li>
<li> 👤 Priya - Dhanbad </li>
<li> 👤 Rohit - Bokaro </li>
3 objects in → 3 <li> out. Add 100 objects and you get 100 rows, no extra code!
Complete React Course  |  Part 2  |  Conditional Rendering & Lists
M6Live demo

Why keys matter (live bug demo)

Type something in a few boxes on both sides, then click Add to top. With key={index} the typed text sticks to the wrong person! With key={item.id} React tracks each row correctly.
App.jsx
LIVELive Preview
Console
✍ Try it Rule: use a stable unique id from your data as the key. Use the index only for lists that never change order.
Complete React Course  |  Part 2  |  Conditional Rendering & Lists
M6Animated explainer

Filter & sort BEFORE you render

🗃 All products12 items from API
→
.filter()category = Home
→
.filter()name includes "ba"
→
.sort()price low to high
→
.map()2 cards on screen
App.jsx
const visible = products
  .filter((p) => category === 'All' || p.category === category)   // step 2
  .filter((p) => p.name.toLowerCase().includes(search.toLowerCase())) // step 3
  .sort((a, b) => sortBy === 'price' ? a.price - b.price : a.name.localeCompare(b.name)); // step 4

return visible.length === 0
  ? <p>No products match "{search}"</p>          // empty state
  : visible.map((p) => <ProductCard key={p.id} product={p} />);  // step 5
Complete React Course  |  Part 2  |  Conditional Rendering & Lists
M6Practice 1 of 10  •  Easy

Example 1: Login / Logout Navbar

● Easy💼 Real project: Navbars of every website
A boolean loggedIn state decides what the navbar shows: a Login button, or the user name with a Logout button.
App.jsx
LIVELive Preview
Console
✍ Try it yourself When logged in, also show a "My Courses" link before the name.
Add <a href="#" style={{color:'#ffa8a8'}}>My Courses</a> inside the logged-in span.
Complete React Course  |  Part 2  |  Conditional Rendering & Lists
M6Practice 2 of 10  •  Easy

Example 2: Notification Badge

● Easy💼 Real project: Bell icons, cart icons, chat apps
The red badge appears only when count > 0 (avoiding the 0 trap), and shows 99+ for big numbers.
App.jsx
LIVELive Preview
Console
✍ Try it yourself Show the text "You are all caught up ✅" below the bell when count is 0.
{count === 0 && <p>You are all caught up</p>}
Complete React Course  |  Part 2  |  Conditional Rendering & Lists
M6Practice 3 of 10  •  Easy

Example 3: Student List with Keys

● Easy💼 Real project: Class registers, contact lists
Map an array of student objects to list items. Each item uses the student's id as its key. A numbered list shows rank too.
App.jsx
LIVELive Preview
Console
✍ Try it yourself Show the class average marks at the bottom using reduce.
students.reduce((s, x) => s + x.marks, 0) / students.length
Complete React Course  |  Part 2  |  Conditional Rendering & Lists
M6Practice 4 of 10  •  Easy

Example 4: Empty Orders State

● Easy💼 Real project: Empty carts, no search results, inbox zero
A good app never shows a blank screen. If the list is empty we show a friendly message and a button; otherwise we show the list.
App.jsx
LIVELive Preview
Console
✍ Try it yourself Change the empty message for a "Wishlist" page: heart icon, "Your wishlist is empty".
Only the JSX inside the first return changes.
Complete React Course  |  Part 2  |  Conditional Rendering & Lists
M6Practice 5 of 10  •  Easy

Example 5: Order Status Labels

● Easy💼 Real project: Delivery tracking (Amazon, Swiggy)
A lookup object maps each status to a colour and step number. A small progress tracker lights up all steps up to the current one.
App.jsx
LIVELive Preview
Console
✍ Try it yourself Add a step "Out for delivery" between Shipped and Delivered. Do the trackers update automatically?
Yes! Just insert it in the STEPS array.
Complete React Course  |  Part 2  |  Conditional Rendering & Lists
M6Practice 6 of 10  •  Medium

Example 6: Search Jharkhand Cities

●● Medium💼 Real project: Search boxes everywhere
The input updates query state. We filter the city list on every render (no second state needed!) and highlight the matching part.
App.jsx
LIVELive Preview
Console
✍ Try it yourself Add a "Clear" button that empties the search box. Show it only when there is text.
{query && <button onClick={() => setQuery('')}>Clear</button>}
Complete React Course  |  Part 2  |  Conditional Rendering & Lists
M6Practice 7 of 10  •  Medium

Example 7: Sort Products

●● Medium💼 Real project: Shopping sites: sort by price / rating
The sort choice lives in state. We sort a copy ([...products]) because sort() changes the array it is called on, and we must never change original data.
App.jsx
LIVELive Preview
Console
✍ Try it yourself Add a "Name Z-A" option. You only need one new line in sorters!
'Name Z-A': (a, b) => b.name.localeCompare(a.name)
Complete React Course  |  Part 2  |  Conditional Rendering & Lists
M6Practice 8 of 10  •  Medium

Example 8: Students Grouped by Section

●● Medium💼 Real project: Reports grouped by class, date or category
First we group the flat array into an object { "10-A": [...], "10-B": [...] } using reduce. Then a nested map: outer for sections, inner for students.
App.jsx
LIVELive Preview
Console
✍ Try it yourself Sort the students alphabetically inside each section.
Use [...list].sort((a, b) => a.name.localeCompare(b.name)).map(...)
Complete React Course  |  Part 2  |  Conditional Rendering & Lists
M6Practice 9 of 10  •  Hard

Example 9: Todo App with Filters

●●● Hard💼 Real project: Task managers (Todoist, Google Tasks)
Combines everything: an array of objects in state, add (spread), toggle (map), delete (filter), a filter state (All/Active/Done) and an empty state. A classic interview project!
App.jsxApp.css
LIVELive Preview
Console
✍ Try it yourself Add a "Clear completed" button that removes all done tasks.
setTodos(todos.filter(t => !t.done))
Complete React Course  |  Part 2  |  Conditional Rendering & Lists
M6Practice 10 of 10  •  Hard

Example 10: Paginated Admin Table

●●● Hard💼 Real project: Admin panels with hundreds of rows
We generate 23 fee records and show 5 per page. State holds the page number; slice() picks the rows for that page. Prev/Next are disabled at the ends and page buttons are created with Array.from.
App.jsx
LIVELive Preview
Console
✍ Try it yourself Add a dropdown to choose rows per page (5, 10, 20). Remember to go back to page 1 when it changes!
Make PER_PAGE a state: const [perPage, setPerPage] = useState(5); in onChange call both setPerPage and setPage(1).
Complete React Course  |  Part 2  |  Conditional Rendering & Lists
M6Check your understanding

Quick Quiz

Click an answer. Wrong answers shake, the right one turns green and explains why.

Q1. {count && <Badge />} with count = 0 shows...
✔ React renders the number 0. Use count > 0 && ...
Q2. What is the best key for a list item?
✔ Keys must be stable and unique among siblings, like a database id.
Q3. To show only matching items you use...
✔ filter keeps items that pass a test; map then renders them.
🎯
Your score: 0 / 3 (first try counts)
Answer all 3 questions. Discuss any wrong answer with your partner before moving on.
Complete React Course  |  Part 2  |  Conditional Rendering & Lists
M6Module summary

Recap: What you learned

  • ✔Use if + early return for big cases; ternary for small ones inside JSX.
  • ✔cond && <X /> shows or hides; beware of 0.
  • ✔Lookup objects replace long if-chains; return null to render nothing.
  • ✔array.map() turns data into JSX; every item needs a stable key.
  • ✔filter → sort (on a copy) → slice → map is the list pipeline.
  • ✔Always design an empty state.
🏆

Module 6 complete!

Finish all 10 examples and the "Try it yourself" tasks before moving on.

Practice folder: D:\react-practice\m06

➡ Next up

Module 7: Forms in React. Collect and validate user input like real apps do.
Complete React Course  |  Part 2  |  Conditional Rendering & Lists
07
MODULE 7  •  PART 2

Forms in React

Login, sign-up, admission, payment, feedback: almost every app collects input. Learn the React way to build forms that check data before sending it.

  • Controlled inputs (animated loop)
  • Text, textarea, select
  • Checkbox and radio buttons
  • One handler for many fields
  • Submitting with preventDefault
  • Validation & error messages
  • Dynamic fields (add/remove)
  • Multi-step forms & libraries
YOU WILL BUILD:Newsletter boxCourse pickerAdmission formLogin validationRegistration wizardJob application
📝
App.jsx
<input
  value={email}
  onChange={e =>
    setEmail(e.target.value)}
/>
10examples
● 5 Easy
● 3 Medium
● 2 Hard
each with live code
Complete React Course  |  BrainBit Infotech, Ranchi
M7Real-world use

Where is this used in real apps?

brainbit-teaching.com/admission
Admission Enquiry 2026
Full name
Kavya Tirkey
Phone
98765
Enter 10 digits
Course
React JS ▾
Batch
◉ Morning ○ Evening
☑ I agree to the terms
Submit enquiry

Every input type in one form

Text, phone, dropdown, radio buttons and a checkbox. Each one is connected to React state.

Instant validation

The phone box turns red with a helpful message before the user even presses Submit.

Data goes somewhere

On submit, the form data object is sent to a server (you will do that in Module 10 with fetch).
Complete React Course  |  Part 2  |  Forms in React
M7Animated explainer

Controlled inputs: React is the boss of the input

App.jsx
function EmailBox() {
  const [email, setEmail] = useState('');
  return (
    <input
      value={email}
      onChange={(e) => setEmail(e.target.value)}
    />
  );
}
⌨️ user types: _
↓
onChange(e)e.target.value = ""
↓
setEmail("")state updated
↓
re-render: value={email}input shows ""
Complete React Course  |  Part 2  |  Forms in React
M7Live demo

Text inputs & textarea

Each input gets value from state and onChange to update it. Because state is always up to date, a live preview costs nothing extra.
App.jsx
LIVELive Preview
Console
✍ Try it Make the preview name ALWAYS uppercase using .toUpperCase().
Complete React Course  |  Part 2  |  Forms in React
M7Live demo

Select, checkbox & radio

select: value + onChange like text. checkbox: use checked and e.target.checked (true/false). radio: all share a name; checked={batch === 'Morning'}.
App.jsx
LIVELive Preview
Console
✍ Try it Add "Data Science" to the course list and a "Night" batch option.
Complete React Course  |  Part 2  |  Forms in React
M7Live demo

One handler for many fields

Big forms use ONE state object and ONE handler. Each input has a name matching a key. [e.target.name] (a computed key) updates the right field.
App.jsx
LIVELive Preview
Console
✍ Try it Add an email field: add it to the initial object and add one input with name="email".
Complete React Course  |  Part 2  |  Forms in React
M7Live demo

Submitting a form

Put inputs inside a <form onSubmit={...}>. Pressing Enter or the submit button calls it. Always call e.preventDefault() first, otherwise the browser reloads the page!
App.jsx
LIVELive Preview
Console
✍ Try it Try submitting an invalid email: the browser blocks it because of type="email" required.
Complete React Course  |  Part 2  |  Forms in React
M7Rules & patterns

Validation: check before you send

App.jsx
function validate(values) {
  const errors = {};
  if (!values.name.trim())
    errors.name = 'Name is required';
  if (!/^[6-9]\d{9}$/.test(values.phone))
    errors.phone = 'Enter a valid 10-digit mobile number';
  if (values.password.length < 8)
    errors.password = 'At least 8 characters';
  return errors;   // {} means everything is OK
}

function handleSubmit(e) {
  e.preventDefault();
  const errs = validate(form);
  setErrors(errs);
  if (Object.keys(errs).length === 0) sendToServer(form);
}
🔍

When to validate?

On submit (simplest), on blur (when leaving a field) or while typing (live). Most apps combine submit + blur.
💬

Good error messages

Say what to do: "Enter 10 digits" is better than "Invalid".
🛡

Server checks too

Front-end validation is for user comfort. The server must ALWAYS validate again for security.
📦

In companies

React Hook Form + Zod handle big forms with less code. Learn the basics first, then try them.
Complete React Course  |  Part 2  |  Forms in React
M7Practice 1 of 10  •  Easy

Example 1: Live Name Preview

● Easy💼 Real project: Profile editors, greeting card makers
A controlled input updates state on every key press, and a greeting card updates instantly. This is the simplest form in React.
App.jsx
LIVELive Preview
Console
✍ Try it yourself Add a second input for the message line and show it instead of "From all of us at BrainBit Infotech".
A second useState + input, then <p>{message || 'From all of us...'}</p>
Complete React Course  |  Part 2  |  Forms in React
M7Practice 2 of 10  •  Easy

Example 2: Newsletter Subscribe

● Easy💼 Real project: Website footers, blogs
A small form with onSubmit and preventDefault. After submitting we show a thank-you message instead of the form (conditional rendering).
App.jsx
LIVELive Preview
Console
✍ Try it yourself Disable the button until the email contains an "@" and a ".".
disabled={!email.includes('@') || !email.includes('.')}
Complete React Course  |  Part 2  |  Forms in React
M7Practice 3 of 10  •  Easy

Example 3: Course Select Shows Fee

● Easy💼 Real project: Booking & enquiry forms
A <select> is controlled with value and onChange. The chosen course looks up its fee and duration from an object.
App.jsx
LIVELive Preview
Console
✍ Try it yourself Add an "Excel + MIS" course (Rs 3,500, 1 month).
One new line in the courses object; the dropdown updates by itself.
Complete React Course  |  Part 2  |  Forms in React
M7Practice 4 of 10  •  Easy

Example 4: Accept Terms Checkbox

● Easy💼 Real project: Sign-up and payment forms
A checkbox uses checked and e.target.checked. The Submit button stays disabled until the box is ticked.
App.jsx
LIVELive Preview
Console
✍ Try it yourself Add a second checkbox "Send me WhatsApp updates" that is optional (does not block the button).
Another useState(false) for whatsapp; it does not go into the disabled condition.
Complete React Course  |  Part 2  |  Forms in React
M7Practice 5 of 10  •  Easy

Example 5: Batch Timing Radio Buttons

● Easy💼 Real project: Selecting one option: slots, sizes, plans
Radio buttons in the same group share the same name. Each is checked when its value equals the state. Styled labels make big clickable cards.
App.jsx
LIVELive Preview
Console
✍ Try it yourself Add a "Night" batch (8 - 10 PM, 6 seats).
Add one object to the batches array.
Complete React Course  |  Part 2  |  Forms in React
M7Practice 6 of 10  •  Medium

Example 6: Admission Enquiry Form

●● Medium💼 Real project: Coaching / school websites
A realistic form: one state object, one handleChange using [name], a submit handler, and a success screen showing what would be sent to the server.
App.jsxApp.css
LIVELive Preview
Console
✍ Try it yourself Add an "email" field (optional). It should appear in the JSON on the success screen.
Add email: '' to empty and an input with name="email".
Complete React Course  |  Part 2  |  Forms in React
M7Practice 7 of 10  •  Medium

Example 7: Login Form with Validation

●● Medium💼 Real project: Login pages of every app
On submit we run validate(), store the errors object in state and show each message under its field. Fields with errors get a red border.
App.jsx
LIVELive Preview
Console
✍ Try it yourself Add a rule: password must contain at least one number. Message: "Add at least one number".
else if (!/\d/.test(password)) e.password = 'Add at least one number';
Complete React Course  |  Part 2  |  Forms in React
M7Practice 8 of 10  •  Medium

Example 8: Add / Remove Phone Numbers

●● Medium💼 Real project: Contact forms, family details, invoice items
Some forms need a variable number of fields. We keep an array in state, render one input per item, and update a single item with map by index.
App.jsx
LIVELive Preview
Console
✍ Try it yourself Allow only digits: ignore any key that is not a number.
In update: value.replace(/\D/g, '') before saving.
Complete React Course  |  Part 2  |  Forms in React
M7Practice 9 of 10  •  Hard

Example 9: 3-Step Registration Wizard

●●● Hard💼 Real project: Sign-up flows, KYC, admission portals
One step state controls which part of the form is visible, and ONE data object collects everything across steps. A progress bar shows how far you are. Next is blocked until the current step is valid.
App.jsxApp.css
LIVELive Preview
Console
✍ Try it yourself Add a 4th step "Payment" (radio: UPI / Cash) between Course and Review.
Add "Payment" to STEPS, a payment field, a step === 2 block, and move Review to step 3.
Complete React Course  |  Part 2  |  Forms in React
M7Practice 10 of 10  •  Hard

Example 10: Job Application with Review Screen

●●● Hard💼 Real project: Job portals (Naukri, LinkedIn Easy Apply)
Full-featured form: validation on blur (when you leave a field) using a touched object, skill checkboxes stored as an array, an error count, and an editable review screen.
App.jsx
LIVELive Preview
Console
✍ Try it yourself Add an "experience" select (Fresher, 1-2 years, 3+ years) and show it on the review screen.
Add experience: 'Fresher' to the state and a select that updates it.
Complete React Course  |  Part 2  |  Forms in React
M7Check your understanding

Quick Quiz

Click an answer. Wrong answers shake, the right one turns green and explains why.

Q1. A "controlled" input means...
✔ value={state} + onChange keeps React in charge of the input.
Q2. Why call e.preventDefault() in onSubmit?
✔ The default form submit reloads the page and you lose your state.
Q3. For a checkbox you read...
✔ Checkboxes give true/false in e.target.checked.
🎯
Your score: 0 / 3 (first try counts)
Answer all 3 questions. Discuss any wrong answer with your partner before moving on.
Complete React Course  |  Part 2  |  Forms in React
M7Module summary

Recap: What you learned

  • ✔Controlled input: value={state} + onChange.
  • ✔Checkbox uses checked; radios share a name.
  • ✔One state object + [e.target.name] handles big forms.
  • ✔onSubmit + e.preventDefault().
  • ✔Validate on submit/blur; store errors in state; show helpful messages.
  • ✔Arrays in state for dynamic fields; a step state for wizards.
🏆

Module 7 complete!

Finish all 10 examples and the "Try it yourself" tasks before moving on.

Practice folder: D:\react-practice\m07

➡ Next up

Module 8: Sharing State & Thinking in React. Make components talk to each other.
Complete React Course  |  Part 2  |  Forms in React
08
MODULE 8  •  PART 2

Sharing State & Thinking in React

When two components need the same data, where should the state live? Learn the official "Thinking in React" method used by professional teams.

  • Data flows down, events flow up
  • The problem of out-of-sync components
  • Lifting state up (animated)
  • Callback props: onSomething
  • Single source of truth
  • Derived state: do not store what you can calculate
  • Thinking in React: 5 steps
  • Prop drilling (and what comes next)
YOU WILL BUILD:Synced convertersMaster-detail viewFilterable product tableCart badgeQuiz appKanban board
🤝
App.jsx
// Parent owns the state
const [qty, setQty] = useState(0);

<Navbar count={qty} />
<Product onAdd={() =>
  setQty(qty + 1)} />
10examples
● 5 Easy
● 3 Medium
● 2 Hard
each with live code
Complete React Course  |  BrainBit Infotech, Ranchi
M8Real-world use

Where is this used in real apps?

myshop.in
MyShop 🛒 3
🐎
Dokra
Add
🧺
Basket
Add
👜
Jute Bag
Add
Navbar and ProductGrid are siblings.
Who should own the cart count?

Siblings need the same data

Clicking "Add" in the product grid must update the cart badge in the Navbar. They are different components!

The answer: their common parent

Move the cart state UP to the parent (App). Pass the count down to Navbar and an onAdd function down to ProductGrid.

Used everywhere

Filters + results, search box + list, chat input + messages, form steps + progress bar.
Complete React Course  |  Part 2  |  Sharing State & Thinking in React
M8Animated explainer

Data flows DOWN, events flow UP

<App />const [count, setCount] = useState(0)
↓
count={0}
↓
onAdd={fn}
<Navbar />🛒 0
<ProductCard />[Add] button
↑ event goes UP: onAdd() ↑
App.jsx
function App() {
  const [count, setCount] = useState(0);
  return (
    <>
      <Navbar count={count} />
      <ProductCard onAdd={() => setCount(count + 1)} />
    </>
  );
}
function ProductCard({ onAdd }) {
  return <button onClick={onAdd}>Add</button>;
}
Complete React Course  |  Part 2  |  Sharing State & Thinking in React
M8Live demo

The problem: components out of sync

Each converter box below has its own state. Type in one and the other has no idea. When two components must show the same data, separate states will always get out of sync.
App.jsx
LIVELive Preview
Console
✍ Try it Type 830 in Rupees. Dollars stays empty: each box only knows its own state.
Complete React Course  |  Part 2  |  Sharing State & Thinking in React
M8Animated explainer

Lifting state up

Before: state in each child

<App />
<MoneyBox INR />own state: 830
<MoneyBox USD />own state: ""

After: state lifted to App

<App />const [inr, setInr] = useState(830)
↓ value={inr}   ↓ value={inr/83}
<MoneyBox INR />no state, uses props
<MoneyBox USD />no state, uses props
↑ onChange(newValue) calls setInr ↑
Complete React Course  |  Part 2  |  Sharing State & Thinking in React
M8Live demo

Lifted state: now they stay in sync

The state lives in App. Each MoneyBox receives a value and an onChange callback. We store only rupees; dollars are calculated from it.
App.jsx
LIVELive Preview
Console
✍ Try it Type in either box: the other updates. Add a third box for Euros (rate 90).
Complete React Course  |  Part 2  |  Sharing State & Thinking in React
M8Golden rule

Derived state: do not store what you can calculate

Wrong.jsx
// WRONG: three states that must be kept in sync by hand
const [items, setItems] = useState([]);
const [count, setCount] = useState(0);
const [total, setTotal] = useState(0);

function add(item) {
  setItems([...items, item]);
  setCount(count + 1);          // easy to forget...
  setTotal(total + item.price); // ...and get out of sync
}
Right.jsx
// RIGHT: one state, everything else is calculated
const [items, setItems] = useState([]);
const count = items.length;
const total = items.reduce((s, it) => s + it.price, 0);

function add(item) {
  setItems([...items, item]);   // that's all!
}
Key ideaAsk: "Can I calculate this from props or other state?" If yes, it is NOT state. Just compute it during render. Fewer states = fewer bugs.
Store in stateCalculate (derive)
the list of todosnumber of done todos
the search textthe filtered results
the cart itemscart total, item count, GST
date of birthage
Complete React Course  |  Part 2  |  Sharing State & Thinking in React
M8Animated explainer

Thinking in React: the 5-step method

Product table
SearchBar🔍 [ba____]   ☐ Only in stock
ProductTable
Home
Bamboo Basket ... Rs 350
Bamboo Mat ... Rs 500
Art
Sohrai Painting ... Rs 2200
  • 1
    Break the UI into components (draw boxes)
  • 2
    Build a static version with props only, no state
  • 3
    Find the minimal state: search text + inStockOnly checkbox. (The filtered list is derived!)
  • 4
    Decide where state lives: the common parent of SearchBar and ProductTable
  • 5
    Add inverse data flow: SearchBar calls callbacks to update the parent
Complete React Course  |  Part 2  |  Sharing State & Thinking in React
M8Animated explainer

Prop drilling: when lifting goes too far

<App /> user = "Kavya"
↓ user
<Layout />does not use user, just passes it
↓ user
<Header />does not use user, just passes it
↓ user
<UserMenu />does not use user, just passes it
↓ user
<Avatar />FINALLY uses user!
🙈

Prop drilling

Passing props through many components that do not need them, just to reach a deep child.
😬

Why it hurts

Every middle component must accept and forward the prop. Renaming it means editing 4 files.
💡

The solution

Context API (Module 13) lets Avatar read the user directly. For big apps: Redux Toolkit or Zustand (Module 15).
Complete React Course  |  Part 2  |  Sharing State & Thinking in React
M8Practice 1 of 10  •  Easy

Example 1: Child Buttons Control Parent Counter

● Easy💼 Real project: Remote controls, toolbars
The parent owns the count. Three child StepButtons receive an onStep callback and a step amount. They do not have any state.
App.jsx
LIVELive Preview
Console
✍ Try it yourself Add a ResetButton child component that receives an onReset prop.
function ResetButton({ onReset }) { return <button onClick={onReset}>Reset</button> } and pass () => setCount(0).
Complete React Course  |  Part 2  |  Sharing State & Thinking in React
M8Practice 2 of 10  •  Easy

Example 2: Child Input Updates Parent Heading

● Easy💼 Real project: Live title editors (Google Docs title)
TitleInput is a child with an input. It calls onTitleChange. The parent stores the title and also shows it in a big heading: two components, one source of truth.
App.jsx
LIVELive Preview
Console
✍ Try it yourself Add a third component WordCount that shows the number of words in the title.
It only needs the title prop; count with title.trim().split(/\s+/).filter(Boolean).length.
Complete React Course  |  Part 2  |  Sharing State & Thinking in React
M8Practice 3 of 10  •  Easy

Example 3: Celsius / Fahrenheit Sync

● Easy💼 Real project: Unit converters (classic React docs example)
We store ONE value (Celsius) in the parent. The Fahrenheit box shows a calculated value and converts back when you type into it. Both boxes are the same reusable component.
App.jsx
LIVELive Preview
Console
✍ Try it yourself Add a Kelvin box (K = C + 273).
Another TempInput with value Number(c) + 273 and onChange v => setC(String(v - 273)).
Complete React Course  |  Part 2  |  Sharing State & Thinking in React
M8Practice 4 of 10  •  Easy

Example 4: Master-Detail View

● Easy💼 Real project: Email apps, contact lists, file managers
The parent stores the selected id. List shows names and reports clicks with onSelect; Detail shows the selected person. Siblings share data through the parent.
App.jsx
LIVELive Preview
Console
✍ Try it yourself Notice we store only the id, not the whole person (derived!). Add a 4th contact and check it works.
Just add an object with id 4.
Complete React Course  |  Part 2  |  Sharing State & Thinking in React
M8Practice 5 of 10  •  Easy

Example 5: Rating Picker Reports to Parent

● Easy💼 Real project: Review forms, feedback surveys
A reusable RatingPicker lets the user hover and click stars, then calls onRate(n). Its hover effect is local state (only it cares); the chosen rating is lifted to the parent form.
App.jsx
LIVELive Preview
Console
✍ Try it yourself Use TWO RatingPickers in the form: "Course content" and "Trainer". Each needs its own state in the parent.
Two useState calls in ReviewForm, and two <RatingPicker> with different value/onRate.
Complete React Course  |  Part 2  |  Sharing State & Thinking in React
M8Practice 6 of 10  •  Medium

Example 6: Filterable Product Table

●● Medium💼 Real project: The official "Thinking in React" project
Built with the 5 steps: SearchBar and ProductTable are siblings. Their parent holds the minimal state (filterText, inStockOnly). The visible rows are derived, not stored.
App.jsxSearchBar.jsxProductTable.jsx
LIVELive Preview
Console
✍ Try it yourself Add a "Max price" number input in SearchBar. You need a new state in the parent and one more filter in ProductTable.
State maxPrice in parent; pass value + callback to SearchBar and maxPrice to ProductTable; skip if p.price > maxPrice.
Complete React Course  |  Part 2  |  Sharing State & Thinking in React
M8Practice 7 of 10  •  Medium

Example 7: Navbar Cart Badge from a Sibling

●● Medium💼 Real project: Every e-commerce header
App owns cart. Navbar receives only the count (derived). ProductGrid receives onAdd. Click Add and watch the badge bounce, two siblings in sync via the parent.
App.jsxApp.css
LIVELive Preview
Console
✍ Try it yourself Add a CartList sibling below the grid that lists the item names in the cart.
Pass items={cart} to it and map to <li>.
Complete React Course  |  Part 2  |  Sharing State & Thinking in React
M8Practice 8 of 10  •  Medium

Example 8: Accordion: Only One Open

●● Medium💼 Real project: FAQ sections, settings panels
In Module 5 each FAQ had its own state, so many could be open. To allow only one, lift the state up: the parent stores openIndex, and each panel gets isOpen and onShow.
App.jsx
LIVELive Preview
Console
✍ Try it yourself Add a button "Close all" above the panels.
<button onClick={() => setOpenIndex(null)}>Close all</button>
Complete React Course  |  Part 2  |  Sharing State & Thinking in React
M8Practice 9 of 10  •  Hard

Example 9: Quiz App with Scoreboard

●●● Hard💼 Real project: E-learning platforms, online tests
The Quiz parent owns current, score and answers. Question reports a choice via onAnswer; ScoreBoard and ProgressBar just display. Each piece is simple because state lives in one place.
App.jsxquestions.jsApp.css
LIVELive Preview
Console
✍ Try it yourself Add 2 more questions in questions.js about your favourite topic. Nothing else needs to change.
Copy an object line, change the text, options and the answer index.
Complete React Course  |  Part 2  |  Sharing State & Thinking in React
M8Practice 10 of 10  •  Hard

Example 10: Mini Kanban Board

●●● Hard💼 Real project: Project tools (Trello, Jira)
One tasks array in the parent; each task has a status. Three Columns are just filtered views of the same array. Moving a task = changing its status with map.
App.jsxApp.css
LIVELive Preview
Console
✍ Try it yourself Add an input + "Add task" button above the board that adds a new task to "To Do".
Use a text state; on click: setTasks([...tasks, { id: Date.now(), text, status: 'To Do' }]).
Complete React Course  |  Part 2  |  Sharing State & Thinking in React
M8Check your understanding

Quick Quiz

Click an answer. Wrong answers shake, the right one turns green and explains why.

Q1. Two sibling components need the same data. Where should the state live?
✔ Lift it to the common parent and pass it down as props.
Q2. How does a child change the parent's state?
✔ The parent passes a function like onChange; the child calls it.
Q3. A cart total that can be calculated from cart items should be...
✔ Derived values are computed, not stored, to avoid getting out of sync.
🎯
Your score: 0 / 3 (first try counts)
Answer all 3 questions. Discuss any wrong answer with your partner before moving on.
Complete React Course  |  Part 2  |  Sharing State & Thinking in React
M8Module summary

Recap: What you learned

  • ✔Data flows DOWN as props; events flow UP through callback props.
  • ✔Separate states drift out of sync; lift shared state to the common parent.
  • ✔Name callbacks onSomething, handlers handleSomething.
  • ✔Keep a single source of truth; derive everything you can.
  • ✔Thinking in React: boxes → static → minimal state → where it lives → inverse flow.
  • ✔Deep prop drilling is a sign you need Context (Module 13).
🏆

Module 8 complete!

Finish all 10 examples and the "Try it yourself" tasks before moving on.

Practice folder: D:\react-practice\m08

➡ Next up

Part 3, Module 9: useEffect & Lifecycle. Timers, saving data and talking to the outside world.
Complete React Course  |  Part 2  |  Sharing State & Thinking in React

</> React Code Lab

Console