React
Event Handling
Build interactive DataFlow dashboard components that respond to user clicks, form inputs, and keyboard events using React's synthetic event system.
React events work differently from regular JavaScript events. Think of them as React's translation layer between your code and the browser. Instead ofaddEventListener, you pass functions directly to JSX elements.
Regular HTML gives you onclick attributes with strings. React gives you onClick props with actual functions. The capital letters matter here — React uses camelCase naming for all event handlers.
The onClick Handler
Your first React event handler handles clicks. The DataFlow team needs a button that shows current revenue when clicked. Here's how it works:function RevenueButton() {
const showRevenue = () => {
alert('Current revenue: $847,293');
};
return (
<button onClick={showRevenue}>
Show Revenue
</button>
);
}What just happened?
React called your showRevenue function when the button was clicked. The function name goes in curly braces without parentheses — onClick={showRevenue} not onClick={showRevenue()}. Try this: add console.log inside the function to see when it runs.
Event Objects
Every event handler receives an event object. This object contains details about what happened — which key was pressed, where the mouse clicked, what the user typed. React wraps browser events in its own SyntheticEvent system. The DataFlow sidebar needs to highlight the clicked navigation item. Here's how you access event details:function NavItem({ label }) {
const handleClick = (event) => {
console.log('Clicked:', event.target.textContent);
console.log('Element type:', event.target.tagName);
event.target.style.background = '#047857';
event.target.style.color = 'white';
};
return (
<div
onClick={handleClick}
style={{ padding: '12px', cursor: 'pointer', border: '1px solid #e5e7eb', margin: '4px 0' }}
>
{label}
</div>
);
}event.target points to the element that was clicked. You can read its content, change its style, or get any property. This is the same DOM element you'd get with regular JavaScript, just wrapped in React's event system.
But there's a better way than directly manipulating styles. React prefers state changes over direct DOM manipulation.
Events with State
Combining events with state creates truly interactive components. When something happens, you update state. React re-renders with the new data. The DataFlow team needs a stats card that toggles between showing revenue in dollars and percentage growth.import { useState } from 'react';
function StatsCard() {
const [showPercentage, setShowPercentage] = useState(false);
const handleToggle = () => {
setShowPercentage(!showPercentage);
};
return (
<div onClick={handleToggle} style={{
padding: '20px',
border: '1px solid #e5e7eb',
borderRadius: '8px',
cursor: 'pointer',
background: showPercentage ? '#ecfdf5' : '#eff6ff'
}}>
<h3>Revenue</h3>
<p style={{ fontSize: '24px', fontWeight: 'bold' }}>
{showPercentage ? '+23.5%' : '$847,293'}
</p>
<small>Click to toggle view</small>
</div>
);
}What just happened?
Each click calls setShowPercentage(!showPercentage) to flip the boolean. React re-renders the component, changing both the displayed value and background color. Try this: add multiple StatsCard components — each maintains its own state.
Form Events
Forms need different event types. Input fields use onChange, not onClick. The DataFlow team needs a search filter that updates results as users type. Here's how form events work:import { useState } from 'react';
function SearchFilter() {
const [query, setQuery] = useState('');
const [results, setResults] = useState([]);
const handleSearch = (event) => {
const searchTerm = event.target.value;
setQuery(searchTerm);
// Simulate filtering data
const mockData = ['Revenue Report', 'User Analytics', 'Sales Data', 'Growth Metrics'];
const filtered = mockData.filter(item =>
item.toLowerCase().includes(searchTerm.toLowerCase())
);
setResults(filtered);
};
return (
<div>
<input
type="text"
placeholder="Search DataFlow reports..."
value={query}
onChange={handleSearch}
style={{ padding: '8px', width: '250px', border: '1px solid #d1d5db' }}
/>
<ul>
{results.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
</div>
);
}event.target.value gives you the current text. This creates a controlled component — React controls the input value through state.
Notice the value={query} prop. This makes the input a controlled component. The input shows whatever's in state, not what the user typed. When they type, onChange updates state, which updates the input. It's a loop that keeps everything synchronized.
Keyboard Events
Keyboard events let you respond to key presses. The DataFlow team wants users to press Enter to submit forms, or Escape to close modals. React provides onKeyDown, onKeyUp, and onKeyPress events.import { useState } from 'react';
function QuickActions() {
const [message, setMessage] = useState('');
const handleKeyDown = (event) => {
if (event.key === 'Enter') {
setMessage('📊 Generating DataFlow report...');
} else if (event.key === 'Escape') {
setMessage('❌ Action cancelled');
} else if (event.key === 'r' && event.ctrlKey) {
event.preventDefault(); // Stop browser refresh
setMessage('🔄 Refreshing dashboard data...');
}
};
return (
<div>
<div
tabIndex="0"
onKeyDown={handleKeyDown}
style={{
padding: '20px',
border: '2px dashed #d1d5db',
borderRadius: '8px',
outline: 'none',
cursor: 'pointer'
}}
>
Click here, then try:
<br />• Enter key
<br />• Escape key
<br />• Ctrl+R
</div>
{message && (
<p style={{ marginTop: '12px', color: '#047857', fontWeight: 'bold' }}>
{message}
</p>
)}
</div>
);
}event.key tells you which key was pressed. Modifier keys like Ctrl, Shift, and Alt have boolean properties: event.ctrlKey, event.shiftKey, event.altKey.
The tabIndex="0" makes the div focusable so it can receive keyboard events. Without this, keyboard events only work on naturally focusable elements like inputs and buttons.
Passing Data to Event Handlers
Sometimes event handlers need extra data beyond the event object. The DataFlow team has a list of report types, and clicking one should show details for that specific report. Here are two ways to pass data:import { useState } from 'react';
function ReportList() {
const [selectedReport, setSelectedReport] = useState('');
const reports = [
{ id: 1, name: 'Revenue Analysis', type: 'financial' },
{ id: 2, name: 'User Engagement', type: 'analytics' },
{ id: 3, name: 'Sales Pipeline', type: 'sales' }
];
// Method 1: Arrow function in JSX
const handleReportClick1 = (report, event) => {
setSelectedReport(`Selected: ${report.name} (${report.type})`);
};
// Method 2: Closure function
const handleReportClick2 = (report) => {
return (event) => {
setSelectedReport(`Via closure: ${report.name} (${report.type})`);
};
};
return (
<div>
<h3>DataFlow Reports</h3>
{reports.map(report => (
<div key={report.id} style={{ margin: '8px 0' }}>
<button
onClick={(e) => handleReportClick1(report, e)}
style={{ marginRight: '8px', padding: '6px 12px' }}
>
{report.name} (Method 1)
</button>
<button
onClick={handleReportClick2(report)}
style={{ padding: '6px 12px' }}
>
{report.name} (Method 2)
</button>
</div>
))}
{selectedReport && (
<p style={{ marginTop: '16px', color: '#1d4ed8', fontWeight: 'bold' }}>
{selectedReport}
</p>
)}
</div>
);
}Common Mistake
Don't call the function immediately: onClick={handleClick()} runs the function during render, not on click. Use onClick={handleClick} to pass the function reference.
Quiz
1. The DataFlow team needs a button that calls a function named handleSubmit when clicked. Which is the correct syntax?
2. In a DataFlow search input with onChange event handler, how do you get the current text the user typed?
3. The DataFlow team needs to pass a specific reportId to a delete function when a button is clicked. What's the best approach?
Up Next: Conditional Rendering
Show and hide DataFlow dashboard sections based on user permissions, loading states, and dynamic data conditions.