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)
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 formsetCount(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']);
Task
Immutable way
Add item
[...arr, item]
Remove item
arr.filter(x => x.id !== id)
Change item
arr.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.
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.
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.
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.
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! 🎉".
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.
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.
●● 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)
●●● 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.
●●● 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).
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 ".".
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)} />
● 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
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 state
Calculate (derive)
the list of todos
number of done todos
the search text
the filtered results
the cart items
cart total, item count, GST
date of birth
age
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.
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.