阿里云主机折上折
  • 微信号
Current Site:Index > Event Handling Specification

Event Handling Specification

Author:Chuan Chen 阅读数:23289人阅读 分类: 前端综合

Component development specifications and event handling specifications are important parts of front-end engineering. Reasonable specifications can improve code maintainability and team collaboration efficiency. Below is a detailed explanation from two aspects: component development and event handling.

Component Development Specifications

Component Naming Convention

Component names should use PascalCase and match the file name. Avoid abbreviations for multi-word combinations to maintain semantic integrity.

// Good  
UserProfileCard.jsx  
OrderStatusBadge.jsx  

// Bad  
userProfile.jsx  // Not PascalCase  
usrPrfCard.jsx   // Abbreviations not recommended  

Directory Structure

Component-related files should be placed in the components directory, with complex components having their own folders:

src/  
  components/  
    Button/  
      index.jsx  
      style.module.css  
      Button.test.js  
    Form/  
      Input/  
        index.jsx  
        InputItem.jsx  

Props Type Definition

Props types must be explicitly defined using TypeScript or PropTypes:

interface ButtonProps {  
  size?: 'small' | 'medium' | 'large';  
  variant?: 'primary' | 'secondary';  
  disabled?: boolean;  
  onClick?: (event: React.MouseEvent) => void;  
}  

const Button: React.FC<ButtonProps> = ({   
  size = 'medium',  
  variant = 'primary',  
  ...props  
}) => {  
  /* ... */  
}  

Style Management

CSS Modules or styled-components are recommended:

// CSS Modules example  
import styles from './Button.module.css';  

const Button = () => (  
  <button className={`${styles.btn} ${styles.primary}`}>  
    Click  
  </button>  
);  

// styled-components example  
const StyledButton = styled.button`  
  padding: ${props => props.size === 'large' ? '12px 24px' : '8px 16px'};  
  background: ${props => props.theme.primary};  
`;  

Event Handling Specifications

Naming Convention

Event handler functions should start with the handle prefix, and callback props should start with the on prefix:

const handleClick = (e) => {  
  console.log('Button clicked', e.target);  
};  

<Button onClick={handleClick} />  

// Exposing events inside components  
function Modal({ onClose }) {  
  const handleClose = () => {  
    // Cleanup logic...  
    onClose?.();  
  };  
}  

Event Object Handling

Always consider event delegation and preventing default behavior:

// List item click event delegation  
function List({ items }) {  
  const handleClick = (e) => {  
    const itemId = e.target.dataset.id;  
    if (itemId) {  
      // Handle specific item click  
    }  
  };  

  return (  
    <ul onClick={handleClick}>  
      {items.map(item => (  
        <li key={item.id} data-id={item.id}>{item.text}</li>  
      ))}  
    </ul>  
  );  
}  

// Form submission  
const handleSubmit = (e) => {  
  e.preventDefault();  
  // Validate and process data  
};  

Asynchronous Event Handling

Loading states and error catching must be handled:

function AsyncButton() {  
  const [loading, setLoading] = useState(false);  

  const handleClick = async () => {  
    try {  
      setLoading(true);  
      await fetchData();  
    } catch (error) {  
      console.error('Fetch failed:', error);  
    } finally {  
      setLoading(false);  
    }  
  };  

  return <button onClick={handleClick} disabled={loading} />;  
}  

Custom Events

Complex components should define detailed event contracts:

// Type definition  
type CalendarEvent = {  
  date: Date;  
  type: 'select' | 'hover';  
  nativeEvent: React.MouseEvent;  
};  

interface CalendarProps {  
  onDateChange?: (event: CalendarEvent) => void;  
}  

// Event triggering  
const emitDateChange = (date: Date, type: CalendarEvent['type'], e: React.MouseEvent) => {  
  onDateChange?.({  
    date,  
    type,  
    nativeEvent: e  
  });  
};  

Performance Optimization

Event Throttling and Debouncing

High-frequency events require performance optimization:

import { throttle, debounce } from 'lodash-es';  

// Throttle scroll events  
const handleScroll = throttle((e) => {  
  console.log('Scrolling', e.target.scrollTop);  
}, 200);  

// Debounce search input  
const handleSearch = debounce((keyword) => {  
  searchAPI(keyword);  
}, 500);  

Event Listener Cleanup

Global event listeners must be removed when the component unmounts:

useEffect(() => {  
  const handleKeyDown = (e) => {  
    if (e.key === 'Escape') handleClose();  
  };  

  window.addEventListener('keydown', handleKeyDown);  
  return () => {  
    window.removeEventListener('keydown', handleKeyDown);  
  };  
}, []);  

Accessibility Standards

Keyboard Events

Keyboard operations must be supported:

<div   
  role="button"  
  tabIndex={0}  
  onClick={handleClick}  
  onKeyDown={(e) => {  
    if (e.key === 'Enter' || e.key === ' ') {  
      handleClick();  
    }  
  }}  
>  
  Clickable element  
</div>  

ARIA Attributes

Complex components should include ARIA attributes:

<div  
  role="dialog"  
  aria-labelledby="dialog-title"  
  aria-modal="true"  
>  
  <h2 id="dialog-title">Prompt</h2>  
  {/* Dialog content */}  
</div>  

Testing Standards

Event Test Cases

Use Testing Library to write event tests:

import { render, fireEvent } from '@testing-library/react';  

test('should trigger onClick', () => {  
  const handleClick = jest.fn();  
  const { getByText } = render(<Button onClick={handleClick} />);  

  fireEvent.click(getByText('Submit'));  
  expect(handleClick).toHaveBeenCalledTimes(1);  
});  

// Simulate keyboard events  
test('should handle keyboard event', () => {  
  const { getByRole } = render(<SearchBox />);  
  const input = getByRole('searchbox');  

  fireEvent.keyDown(input, { key: 'Enter', code: 'Enter' });  
  // Verify search logic  
});  

Documentation Standards

Component Documentation

Use Storybook or JSDoc to document component events:

/**  
 * Generic button component  
 *   
 * @param {Object} props - Component props  
 * @param {'small'|'medium'|'large'} [props.size=medium] - Button size  
 * @param {Function} props.onClick - Click event callback  
 */  
export function Button({ size = 'medium', onClick }) {  
  // ...  
}  

Event Flow Diagram

For complex interactions, it is recommended to draw an event flow diagram:

User click → Triggers handleClick → Validates data → Calls onSubmit → Initiates API request  
          ↑               ↓  
          Error feedback ← Request fails  

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

上一篇:状态管理规范

下一篇:样式隔离方案

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.