React Best Practices
Guidelines for React code style and common pitfalls to avoid
React Best Practices
This document outlines the best practices to follow when developing React components for VidsGenius.
Code Style
JSX Quotes and Entities
IMPORTANT: Unescaped entities cause deployment errors even though they may work in local development. Always escape the following characters:
- Use proper JSX entity references for special characters:
- For apostrophes: Use
'or'(preferred in JSX) instead of'- Example:
It'sorIt'sinstead ofIt's
- Example:
- For quotes: Use
"or"instead of"- Example:
The "example"instead ofThe "example"
- Example:
- For ampersands: Use
&instead of&- Example:
Standard & Poorinstead ofStandard & Poor
- Example:
- For apostrophes: Use
This prevents React's no-unescaped-entities errors during build and deployment.
-
Examples:
// Good: <p>Don't forget to check the "terms" section</p> // Avoid: <p>Don't forget to check the "terms" section</p> -
Why this matters:
- Improves code consistency
- Prevents potential rendering issues in some browsers
- Makes code more compatible with JSX parsing tools
- Helps with internationalization and localization
Component Organization
-
Use the "use client" directive:
- Add
"use client";at the top of any component file that uses React hooks - This is required for Next.js Client Components
- Add
-
Prefer functional components over class components:
// Good: function MyComponent({ prop1, prop2 }) { return <div>{prop1}</div>; } // Avoid: class MyComponent extends React.Component { render() { return <div>{this.props.prop1}</div>; } } -
Use named exports for components:
// Good: export function MyComponent() {...} // Avoid: export default function() {...}
State Management
-
Use React hooks appropriately:
useStatefor component-local stateuseReducerfor complex state logicuseContextfor global state accessed by many componentsuseMemoanduseCallbackfor performance optimization (only when needed)
-
Keep state as local as possible:
- Don't lift state higher than necessary
- Use composition to pass state down when needed
Performance Optimization
-
Avoid unnecessary renders:
- Use memoization (
React.memo,useMemo,useCallback) for expensive computations - Avoid creating new objects or functions in render
- Use memoization (
-
Use proper keys for lists:
// Good: {items.map(item => <ListItem key={item.id} {...item} />)} // Avoid: {items.map((item, index) => <ListItem key={index} {...item} />)} // Only use index as last resort
Testing
-
Write unit tests for components:
- Test component rendering
- Test user interactions
- Test edge cases and error states
-
Use React Testing Library for component tests:
- Focus on user interaction rather than implementation details
- Test what the user sees and can do
Documentation
-
Add comments for complex logic:
- Explain "why" rather than "what"
- Document any non-obvious behavior
-
Use JSDoc for component props:
/** * Button component with various styles * * @param {Object} props - Component props * @param {string} props.variant - Button style variant * @param {ReactNode} props.children - Button content * @param {function} props.onClick - Click handler */ export function Button({ variant, children, onClick }) { // ... }
By following these practices, we can maintain a consistent, high-quality codebase that is easier to maintain and extend.