ai-playbook 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +146 -0
- package/agents/README.md +168 -0
- package/agents/SKILL.md +633 -0
- package/agents/architect/AGENT.md +44 -0
- package/agents/architect/README.md +5 -0
- package/agents/coder/AGENT.md +43 -0
- package/agents/coder/README.md +5 -0
- package/agents/debugger/AGENT.md +42 -0
- package/agents/debugger/README.md +6 -0
- package/agents/devops/AGENT.md +43 -0
- package/agents/devops/README.md +5 -0
- package/agents/documentation/AGENT.md +45 -0
- package/agents/documentation/README.md +5 -0
- package/agents/examples.md +550 -0
- package/agents/performance/AGENT.md +45 -0
- package/agents/performance/README.md +6 -0
- package/agents/planner/AGENT.md +44 -0
- package/agents/planner/README.md +6 -0
- package/agents/product-owner/AGENT.md +46 -0
- package/agents/product-owner/README.md +6 -0
- package/agents/refactorer/AGENT.md +44 -0
- package/agents/refactorer/README.md +6 -0
- package/agents/release-manager/AGENT.md +45 -0
- package/agents/release-manager/README.md +6 -0
- package/agents/researcher/AGENT.md +44 -0
- package/agents/researcher/README.md +6 -0
- package/agents/reviewer/AGENT.md +43 -0
- package/agents/reviewer/README.md +6 -0
- package/agents/security/AGENT.md +46 -0
- package/agents/security/README.md +6 -0
- package/agents/support/AGENT.md +45 -0
- package/agents/support/README.md +6 -0
- package/agents/tester/AGENT.md +46 -0
- package/agents/tester/README.md +5 -0
- package/bin/cli.js +186 -0
- package/commands/README.md +266 -0
- package/commands/build.md +135 -0
- package/commands/clean.md +126 -0
- package/commands/deploy-prod.md +171 -0
- package/commands/deploy-staging.md +147 -0
- package/commands/deps.md +169 -0
- package/commands/dev.md +132 -0
- package/commands/format.md +142 -0
- package/commands/lint.md +125 -0
- package/commands/migrate.md +159 -0
- package/commands/release.md +183 -0
- package/commands/rollback.md +152 -0
- package/commands/seed.md +178 -0
- package/commands/setup.md +109 -0
- package/commands/test.md +134 -0
- package/commands/validate.md +147 -0
- package/context/README.md +7 -0
- package/context/aem.md +47 -0
- package/context/architecture.md +51 -0
- package/context/bullminder.md +57 -0
- package/context/coding-style.md +42 -0
- package/context/communication.md +53 -0
- package/context/company.md +46 -0
- package/context/engineering.md +63 -0
- package/context/project-template.md +71 -0
- package/context/trading.md +52 -0
- package/hooks/README.md +326 -0
- package/hooks/code-review/README.md +6 -0
- package/hooks/code-review/check-coverage.md +101 -0
- package/hooks/custom/README.md +6 -0
- package/hooks/custom/project-specific-hooks.md +273 -0
- package/hooks/deployment/README.md +6 -0
- package/hooks/deployment/health-check.md +102 -0
- package/hooks/deployment/pre-deploy-check.md +84 -0
- package/hooks/documentation/README.md +6 -0
- package/hooks/documentation/update-changelog.md +146 -0
- package/hooks/post-task/README.md +5 -0
- package/hooks/post-task/run-tests.md +61 -0
- package/hooks/pre-commit/README.md +6 -0
- package/hooks/pre-commit/format.md +63 -0
- package/hooks/pre-commit/lint.md +62 -0
- package/hooks/pre-commit/type-check.md +78 -0
- package/hooks/pre-task/README.md +6 -0
- package/hooks/pre-task/check-branch.md +48 -0
- package/hooks/pre-task/validate-environment.md +48 -0
- package/hooks/security-check/README.md +6 -0
- package/hooks/security-check/dependency-audit.md +85 -0
- package/hooks/security-check/secrets-scan.md +77 -0
- package/hooks/test-before-finish/README.md +6 -0
- package/hooks/test-before-finish/run-all-tests.md +128 -0
- package/index.js +69 -0
- package/knowledge/README.md +33 -0
- package/knowledge/ai-agents.md +74 -0
- package/knowledge/decision-making.md +73 -0
- package/knowledge/documentation.md +67 -0
- package/knowledge/engineering-principles.md +65 -0
- package/knowledge/product-discovery.md +68 -0
- package/knowledge/security-privacy.md +54 -0
- package/knowledge/testing-quality.md +63 -0
- package/package.json +63 -0
- package/patterns/README.md +7 -0
- package/prompts/README.md +208 -0
- package/prompts/architect/README.md +96 -0
- package/prompts/architect/design-system.md +140 -0
- package/prompts/debugger/README.md +96 -0
- package/prompts/debugger/diagnose-issue.md +141 -0
- package/prompts/developer/README.md +129 -0
- package/prompts/developer/fix-bug.md +136 -0
- package/prompts/developer/implement-feature.md +133 -0
- package/prompts/product-owner/README.md +116 -0
- package/prompts/product-owner/define-feature.md +145 -0
- package/prompts/reviewer/README.md +91 -0
- package/prompts/reviewer/code-review.md +129 -0
- package/prompts/support/README.md +154 -0
- package/prompts/support/resolve-issue.md +124 -0
- package/roles/README.md +6 -0
- package/roles/design-architect/README.md +98 -0
- package/roles/design-architect/accessibility/README.md +33 -0
- package/roles/design-architect/accessibility/checklists.md +29 -0
- package/roles/design-architect/accessibility/examples.md +35 -0
- package/roles/design-architect/checklists.md +76 -0
- package/roles/design-architect/component-library/README.md +35 -0
- package/roles/design-architect/component-library/checklists.md +29 -0
- package/roles/design-architect/component-library/examples.md +35 -0
- package/roles/design-architect/design-system/README.md +35 -0
- package/roles/design-architect/design-system/checklists.md +27 -0
- package/roles/design-architect/design-system/examples.md +41 -0
- package/roles/design-architect/examples/README.md +31 -0
- package/roles/design-architect/examples/checklists.md +26 -0
- package/roles/design-architect/examples/examples.md +46 -0
- package/roles/design-architect/examples.md +90 -0
- package/roles/design-architect/figma/README.md +33 -0
- package/roles/design-architect/figma/checklists.md +27 -0
- package/roles/design-architect/figma/examples.md +38 -0
- package/roles/design-architect/responsibilities.md +73 -0
- package/roles/design-architect/responsive/README.md +34 -0
- package/roles/design-architect/responsive/checklists.md +26 -0
- package/roles/design-architect/responsive/examples.md +39 -0
- package/roles/design-architect/role.md +129 -0
- package/roles/design-architect/skill-map.md +42 -0
- package/roles/design-architect/triggers.md +110 -0
- package/roles/design-architect/ui/README.md +36 -0
- package/roles/design-architect/ui/checklists.md +29 -0
- package/roles/design-architect/ui/examples.md +28 -0
- package/roles/design-architect/usability/README.md +34 -0
- package/roles/design-architect/usability/checklists.md +28 -0
- package/roles/design-architect/usability/examples.md +31 -0
- package/roles/design-architect/ux/README.md +36 -0
- package/roles/design-architect/ux/checklists.md +28 -0
- package/roles/design-architect/ux/examples.md +37 -0
- package/roles/design-architect/wireframes/README.md +34 -0
- package/roles/design-architect/wireframes/checklists.md +25 -0
- package/roles/design-architect/wireframes/examples.md +32 -0
- package/roles/design-architect/workflow.md +80 -0
- package/roles/devops/README.md +101 -0
- package/roles/devops/ansible/README.md +6 -0
- package/roles/devops/checklists.md +413 -0
- package/roles/devops/ci-cd/README.md +169 -0
- package/roles/devops/ci-cd/checklists.md +289 -0
- package/roles/devops/ci-cd/examples.md +429 -0
- package/roles/devops/cloud-platforms/README.md +109 -0
- package/roles/devops/cost-optimization/README.md +131 -0
- package/roles/devops/disaster-recovery/README.md +118 -0
- package/roles/devops/docker/README.md +6 -0
- package/roles/devops/examples/README.md +6 -0
- package/roles/devops/examples.md +775 -0
- package/roles/devops/github-actions/README.md +6 -0
- package/roles/devops/helm/README.md +6 -0
- package/roles/devops/infrastructure-as-code/README.md +160 -0
- package/roles/devops/infrastructure-as-code/checklists.md +124 -0
- package/roles/devops/jenkins/README.md +6 -0
- package/roles/devops/kubernetes/README.md +150 -0
- package/roles/devops/kubernetes/checklists.md +192 -0
- package/roles/devops/kubernetes/examples.md +189 -0
- package/roles/devops/monitoring/README.md +93 -0
- package/roles/devops/networking/README.md +83 -0
- package/roles/devops/performance/README.md +104 -0
- package/roles/devops/responsibilities.md +95 -0
- package/roles/devops/role.md +130 -0
- package/roles/devops/security/README.md +126 -0
- package/roles/devops/skill-map.md +162 -0
- package/roles/devops/terraform/README.md +6 -0
- package/roles/devops/triggers.md +241 -0
- package/roles/devops/workflow.md +197 -0
- package/roles/qa/README.md +16 -0
- package/roles/qa/api-testing/README.md +6 -0
- package/roles/qa/automation/README.md +6 -0
- package/roles/qa/checklists.md +24 -0
- package/roles/qa/examples/README.md +6 -0
- package/roles/qa/examples.md +27 -0
- package/roles/qa/performance/README.md +6 -0
- package/roles/qa/playwright/README.md +6 -0
- package/roles/qa/responsibilities.md +16 -0
- package/roles/qa/role.md +47 -0
- package/roles/qa/selenium/README.md +6 -0
- package/roles/qa/skill-map.md +14 -0
- package/roles/qa/triggers.md +10 -0
- package/roles/qa/workflow.md +9 -0
- package/roles/software-architect/README.md +16 -0
- package/roles/software-architect/agents/README.md +6 -0
- package/roles/software-architect/ai-architecture/README.md +6 -0
- package/roles/software-architect/aws/README.md +6 -0
- package/roles/software-architect/azure/README.md +6 -0
- package/roles/software-architect/caching/README.md +6 -0
- package/roles/software-architect/checklists.md +25 -0
- package/roles/software-architect/cloud/README.md +6 -0
- package/roles/software-architect/database-design/README.md +6 -0
- package/roles/software-architect/diagrams/README.md +6 -0
- package/roles/software-architect/distributed-systems/README.md +7 -0
- package/roles/software-architect/docker/README.md +6 -0
- package/roles/software-architect/event-driven/README.md +7 -0
- package/roles/software-architect/examples/README.md +6 -0
- package/roles/software-architect/examples.md +22 -0
- package/roles/software-architect/gcp/README.md +6 -0
- package/roles/software-architect/kubernetes/README.md +6 -0
- package/roles/software-architect/messaging/README.md +6 -0
- package/roles/software-architect/rag/README.md +7 -0
- package/roles/software-architect/responsibilities.md +17 -0
- package/roles/software-architect/role.md +46 -0
- package/roles/software-architect/scalability/README.md +6 -0
- package/roles/software-architect/security/README.md +6 -0
- package/roles/software-architect/skill-map.md +15 -0
- package/roles/software-architect/system-design/README.md +6 -0
- package/roles/software-architect/triggers.md +10 -0
- package/roles/software-architect/vector-db/README.md +6 -0
- package/roles/software-architect/workflow.md +9 -0
- package/roles/software-developer/README.md +116 -0
- package/roles/software-developer/api/README.md +365 -0
- package/roles/software-developer/api/checklist.md +131 -0
- package/roles/software-developer/api/examples.md +459 -0
- package/roles/software-developer/authentication/README.md +26 -0
- package/roles/software-developer/authentication/checklists.md +22 -0
- package/roles/software-developer/authentication/examples.md +32 -0
- package/roles/software-developer/authorization/README.md +26 -0
- package/roles/software-developer/authorization/checklists.md +21 -0
- package/roles/software-developer/authorization/examples.md +27 -0
- package/roles/software-developer/backend/README.md +26 -0
- package/roles/software-developer/backend/checklists.md +21 -0
- package/roles/software-developer/backend/examples.md +21 -0
- package/roles/software-developer/cache/README.md +25 -0
- package/roles/software-developer/cache/checklists.md +21 -0
- package/roles/software-developer/cache/examples.md +22 -0
- package/roles/software-developer/checklists.md +122 -0
- package/roles/software-developer/code-review/README.md +23 -0
- package/roles/software-developer/code-review/checklists.md +22 -0
- package/roles/software-developer/code-review/examples.md +20 -0
- package/roles/software-developer/database/README.md +27 -0
- package/roles/software-developer/database/checklists.md +21 -0
- package/roles/software-developer/database/examples.md +27 -0
- package/roles/software-developer/debugging/README.md +24 -0
- package/roles/software-developer/debugging/checklists.md +20 -0
- package/roles/software-developer/debugging/examples.md +28 -0
- package/roles/software-developer/examples/README.md +22 -0
- package/roles/software-developer/examples/checklists.md +8 -0
- package/roles/software-developer/examples/examples.md +25 -0
- package/roles/software-developer/examples.md +378 -0
- package/roles/software-developer/frontend/README.md +76 -0
- package/roles/software-developer/frontend/accessibility/README.md +136 -0
- package/roles/software-developer/frontend/accessibility/best-practices.md +368 -0
- package/roles/software-developer/frontend/code-quality/README.md +136 -0
- package/roles/software-developer/frontend/code-quality/best-practices.md +309 -0
- package/roles/software-developer/frontend/components/README.md +65 -0
- package/roles/software-developer/frontend/components/best-practices.md +273 -0
- package/roles/software-developer/frontend/debugging/README.md +149 -0
- package/roles/software-developer/frontend/debugging/best-practices.md +329 -0
- package/roles/software-developer/frontend/examples/README.md +19 -0
- package/roles/software-developer/frontend/examples/checklists.md +8 -0
- package/roles/software-developer/frontend/examples/examples.md +17 -0
- package/roles/software-developer/frontend/logging-observability/README.md +196 -0
- package/roles/software-developer/frontend/logging-observability/best-practices.md +430 -0
- package/roles/software-developer/frontend/performance/README.md +99 -0
- package/roles/software-developer/frontend/performance/best-practices.md +350 -0
- package/roles/software-developer/frontend/state-management/README.md +85 -0
- package/roles/software-developer/frontend/state-management/best-practices.md +344 -0
- package/roles/software-developer/frontend/testing/README.md +114 -0
- package/roles/software-developer/frontend/testing/best-practices.md +272 -0
- package/roles/software-developer/fullstack/README.md +25 -0
- package/roles/software-developer/fullstack/checklists.md +19 -0
- package/roles/software-developer/fullstack/examples.md +14 -0
- package/roles/software-developer/graphql/README.md +24 -0
- package/roles/software-developer/graphql/checklists.md +20 -0
- package/roles/software-developer/graphql/examples.md +24 -0
- package/roles/software-developer/integration-tests/README.md +25 -0
- package/roles/software-developer/integration-tests/checklists.md +20 -0
- package/roles/software-developer/integration-tests/examples.md +18 -0
- package/roles/software-developer/java/README.md +24 -0
- package/roles/software-developer/java/checklists.md +16 -0
- package/roles/software-developer/java/examples.md +22 -0
- package/roles/software-developer/javascript/README.md +24 -0
- package/roles/software-developer/javascript/checklists.md +15 -0
- package/roles/software-developer/javascript/examples.md +18 -0
- package/roles/software-developer/logging/README.md +105 -0
- package/roles/software-developer/logging/checklists.md +48 -0
- package/roles/software-developer/logging/examples.md +135 -0
- package/roles/software-developer/messaging/README.md +24 -0
- package/roles/software-developer/messaging/checklists.md +21 -0
- package/roles/software-developer/messaging/examples.md +26 -0
- package/roles/software-developer/microservices/README.md +25 -0
- package/roles/software-developer/microservices/checklists.md +21 -0
- package/roles/software-developer/microservices/examples.md +21 -0
- package/roles/software-developer/node/README.md +25 -0
- package/roles/software-developer/node/checklists.md +15 -0
- package/roles/software-developer/node/examples.md +15 -0
- package/roles/software-developer/nosql/README.md +24 -0
- package/roles/software-developer/nosql/checklists.md +21 -0
- package/roles/software-developer/nosql/examples.md +20 -0
- package/roles/software-developer/observability/README.md +25 -0
- package/roles/software-developer/observability/checklists.md +21 -0
- package/roles/software-developer/observability/examples.md +22 -0
- package/roles/software-developer/performance/README.md +26 -0
- package/roles/software-developer/performance/checklists.md +20 -0
- package/roles/software-developer/performance/examples.md +20 -0
- package/roles/software-developer/python/README.md +25 -0
- package/roles/software-developer/python/checklists.md +15 -0
- package/roles/software-developer/python/examples.md +17 -0
- package/roles/software-developer/react/README.md +24 -0
- package/roles/software-developer/react/checklists.md +15 -0
- package/roles/software-developer/react/examples.md +22 -0
- package/roles/software-developer/refactoring/README.md +23 -0
- package/roles/software-developer/refactoring/checklists.md +21 -0
- package/roles/software-developer/refactoring/examples.md +11 -0
- package/roles/software-developer/responsibilities.md +58 -0
- package/roles/software-developer/role.md +127 -0
- package/roles/software-developer/skill-map.md +88 -0
- package/roles/software-developer/springboot/README.md +25 -0
- package/roles/software-developer/springboot/checklists.md +15 -0
- package/roles/software-developer/springboot/examples.md +21 -0
- package/roles/software-developer/sql/README.md +24 -0
- package/roles/software-developer/sql/checklists.md +22 -0
- package/roles/software-developer/sql/examples.md +20 -0
- package/roles/software-developer/testing/README.md +25 -0
- package/roles/software-developer/testing/checklists.md +21 -0
- package/roles/software-developer/testing/examples.md +19 -0
- package/roles/software-developer/triggers.md +550 -0
- package/roles/software-developer/typescript/README.md +25 -0
- package/roles/software-developer/typescript/checklists.md +15 -0
- package/roles/software-developer/typescript/examples.md +18 -0
- package/roles/software-developer/unit-tests/README.md +24 -0
- package/roles/software-developer/unit-tests/checklists.md +19 -0
- package/roles/software-developer/unit-tests/examples.md +22 -0
- package/roles/software-developer/workflow.md +196 -0
- package/roles/sre/README.md +16 -0
- package/roles/sre/alerts/README.md +6 -0
- package/roles/sre/availability/README.md +6 -0
- package/roles/sre/chaos/README.md +6 -0
- package/roles/sre/checklists.md +24 -0
- package/roles/sre/examples/README.md +6 -0
- package/roles/sre/examples.md +19 -0
- package/roles/sre/observability/README.md +6 -0
- package/roles/sre/reliability/README.md +6 -0
- package/roles/sre/responsibilities.md +16 -0
- package/roles/sre/role.md +46 -0
- package/roles/sre/skill-map.md +14 -0
- package/roles/sre/slos/README.md +6 -0
- package/roles/sre/triggers.md +10 -0
- package/roles/sre/workflow.md +9 -0
- package/roles/support-engineer/README.md +16 -0
- package/roles/support-engineer/checklists.md +24 -0
- package/roles/support-engineer/datadog/README.md +6 -0
- package/roles/support-engineer/examples/README.md +6 -0
- package/roles/support-engineer/examples.md +17 -0
- package/roles/support-engineer/incident-response/README.md +6 -0
- package/roles/support-engineer/kubernetes/README.md +6 -0
- package/roles/support-engineer/linux/README.md +6 -0
- package/roles/support-engineer/logs/README.md +6 -0
- package/roles/support-engineer/monitoring/README.md +6 -0
- package/roles/support-engineer/networking/README.md +6 -0
- package/roles/support-engineer/newrelic/README.md +6 -0
- package/roles/support-engineer/postmortem/README.md +6 -0
- package/roles/support-engineer/production/README.md +6 -0
- package/roles/support-engineer/responsibilities.md +16 -0
- package/roles/support-engineer/role.md +47 -0
- package/roles/support-engineer/root-cause-analysis/README.md +6 -0
- package/roles/support-engineer/runbooks/README.md +6 -0
- package/roles/support-engineer/skill-map.md +14 -0
- package/roles/support-engineer/splunk/README.md +6 -0
- package/roles/support-engineer/triggers.md +10 -0
- package/roles/support-engineer/troubleshooting/README.md +6 -0
- package/roles/support-engineer/workflow.md +9 -0
- package/setup.sh +204 -0
- package/skills/.claude/README.md +7 -0
- package/skills/README.md +21 -0
- package/skills/ai-agents/README.md +207 -0
- package/skills/ai-agents/examples.md +335 -0
- package/skills/ai-agents/skill.md +392 -0
- package/skills/architecture/README.md +198 -0
- package/skills/architecture/examples.md +316 -0
- package/skills/architecture/skill.md +189 -0
- package/skills/design-architecture/README.md +107 -0
- package/skills/design-architecture/examples.md +84 -0
- package/skills/design-architecture/skill.md +192 -0
- package/skills/devops/README.md +177 -0
- package/skills/devops/examples.md +376 -0
- package/skills/devops/skill.md +210 -0
- package/skills/documentation/README.md +182 -0
- package/skills/documentation/examples.md +364 -0
- package/skills/documentation/skill.md +200 -0
- package/skills/performance/README.md +177 -0
- package/skills/performance/examples.md +376 -0
- package/skills/performance/skill.md +199 -0
- package/skills/qa/README.md +106 -0
- package/skills/qa/examples.md +84 -0
- package/skills/qa/skill.md +384 -0
- package/skills/security/README.md +108 -0
- package/skills/security/examples.md +85 -0
- package/skills/security/skill.md +223 -0
- package/skills/software-development/README.md +239 -0
- package/skills/software-development/assessment.md +0 -0
- package/skills/software-development/checklists.md +0 -0
- package/skills/software-development/examples.md +375 -0
- package/skills/software-development/prompts.md +0 -0
- package/skills/software-development/skill.md +390 -0
- package/skills/software-development/templates/README.md +7 -0
- package/skills/software-development/templates/api-development.md +0 -0
- package/skills/software-development/templates/bug-fix.md +0 -0
- package/skills/software-development/templates/code-review.md +0 -0
- package/skills/software-development/templates/feature-implementation.md +0 -0
- package/skills/software-development/templates/llm-integration.md +0 -0
- package/skills/software-development/templates/performance-review.md +0 -0
- package/skills/software-development/templates/security-review.md +0 -0
- package/skills/software-development/templates/test-generation.md +0 -0
- package/skills/software-development/tools.md +0 -0
- package/skills/software-development/workflows.md +0 -0
- package/skills/sre/README.md +107 -0
- package/skills/sre/examples.md +379 -0
- package/skills/sre/skill.md +256 -0
- package/skills/support-engineering/README.md +107 -0
- package/skills/support-engineering/examples.md +85 -0
- package/skills/support-engineering/skill.md +103 -0
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
# Code Quality: Best Practices
|
|
2
|
+
|
|
3
|
+
High-quality code is readable, maintainable, and predictable. This guide covers naming, structure, and practices that make code a pleasure to work with.
|
|
4
|
+
|
|
5
|
+
## Naming Conventions
|
|
6
|
+
|
|
7
|
+
Clear names are worth the extra characters. Use established conventions for consistency.
|
|
8
|
+
|
|
9
|
+
```javascript
|
|
10
|
+
// Components: PascalCase
|
|
11
|
+
function UserProfile() { }
|
|
12
|
+
function ShoppingCart() { }
|
|
13
|
+
function FormInput() { }
|
|
14
|
+
|
|
15
|
+
// Functions and variables: camelCase
|
|
16
|
+
function calculateTotal() { }
|
|
17
|
+
let userCount = 0;
|
|
18
|
+
const handleClick = () => { };
|
|
19
|
+
|
|
20
|
+
// Constants: UPPER_SNAKE_CASE
|
|
21
|
+
const MAX_RETRIES = 3;
|
|
22
|
+
const API_BASE_URL = 'https://api.example.com';
|
|
23
|
+
const DEFAULT_TIMEOUT = 5000;
|
|
24
|
+
|
|
25
|
+
// Boolean variables: is/has/should prefix
|
|
26
|
+
const isLoading = true;
|
|
27
|
+
const hasError = false;
|
|
28
|
+
const shouldRender = true;
|
|
29
|
+
const isEnabled = true;
|
|
30
|
+
|
|
31
|
+
// BAD: Unclear names
|
|
32
|
+
let x = 10; // What is x?
|
|
33
|
+
let temp = []; // Temporary what?
|
|
34
|
+
let data = null; // What data?
|
|
35
|
+
let d = new Date(); // 'd' doesn't convey meaning
|
|
36
|
+
|
|
37
|
+
// GOOD: Clear, specific names
|
|
38
|
+
let maxConnectionRetries = 10;
|
|
39
|
+
let temporaryUploadQueue = [];
|
|
40
|
+
let cachedUserData = null;
|
|
41
|
+
let requestStartTime = new Date();
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Function Size
|
|
45
|
+
|
|
46
|
+
Keep functions small and focused. A function that fits on one screen is easier to understand.
|
|
47
|
+
|
|
48
|
+
```javascript
|
|
49
|
+
// BAD: 50-line function mixing concerns
|
|
50
|
+
function processUserData(userId) {
|
|
51
|
+
// Validation
|
|
52
|
+
if (!userId) throw new Error('User ID required');
|
|
53
|
+
if (typeof userId !== 'number') throw new Error('Must be number');
|
|
54
|
+
|
|
55
|
+
// Fetch data
|
|
56
|
+
const user = fetchUser(userId);
|
|
57
|
+
if (!user) throw new Error('User not found');
|
|
58
|
+
|
|
59
|
+
// Transform data
|
|
60
|
+
const formatted = {
|
|
61
|
+
id: user.id,
|
|
62
|
+
displayName: `${user.firstName} ${user.lastName}`,
|
|
63
|
+
emails: user.emails.map(e => e.address),
|
|
64
|
+
createdAt: new Date(user.createdAt),
|
|
65
|
+
isActive: user.status === 'active'
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
// Update cache
|
|
69
|
+
cache.set(`user:${userId}`, formatted);
|
|
70
|
+
|
|
71
|
+
// Log
|
|
72
|
+
console.log(`Processed user ${userId}`);
|
|
73
|
+
|
|
74
|
+
return formatted;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// GOOD: Small, focused functions
|
|
78
|
+
function validateUserId(userId) {
|
|
79
|
+
if (!userId) throw new Error('User ID required');
|
|
80
|
+
if (typeof userId !== 'number') throw new Error('Must be number');
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function formatUserData(user) {
|
|
84
|
+
return {
|
|
85
|
+
id: user.id,
|
|
86
|
+
displayName: `${user.firstName} ${user.lastName}`,
|
|
87
|
+
emails: user.emails.map(e => e.address),
|
|
88
|
+
createdAt: new Date(user.createdAt),
|
|
89
|
+
isActive: user.status === 'active'
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function processUserData(userId) {
|
|
94
|
+
validateUserId(userId);
|
|
95
|
+
const user = fetchUser(userId);
|
|
96
|
+
const formatted = formatUserData(user);
|
|
97
|
+
cache.set(`user:${userId}`, formatted);
|
|
98
|
+
return formatted;
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Avoid Deep Nesting
|
|
103
|
+
|
|
104
|
+
Nesting makes code hard to follow. Keep it shallow using early returns, guard clauses, and extraction.
|
|
105
|
+
|
|
106
|
+
```javascript
|
|
107
|
+
// BAD: Deeply nested (hard to follow)
|
|
108
|
+
function handleUserUpdate(user) {
|
|
109
|
+
if (user) {
|
|
110
|
+
if (user.isActive) {
|
|
111
|
+
if (user.email) {
|
|
112
|
+
if (user.profile) {
|
|
113
|
+
if (user.profile.updated) {
|
|
114
|
+
sendNotification(user.email, 'Profile updated');
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// GOOD: Flat with guard clauses (clear flow)
|
|
123
|
+
function handleUserUpdate(user) {
|
|
124
|
+
if (!user) return;
|
|
125
|
+
if (!user.isActive) return;
|
|
126
|
+
if (!user.email) return;
|
|
127
|
+
if (!user.profile?.updated) return;
|
|
128
|
+
|
|
129
|
+
sendNotification(user.email, 'Profile updated');
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// GOOD: Extract conditions
|
|
133
|
+
function isValidUserForNotification(user) {
|
|
134
|
+
return user?.isActive && user?.email && user?.profile?.updated;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function handleUserUpdate(user) {
|
|
138
|
+
if (!isValidUserForNotification(user)) return;
|
|
139
|
+
sendNotification(user.email, 'Profile updated');
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## TypeScript for Type Safety
|
|
144
|
+
|
|
145
|
+
Use TypeScript to catch errors at development time, not production.
|
|
146
|
+
|
|
147
|
+
```javascript
|
|
148
|
+
// WITHOUT TypeScript: bug found after deployment
|
|
149
|
+
function getUser(id) {
|
|
150
|
+
return fetch(`/api/users/${id}`).then(r => r.json());
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const user = getUser('invalid'); // Oops, id should be number
|
|
154
|
+
user.toUpperCase(); // Oops, user is an object, not a string
|
|
155
|
+
|
|
156
|
+
// WITH TypeScript: caught immediately
|
|
157
|
+
function getUser(id: number): Promise<User> {
|
|
158
|
+
return fetch(`/api/users/${id}`).then(r => r.json());
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const user = getUser('invalid'); // Error: Argument of type 'string' is not assignable to parameter of type 'number'
|
|
162
|
+
user.toUpperCase(); // Error: Property 'toUpperCase' does not exist on type 'User'
|
|
163
|
+
|
|
164
|
+
interface User {
|
|
165
|
+
id: number;
|
|
166
|
+
name: string;
|
|
167
|
+
email: string;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Strong typing catches errors early
|
|
171
|
+
function formatUserEmail(user: User): string {
|
|
172
|
+
return `${user.name} <${user.email}>`;
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## Import Organization
|
|
177
|
+
|
|
178
|
+
Organize imports consistently: standard library → third-party → local.
|
|
179
|
+
|
|
180
|
+
```javascript
|
|
181
|
+
// GOOD: Organized imports
|
|
182
|
+
import { useState, useEffect } from 'react';
|
|
183
|
+
import { format } from 'date-fns';
|
|
184
|
+
import axios from 'axios';
|
|
185
|
+
|
|
186
|
+
import { UserCard } from './UserCard';
|
|
187
|
+
import { api } from '../services/api';
|
|
188
|
+
import { COLORS } from '../constants';
|
|
189
|
+
|
|
190
|
+
// Within local imports, group by type:
|
|
191
|
+
// Components → hooks → utilities → constants
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## Comments are Not Excuses
|
|
195
|
+
|
|
196
|
+
Comments should explain **why**, not **what**. If you need to comment what code does, refactor to be clearer.
|
|
197
|
+
|
|
198
|
+
```javascript
|
|
199
|
+
// BAD: Unnecessary comments (what is obvious from code)
|
|
200
|
+
function add(a, b) {
|
|
201
|
+
// Add a and b
|
|
202
|
+
return a + b; // return the sum
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
const users = []; // Empty array for users
|
|
206
|
+
|
|
207
|
+
// GOOD: Only necessary comments (why, not what)
|
|
208
|
+
// Cache is cleared after 5 minutes to prevent stale data
|
|
209
|
+
const CACHE_TTL = 5 * 60 * 1000;
|
|
210
|
+
|
|
211
|
+
// We use a Set instead of array for O(1) lookup performance
|
|
212
|
+
const seenIds = new Set();
|
|
213
|
+
|
|
214
|
+
// Retry logic: exponential backoff with jitter to avoid thundering herd
|
|
215
|
+
function calculateBackoff(attempt) {
|
|
216
|
+
const exponential = Math.pow(2, attempt) * 1000;
|
|
217
|
+
const jitter = Math.random() * exponential * 0.1;
|
|
218
|
+
return exponential + jitter;
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
## DRY (Don't Repeat Yourself)
|
|
223
|
+
|
|
224
|
+
If you find identical logic in multiple places, extract it.
|
|
225
|
+
|
|
226
|
+
```javascript
|
|
227
|
+
// BAD: Repeated validation
|
|
228
|
+
function validateEmail(email) {
|
|
229
|
+
if (!email) throw new Error('Email required');
|
|
230
|
+
if (!email.includes('@')) throw new Error('Invalid email');
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
function validateUsername(username) {
|
|
234
|
+
if (!username) throw new Error('Username required');
|
|
235
|
+
if (username.length < 3) throw new Error('Username too short');
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// GOOD: Reusable validation
|
|
239
|
+
function required(value, fieldName) {
|
|
240
|
+
if (!value) throw new Error(`${fieldName} required`);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
function minLength(value, min, fieldName) {
|
|
244
|
+
if (value.length < min) throw new Error(`${fieldName} minimum ${min} characters`);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
function validateEmail(email) {
|
|
248
|
+
required(email, 'Email');
|
|
249
|
+
if (!email.includes('@')) throw new Error('Invalid email');
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
function validateUsername(username) {
|
|
253
|
+
required(username, 'Username');
|
|
254
|
+
minLength(username, 3, 'Username');
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
## Code Review Checklist
|
|
259
|
+
|
|
260
|
+
When reviewing code (yours or others), check:
|
|
261
|
+
|
|
262
|
+
```
|
|
263
|
+
Clarity & Readability:
|
|
264
|
+
- [ ] Variable and function names are clear
|
|
265
|
+
- [ ] Functions are small and focused (< 30 lines)
|
|
266
|
+
- [ ] Logic is easy to follow
|
|
267
|
+
- [ ] Comments explain why, not what
|
|
268
|
+
|
|
269
|
+
Correctness:
|
|
270
|
+
- [ ] No obvious bugs (off-by-one, null checks, type mismatches)
|
|
271
|
+
- [ ] Error handling is appropriate
|
|
272
|
+
- [ ] Edge cases are considered
|
|
273
|
+
- [ ] Logic matches requirements
|
|
274
|
+
|
|
275
|
+
Type Safety:
|
|
276
|
+
- [ ] TypeScript types are correct
|
|
277
|
+
- [ ] No use of 'any' unless absolutely necessary
|
|
278
|
+
- [ ] Prop types documented
|
|
279
|
+
|
|
280
|
+
Testing:
|
|
281
|
+
- [ ] Code is testable (not too tightly coupled)
|
|
282
|
+
- [ ] Complex logic has tests
|
|
283
|
+
- [ ] Edge cases are tested
|
|
284
|
+
|
|
285
|
+
Performance:
|
|
286
|
+
- [ ] No obvious inefficiencies
|
|
287
|
+
- [ ] No unnecessary re-renders (if React)
|
|
288
|
+
- [ ] No blocking operations
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
## Code Quality Best Practices Checklist
|
|
292
|
+
|
|
293
|
+
- [ ] All names follow conventions (PascalCase, camelCase, UPPER_SNAKE_CASE)
|
|
294
|
+
- [ ] Functions are small and focused
|
|
295
|
+
- [ ] Nesting is shallow (max 2-3 levels)
|
|
296
|
+
- [ ] TypeScript types are used throughout
|
|
297
|
+
- [ ] Imports organized consistently
|
|
298
|
+
- [ ] Comments explain why, not what
|
|
299
|
+
- [ ] No repeated code (DRY principle)
|
|
300
|
+
- [ ] Dead code removed
|
|
301
|
+
- [ ] No console.log() statements in production code
|
|
302
|
+
- [ ] Code passes linter without warnings
|
|
303
|
+
|
|
304
|
+
## Related Guidance
|
|
305
|
+
|
|
306
|
+
- `/components` — component structure and naming
|
|
307
|
+
- `/testing` — writing testable code
|
|
308
|
+
- `/tools-setup` — linters, formatters, and tooling
|
|
309
|
+
- `/debugging` — understanding code behavior
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Components
|
|
2
|
+
|
|
3
|
+
Senior frontend developers design components that are reusable, maintainable, and composable.
|
|
4
|
+
|
|
5
|
+
## Key Principles
|
|
6
|
+
|
|
7
|
+
- **Single Responsibility** — component does one thing well
|
|
8
|
+
- **Composability** — can be combined with other components
|
|
9
|
+
- **Prop Clarity** — props are clear, typed, documented
|
|
10
|
+
- **No Side Effects** — no surprise mutations or external effects
|
|
11
|
+
- **Testability** — component behavior predictable and testable
|
|
12
|
+
|
|
13
|
+
## Component Design Patterns
|
|
14
|
+
|
|
15
|
+
### Container vs Presentational (Smart vs Dumb)
|
|
16
|
+
- **Presentational** — receives data via props, renders UI, no state logic
|
|
17
|
+
- **Container** — manages state, data fetching, passes to presentational
|
|
18
|
+
- Use both for separation of concerns
|
|
19
|
+
|
|
20
|
+
### Composition Over Inheritance
|
|
21
|
+
- Build complex components from simpler ones
|
|
22
|
+
- Avoids deep inheritance hierarchies
|
|
23
|
+
- Easier to test and reason about
|
|
24
|
+
|
|
25
|
+
### Render Props & Higher-Order Components
|
|
26
|
+
- Extract reusable logic into shared patterns
|
|
27
|
+
- Render props: pass function as prop for flexibility
|
|
28
|
+
- HOCs: wrap component to add behavior
|
|
29
|
+
- Hooks: modern alternative, preferred for new code
|
|
30
|
+
|
|
31
|
+
## Props Design
|
|
32
|
+
|
|
33
|
+
### What to Pass
|
|
34
|
+
- Stable data (primitives, objects)
|
|
35
|
+
- Callbacks for user actions
|
|
36
|
+
- Render functions for flexibility
|
|
37
|
+
- Configuration options
|
|
38
|
+
|
|
39
|
+
### What NOT to Pass
|
|
40
|
+
- Avoid prop drilling (passing through intermediate components)
|
|
41
|
+
- Don't pass component instance state
|
|
42
|
+
- Don't pass circular references
|
|
43
|
+
|
|
44
|
+
Use context or state management for deeply nested data.
|
|
45
|
+
|
|
46
|
+
## Component Lifecycle Concerns
|
|
47
|
+
|
|
48
|
+
- **Mount** — initialize resources, fetch data
|
|
49
|
+
- **Update** — respond to prop changes
|
|
50
|
+
- **Unmount** — cleanup resources, cancel requests
|
|
51
|
+
- Handle all three phases explicitly
|
|
52
|
+
|
|
53
|
+
## Anti-Patterns
|
|
54
|
+
|
|
55
|
+
- Monolithic components (>200 lines suggest decomposition)
|
|
56
|
+
- Components that manage unrelated state
|
|
57
|
+
- Mixing presentation and business logic
|
|
58
|
+
- Props drilling through 3+ levels
|
|
59
|
+
- Implicit dependencies (magic strings, hardcoded values)
|
|
60
|
+
|
|
61
|
+
## Related Guidance
|
|
62
|
+
|
|
63
|
+
- `../testing/` - testing component behavior
|
|
64
|
+
- `../state-management/` - managing component data
|
|
65
|
+
- `../code-quality/` - formatting and style standards
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
# Components: Best Practices
|
|
2
|
+
|
|
3
|
+
Senior frontend developers design components that balance reusability, maintainability, and clarity. This guide provides actionable patterns for building better components.
|
|
4
|
+
|
|
5
|
+
## Design for Reusability
|
|
6
|
+
|
|
7
|
+
Build components that solve a specific problem once, then reuse them everywhere. This requires thinking about what makes a component truly reusable.
|
|
8
|
+
|
|
9
|
+
**Single Responsibility Principle (SRP):** Each component should have one reason to change. If you find yourself describing a component with "and," it probably does too much.
|
|
10
|
+
|
|
11
|
+
```javascript
|
|
12
|
+
// BAD: UserProfile does authentication, display, and data fetching
|
|
13
|
+
function UserProfile({ userId }) {
|
|
14
|
+
const [user, setUser] = useState(null);
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
fetchUser(userId).then(setUser);
|
|
17
|
+
}, [userId]);
|
|
18
|
+
|
|
19
|
+
if (!user) return <div>Loading...</div>;
|
|
20
|
+
return (
|
|
21
|
+
<div>
|
|
22
|
+
<h2>{user.name}</h2>
|
|
23
|
+
<p>{user.email}</p>
|
|
24
|
+
<button onClick={() => logout()}>Logout</button>
|
|
25
|
+
</div>
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// GOOD: Separate concerns
|
|
30
|
+
function UserProfile({ user, onLogout }) {
|
|
31
|
+
return (
|
|
32
|
+
<div>
|
|
33
|
+
<h2>{user.name}</h2>
|
|
34
|
+
<p>{user.email}</p>
|
|
35
|
+
<button onClick={onLogout}>Logout</button>
|
|
36
|
+
</div>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function UserProfileContainer({ userId }) {
|
|
41
|
+
const [user, setUser] = useState(null);
|
|
42
|
+
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
fetchUser(userId).then(setUser);
|
|
45
|
+
}, [userId]);
|
|
46
|
+
|
|
47
|
+
if (!user) return <div>Loading...</div>;
|
|
48
|
+
return <UserProfile user={user} onLogout={logout} />;
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**Composition over inheritance:** Build complex components by combining simpler ones rather than through inheritance.
|
|
53
|
+
|
|
54
|
+
```javascript
|
|
55
|
+
// GOOD: Compose smaller components
|
|
56
|
+
function Card({ children, title, actions }) {
|
|
57
|
+
return (
|
|
58
|
+
<div className="card">
|
|
59
|
+
<div className="card-header">
|
|
60
|
+
<h3>{title}</h3>
|
|
61
|
+
<div className="card-actions">{actions}</div>
|
|
62
|
+
</div>
|
|
63
|
+
<div className="card-body">{children}</div>
|
|
64
|
+
</div>
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function UserCard({ user, onEdit, onDelete }) {
|
|
69
|
+
return (
|
|
70
|
+
<Card
|
|
71
|
+
title={user.name}
|
|
72
|
+
actions={
|
|
73
|
+
<>
|
|
74
|
+
<button onClick={onEdit}>Edit</button>
|
|
75
|
+
<button onClick={onDelete}>Delete</button>
|
|
76
|
+
</>
|
|
77
|
+
}
|
|
78
|
+
>
|
|
79
|
+
<p>{user.email}</p>
|
|
80
|
+
<p>{user.role}</p>
|
|
81
|
+
</Card>
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Props Design
|
|
87
|
+
|
|
88
|
+
Well-designed props make components predictable and reusable. Props should communicate intent clearly.
|
|
89
|
+
|
|
90
|
+
**Be explicit:** Each prop should have a clear name and purpose. Use TypeScript or JSDoc to document.
|
|
91
|
+
|
|
92
|
+
```javascript
|
|
93
|
+
// GOOD: Explicit props with documentation
|
|
94
|
+
/**
|
|
95
|
+
* Button component
|
|
96
|
+
* @param {string} variant - 'primary' | 'secondary' | 'danger'
|
|
97
|
+
* @param {boolean} disabled - whether button is clickable
|
|
98
|
+
* @param {function} onClick - callback when clicked
|
|
99
|
+
* @param {ReactNode} children - button label
|
|
100
|
+
*/
|
|
101
|
+
function Button({ variant = 'primary', disabled = false, onClick, children }) {
|
|
102
|
+
return (
|
|
103
|
+
<button
|
|
104
|
+
className={`btn btn-${variant}`}
|
|
105
|
+
disabled={disabled}
|
|
106
|
+
onClick={onClick}
|
|
107
|
+
>
|
|
108
|
+
{children}
|
|
109
|
+
</button>
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**Avoid prop drilling:** Don't pass props through multiple intermediate components to reach a deeply nested component. Use Context or state management instead.
|
|
115
|
+
|
|
116
|
+
```javascript
|
|
117
|
+
// BAD: Prop drilling through multiple levels
|
|
118
|
+
function Page({ user }) {
|
|
119
|
+
return <MainLayout user={user} />;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function MainLayout({ user }) {
|
|
123
|
+
return <Sidebar user={user} />;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function Sidebar({ user }) {
|
|
127
|
+
return <UserMenu user={user} />;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function UserMenu({ user }) {
|
|
131
|
+
return <span>{user.name}</span>;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// GOOD: Use Context for deeply nested data
|
|
135
|
+
const UserContext = createContext();
|
|
136
|
+
|
|
137
|
+
function Page({ user }) {
|
|
138
|
+
return (
|
|
139
|
+
<UserContext.Provider value={user}>
|
|
140
|
+
<MainLayout />
|
|
141
|
+
</UserContext.Provider>
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function UserMenu() {
|
|
146
|
+
const user = useContext(UserContext);
|
|
147
|
+
return <span>{user.name}</span>;
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Component Lifecycle
|
|
152
|
+
|
|
153
|
+
Components go through distinct phases. Handle each one explicitly.
|
|
154
|
+
|
|
155
|
+
- **Mount:** Initialize resources, fetch data if needed
|
|
156
|
+
- **Update:** Respond to prop or state changes
|
|
157
|
+
- **Unmount:** Clean up resources, cancel pending requests
|
|
158
|
+
|
|
159
|
+
```javascript
|
|
160
|
+
function UserData({ userId }) {
|
|
161
|
+
const [data, setData] = useState(null);
|
|
162
|
+
const [error, setError] = useState(null);
|
|
163
|
+
|
|
164
|
+
useEffect(() => {
|
|
165
|
+
let mounted = true;
|
|
166
|
+
|
|
167
|
+
// Mount: fetch data
|
|
168
|
+
fetchUser(userId)
|
|
169
|
+
.then(result => {
|
|
170
|
+
if (mounted) setData(result);
|
|
171
|
+
})
|
|
172
|
+
.catch(err => {
|
|
173
|
+
if (mounted) setError(err);
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
// Unmount: cleanup
|
|
177
|
+
return () => {
|
|
178
|
+
mounted = false; // prevent state updates after unmount
|
|
179
|
+
};
|
|
180
|
+
}, [userId]); // Update: refetch when userId changes
|
|
181
|
+
|
|
182
|
+
if (error) return <div>Error: {error.message}</div>;
|
|
183
|
+
if (!data) return <div>Loading...</div>;
|
|
184
|
+
return <div>{data.name}</div>;
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## Performance Basics
|
|
189
|
+
|
|
190
|
+
Use memoization strategically to prevent unnecessary re-renders, but don't optimize prematurely.
|
|
191
|
+
|
|
192
|
+
```javascript
|
|
193
|
+
// Memoize when:
|
|
194
|
+
// 1. Component has complex render logic
|
|
195
|
+
// 2. Receives expensive props (objects/functions from parent)
|
|
196
|
+
// 3. Parent re-renders frequently
|
|
197
|
+
|
|
198
|
+
const UserProfile = React.memo(function UserProfile({ user, onUpdate }) {
|
|
199
|
+
return (
|
|
200
|
+
<div>
|
|
201
|
+
<h2>{user.name}</h2>
|
|
202
|
+
<button onClick={onUpdate}>Update</button>
|
|
203
|
+
</div>
|
|
204
|
+
);
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
// For callbacks, use useCallback to maintain referential equality
|
|
208
|
+
function Parent() {
|
|
209
|
+
const [count, setCount] = useState(0);
|
|
210
|
+
|
|
211
|
+
const handleUpdate = useCallback(() => {
|
|
212
|
+
// update logic
|
|
213
|
+
}, []); // Dependencies matter!
|
|
214
|
+
|
|
215
|
+
return <UserProfile user={user} onUpdate={handleUpdate} />;
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## Testing Approach
|
|
220
|
+
|
|
221
|
+
Design components to be testable by keeping them simple and pure.
|
|
222
|
+
|
|
223
|
+
```javascript
|
|
224
|
+
// GOOD: Testable component
|
|
225
|
+
function Button({ variant, disabled, onClick, children }) {
|
|
226
|
+
return (
|
|
227
|
+
<button className={`btn btn-${variant}`} disabled={disabled} onClick={onClick}>
|
|
228
|
+
{children}
|
|
229
|
+
</button>
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Easy to test: just check props map to output
|
|
234
|
+
test('Button renders with correct variant', () => {
|
|
235
|
+
render(<Button variant="primary">Click me</Button>);
|
|
236
|
+
expect(screen.getByRole('button')).toHaveClass('btn-primary');
|
|
237
|
+
});
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
## Documentation
|
|
241
|
+
|
|
242
|
+
Code comments should explain **why**, not **what**. The code shows what it does; comments explain design decisions.
|
|
243
|
+
|
|
244
|
+
```javascript
|
|
245
|
+
// GOOD: Comments explain intent
|
|
246
|
+
// We use a separate loading state instead of checking data === null
|
|
247
|
+
// because null is also a valid data value (empty results)
|
|
248
|
+
const [data, setData] = useState(null);
|
|
249
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
250
|
+
|
|
251
|
+
// BAD: Obvious from code
|
|
252
|
+
const [data, setData] = useState(null); // set data to null
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## Component Best Practices Checklist
|
|
256
|
+
|
|
257
|
+
- [ ] Component has single, clear responsibility
|
|
258
|
+
- [ ] Props are explicit and typed
|
|
259
|
+
- [ ] No prop drilling beyond 2 levels
|
|
260
|
+
- [ ] Component handles mount, update, and unmount phases
|
|
261
|
+
- [ ] Memoization used only where measurably beneficial
|
|
262
|
+
- [ ] Rendering logic is pure (no side effects)
|
|
263
|
+
- [ ] Component can be tested in isolation
|
|
264
|
+
- [ ] Documentation explains design decisions, not code
|
|
265
|
+
- [ ] Component reusable without modification
|
|
266
|
+
- [ ] Dependent cleanup happens in unmount phase
|
|
267
|
+
|
|
268
|
+
## Related Guidance
|
|
269
|
+
|
|
270
|
+
- `/testing` — testing component behavior
|
|
271
|
+
- `/state-management` — managing component data
|
|
272
|
+
- `/code-quality` — naming and style standards
|
|
273
|
+
- `/performance` — optimization techniques
|