React Problem Solution Code
Levels 1 & 2: Problems 1–10
These cover the basic syntax of useState, useEffect, and useRef.
1. The Simple Counter
JavaScript
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
<button onClick={() => count > 0 && setCount(count -
1)}>Decrement</button>
</div>
);
}
2. The Input Mirror
JavaScript
function InputMirror() {
const [text, setText] = useState("");
return (
<div>
<input type="text" onChange={(e) => setText([Link])} />
<h1>{text}</h1>
</div>
);
}
3. Visibility Toggle
JavaScript
function Toggle() {
const [isVisible, setIsVisible] = useState(true);
return (
<div>
<button onClick={() => setIsVisible(!isVisible)}>Show/Hide</button>
{isVisible && <p>Now you see me!</p>}
</div>
);
}
4. Background Switcher
JavaScript
function ColorSwitcher() {
const [color, setColor] = useState("white");
return (
<div style={{ backgroundColor: color, height: "100vh" }}>
<button onClick={() => setColor("blue")}>Blue</button>
<button onClick={() => setColor("red")}>Red</button>
</div>
);
}
5. Auto-Focus Input
JavaScript
function AutoFocus() {
const inputRef = useRef(null);
useEffect(() => {
[Link]();
}, []); // Empty array means this runs once on mount
return <input ref={inputRef} placeholder="I focus on load" />;
}
6. Document Title Sync
JavaScript
function TitleSync() {
const [count, setCount] = useState(0);
useEffect(() => {
[Link] = `Count: ${count}`;
}, [count]); // Only runs when count changes
return <button onClick={() => setCount(count + 1)}>Update Title</button>;
}
7. The Live Clock
JavaScript
function Clock() {
const [time, setTime] = useState(new Date().toLocaleTimeString());
useEffect(() => {
const timer = setInterval(() => {
setTime(new Date().toLocaleTimeString());
}, 1000);
return () => clearInterval(timer); // Cleanup is vital!
}, []);
return <h2>{time}</h2>;
}
8. Window Width Tracker
JavaScript
function WindowWidth() {
const [width, setWidth] = useState([Link]);
useEffect(() => {
const handleResize = () => setWidth([Link]);
[Link]("resize", handleResize);
return () => [Link]("resize", handleResize);
}, []);
return <p>Window Width: {width}px</p>;
}
9. The Persistent Name
JavaScript
function PersistentName() {
const [name, setName] = useState(() => [Link]("name") ||
"");
useEffect(() => {
[Link]("name", name);
}, [name]);
return <input value={name} onChange={(e) => setName([Link])}
/>;
}
10. Click Counter (No Render)
JavaScript
function RefCounter() {
const clickCount = useRef(0);
const handleTap = () => { [Link]++; };
const showTotal = () => { alert(`Total clicks: ${[Link]}`); };
return (
<div>
<button onClick={handleTap}>Tap (No UI update)</button>
<button onClick={showTotal}>Show Total</button>
</div>
);
}
Moving into Level 3 & 4 (Problems 11–20), the complexity increases.
We are now focusing on Immutability (never modifying state directly)
and managing more complex data like arrays and API responses.
Levels 3 & 4: Problems 11–20
11. The Simple Todo List
JavaScript
function TodoList() {
const [todos, setTodos] = useState([]);
const [input, setInput] = useState("");
const addTodo = () => {
if (input) {
setTodos([...todos, { id: [Link](), text: input }]); // Spread
operator
setInput("");
};
return (
<div>
<input value={input} onChange={(e) => setInput([Link])} />
<button onClick={addTodo}>Add</button>
<ul>{[Link](t => <li key={[Link]}>{[Link]}</li>)}</ul>
</div>
);
12. Item Deleter
JavaScript
// Use the todos from #11
const deleteTodo = (id) => {
setTodos([Link](todo => [Link] !== id)); // Filter creates a new
array
};
13. The Checklist (Updating Objects in Arrays)
JavaScript
function Checklist() {
const [items, setItems] = useState([{ id: 1, text: "Buy Milk", done:
false }]);
const toggleDone = (id) => {
setItems([Link](item =>
[Link] === id ? { ...item, done: ![Link] } : item
));
};
return (
<ul>
{[Link](item => (
<li key={[Link]} onClick={() => toggleDone([Link])}
style={{ textDecoration: [Link] ? 'line-through' : 'none' }}>
{[Link]}
</li>
))}
</ul>
);
14. Multi-Input Form (Single Object)
JavaScript
function MultiForm() {
const [form, setForm] = useState({ firstName: "", lastName: "", email:
"" });
const handleChange = (e) => {
setForm({ ...form, [[Link]]: [Link] });
};
return (
<form>
<input name="firstName" onChange={handleChange}
placeholder="First Name" />
<input name="lastName" onChange={handleChange}
placeholder="Last Name" />
<p>{[Link]} {[Link]}</p>
</form>
);
15. Search Filter
JavaScript
function SearchFilter() {
const names = ["Alice", "Bob", "Charlie", "David"];
const [query, setQuery] = useState("");
const [filtered, setFiltered] = useState(names);
useEffect(() => {
setFiltered([Link](n =>
[Link]().includes([Link]())));
}, [query]);
return (
<div>
<input onChange={(e) => setQuery([Link])}
placeholder="Search..." />
{[Link](n => <p key={n}>{n}</p>)}
</div>
);
16. The "Previous" State
JavaScript
function PrevState() {
const [count, setCount] = useState(0);
const prevCountRef = useRef();
useEffect(() => {
[Link] = count; // Updates AFTER render
}, [count]);
return (
<h1>Now: {count}, Before: {[Link]}</h1>
);
17. API Data Fetcher
JavaScript
function Fetcher() {
const [posts, setPosts] = useState([]);
useEffect(() => {
fetch('[Link]
.then(res => [Link]())
.then(data => setPosts([Link](0, 5)));
}, []);
return <ul>{[Link](p => <li key={[Link]}>{[Link]}</li>)}</ul>;
18. Loading & Error States
JavaScript
function SafeFetcher() {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
fetch('[Link]
.then(res => [Link]())
.then(setData)
.catch(setError)
.finally(() => setLoading(false));
}, []);
if (loading) return <p>Loading...</p>;
if (error) return <p>Error!</p>;
return <div>{[Link](data)}</div>;
19. The Debounced Input
JavaScript
function Debounce() {
const [val, setVal] = useState("");
useEffect(() => {
const handler = setTimeout(() => [Link]("Searching for:", val),
500);
return () => clearTimeout(handler); // Clear if user types again within
500ms
}, [val]);
return <input onChange={(e) => setVal([Link])} />;
20. Video Player Controller
JavaScript
function VideoPlayer() {
const videoRef = useRef(null);
return (
<div>
<video ref={videoRef} width="250" src="sample.mp4" />
<button onClick={() => [Link]()}>Play</button>
<button onClick={() => [Link]()}>Pause</button>
</div>
);
Moving into Level 5 & 6 (Problems 21–30), we are getting into more
sophisticated territory. These solutions deal with timing, external browser
APIs, and using useRef as a "storage" that doesn't trigger renders.
Levels 5 & 6: Problems 21–30
21. The Countdown Timer
JavaScript
function Countdown() {
const [seconds, setSeconds] = useState(60);
const [isActive, setIsActive] = useState(false);
useEffect(() => {
let interval = null;
if (isActive && seconds > 0) {
interval = setInterval(() => setSeconds(s => s - 1), 1000);
return () => clearInterval(interval);
}, [isActive, seconds]);
return (
<div>
<h1>{seconds}</h1>
<button onClick={() => setIsActive(true)}
disabled={isActive}>Start</button>
</div>
);
22. Syncing Tabs (Storage Event)
JavaScript
function TabSync() {
const [msg, setMsg] = useState("");
useEffect(() => {
const handleStorage = (e) => {
if ([Link] === "sync-msg") setMsg([Link]);
};
[Link]("storage", handleStorage);
return () => [Link]("storage", handleStorage);
}, []);
const update = (val) => {
setMsg(val);
[Link]("sync-msg", val);
};
return <input value={msg} onChange={(e) => update([Link])} />;
23. Click Outside to Close
JavaScript
function Dropdown() {
const [isOpen, setIsOpen] = useState(false);
const menuRef = useRef();
useEffect(() => {
const closeMenu = (e) => {
if ([Link] && )
setIsOpen(false);
};
[Link]("mousedown", closeMenu);
return () => [Link]("mousedown", closeMenu);
}, []);
return (
<div ref={menuRef}>
<button onClick={() => setIsOpen(!isOpen)}>Toggle Menu</button>
{isOpen && <ul><li>Option 1</li><li>Option 2</li></ul>}
</div>
);
24. The Character Limit
JavaScript
function TweetBox() {
const [text, setText] = useState("");
const limit = 280;
const isOver = [Link] > limit;
return (
<div>
<textarea value={text} onChange={(e) => setText([Link])} />
<p style={{ color: isOver ? 'red' : 'black' }}>
{limit - [Link]} characters left
</p>
</div>
);
25. The Fetch "Abort"
JavaScript
useEffect(() => {
const controller = new AbortController();
fetch(url, { signal: [Link] })
.then(res => [Link]())
.then(setData)
.catch(err => { if ([Link] !== 'AbortError') [Link](err); });
return () => [Link](); // Cleanup cancels the fetch
}, [url]);
26. The Scroll-to-Bottom
JavaScript
function Chat() {
const [messages, setMessages] = useState(["Hi!"]);
const endRef = useRef(null);
useEffect(() => {
[Link]?.scrollIntoView({ behavior: "smooth" });
}, [messages]);
return (
<div style={{ height: '200px', overflowY: 'scroll' }}>
{[Link]((m, i) => <p key={i}>{m}</p>)}
<div ref={endRef} />
</div>
);
}
27. The "Is First Render" Flag
JavaScript
function OnlyUpdate() {
const [count, setCount] = useState(0);
const isFirstRender = useRef(true);
useEffect(() => {
if ([Link]) {
[Link] = false;
return;
[Link]("Effect ran on update, not mount!");
}, [count]);
return <button onClick={() => setCount(c => c + 1)}>Increment</button>;
28. The Interval Stop/Start (Ref for ID)
JavaScript
function Stopwatch() {
const [time, setTime] = useState(0);
const timerRef = useRef(null);
const start = () => {
if ([Link]) return;
[Link] = setInterval(() => setTime(t => t + 1), 100);
};
const stop = () => {
clearInterval([Link]);
[Link] = null;
};
return (
<div>
<h1>{time}</h1>
<button onClick={start}>Start</button>
<button onClick={stop}>Stop</button>
</div>
);
}
29. Form Validation Trigger (On Blur)
JavaScript
function ValidateBlur() {
const [email, setEmail] = useState("");
const [error, setError] = useState("");
const touched = useRef(false);
const validate = (val) => {
if () setError("Invalid email");
else setError("");
};
return (
<input
value={email}
onChange={(e) => {
setEmail([Link]);
if ([Link]) validate([Link]);
}}
onBlur={() => {
[Link] = true;
validate(email);
}}
/>
);
30. Image Lazy Loader
JavaScript
function LazyImage({ src }) {
const [visible, setVisible] = useState(false);
const imgRef = useRef();
useEffect(() => {
const observer = new IntersectionObserver(([entry]) => {
if ([Link]) setVisible(true);
});
[Link]([Link]);
return () => [Link]();
}, []);
return <div ref={imgRef}>{visible ? <img src={src} /> : "Loading..."}</div>;
Now we move into Level 7 & 8 (Problems 31–40). This is where you
become a truly efficient React developer by learning to abstract logic.
Instead of writing complex useEffect blocks inside your components, you’ll
create reusable tools.
Levels 7 & 8: Problems 31–40 (Custom Hooks)
31. useToggle
JavaScript
function useToggle(initialValue = false) {
const [value, setValue] = useState(initialValue);
const toggle = () => setValue(v => !v);
return [value, toggle];
// Usage
const [isModalOpen, toggleModal] = useToggle();
32. useLocalStorage
JavaScript
function useLocalStorage(key, initialValue) {
const [storedValue, setStoredValue] = useState(() => {
const item = [Link](key);
return item ? [Link](item) : initialValue;
});
const setValue = (value) => {
setStoredValue(value);
[Link](key, [Link](value));
};
return [storedValue, setValue];
33. useFetch
JavaScript
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch(url)
.then(res => [Link]())
.then(d => { setData(d); setLoading(false); });
}, [url]);
return { data, loading };
34. useKeyPress
JavaScript
function useKeyPress(targetKey) {
const [keyPressed, setKeyPressed] = useState(false);
useEffect(() => {
const downHandler = ({ key }) => { if (key === targetKey)
setKeyPressed(true); };
const upHandler = ({ key }) => { if (key === targetKey)
setKeyPressed(false); };
[Link]("keydown", downHandler);
[Link]("keyup", upHandler);
return () => {
[Link]("keydown", downHandler);
[Link]("keyup", upHandler);
};
}, [targetKey]);
return keyPressed;
35. useOnlineStatus
JavaScript
function useOnlineStatus() {
const [isOnline, setIsOnline] = useState([Link]);
useEffect(() => {
const online = () => setIsOnline(true);
const offline = () => setIsOnline(false);
[Link]("online", online);
[Link]("offline", offline);
return () => {
[Link]("online", online);
[Link]("offline", offline);
};
}, []);
return isOnline;
36. The Multi-Step Form
JavaScript
function MultiStep() {
const [step, setStep] = useState(1);
const [formData, setFormData] = useState({ name: "", email: "" });
return (
<div>
{step === 1 && <input onChange={e => setFormData({...formData,
name: [Link]})} />}
{step === 2 && <input onChange={e => setFormData({...formData,
email: [Link]})} />}
<button onClick={() => setStep(s => s - 1)}>Back</button>
<button onClick={() => setStep(s => s + 1)}>Next</button>
</div>
);
}
37. Dependent Selects
JavaScript
function DependentSelects() {
const data = { USA: ["NY", "LA"], Canada: ["Toronto", "Vancouver"] };
const [country, setCountry] = useState("USA");
const [city, setCity] = useState("");
useEffect(() => {
setCity(data[country][0]); // Reset city when country changes
}, [country]);
return (
<select onChange={e => setCountry([Link])}>
{[Link](data).map(c => <option key={c}>{c}</option>)}
</select>
);
38. The "Undo" Feature
JavaScript
function UndoInput() {
const [text, setText] = useState("");
const history = useRef([]);
const handleUpdate = (val) => {
[Link](text);
if ([Link] > 5) [Link]();
setText(val);
};
const undo = () => {
if ([Link] > 0) setText([Link]());
};
return (
<>
<input value={text} onChange={e => handleUpdate([Link])} />
<button onClick={undo}>Undo</button>
</>
);
}
39. Infinite Scroll Trigger
JavaScript
function InfiniteList() {
const observerTarget = useRef(null);
const [page, setPage] = useState(1);
useEffect(() => {
const observer = new IntersectionObserver(entries => {
if (entries[0].isIntersecting) setPage(p => p + 1);
}, { threshold: 1.0 });
if ([Link]) [Link]([Link]);
return () => [Link]();
}, []);
return (
<div>
{/* List items here */}
<div ref={observerTarget} style={{ height: '10px' }}>Loading
more...</div>
</div>
);
40. The Dark Mode Theme
JavaScript
function useTheme() {
const [theme, setTheme] = useState([Link]("theme") ||
"light");
useEffect(() => {
[Link] = theme;
[Link]("theme", theme);
}, [theme]);
const toggleTheme = () => setTheme(t => t === "light" ? "dark" : "light");
return { theme, toggleTheme };
Here are the final 10 problems (Level 9 & 10). These focus on
professional-grade patterns: performance optimization, advanced
browser APIs, and state-logic debugging.
Levels 9 & 10: Problems 41–50 (Mastery)
41. The Mouse Tracker
JavaScript
function MouseTracker() {
const [position, setPosition] = useState({ x: 0, y: 0 });
useEffect(() => {
const handleMove = (e) => setPosition({ x: [Link], y: [Link] });
[Link]("mousemove", handleMove);
return () => [Link]("mousemove", handleMove);
}, []);
return <p>Mouse at: {position.x}, {position.y}</p>;
42. Virtualized List Prep (Height Calculation)
JavaScript
function MeasureContainer() {
const containerRef = useRef();
const [height, setHeight] = useState(0);
useEffect(() => {
if ([Link]) {
setHeight([Link]().height);
}, []);
return <div ref={containerRef} style={{ height: '50vh' }}>Container height:
{height}px</div>;
43. The Throttled Scroll
JavaScript
function ScrollProgress() {
const [scroll, setScroll] = useState(0);
const throttling = useRef(false);
useEffect(() => {
const handleScroll = () => {
if (![Link]) {
[Link] = true;
setTimeout(() => {
const totalHeight = [Link] -
[Link];
setScroll(([Link] / totalHeight) * 100);
[Link] = false;
}, 100); // Only update state every 100ms
};
[Link]("scroll", handleScroll);
return () => [Link]("scroll", handleScroll);
}, []);
return <div style={{ width: `${scroll}%`, height: '5px', background: 'blue',
position: 'fixed' }} />;
44. Memoized Factorial
JavaScript
function FactorialCalculator() {
const [num, setNum] = useState(1);
const [otherState, setOtherState] = useState(false);
// useMemo prevents re-calculation when 'otherState' changes
const result = useMemo(() => {
[Link]("Calculating...");
const fact = (n) => (n <= 1 ? 1 : n * fact(n - 1));
return fact(num);
}, [num]);
return (
<div>
<input type="number" value={num} onChange={e =>
setNum(Number([Link]))} />
<p>Result: {result}</p>
<button onClick={() => setOtherState(!otherState)}>Toggle Other
State</button>
</div>
);
45. The Form "Dirty" State
JavaScript
function UnsavedChanges() {
const [text, setText] = useState("");
const isDirty = useRef(false);
useEffect(() => {
const warning = (e) => {
if ([Link]) [Link]();
};
[Link] = [Link] ? warning : null;
}, [text]);
return <input value={text} onChange={e => { setText([Link]);
[Link] = true; }} />;
46. useMediaQuery
JavaScript
function useMediaQuery(query) {
const [matches, setMatches] =
useState([Link](query).matches);
useEffect(() => {
const media = [Link](query);
const listener = () => setMatches([Link]);
[Link]("change", listener);
return () => [Link]("change", listener);
}, [query]);
return matches;
47. The Search Cache
JavaScript
function CachedSearch() {
const [query, setQuery] = useState("");
const [results, setResults] = useState([]);
const cache = useRef({});
const search = async () => {
if ([Link][query]) {
setResults([Link][query]);
return;
const res = await fetch(`[Link]
const data = await [Link]();
[Link][query] = data; // Store in ref
setResults(data);
};
}
48. useWhyDidYouUpdate (The Debugger)
JavaScript
function useWhyDidYouUpdate(name, props) {
const prevProps = useRef();
useEffect(() => {
if ([Link]) {
const allKeys = [Link]({ ...[Link], ...props });
const changes = {};
[Link](key => {
if ([Link][key] !== props[key]) {
changes[key] = { from: [Link][key], to: props[key] };
});
if ([Link](changes).length) [Link](`[Update in ${name}]`,
changes);
[Link] = props;
});
}
49. The Animation Trigger
JavaScript
function FadeIn() {
const domRef = useRef();
const [isVisible, setVisible] = useState(false);
useEffect(() => {
const observer = new IntersectionObserver(entries => {
[Link](entry => setVisible([Link]));
});
[Link]([Link]);
}, []);
return (
<div ref={domRef} className={`fade-in-section ${isVisible ? 'is-visible' :
''}`}>
I fade in when you see me!
</div>
);
}
50. The "Master" useInterval
JavaScript
function useInterval(callback, delay) {
const savedCallback = useRef();
useEffect(() => {
[Link] = callback;
}, [callback]);
useEffect(() => {
if (delay !== null) {
const id = setInterval(() => [Link](), delay);
return () => clearInterval(id);
}, [delay]);