Skip to content

Commit 04ec52b

Browse files
committed
usestate hooks examples
1 parent a334a2c commit 04ec52b

File tree

2 files changed

+162
-6
lines changed

2 files changed

+162
-6
lines changed
Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,20 @@
1-
import CounterBasic from "./examples/CounterBasic";
2-
import LazyInit from "./examples/LazyInit";
1+
/**
2+
* UseState Showcase
3+
* Renders a curated path from beginner β†’ advanced `useState` scenarios.
4+
* Add/remove examples here as you grow.
5+
*/
6+
import CounterBasic from "./examples/01_CounterBasics";
7+
import FunctionalUpdateVsStale from "./examples/02_FunctionalUpdateVsStale";
8+
import LazyInit from "./examples/03_LazyInit";
9+
import ObjectAndArrayUpdates from "./examples/04_ObjectAndArrayUpdates";
10+
import ControlledFormMinimal from "./examples/05_ControlledFormMinimal";
11+
import BatchingAndTiming from "./examples/06_BatchingAndTiming";
12+
import UndoRedoMinimal from "./examples/07_UndoRedoMinimal";
13+
import PersistLocalStorage from "./examples/08_PersistLocalStorage";
314

415
function Demo({ title, children }: { title: string; children: React.ReactNode }) {
516
return (
6-
<article style={{ border: "1px solid #ddd", padding: 16, marginBottom: 16 }}>
17+
<article style={{ border: "1px solid #e5e7eb", padding: 16, marginBottom: 16, borderRadius: 8 }}>
718
<h3 style={{ marginTop: 0 }}>{title}</h3>
819
{children}
920
</article>
@@ -13,9 +24,15 @@ function Demo({ title, children }: { title: string; children: React.ReactNode })
1324
export default function UseStateShowcase() {
1425
return (
1526
<section>
16-
<h1>useState β€” Examples</h1>
17-
<Demo title="Basic Counter"><CounterBasic /></Demo>
18-
<Demo title="Lazy Initialization"><LazyInit /></Demo>
27+
<h1>useState β€” Curated Examples</h1>
28+
<Demo title="1) CounterBasic"><CounterBasic /></Demo>
29+
<Demo title="2) FunctionalUpdateVsStale"><FunctionalUpdateVsStale /></Demo>
30+
<Demo title="3) LazyInit"><LazyInit /></Demo>
31+
<Demo title="4) ObjectAndArrayUpdates"><ObjectAndArrayUpdates /></Demo>
32+
<Demo title="5) ControlledFormMinimal"><ControlledFormMinimal /></Demo>
33+
<Demo title="6) BatchingAndTiming"><BatchingAndTiming /></Demo>
34+
<Demo title="7) UndoRedoMinimal"><UndoRedoMinimal /></Demo>
35+
<Demo title="8) PersistLocalStorage"><PersistLocalStorage /></Demo>
1936
</section>
2037
);
2138
}
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
# 🧩 useState Examples Guide
2+
3+
This folder contains a curated set of **8 progressively complex examples** that demonstrate how to use React's `useState` hook effectively.
4+
5+
The goal is to **cover all major scenarios you'll encounter in real-world projects** β€” from the simplest counter to advanced undo/redo and persistence.
6+
7+
---
8+
9+
## πŸ“š Why these examples?
10+
11+
- ⚑ **Incremental learning**: Start with a simple counter and gradually move to complex state management.
12+
- 🧠 **Key mental models**: Functional updates, batching, immutability.
13+
- πŸ› οΈ **Real-world patterns**: Forms, arrays, objects, persistence, history.
14+
- 🚨 **Pitfalls included**: Stale state bugs, unnecessary recomputation, derived state anti-patterns.
15+
16+
By the end, you'll have hands-on practice with **all scenarios where `useState` shines**.
17+
18+
---
19+
20+
## πŸ“‚ Examples Overview
21+
22+
### 1. πŸ”’ [`CounterBasic.tsx`](./examples/01_CounterBasics.tsx)
23+
**What it shows:** The simplest possible useState example
24+
**Why it matters:** This is your first step into React state management
25+
**Key concepts:**
26+
- How to initialize state with a starting value (0)
27+
- How to read the current state value
28+
- Two ways to update state: direct (`count + 1`) vs functional (`c => c + 1`)
29+
- Why functional updates are often safer
30+
31+
**Real-world use:** Any time you need a number that goes up/down (likes, cart items, page numbers)
32+
33+
---
34+
35+
### 2. ⚠️ [`FunctionalUpdateVsStale.tsx`](./examples/02_FunctionalUpdateVsStale.tsx)
36+
**What it shows:** A common bug where updates don't work as expected
37+
**Why it matters:** This bug happens in real apps and is confusing for beginners
38+
**The problem:** When you click "+2 (wrong)", it only adds 1 instead of 2
39+
**Why it happens:** Both `setN(n + 1)` calls read the same old value of `n`
40+
**The solution:** Use `setN(v => v + 1)` - React gives you the latest value each time
41+
42+
**Real-world use:** Any time you need multiple updates in one function (like increment counters multiple times)
43+
44+
---
45+
46+
### 3. πŸš€ [`LazyInit.tsx`](./examples/03_LazyInit.tsx)
47+
**What it shows:** How to avoid expensive calculations on every render
48+
**Why it matters:** Improves performance when initial state is costly to compute
49+
**The trick:** Pass a function `useState(() => expensiveInit())` instead of calling it directly
50+
**What happens:** The expensive function only runs once, not on every render
51+
52+
**Real-world use:** Reading from localStorage, complex calculations, API calls for initial data
53+
54+
---
55+
56+
### 4. πŸ“ [`ObjectAndArrayUpdates.tsx`](./examples/04_ObjectAndArrayUpdates.tsx)
57+
**What it shows:** How to update complex data (objects and arrays) correctly
58+
**Why it matters:** React only re-renders when it detects state changes
59+
**Key rule:** Never mutate (directly change) state - always create new objects/arrays
60+
**Techniques shown:**
61+
- Object updates: `{...user, city: "Bangalore"}` (spread operator)
62+
- Array additions: `[...todos, newTodo]`
63+
- Array updates: `todos.map(t => t.id === id ? {...t, done: !t.done} : t)`
64+
- Array removals: `todos.filter(t => t.id !== id)`
65+
66+
**Real-world use:** Todo lists, shopping carts, user profiles, any complex data
67+
68+
---
69+
70+
### 5. πŸ“‹ [`ControlledFormMinimal.tsx`](./examples/05_ControlledFormMinimal.tsx)
71+
**What it shows:** How to manage form inputs with React state
72+
**Why it matters:** Forms are everywhere in web apps
73+
**Key concept:** "Controlled components" - React controls the input values
74+
**Pattern shown:** Store all form fields in one state object
75+
**Benefits:** Easy to reset, validate, and submit form data
76+
77+
**Real-world use:** Login forms, registration, settings pages, any user input
78+
79+
---
80+
81+
### 6. ⏱️ [`BatchingAndTiming.tsx`](./examples/06_BatchingAndTiming.tsx)
82+
**What it shows:** How React groups multiple state updates together
83+
**Why it matters:** Understanding when your component re-renders
84+
**Key insight:** Multiple `setState` calls in the same event only cause one re-render
85+
**What you'll see:** All 3 increments happen at once, not one by one
86+
87+
**Real-world use:** Understanding performance and when side effects run
88+
89+
---
90+
91+
### 7. ↩️ [`UndoRedoMinimal.tsx`](./examples/07_UndoRedoMinimal.tsx)
92+
**What it shows:** How to build undo/redo functionality with just useState
93+
**Why it matters:** Shows advanced state management without external libraries
94+
**The pattern:** Three state pieces - past (history), present (current), future (undone actions)
95+
**How it works:**
96+
- New action β†’ save current to past, clear future
97+
- Undo β†’ move current to future, restore from past
98+
- Redo β†’ move current to past, restore from future
99+
100+
**Real-world use:** Text editors, drawing apps, any app where users make mistakes
101+
102+
---
103+
104+
### 8. πŸ’Ύ [`PersistLocalStorage.tsx`](./examples/08_PersistLocalStorage.tsx)
105+
**What it shows:** How to save state so it survives page reloads
106+
**Why it matters:** Users expect their settings/data to persist
107+
**Two key parts:**
108+
- Lazy init: `useState(() => localStorage.getItem("theme") || "light")`
109+
- Save on change: `useEffect(() => localStorage.setItem("theme", theme), [theme])`
110+
111+
**Real-world use:** User preferences, shopping cart, draft content, any data that should persist
112+
113+
---
114+
115+
## ⚠️ Common Pitfalls with `useState`
116+
117+
- **Stale closures** β†’ always prefer functional updates inside async code or multiple updates.
118+
- **Mutating state directly** β†’ React won't detect changes if reference doesn't change.
119+
- **Derived state duplication** β†’ don't store something in state if it can be computed from props/other state.
120+
- **Heavy initialization** β†’ use lazy init to avoid recomputing on every render.
121+
122+
---
123+
124+
## πŸ€” When NOT to use `useState`
125+
126+
- When state transitions become complex (e.g., undo/redo with multiple branches, async workflows) β†’ prefer `useReducer`.
127+
- When global/shared state is needed β†’ use `useContext` or state libraries.
128+
- When you need to derive data from other sources (props, memoization) β†’ use `useMemo` instead of duplicating state.
129+
130+
---
131+
132+
## πŸ† Next Steps
133+
134+
1. Open [`UseState.tsx`](./UseState.tsx).
135+
2. Uncomment examples one by one to practice.
136+
3. Observe re-renders, console logs, and experiment.
137+
4. Compare your intuition with actual React behavior.
138+
139+
> πŸ’‘ Mastering these patterns will make hooks like `useReducer`, `useEffect`, and `useRef` much easier to learn β€” since they often build on these foundations.

0 commit comments

Comments
Β (0)