Falytom logoFALYTOM
Games
ToolsUI ComponentsServicesProductsAbout
menu
  1. Home
  2. /Web Development
  3. /React
  4. /Handling Events
Your Progress0%
0 of 42 completed

React Topics

Getting Started

  • What is React?
  • React vs Vanilla JavaScript
  • Setting Up Your Environment
  • Your First React App

JSX Fundamentals

  • Introduction to JSX
  • JSX Expressions and Variables
  • Conditional Rendering
  • Lists and Keys
  • Styling in JSX

Components Basics

  • Function Components
  • Props
  • Children Prop
  • Props Destructuring
  • Component Composition

State Management

  • Introduction to State
  • useState Hook
  • State Updates and Re-renders
  • Multiple State Variables
  • State Best Practices

Events and Interactivity

  • Handling Events
  • Event Objects
  • Forms in React
  • Form Validation

Side Effects and Data

  • Introduction to useEffect
  • Data Fetching
  • Cleanup Functions
  • Dependency Arrays

Advanced Hooks

  • useRef Hook
  • useContext Hook
  • useMemo Hook
  • useCallback Hook

React Patterns

  • Custom Hooks
  • Higher-Order Components
  • Render Props Pattern

React Router

  • Introduction to React Router
  • Routes and Navigation
  • Dynamic Routes and Parameters

Best Practices

  • Component Organization
  • Performance Optimization
  • Error Handling
  • Testing React Components

Real World Project

  • Building a Complete App

Handling Events

Responding to user interactions

You've learned about components, props, and state. Now it's time to make your applications truly interactive! Events are how users interact with your app - clicking buttons, typing in inputs, submitting forms, and more. In this lesson, you'll learn how to handle events in React, the differences from HTML events, and the most common event types you'll use every day.

React Events vs HTML Events

React events look similar to HTML events, but with some important differences:

react-vs-html.jsx
// HTML - lowercase, string
<button onclick="handleClick()">Click Me</button>

// React - camelCase, function reference
<button onClick={handleClick}>Click Me</button>

// Key differences:
// 1. React uses camelCase (onClick, not onclick)
// 2. React passes function reference (onClick={handleClick}, not "handleClick()")
// 3. React events are synthetic (cross-browser compatible)
// 4. You can't return false to prevent default (must use preventDefault)

React Event Naming:

  • Always camelCase: onClick, onChange, onSubmit
  • Not lowercase like HTML: ❌ onclick, ❌ onchange
  • Pass function reference: onClick={handleClick}
  • Not a string: ❌ onClick="handleClick()"

onClick - Button Clicks

The most common event you'll use is onClick for handling button clicks:

Basic onClick Handler

onclick-basic.jsx
function Button() {
  // Define handler function
  const handleClick = () => {
    alert('Button clicked!')
  }
  
  return (
    <button onClick={handleClick}>
      Click Me
    </button>
  )
}

// When user clicks the button, handleClick runs

Inline Handler

onclick-inline.jsx
function Button() {
  return (
    <button onClick={() => alert('Clicked!')}>
      Click Me
    </button>
  )
}

// Inline arrow function - useful for simple actions
// But prefer separate functions for complex logic

Handler with State

onclick-state.jsx
function Counter() {
  const [count, setCount] = React.useState(0)
  
  const handleIncrement = () => {
    setCount(count + 1)
  }
  
  const handleDecrement = () => {
    setCount(count - 1)
  }
  
  const handleReset = () => {
    setCount(0)
  }
  
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={handleIncrement}>+</button>
      <button onClick={handleDecrement}>-</button>
      <button onClick={handleReset}>Reset</button>
    </div>
  )
}

⚠️ Common onClick Mistake

❌ Wrong: onClick={handleClick()}
This calls the function immediately during render!

✅ Correct: onClick={handleClick}
This passes the function to be called on click

✅ Also correct: onClick={() => handleClick()}
Wrap in arrow function if you need to pass arguments

onChange - Input Changes

Use onChange to respond to input field changes:

Text Input

onchange-text.jsx
function NameInput() {
  const [name, setName] = React.useState('')
  
  const handleChange = (event) => {
    setName(event.target.value)  // Get the input value
  }
  
  return (
    <div>
      <input
        type="text"
        value={name}
        onChange={handleChange}
        placeholder="Enter your name"
      />
      <p>Hello, {name || 'stranger'}!</p>
    </div>
  )
}

// event.target.value contains the current input value

Inline onChange

