
ReactJS
Combine state and events to create components that respond to user actions like clicks, typing, hovering, and more.
Every interaction should update state, which triggers a re-render. The component's display always reflects its current state.
User actions trigger event handlers. Event handlers update state. State changes cause re-renders. This cycle creates interactivity.
import { useState } from 'react';
function InteractiveButton() {
const [count, setCount] = useState(0);
const [isPressed, setIsPressed] = useState(false);
return (
<button
onMouseDown={() => setIsPressed(true)}
onMouseUp={() => setIsPressed(false)}
onClick={() => setCount(count + 1)}
style={{
background: isPressed ? '#ff0000' : '#0000ff',
}}
>
Click me! ({count})
</button>
);
}<details>
<summary>📚 More Examples</summary>
// Example: Interactive menu
function Menu() {
const [isOpen, setIsOpen] = useState(false);
return (
<div>
<button onClick={() => setIsOpen(!isOpen)}>
{isOpen ? 'Close' : 'Open'} Menu
</button>
{isOpen && (
<ul>
<li>Home</li>
<li>About</li>
<li>Contact</li>
</ul>
)}
</div>
);
}</details>
Here's a complete example that combines state, forms, and lists:
import { useState } from 'react';
function TodoApp() {
const [todos, setTodos] = useState([]);
const [input, setInput] = useState('');
const addTodo = () => {
if (input.trim() === '') return;
setTodos([...todos, { id: Date.now(), text: input, done: false }]);
setInput('');
};
const toggleTodo = (id) => {
setTodos(
todos.map(todo =>
todo.id === id ? { ...todo, done: !todo.done } : todo
)
);
};
const deleteTodo = (id) => {
setTodos(todos.filter(todo => todo.id !== id));
};
const handleKeyPress = (e) => {
if (e.key === 'Enter') addTodo();
};
return (
<div style={{ maxWidth: '400px', margin: '0 auto' }}>
<h1>My Todos</h1>
<div style={{ display: 'flex', gap: '8px', marginBottom: '16px' }}>
<input
value={input}
onChange={(e) => setInput(e.target.value)}
onKeyPress={handleKeyPress}
placeholder="Add a new todo"
/>
<button onClick={addTodo}>Add</button>
</div>
<ul style={{ listStyle: 'none', padding: 0 }}>
{todos.length === 0 ? (
<p>No todos yet. Add one to get started!</p>
) : (
todos.map(todo => (
<li
key={todo.id}
style={{
padding: '12px',
backgroundColor: '#f0f0f0',
marginBottom: '8px',
borderRadius: '4px',
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
}}
>
<label>
<input
type="checkbox"
checked={todo.done}
onChange={() => toggleTodo(todo.id)}
/>
<span
style={{
marginLeft: '8px',
textDecoration: todo.done ? 'line-through' : 'none',
}}
>
{todo.text}
</span>
</label>
<button onClick={() => deleteTodo(todo.id)}>Delete</button>
</li>
))
)}
</ul>
<p style={{ marginTop: '16px', fontSize: '14px', color: '#666' }}>
{todos.length} total, {todos.filter(t => !t.done).length} remaining
</p>
</div>
);
}
export default TodoApp;<details>
<summary>📚 More Examples</summary>
// Example: Color picker
function ColorPicker() {
const [color, setColor] = useState('#ff0000');
const [history, setHistory] = useState(['#ff0000']);
const colors = ['#ff0000', '#00ff00', '#0000ff', '#ffff00'];
const pickColor = (newColor) => {
setColor(newColor);
setHistory([...history, newColor]);
};
return (
<div>
<div style={{ width: '200px', height: '200px', backgroundColor: color }} />
<div style={{ display: 'flex', gap: '8px', marginTop: '16px' }}>
{colors.map(c => (
<button
key={c}
onClick={() => pickColor(c)}
style={{
width: '40px',
height: '40px',
backgroundColor: c,
border: color === c ? '3px solid black' : 'none',
}}
/>
))}
</div>
<p>History: {history.length} colors</p>
</div>
);
}</details>
Learn these common patterns for building interactive features:
// Toggle visibility
const [isVisible, setIsVisible] = useState(false);
<button onClick={() => setIsVisible(!isVisible)}>
{isVisible ? 'Hide' : 'Show'}
</button>
// Counter with limits
const [count, setCount] = useState(0);
const increment = () => count < 10 && setCount(count + 1);
const decrement = () => count > 0 && setCount(count - 1);
// Hover effects
const [isHovered, setIsHovered] = useState(false);
<div
onMouseEnter={() => setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}
style={{ background: isHovered ? 'yellow' : 'white' }}
>
Hover me
</div>| Pattern | Purpose |
|---|---|
| Toggle | Show/hide elements with boolean state |
| Counter | Track clicks or events with number state |
| Form | Capture user input with string state |
| List | Add/remove items with array state |
| Conditional | Show different content based on state |
Ready to practice? Challenges | View Quiz
Resources
Ojasa Mirai
Master AI-powered development skills through structured learning, real projects, and verified credentials. Whether you're upskilling your team or launching your career, we deliver the skills companies actually need.
Learn Deep • Build Real • Verify Skills • Launch Forward