State in React
State is data the component owns and can change. A cart quantity, a modal open flag, the text in a search box. When state changes, React re-renders that component and its children. Props are not state — props arrived from the parent and this component must not assign to them.
In a function you write const [qty, setQty] = useState(1). qty is the current value for this paint. setQty(2) schedules the next paint. If you console.log(qty) on the line right after setQty(2), you still see 1. Updates are async to the next render. That surprise is a viva favourite.
You never do qty++ on the state variable and hope the screen moves. You also don’t mutate an object in place: user.name = 'Asha'; setUser(user) may not re-render because the reference is the same. Copy, then set: setUser({ ...user, name: 'Asha' }). Arrays: setItems([...items, next]), not items.push(next).
Let’s do a cart on the board. Qty starts at 1. Button + calls setQty(qty + 1). Screen: Qty 1 → Qty 2. Price child receives amount={49 * qty} as a prop. Qty is state in the parent. amount is a prop in Price. Two different words, one data flow.
Lift state up when two siblings need the same value. Search box and result list both care about the query — parent holds query, passes down. If only one card cares whether it is expanded, that flag can stay inside the card. ‘Always lift everything to App’ is how Context hell starts.
Trap: storing derived values in extra state (fullName when you already have first + last). Compute during render: const full = first + ' ' + last. Extra state goes stale. Also trap: putting server data only in a ref and wondering why the <p> is empty — refs don’t re-render.
State in React — on screen — Qty 1. Click → Qty 2. qty lives in Cart. Parent did not pass it.
useState(1)
│ click
▼
setQty(2)
│
▼
UI re-rendersOwned vs props + setter + no mutate.