onchange-inline.jsx
function SearchBox() {
  const [query, setQuery] = React.useState('')
  
  return (
    <input
      type="text"
      value={query}
      onChange={(e) => setQuery(e.target.value)}
      placeholder="Search..."
    />
  )
}

// Inline is fine for simple value updates
// 'e' is short for 'event' - commonly used

Checkbox

onchange-checkbox.jsx
function ToggleSwitch() {
  const [isChecked, setIsChecked] = React.useState(false)
  
  const handleChange = (event) => {
    setIsChecked(event.target.checked)  // Use .checked, not .value!
  }
  
  return (
    <label>
      <input
        type="checkbox"
        checked={isChecked}
        onChange={handleChange}
      />
      {isChecked ? 'Enabled' : 'Disabled'}
    </label>
  )
}

Select Dropdown

onchange-select.jsx
function ColorPicker() {
  const [color, setColor] = React.useState('red')
  
  return (
    <div>
      <select value={color} onChange={(e) => setColor(e.target.value)}>
        <option value="red">Red</option>
        <option value="blue">Blue</option>
        <option value="green">Green</option>
      </select>
      <p>Selected color: {color}</p>
    </div>
  )
}

Textarea

onchange-textarea.jsx
function MessageBox() {
  const [message, setMessage] = React.useState('')
  
  return (
    <div>
      <textarea
        value={message}
        onChange={(e) => setMessage(e.target.value)}
        placeholder="Enter your message..."
        rows={4}
      />
      <p>Character count: {message.length}</p>
    </div>
  )
}

onSubmit - Form Submission

Handle form submissions with onSubmit:

onsubmit.jsx
function LoginForm() {
  const [email, setEmail] = React.useState('')
  const [password, setPassword] = React.useState('')
  
  const handleSubmit = (event) => {
    event.preventDefault()  // Prevent page reload!
    
    console.log('Submitted:', { email, password })
    // Here you would send data to server
  }
  
  return (
    <form onSubmit={handleSubmit}>
      <input
        type="email"
        value={email}
        onChange={(e) => setEmail(e.target.value)}
        placeholder="Email"
      />
      <input
        type="password"
        value={password}
        onChange={(e) => setPassword(e.target.value)}
        placeholder="Password"
      />
      <button type="submit">Login</button>
    </form>
  )
}

// IMPORTANT: Always use event.preventDefault() in onSubmit
// to prevent the default form submission behavior (page reload)

Form Submission - Don't Forget preventDefault!

Without event.preventDefault(), the form will submit traditionally (page will reload). This is almost never what you want in a React app. Always call event.preventDefault() at the start of your onSubmit handler.

Other Common Events

Mouse Events

mouse-events.jsx
function MouseEvents() {
  const [status, setStatus] = React.useState('Idle')
  
  return (
    <div>
      <button
        onClick={() => setStatus('Clicked')}
        onDoubleClick={() => setStatus('Double-clicked')}
        onMouseEnter={() => setStatus('Mouse entered')}
        onMouseLeave={() => setStatus('Mouse left')}
        onMouseDown={() => setStatus('Mouse down')}
        onMouseUp={() => setStatus('Mouse up')}
      >
        Hover or click me
      </button>
      <p>Status: {status}</p>
    </div>
  )
}

// Common mouse events:
// onClick - single click
// onDoubleClick - double click
// onMouseEnter - mouse enters element
// onMouseLeave - mouse leaves element
// onMouseDown - mouse button pressed
// onMouseUp - mouse button released
// onMouseMove - mouse moves over element

Keyboard Events

keyboard-events.jsx
function KeyboardEvents() {
  const [key, setKey] = React.useState('')
  
  const handleKeyDown = (event) => {
    setKey(`Key pressed: ${event.key}`)
  }
  
  const handleKeyPress = (event) => {
    if (event.key === 'Enter') {
      alert('Enter pressed!')
    }
  }
  
  return (
    <div>
      <input
        type="text"
        onKeyDown={handleKeyDown}
        onKeyPress={handleKeyPress}
        placeholder="Type something..."
      />
      <p>{key}</p>
    </div>
  )
}

// Common keyboard events:
// onKeyDown - key is pressed down
// onKeyUp - key is released
// onKeyPress - key press (deprecated, use onKeyDown)

Focus Events

focus-events.jsx
function FocusEvents() {
  const [focused, setFocused] = React.useState(false)
  
  return (
    <div>
      <input
        type="text"
        onFocus={() => setFocused(true)}
        onBlur={() => setFocused(false)}
        placeholder="Click to focus"
      />
      <p>{focused ? 'Input is focused' : 'Input is not focused'}</p>
    </div>
  )
}

