Token导航 LogoToken导航TokenDH.com
研究检索需要联网github未标认证来源可访问许可证需确认审计通过

ideal-react-componentideal React component 搜索

Agent Skill

用于辅助前端页面、组件、样式和交互逻辑的开发与维护。它适合让 Agent 生成或审查 React、Next.js、Vue、Tailwind、CSS 等相关代码,整理组件结构,或定位布局和性能问题。使用时需要结合项目现有设计系统、路由和构建方式,避免只生成孤立片段;涉及页面改动时,应配合本地预览和构建检查确认视觉效果。

总安装

729

周安装

31

GitHub Stars

2

下载量

255
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:ideal-react-component(ideal React component 搜索)
来源仓库:https://github.com/antjanus/skillbox
仓库路径:skills/ideal-react-component
安装命令:
npx skills add https://github.com/antjanus/skillbox --skill ideal-react-component
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/antjanus/skillbox --skill ideal-react-component

简介

用于辅助前端页面、组件和样式逻辑的开发与维护。

  • 适合生成或审查 React、Next.js、Vue 等相关代码。
  • 通过 GitHub 安装,支持 Codex、Claude、Cursor 等宿主。
  • 需结合项目现有设计系统和路由方式使用。ideal-react-component 属于研究检索类 Skill,可作为该场景下的辅助能力补充。
  • 涉及页面改动时应配合本地预览和构建检查。

SKILL.md

Ideal React Component Structure

Overview

A battle-tested pattern for organizing React component files that emphasizes readability, maintainability, and logical flow. This structure helps teams maintain consistency and makes components easier to understand at a glance.

Core principle: Declare everything in a predictable order--imports to styles to types to logic to render--so developers know where to find things.

When to Use

Always use when:

  • Creating new React components
  • Refactoring existing components
  • Reviewing component structure during code review
  • Onboarding developers to component patterns

Useful for:

  • Establishing team conventions
  • Maintaining large component libraries
  • Teaching React best practices
  • Reducing cognitive load when reading components

