10_Fragments & Event Handling - Maniconserve/React-Wiki GitHub Wiki

Part 1 — Fragments

The Problem

JSX requires every component to return a single root element. The usual fix is to wrap everything in a <div> — but this adds an extra, unnecessary node to the DOM.

// ❌ Two root elements — not allowed
function App() {
  return (
    <h1>Title</h1>
    <p>Paragraph</p>
  );
}

// ✅ Works, but adds an unwanted <div> to the DOM
function App() {
  return (
    <div>
      <h1>Title</h1>
      <p>Paragraph</p>
    </div>
  );
}

If you inspect the browser DOM, you'll see an extra <div> wrapping your content — which can break layouts, especially with flexbox or grid.


The Solution — Fragments

A Fragment groups elements without adding any extra node to the DOM.

Syntax 1 — Full Fragment

import React from 'react';

function App() {
  return (
    <React.Fragment>
      <h1>Title</h1>
      <p>Paragraph</p>
    </React.Fragment>
  );
}

Syntax 2 — Shorthand (most common)

function App() {
  return (
    <>
      <h1>Title</h1>
      <p>Paragraph</p>
    </>
  );
}

Both produce the same output — <h1> and <p> appear directly in the DOM with no wrapper element.


When You MUST Use <React.Fragment> Over <>

The shorthand <> does not support attributes. If you need to pass a key prop (e.g., when rendering a list of fragments), you must use the full syntax.

const items = [
  { id: 1, label: 'Name', value: 'Arjun' },
  { id: 2, label: 'City', value: 'Hyderabad' },
];

function InfoList() {
  return (
    <dl>
      {items.map(item => (
        <React.Fragment key={item.id}>
          <dt>{item.label}</dt>
          <dd>{item.value}</dd>
        </React.Fragment>
      ))}
    </dl>
  );
}

<> cannot take a key prop — use <React.Fragment key={...}> in lists.


Fragment vs <div> — DOM Comparison

// With <div> wrapper
<div>          // ← extra node in DOM
  <h1>Title</h1>
  <p>Paragraph</p>
</div>

// With Fragment
<h1>Title</h1>  //  no wrapper in DOM
<p>Paragraph</p>

Part 2 — Event Handling

React handles events similarly to HTML but with a few differences — event names are camelCase and you pass a function reference, not a string.


Basic Click Event

function Button() {
  function handleClick() {
    alert('Button clicked!');
  }

  return <button onClick={handleClick}>Click Me</button>;
}

Pass the function reference {handleClick} — do NOT call it {handleClick()}.
{handleClick()} runs immediately when the component renders, not when clicked.

// ❌ Wrong — runs on render, not on click
<button onClick={handleClick()}>Click Me</button>

// ✅ Correct — runs on click
<button onClick={handleClick}>Click Me</button>

Inline Arrow Function

Use an inline arrow function when you need to pass arguments to the handler.

function App() {
  function greet(name) {
    alert(`Hello, ${name}!`);
  }

  return <button onClick={() => greet('Arjun')}>Greet</button>;
}

The Event Object

React automatically passes an event object to your handler. It contains details about the event — which key was pressed, what element was clicked, the input value, and so on.

function App() {
  function handleClick(event) {
    console.log(event.type);   // "click"
    console.log(event.target); // the button element
  }

  return <button onClick={handleClick}>Click Me</button>;
}

Common Events

onClick — Button / any element

function Counter() {
  function handleClick() {
    console.log('clicked');
  }

  return <button onClick={handleClick}>Click</button>;
}

onChange — Input, Select, Textarea

Fires every time the value changes. Use event.target.value to read the current value.

function Form() {
  function handleChange(event) {
    console.log(event.target.value); // what user typed
  }

  return <input type="text" onChange={handleChange} placeholder="Type here" />;
}

onSubmit — Form

Always call event.preventDefault() to stop the page from refreshing on submit.

function LoginForm() {
  function handleSubmit(event) {
    event.preventDefault(); // prevents page reload
    console.log('Form submitted');
  }

  return (
    <form onSubmit={handleSubmit}>
      <input type="text" placeholder="Username" />
      <button type="submit">Login</button>
    </form>
  );
}

onMouseEnter / onMouseLeave — Hover

function HoverBox() {
  return (
    <div
      onMouseEnter={() => console.log('Mouse entered')}
      onMouseLeave={() => console.log('Mouse left')}
      style={{ padding: '20px', background: '#eee' }}
    >
      Hover over me
    </div>
  );
}

onKeyDown — Keyboard

function SearchBox() {
  function handleKeyDown(event) {
    if (event.key === 'Enter') {
      console.log('Searching for:', event.target.value);
    }
  }

  return <input type="text" onKeyDown={handleKeyDown} placeholder="Search..." />;
}

Event Handler as a Prop (passing down to child)

You can pass event handlers from a parent to a child component as props.

// Child component
function Button({ onPress, label }) {
  return <button onClick={onPress}>{label}</button>;
}

// Parent component
function App() {
  function handlePress() {
    alert('Parent handled the click!');
  }

  return <Button onPress={handlePress} label="Click Me" />;
}

Common Events — Quick Reference

Event Trigger Common Use
onClick Mouse click Buttons, links, cards
onChange Value changes Inputs, selects, textareas
onSubmit Form submitted Login, search, contact forms
onMouseEnter Mouse enters element Hover effects
onMouseLeave Mouse leaves element Hover effects
onKeyDown Key pressed down Shortcuts, Enter to submit
onKeyUp Key released Live search
onFocus Element focused Input highlights
onBlur Element loses focus Validation on leave
onDoubleClick Double click Edit mode toggle

Quick Reference

Topic Syntax
Fragment shorthand <> ... </>
Fragment with key <React.Fragment key={id}> ... </React.Fragment>
Click handler <button onClick={handleClick}>
Inline with argument <button onClick={() => fn(arg)}>
Event object function handle(event) { event.target... }
Prevent default event.preventDefault()
Pass handler as prop <Child onPress={handleClick} />

⚠️ **GitHub.com Fallback** ⚠️