Skip to content

Latest commit

 

History

History
392 lines (305 loc) · 9.22 KB

File metadata and controls

392 lines (305 loc) · 9.22 KB
name react-dev-helper
description This skill assists with React + TypeScript project development by providing project standards, coding guidelines, and common workflows. Use this skill when working on React projects to ensure code quality, maintain consistent style, follow best practices, and execute common development tasks correctly. The skill emphasizes test-first development and ESLint compliance.

React Dev Helper

Overview

Assist with React + TypeScript project development by providing coding standards, development workflows, and best practices. Ensure all code follows project conventions and passes quality checks before committing.

Project Standards

Technology Stack

  • Framework: React with TypeScript
  • Language Features: ES6+ syntax
  • Component Style: Functional components (prefer over class components)
  • Naming Convention: camelCase for variables and functions

Code Quality Requirements

Before any code modification or commit:

  1. ✅ Run tests to ensure existing functionality works
  2. ✅ Check for ESLint errors and warnings
  3. ✅ Verify TypeScript types are correct
  4. ✅ Ensure code follows project style guidelines

Development Workflow

Follow this workflow for all development tasks:

1. Before Starting Development

Run Tests First:

npm test

Verify all existing tests pass before making changes. This establishes a baseline.

Check Current Code Quality:

npm run lint
# or if ESLint is configured separately
npx eslint .

2. During Development

Component Development Guidelines:

  • Use functional components with hooks
  • Extract reusable logic into custom hooks
  • Keep components small and focused (single responsibility)
  • Use TypeScript interfaces for props and state

Example Good Component:

interface ButtonProps {
  label: string;
  onClick: () => void;
  disabled?: boolean;
}

const Button: React.FC<ButtonProps> = ({ label, onClick, disabled = false }) => {
  return (
    <button onClick={onClick} disabled={disabled}>
      {label}
    </button>
  );
};

export default Button;

Naming Conventions:

  • Variables and functions: camelCase
  • Components: PascalCase
  • Constants: UPPER_SNAKE_CASE
  • Private functions: prefix with underscore _privateFunction
  • Boolean variables: prefix with is, has, should (e.g., isLoading, hasError)

Import Organization:

// 1. External libraries
import React, { useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';

// 2. Internal components
import Button from './components/Button';
import Header from './components/Header';

// 3. Utilities and helpers
import { formatDate } from './utils/dateUtils';
import { API_BASE_URL } from './constants';

// 4. Types
import type { User, Post } from './types';

// 5. Styles
import './App.css';

3. Before Committing

Pre-Commit Checklist:

Run this sequence before every commit:

  1. Run all tests:

    npm test

    All tests must pass. If any fail, fix them before proceeding.

  2. Check ESLint:

    npm run lint
    # Fix any errors
    npm run lint -- --fix  # Auto-fix where possible

    No ESLint errors should remain.

  3. Type check:

    npx tsc --noEmit

    Verify no TypeScript errors.

  4. Build verification (optional but recommended):

    npm run build

    Ensure production build succeeds.

Common Commands Reference

Development Commands

Command Purpose When to Use
npm run dev Start development server Beginning development session
npm test Run test suite Before changes, during development, before commit
npm run build Build for production Before deployment, verify build works
npm run lint Check code style Before commit
npm run lint -- --fix Auto-fix lint issues Fix formatting issues
npm install <package> Add new dependency Adding new library
npm install --save-dev <package> Add dev dependency Adding development tool

Testing Commands

# Run all tests
npm test

# Run tests in watch mode
npm test -- --watch

# Run tests with coverage
npm test -- --coverage

# Run specific test file
npm test -- ComponentName.test.tsx

Code Style Guidelines

ES6+ Features to Use

Prefer:

  • Arrow functions for callbacks
  • Destructuring for props and objects
  • Template literals for string interpolation
  • Spread operator for object/array operations
  • Optional chaining (?.) and nullish coalescing (??)
  • const and let (never var)

Example:

// Good
const UserProfile = ({ user, onUpdate }) => {
  const { name, email, avatar } = user;
  const displayName = name ?? 'Anonymous';

  return (
    <div>
      <img src={avatar} alt={`${displayName}'s avatar`} />
      <p>{displayName}</p>
      <p>{email?.toLowerCase()}</p>
    </div>
  );
};

// Avoid
var UserProfile = function(props) {
  var name = props.user.name;
  var email = props.user.email;
  // ...
};

Component Patterns

State Management:

// Use useState for local state
const [count, setCount] = useState<number>(0);

// Use useReducer for complex state
const [state, dispatch] = useReducer(reducer, initialState);

// Use custom hooks for reusable logic
const { data, loading, error } = useFetchData(url);

Side Effects:

// Use useEffect for side effects
useEffect(() => {
  // Effect logic
  return () => {
    // Cleanup
  };
}, [dependencies]);

Memoization:

// Memoize expensive calculations
const expensiveValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

// Memoize callback functions
const handleClick = useCallback(() => {
  doSomething(a, b);
}, [a, b]);

TypeScript Best Practices

Type Definitions

Props Interface:

// Define clear prop types
interface UserCardProps {
  user: User;
  showAvatar?: boolean;
  onEdit?: (userId: string) => void;
}

// Use the interface
const UserCard: React.FC<UserCardProps> = ({ user, showAvatar = true, onEdit }) => {
  // Component implementation
};

State Types:

// Type your state
interface FormState {
  username: string;
  email: string;
  errors: Record<string, string>;
}

const [formState, setFormState] = useState<FormState>({
  username: '',
  email: '',
  errors: {}
});

Avoid any:

// Bad
const data: any = fetchData();

// Good
interface ApiResponse {
  data: User[];
  status: number;
}
const response: ApiResponse = fetchData();

Testing Guidelines

Write Tests For

  • All components with logic
  • Utility functions
  • Custom hooks
  • API interactions
  • Complex state management

Test Structure

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

describe('Button Component', () => {
  it('renders with correct label', () => {
    render(<Button label="Click me" onClick={() => {}} />);
    expect(screen.getByText('Click me')).toBeInTheDocument();
  });

  it('calls onClick when clicked', () => {
    const handleClick = jest.fn();
    render(<Button label="Click" onClick={handleClick} />);

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

  it('is disabled when disabled prop is true', () => {
    render(<Button label="Click" onClick={() => {}} disabled />);
    expect(screen.getByRole('button')).toBeDisabled();
  });
});

Common Issues and Solutions

ESLint Errors

"React must be in scope" (older React versions)

// Add import even if not directly used
import React from 'react';

"Missing key prop"

// Always add key when mapping
{items.map(item => <div key={item.id}>{item.name}</div>)}

"Missing dependency in useEffect"

// Add all dependencies or use ESLint disable if intentional
useEffect(() => {
  fetchData(userId);
}, [userId]); // Include all used variables

TypeScript Errors

"Property does not exist on type"

// Define proper interface
interface User {
  id: string;
  name: string;
  email?: string; // Optional property
}

Pre-Development Checklist

Before starting any new feature or bug fix:

  • Pull latest changes from main branch
  • Run npm install to ensure dependencies are up to date
  • Run npm test to verify all tests pass
  • Run npm run lint to check for existing issues
  • Understand the task requirements clearly
  • Plan component structure if building new features

Pre-Commit Checklist

Before committing code:

  • All tests pass (npm test)
  • No ESLint errors (npm run lint)
  • No TypeScript errors (npx tsc --noEmit)
  • Code follows naming conventions
  • Components are functional (not class-based)
  • Proper TypeScript types are defined
  • New functionality has tests
  • Console logs removed (except intentional logging)
  • Comments explain "why", not "what"
  • Build succeeds (npm run build)

Resources

references/

  • react-patterns.md - Common React patterns and anti-patterns reference
  • typescript-guide.md - TypeScript specific guidelines for React development
  • testing-guide.md - Comprehensive testing strategies and examples