Avoid when:

  • Working with class components (this pattern is for function components)
  • Component is < 20 lines and simple (don't over-engineer)
  • Project has different established conventions (consistency > perfection)

The Ideal Structure

Components should follow this seven-section pattern:

// 1. IMPORTS (organized by source)
import React, { useState, useEffect } from 'react';
import { useQuery } from 'react-query';

import { formatDate } from '@/utils/date';
import { api } from '@/services/api';

import { Button } from './Button';

// 2. STYLED COMPONENTS (prefixed with "Styled")
const StyledContainer = styled.div`
  padding: 1rem;
  background: white;
`;

// 3. TYPE DEFINITIONS (ComponentNameProps pattern)
type UserProfileProps = {
  userId: string;
  onUpdate?: (user: User) => void;
};

// 4. COMPONENT FUNCTION
export const UserProfile = ({ userId, onUpdate }: UserProfileProps): JSX.Element => {
  // 5. LOGIC SECTIONS (in this order)
  // - Local state
  // - Custom/data hooks
  // - useEffect/useLayoutEffect
  // - Post-processing
  // - Callback handlers

  // 6. CONDITIONAL RENDERING (exit early)
  if (isLoading) return <Loading />;
  if (error) return <Error message={error.message} />;
  if (!data) return <Empty />;

  // 7. DEFAULT RENDER (success state)
  return (
    <StyledContainer>
      {/* Main component JSX */}
    </StyledContainer>
  );
};

JavaScript: Same pattern without type annotations (skip Section 3 or use JSDoc).

Section 1: Import Organization

Order imports by source to reduce cognitive load:

// ✅ Good: Clear grouping with blank lines
import React, { useState, useEffect, useMemo } from 'react';
import { useQuery, useMutation } from 'react-query';
import { format } from 'date-fns';

import { api } from '@/services/api';
import { formatCurrency } from '@/utils/format';

import { Button } from './Button';
import { Card } from './Card';
// ❌ Bad: Random order, no grouping
import { Button } from './Button';
import { format } from 'date-fns';
import React, { useState } from 'react';
import { api } from '@/services/api';
import { useQuery } from 'react-query';

Import priority:

  1. React imports (first)
  2. Third-party libraries (followed by blank line)
  3. Internal/aliased imports (@/) (followed by blank line)
  4. Local component imports (same directory)

Section 2: Styling

The key principle is separating styling from logic. The approach depends on your styling solution:

styled-components / emotion: Prefix with Styled for instant recognition:

const StyledTitle = styled.h2font-size: 1.5rem; margin-bottom: 0.5rem;;

export const Card = ({title, children}) => ({title} {children});

</Good>

<Bad>

// ❌ Bad: Can't tell if CardWrapper is styled or contains logic const CardWrapper = styled.div border: 1px solid #ccc; ;

const Title = styled.h2 font-size: 1.5rem; ;


**When styled components grow large:**

- Move to co-located `ComponentName.styled.ts` file
- Import as `import * as S from './ComponentName.styled'`
- Use as `<S.Container>`, `<S.Title>`, etc.

**Tailwind CSS:** Extract repeated utility sets into components or use `@apply`:

// Wrapper component keeps JSX clean const Card = ({ title, children }: CardProps) => ( <div className="border border-gray-300 rounded-lg p-4"> <h2 className="text-xl mb-2">{title}</h2> {children} </div> );


**CSS Modules:** Import as `styles` and use bracket notation:

import styles from './Card.module.css';

const Card = ({ title, children }: CardProps) => ( <div className={styles.container}> <h2 className={styles.title}>{title}</h2> {children} </div> );


**JavaScript:** Same patterns work for `.js`/`.jsx` files.

## Section 3: Type Definitions

**Declare types immediately above the component for visibility:**

export const Button = ({variant = 'primary', size = 'md', onClick, children}: ButtonProps): JSX.Element => {// Component logic};

</Good>

<Bad>

// ❌ Bad: Inline types hide the API
export const Button = ({ variant, size, onClick, children }: {
  variant?: 'primary' | 'secondary'; size?: 'sm' | 'md' | 'lg';
  onClick: () => void; children: React.ReactNode;
}) => { /* ... */ };

Naming: Props: ComponentNameProps. Return types: JSX.Element (or custom: ComponentNameReturn).

JavaScript: Use JSDoc @typedef and @param annotations for equivalent documentation.

Why: Makes component API visible at a glance, easier to modify without disturbing component code, better for documentation.

Section 4: Component Function

Use named exports with const arrow functions:

Why const + arrow functions:

  • Easy to wrap with useCallback later if needed
  • Consistent with other hooks and callbacks in component
  • Named exports are easier to refactor and search for

JavaScript: Same pattern without type annotations.

Section 5: Logic Flow

Organize component logic in this strict order:

export const UserProfile = ({ userId }: UserProfileProps): JSX.Element => {
  // 5.1 - LOCAL STATE
  const [isEditing, setIsEditing] = useState(false);
  const inputRef = useRef<HTMLInputElement>(null);

  // 5.2 - CUSTOM/DATA HOOKS
  const { data: user, isLoading, error } = useQuery(['user', userId], () => api.getUser(userId));
  const { mutate: updateUser } = useMutation(api.updateUser);

  // 5.3 - useEffect/useLayoutEffect
  useEffect(() => {
    if (isEditing && inputRef.current) inputRef.current.focus();
  }, [isEditing]);

  // 5.4 - POST-PROCESSING
  const displayName = user ? `${user.firstName} ${user.lastName}` : '';

  // 5.5 - CALLBACK HANDLERS
  const handleEdit = () => setIsEditing(true);
  const handleSave = (updates: Partial<User>) => { updateUser(updates); setIsEditing(false); };

  // [Next: Conditional rendering, then Default render]
};

Why this order: Respects React's hook rules, puts dependent logic after dependencies, makes component flow easy to trace.

JavaScript: Same ordering applies without type annotations.

Section 6: Conditional Rendering

Exit early for loading, error, and empty states:

// Success state continues below return {/* Main component JSX */};

</Good>

<Bad>

// ❌ Bad: Nested ternaries are hard to read return ( <div> {isLoading ? <LoadingSpinner /> : error ? <ErrorMessage /> : !data ? <EmptyState /> : ( <div>{/* Main component JSX buried deep */}</div> )} </div> );


**Benefits of early returns:**

- Reduces nesting depth
- Main success render stays at bottom (most important case)
- Each condition is independent and easy to test
- TypeScript can narrow types after guards

**JavaScript:** Same pattern applies.

## Section 7: Default Render

**Keep the success/default render at the bottom, after all early returns:**

// Success state - the main component render return ( <StyledContainer> <StyledHeader> <StyledTitle>{displayName}</StyledTitle> <Button onClick={handleEdit}>Edit</Button> </StyledHeader> {isEditing ? ( <EditForm user={user} onSave={handleSave} onCancel={handleCancel} /> ) : ( <UserDetails user={user} /> )} </StyledContainer> );


**Why:** Most important case (happy path) is most visible. All error states eliminated, all data and handlers already declared.

## Refactoring: Extract to Custom Hooks

When components exceed 50 lines of logic or 200 lines total, extract stateful logic into a `use[Domain]` custom hook. The component becomes presentation-focused; the hook owns state and data flow.

See **[Refactoring to Custom Hooks](https://github.com/antjanus/skillbox/blob/HEAD/skills/ideal-react-component/./reference/REFACTORING.md)** for full examples, extraction criteria, and hook composition patterns.

## Common Hooks Antipatterns (Quick Reference)

These are the most frequent causes of infinite loops, stale data, and unexpected re-renders:

**1. useEffect as onChange callback** - Causes double renders or infinite loops:

// ❌ Bad: Effect syncs state derived from other state useEffect(() => { setFullName(${first} ${last}); }, [first, last]);

// ✅ Good: Derive during render instead const fullName = ${first} ${last};


**2. useState initial value not updating with props:**

// ❌ Bad: Initial value only runs once, won't track prop changes const [value, setValue] = useState(props.initialValue);

// ✅ Good: Use a key to reset, or useEffect to sync <Component key={itemId} initialValue={data.value} />


**3. Non-exhaustive dependency arrays** - Causes stale closures:

// ❌ Bad: Missing dependency means stale count value useEffect(() => { setTotal(count * price); }, [price]);

// ✅ Good: Include all dependencies useEffect(() => { setTotal(count * price); }, [count, price]);


For detailed explanations and more patterns, see **[React Hooks Antipatterns](https://github.com/antjanus/skillbox/blob/HEAD/skills/ideal-react-component/./reference/HOOKS-ANTIPATTERNS.md)**.

## Deep Reference

- **[Complete Component Examples](https://github.com/antjanus/skillbox/blob/HEAD/skills/ideal-react-component/./reference/COMPLETE-EXAMPLES.md)** - Full TypeScript and JavaScript component examples
- **[Refactoring to Custom Hooks](https://github.com/antjanus/skillbox/blob/HEAD/skills/ideal-react-component/./reference/REFACTORING.md)** - Extraction criteria, full examples, hook composition
- **[React Hooks Antipatterns](https://github.com/antjanus/skillbox/blob/HEAD/skills/ideal-react-component/./reference/HOOKS-ANTIPATTERNS.md)** - Deep dive on infinite loops, stale closures, dependency arrays

*Only load these when specifically needed to save context.*

## Quality Signals

A well-structured React component has these properties:

- **Imports grouped by source** — React, third-party, internal, local — with blank lines between
- **Types declared above the component** — component API visible at a glance
- **Logic follows the strict order** — state, hooks, effects, post-processing, handlers
- **Early returns for edge cases** — loading/error/empty states exit before the main render
- **Success render at the bottom** — the happy path is the most visible code
- **Under 200 lines** or logic extracted to custom hooks

## Quick Reference

| Section | What Goes Here | Why |
| --- | --- | --- |
| 1. Imports | React, libraries, internal, local | Easy to find dependencies |
| 2. Styling | Styled components, Tailwind, CSS Modules | Visual separation from logic |
| 3. Type Definitions | `*Props`, `*Return` types | Component API visibility |
| 4. Component Function | `export const Component =` | Named exports for refactoring |
| 5. Logic Flow | State -> Hooks -> Effects -> Handlers | Respects hook rules, logical order |
| 6. Conditional Rendering | Early returns for edge cases | Reduces nesting |
| 7. Default Render | Success state JSX | Most important case most visible |

## Troubleshooting

### Problem: Component is getting too long (> 200 lines)

**Cause:** Too much logic in one file

**Solution:**

1. Extract data fetching to custom hook (`useUserProfile`)
2. Move styled components to `ComponentName.styled.ts`
3. Split into smaller sub-components
4. Extract complex calculations to utility functions

### Problem: Can't decide if something should be a styled component or a sub-component

**Solution:**

- **Styled component** if it only adds styling (no props, no logic)
- **Sub-component** if it has its own props, state, or logic

### Problem: TypeScript types getting complex

**Solution:** Split component into smaller pieces, extract shared types to `types.ts`, use utility types (`Pick`, `Omit`, `Partial`).

### Problem: Hooks causing infinite re-render loop, stale data, or state not syncing

**Solution:** See the **Common Hooks Antipatterns** section above for the top 3 patterns, or load **[React Hooks Antipatterns](https://github.com/antjanus/skillbox/blob/HEAD/skills/ideal-react-component/./reference/HOOKS-ANTIPATTERNS.md)** for the full guide.

## Variations and Flexibility

**This is a pattern, not a law.** Adapt as needed:

- **Small components** (< 50 lines) can skip some structure
- **Simple components** without state can skip logic sections
- **React Server Components** don't use hooks or client state - skip logic sections, focus on data fetching and render

## Integration

**Works with:** styled-components, emotion, Tailwind CSS, CSS Modules, React Query / TanStack Query, SWR, Zustand / Redux

**Pairs well with:** ESLint (`eslint-plugin-import`), Prettier, TypeScript, Storybook, Vitest / Jest

**Note on GSD workflows:** When using GSD skills (discuss-phase, execute-phase) for React work, this skill won't auto-activate — GSD owns the execution pipeline. Reference this skill explicitly with `/ideal-react-component` during GSD phases that create React components, or add it to your project's CLAUDE.md as a convention to follow.

## References

- [The Anatomy of My Ideal React Component](https://antjanus.com/digital-garden/the-anatomy-of-my-ideal-react-component) - Antonin Januska
- [Common React Hooks Antipatterns and Gotchas](https://antjanus.com/digital-garden/common-react-hooks-antipatterns-and-gotchas) - Antonin Januska
- [React Hooks Rules](https://react.dev/reference/rules/rules-of-hooks) | [Custom Hooks Guide](https://react.dev/learn/reusing-logic-with-custom-hooks)
- [TypeScript React Cheatsheet](https://react-typescript-cheatsheet.netlify.app/) | [Thinking in React](https://react.dev/learn/thinking-in-react)

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Codex

37.79%
按下载量换算96

Claude

32.22%
按下载量换算82

Cursor

17.8%
按下载量换算45

Gemini CLI

10.1%
按下载量换算26

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills