A modern React learning application built with TypeScript, Vite, and Tailwind CSS. This project serves as a comprehensive guide to React concepts, CSS patterns, and performance optimizations.
-
π React Performance Optimization Examples
- React.memo usage
- useCallback implementation
- useMemo examples
-
π¨ CSS Pattern Examples
- Responsive Design
- Grid & Flexbox layouts
- Positions & Display properties
- Transitions & Animations
- Loading Skeletons
-
β‘ Performance Examples
- Debouncing & Throttling with HOCs
- Custom React Hooks
- React 18
- TypeScript
- Vite
- Tailwind CSS
- ESLint & Prettier
- Husky for Git hooks
- Clone the repository
git clone <repository-url>
cd learn-react- Install dependencies
npm install- Start the development server
npm run dev- Build for production
npm run buildnpm run dev- Start development servernpm run build- Build for productionnpm run lint- Run ESLintnpm run format- Run Prettier formattingnpm run type-check- Run TypeScript type checking
src/
βββ components/
β βββ layout/ # Layout components
β βββ ui/ # Reusable UI components
βββ pages/
β βββ css-patterns/ # CSS example pages
β βββ performance/ # Performance example pages
βββ main.tsx # Application entry point
This section documents all the commands used to set up this project from scratch.
- Create Vite project with React and TypeScript
npm create vite@latest learn-react -- --template react-ts
cd learn-react
npm install- Install and configure Tailwind CSS
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -pAdd to tailwind.config.js:
/** @type {import('tailwindcss').Config} */
export default {
content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
theme: {
extend: {},
},
plugins: [],
};Add to src/index.css:
@tailwind base;
@tailwind components;
@tailwind utilities;- Install ESLint and related packages
npm install --save-dev eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-react eslint-plugin-react-hooks prettier eslint-config-prettier eslint-plugin-prettier- Create ESLint configuration (.eslintrc.json)
{
"env": {
"browser": true,
"es2021": true,
"node": true
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:react/recommended",
"plugin:react-hooks/recommended",
"plugin:prettier/recommended"
],
"parser": "@typescript-eslint/parser",
"plugins": ["react", "@typescript-eslint", "prettier"],
"rules": {
"react/react-in-jsx-scope": "off",
"react/prop-types": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
"@typescript-eslint/no-explicit-any": "off",
"react-hooks/exhaustive-deps": "warn",
"prettier/prettier": "error"
}
}- Create Prettier configuration (.prettierrc)
{
"semi": true,
"tabWidth": 2,
"printWidth": 100,
"singleQuote": true,
"trailingComma": "es5",
"bracketSpacing": true,
"jsxBracketSameLine": false
}- Install Husky and lint-staged
npm install --save-dev husky lint-staged- Initialize Husky
npx husky-init && npm install- Create lint-staged configuration (.lintstagedrc)
{
"*.{js,jsx,ts,tsx}": ["eslint --fix", "prettier --write"],
"*.{json,md,yml,yaml}": ["prettier --write"]
}- Update package.json scripts
{
"scripts": {
"lint": "eslint \"src/**/*.{ts,tsx}\" --fix",
"format": "prettier --write \"**/*.{ts,tsx,js,jsx,json,md}\"",
"type-check": "tsc --noEmit",
"prepare": "husky install",
"precommit": "lint-staged",
"prepush": "npm run type-check"
}
}- Development server
npm run dev- Lint and format code
npm run lint
npm run format- Type checking
npm run type-check- If ESLint configuration conflicts occur:
rm eslint.config.js # Remove new-style config if it exists- If Husky hooks need to be made executable:
chmod +x .husky/pre-commit
chmod +x .husky/pre-push- If you need to skip Husky hooks temporarily:
git commit -m "message" --no-verifyThis project uses Jest and React Testing Library for unit testing. Here's how to run the tests:
# Run all tests
npm test
# Run tests in watch mode (for development)
npm run test:watch
# Run tests with coverage report
npm run test:coverageTests are co-located with their components and follow the naming pattern *.test.tsx. For example:
src/
components/
Button/
Button.tsx
Button.test.tsx
pages/
FormValidation/
FormValidation.tsx
FormValidation.test.tsx
-
Component Testing
- Test rendering
- Test user interactions
- Test different states (loading, error, success)
- Test prop variations
-
Form Testing
- Test validation rules
- Test error messages
- Test submission behavior
- Test loading states
-
Async Testing
- Use
async/awaitwith user events - Use
waitForfor async operations - Test loading and success states
- Use
-
Test Organization
- Group related tests with
describe - Use clear test descriptions
- Keep tests focused and isolated
- Group related tests with
import { render, screen } from '@testing-library/react';
import Button from './Button';
describe('Button Component', () => {
test('renders with text', () => {
render(<Button>Click me</Button>);
expect(screen.getByText('Click me')).toBeInTheDocument();
});
test('handles click events', () => {
const handleClick = jest.fn();
render(<Button onClick={handleClick}>Click me</Button>);
fireEvent.click(screen.getByText('Click me'));
expect(handleClick).toHaveBeenCalledTimes(1);
});
});- Install dependencies:
npm install --save-dev jest @types/jest @testing-library/react @testing-library/jest-dom @testing-library/user-event jest-environment-jsdom ts-jest identity-obj-proxy- Create Jest config (jest.config.ts):
export default {
preset: 'ts-jest',
testEnvironment: 'jsdom',
setupFilesAfterEnv: ['<rootDir>/src/setupTests.ts'],
moduleNameMapper: {
'\\.(css|less|scss|sass)$': 'identity-obj-proxy',
},
};- Add test scripts to package.json:
{
"scripts": {
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage"
}
}