// Common focus events:
// onFocus - element gains focus
// onBlur - element loses focus

Scroll Events

scroll-events.jsx
function ScrollTracker() {
  const [scrollTop, setScrollTop] = React.useState(0)
  
  const handleScroll = (event) => {
    setScrollTop(event.target.scrollTop)
  }
  
  return (
    <div
      onScroll={handleScroll}
      style={{ height: '200px', overflow: 'auto' }}
    >
      <div style={{ height: '1000px' }}>
        <p>Scroll position: {scrollTop}px</p>
        <p>Scroll down to see the value change...</p>
      </div>
    </div>
  )
}

Passing Arguments to Handlers

Using Arrow Functions

passing-args-arrow.jsx
function ButtonList() {
  const handleClick = (id) => {
    alert(`Button ${id} clicked`)
  }
  
  return (
    <div>
      <button onClick={() => handleClick(1)}>Button 1</button>
      <button onClick={() => handleClick(2)}>Button 2</button>
      <button onClick={() => handleClick(3)}>Button 3</button>
    </div>
  )
}

// Wrap in arrow function to pass arguments

Using bind (Alternative)

passing-args-bind.jsx
function ButtonList() {
  const handleClick = (id, event) => {
    alert(`Button ${id} clicked`)
  }
  
  return (
    <div>
      <button onClick={handleClick.bind(null, 1)}>Button 1</button>
      <button onClick={handleClick.bind(null, 2)}>Button 2</button>
      <button onClick={handleClick.bind(null, 3)}>Button 3</button>
    </div>
  )
}

// bind creates a new function with preset arguments
// Less common than arrow functions

Passing Data Attributes

passing-data-attrs.jsx
function ProductList() {
  const products = [
    { id: 1, name: 'Laptop' },
    { id: 2, name: 'Mouse' },
    { id: 3, name: 'Keyboard' }
  ]
  
  const handleClick = (event) => {
    const id = event.target.dataset.id
    const name = event.target.dataset.name
    alert(`Clicked: ${name} (ID: ${id})`)
  }
  
  return (
    <div>
      {products.map(product => (
        <button
          key={product.id}
          data-id={product.id}
          data-name={product.name}
          onClick={handleClick}
        >
          {product.name}
        </button>
      ))}
    </div>
  )
}

// Use data-* attributes to store info on elements
// Access via event.target.dataset

Interactive Demo

ReactPlayground.jsx
Code Editor
Preview

💡 Tip: Edit the code above and click "Run" to see your changes

Event Handler Patterns

Pattern 1: Named Handler Functions

pattern-named.jsx
// ✅ Good for complex logic
function Form() {
  const [data, setData] = React.useState({ name: '', email: '' })
  
  const handleNameChange = (event) => {
    setData({ ...data, name: event.target.value })
  }
  
  const handleEmailChange = (event) => {
    setData({ ...data, email: event.target.value })
  }
  
  const handleSubmit = (event) => {
    event.preventDefault()
    console.log('Submitting:', data)
  }
  
  return (
    <form onSubmit={handleSubmit}>
      <input value={data.name} onChange={handleNameChange} />
      <input value={data.email} onChange={handleEmailChange} />
      <button type="submit">Submit</button>
    </form>
  )
}

Pattern 2: Generic Handler

pattern-generic.jsx
// ✅ Good for forms with many fields
function Form() {
  const [data, setData] = React.useState({ name: '', email: '', phone: '' })
  
  const handleChange = (event) => {
    const { name, value } = event.target
    setData({ ...data, [name]: value })
  }
  
  return (
    <form>
      <input name="name" value={data.name} onChange={handleChange} />
      <input name="email" value={data.email} onChange={handleChange} />
      <input name="phone" value={data.phone} onChange={handleChange} />
    </form>
  )
}

// Single handler for all inputs - uses the 'name' attribute

Pattern 3: Inline for Simple Actions

pattern-inline.jsx
// ✅ Good for simple, one-line actions
function Counter() {
  const [count, setCount] = React.useState(0)
  
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>+</button>
      <button onClick={() => setCount(count - 1)}>-</button>
      <button onClick={() => setCount(0)}>Reset</button>
    </div>
  )
}

Common Event Handling Mistakes

1. Calling Function Immediately

mistake-immediate.jsx
// ❌ Wrong - calls function during render
<button onClick={handleClick()}>Click</button>

// ✅ Correct - passes function reference
<button onClick={handleClick}>Click</button>

// ✅ Also correct - arrow function
<button onClick={() => handleClick()}>Click</button>

2. Forgetting preventDefault

mistake-prevent.jsx
// ❌ Wrong - form will reload page
const handleSubmit = (event) => {
  console.log('Submitting...')
  // Page reloads here!
}

// ✅ Correct - prevent default behavior
const handleSubmit = (event) => {
  event.preventDefault()
  console.log('Submitting...')
}

3. Wrong Event Property for Checkboxes

mistake-checkbox.jsx
// ❌ Wrong - checkboxes use .checked, not .value
const handleChange = (event) => {
  setIsChecked(event.target.value)  // This won't work!
}

// ✅ Correct - use .checked for checkboxes
const handleChange = (event) => {
  setIsChecked(event.target.checked)
}

4. Not Using Controlled Components

mistake-uncontrolled.jsx
// ❌ Bad - uncontrolled (input value not in state)
function Form() {
  const handleChange = (event) => {
    console.log(event.target.value)
  }
  
  return <input onChange={handleChange} />
}

// ✅ Good - controlled (value in state)
function Form() {
  const [value, setValue] = React.useState('')
  
  return (
    <input
      value={value}
      onChange={(e) => setValue(e.target.value)}
    />
  )
}

Key Takeaways

  • React events use camelCase: onClick, onChange, onSubmit
  • Pass function reference, not call: onClick={fn}, not onClick={fn()}
  • Use event.target.value for input values
  • Use event.target.checked for checkbox values
  • Always use event.preventDefault() in onSubmit
  • Use inline arrow functions to pass arguments
  • Common events: onClick, onChange, onSubmit, onKeyDown, onFocus, onBlur
  • Event handlers receive the event object as first argument
  • Prefer named functions for complex logic
  • Use inline functions for simple, one-line actions
  • Use generic handlers for forms with many fields
  • Always use controlled components for form inputs

What's Next?

You now know how to handle user interactions in React! You can respond to clicks, input changes, form submissions, and more.

But there's more to learn about events. In the next lesson, you'll dive deeper into event objects:

  • What information is in the event object
  • How to access event properties
  • Using preventDefault and stopPropagation
  • Understanding synthetic events
  • Advanced event handling patterns

Get ready to become an event handling expert! 🎯

Learning how to handle user interactions in React!

Previous
State Best Practices
Next
Event Objects

Never Miss a New React Tutorial

Join 2,000+ developers learning React step-by-step. Get new tutorials, tips, and exclusive resources delivered to your inbox - completely FREE.

You might also like

UI Components

Ready-made components for your projects

Developer Tools

Boost productivity with handy generators

HTML Game

Learn HTML concepts through interactive gameplay

Join Our Web Development Training Program

Master frontend & backend development with hands-on projects.

React Tutorials

0 of 42 completed

Your Progress0%

Topics

Getting Started

  • What is React?
  • React vs Vanilla JavaScript
  • Setting Up Your Environment
  • Your First React App

JSX Fundamentals

  • Introduction to JSX
  • JSX Expressions and Variables
  • Conditional Rendering
  • Lists and Keys
  • Styling in JSX

Components Basics

  • Function Components
  • Props
  • Children Prop
  • Props Destructuring
  • Component Composition

State Management

  • Introduction to State
  • useState Hook
  • State Updates and Re-renders
  • Multiple State Variables
  • State Best Practices

Events and Interactivity

  • Handling Events
  • Event Objects
  • Forms in React
  • Form Validation

Side Effects and Data

  • Introduction to useEffect
  • Data Fetching
  • Cleanup Functions
  • Dependency Arrays

Advanced Hooks

  • useRef Hook
  • useContext Hook
  • useMemo Hook
  • useCallback Hook

React Patterns

  • Custom Hooks
  • Higher-Order Components
  • Render Props Pattern

React Router

  • Introduction to React Router
  • Routes and Navigation
  • Dynamic Routes and Parameters

Best Practices

  • Component Organization
  • Performance Optimization
  • Error Handling
  • Testing React Components

Real World Project

  • Building a Complete App
Falytom logoFALYTOM

Learn technologies like HTML, CSS, JavaScript, React, NodeJS and more through interactive games, tutorials, components and free tools. Transform your businesses with AI chatbots, SEO-optimized websites, and professional development services.

© 2025 Tomilola Group
  • Facebook logo
  • Twitter logo
  • Instagram logo
  • LinkedIn logo
  • GitHub logo
  • YouTube logo