Ojasa Mirai

Ojasa Mirai

ReactJS

Loading...

Learning Level

🟢 Beginner🔵 Advanced
💾 Introduction to State⚛️ Using useState Hook🔄 Updating State Correctly🎯 Initial State Values🚫 Common State Mistakes📊 Multiple State Variables🔗 State & Rendering📝 Forms with State🏗️ State Structure Best Practices
Reactjs/State/Interactive Components

🎮 Building Interactive Components — Making Apps Responsive

Combine state and events to create components that respond to user actions like clicks, typing, hovering, and more.


🎯 Responding to User Actions

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>

💡 Building a Real Component: Todo App

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>

🔧 Common Interactive Patterns

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>

📊 Summary

PatternPurpose
ToggleShow/hide elements with boolean state
CounterTrack clicks or events with number state
FormCapture user input with string state
ListAdd/remove items with array state
ConditionalShow different content based on state

🔑 Key Takeaways

  • ✅ State changes trigger re-renders
  • ✅ Event handlers update state
  • ✅ UI always reflects current state
  • ✅ Combine multiple state variables for complex interactions
  • ✅ Use callbacks to handle user actions
  • ✅ Build interactive features by chaining state updates

Ready to practice? Challenges | View Quiz


Resources

Python Docs

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

Courses

PythonFastapiReactJSCloud

© 2026 Ojasa Mirai. All rights reserved.

TwitterGitHubLinkedIn