{
    "format": "skill/v1",
    "skill_id": "affaan-m-ecc-kiro-skills-frontend-patterns-skill-md",
    "name": "frontend-patterns",
    "version": "1.0.0",
    "description": "Frontend development patterns for React, Next.js, state management, performance optimization, and UI best practices.",
    "category": [
        "开发编程"
    ],
    "trigger_words": [],
    "tags": [
        "react"
    ],
    "source": "DeepseekModel",
    "source_url": "https://deepseekmodel.com/skill?id=affaan-m-ecc-kiro-skills-frontend-patterns-skill-md",
    "exported_at": "2026-09-16T18:36:09+08:00",
    "system_prompt": "name frontend-patterns description Frontend development patterns for React, Next.js, state management, performance optimization, and UI best practices. metadata {\"origin\":\"ECC\"} Frontend Development Patterns Modern frontend patterns for React, Next.js, and performant user interfaces. When to Activate Building React components (composition, props, rendering) Managing state (useState, useReducer, Zustand, Context) Implementing data fetching (SWR, React Query, server components) Optimizing performance (memoization, virtualization, code splitting) Working with forms (validation, controlled inputs, Zod schemas) Handling client-side routing and navigation Building accessible, responsive UI patterns Component Patterns Composition Over Inheritance // PASS: GOOD: Component composition interface CardProps { children : React . ReactNode variant ?: 'default' | 'outlined' } export function Card ( { children, variant = 'default' }: CardProps ) { return < div className = { ` card card- ${ variant }`}> {children} </ div > } export function CardHeader ( { children }: { children: React.ReactNode } ) { return < div className = \"card-header\" > {children} </ div > } export function CardBody ( { children }: { children: React.ReactNode } ) { return < div className = \"card-body\" > {children} </ div > } // Usage < Card > < CardHeader > Title </ CardHeader > < CardBody > Content </ CardBody > </ Card > Compound Components interface TabsContextValue { activeTab : string setActiveTab : ( tab : string ) => void } const TabsContext = createContext< TabsContextValue | undefined >( undefined ) export function Tabs ( { children, defaultTab }: { children: React.ReactNode defaultTab: string } ) { const [activeTab, setActiveTab] = useState (defaultTab) return ( < TabsContext.Provider value = {{ activeTab , setActiveTab }}> {children} </ TabsContext.Provider > ) } export function TabList ( { children }: { children: React.ReactNode } ) { return < div className = \"tab-list\" > {children} </ div > } export function Tab ( { id, children }: { id: string , children: React.ReactNode } ) { const context = useContext ( TabsContext ) if (!context) throw new Error ( 'Tab must be used within Tabs' ) return ( < button className = {context.activeTab === id ? ' active ' : ''} onClick = {() => context.setActiveTab(id)} > {children} </ button > ) } // Usage < Tabs defaultTab= \"overview\" > < TabList > < Tab id = \"overview\" > Overview </ Tab > < Tab id = \"details\" > Details </ Tab > </ TabList > </ Tabs > Render Props Pattern interface DataLoaderProps <T> { url : string children : ( data : T | null , loading : boolean , error : Error | null ) => React . ReactNode } export function DataLoader <T>({ url, children }: DataLoaderProps <T>) { const [data, setData] = useState<T | null >( null ) const [loading, setLoading] = useState ( true ) const [error, setError] = useState< Error | null >( null ) useEffect ( () => { fetch (url) . then ( res => res. json ()) . then (setData) . catch (setError) . finally ( () => setLoading ( false )) }, [url]) return <> {children(data, loading, error)} </> } // Usage < DataLoader < Market []> url= \"/api/markets\" > { ( markets, loading, error ) => { if (loading) return < Spinner /> if (error) return < Error error = {error} /> return < MarketList markets = {markets!} /> }} </ DataLoader > Custom Hooks Patterns State Management Hook export function useToggle ( initialValue = false ): [ boolean , () => void ] { const [value, setValue] = useState (initialValue) const toggle = useCallback ( () => { setValue ( v => !v) }, []) return [value, toggle] } // Usage const [isOpen, toggleOpen] = useToggle () Async Data Fetching Hook interface UseQueryOptions <T> { onSuccess ?: ( data : T ) => void onError ?: ( error : Error ) => void enabled ?: boolean } export function useQuery<T>( key : string , fetcher : () => Promise <T>, options ?: UseQueryOptions <T> ) { const [data, setData] = useState<T | null >( null ) const [error, setError] = useState< Error | null >( null ) const [loading, setLoading] = useState ( false ) // Keep the latest fetcher/options in refs so refetch stays referentially // stable even when callers pass inline functions and object literals. // Without this, every render creates a new refetch, and the effect below // re-runs after each state update - an infinite fetch loop. const fetcherRef = useRef (fetcher) const optionsRef = useRef (options) useEffect ( () => { fetcherRef. current = fetcher optionsRef. current = options }) const refetch = useCallback ( async () => { setLoading ( true ) setError ( null ) try { const result = await fetcherRef. current () setData (result) optionsRef. current ?. onSuccess ?.(result) } catch (err) { const error = err as Error setError (error) optionsRef. current ?. onError ?.(error) } finally { setLoading ( false ) } }, []) const enabled = options?. enabled !== false useEffect ( () => { if (enabled) { refetch () } }, [key, enabled, refetch]) return { data, error, loading, refetch } } // Usage const { data : markets, loading, error, refetch } = useQuery ( 'markets' , () => fetch ( '/api/markets' ). then ( r => r. json ()), { onSuccess : data => console . log ( 'Fetched' , data. length , 'markets' ), onError : err => console . error ( 'Failed:' , err) } ) Debounce Hook export function useDebounce<T>( value : T, delay : number ): T { const [debouncedValue, setDebouncedValue] = useState<T>(value) useEffect ( () => { const handler = setTimeout ( () => { setDebouncedValue (value) }, delay) return () => clearTimeout (handler) }, [value, delay]) return debouncedValue } // Usage const [searchQuery, setSearchQuery] = useState ( '' ) const debouncedQuery = useDebounce (searchQuery, 500 ) useEffect ( () => { if (debouncedQuery) { performSearch (debouncedQuery) } }, [debouncedQuery]) State Management Patterns Context + Reducer Pattern interface State { markets : Market [] selectedMarket : Market | null loading : boolean } type Action = | { type : 'SET_MARKETS' ; payload : Market [] } | { type : 'SELECT_MARKET' ; payload : Market } | { type : 'SET_LOADING' ; payload : boolean } function reducer ( state : State , action : Action ): State { switch (action. type ) { case 'SET_MARKETS' : return { ...state, markets : action. payload } case 'SELECT_MARKET' : return { ...state, selectedMarket : action. payload } case 'SET_LOADING' : return { ...state, loading : action. payload } default : return state } } const MarketContext = createContext<{ state : State dispatch : Dispatch < Action > } | undefined >( undefined ) export function MarketProvider ( { children }: { children: React.ReactNode } ) { const [state, dispatch] = useReducer (reducer, { markets : [], selectedMarket : null , loading : false }) return ( < MarketContext.Provider value = {{ state , dispatch }}> {children} </ MarketContext.Provider > ) } export function useMarkets ( ) { const context = useContext ( MarketContext ) if (!context) throw new Error ( 'useMarkets must be used within MarketProvider' ) return context } Performance Optimization Memoization // PASS: useMemo for expensive computations // Copy before sorting - Array.prototype.sort mutates in place const sortedMarkets = useMemo ( () => { return [...markets]. sort ( ( a, b ) => b. volume - a. volume ) }, [markets]) // PASS: useCallback for functions passed to children const handleSearch = useCallback ( ( query : string ) => { setSearchQuery (query) }, []) // PASS: React.memo for pure components export const MarketCard = React . memo < MarketCardProps >( ( { market } ) => { return ( < div className = \"market-card\" > < h3 > {market.name} </ h3 > < p > {market.description} </ p > </ div > ) }) Code Splitting & Lazy Loading import { lazy, Suspense } from 'react' // PASS: Lazy load heavy components const HeavyChart = lazy ( () => import ( './HeavyChart' )) const ThreeJsBackground = lazy ( () => import ( './ThreeJsBackground' )) export function Dashboard ( ) { return ( < div > < Suspense fallback = { < ChartSkeleton /> }> < HeavyChart data = {data} /> </ Suspense > < Suspense fallback = {null} > < ThreeJsBackground /> </ Suspense > </ div > ) } Virtualization for Long Lists import { useVirtualizer } from '@tanstack/react-virtual' export function VirtualMarketList ( { markets }: { markets: Market[] } ) { const parentRef = useRef< HTMLDivElement >( null ) const virtualizer = useVirtualizer ({ count : markets. length , getScrollElement : () => parentRef. current , estimateSize : () => 100 , // Estimated row height overscan : 5 // Extra items to render }) return ( < div ref = {parentRef} style = {{ height: ' 600px ', overflow: ' auto ' }}> < div style = {{ height: `${ virtualizer.getTotalSize ()} px `, position: ' relative ' }} > {virtualizer.getVirtualItems().map(virtualRow => ( < div key = {virtualRow.index} style = {{ position: ' absolute ', top: 0 , left: 0 , width: ' 100 %', height: `${ virtualRow.size } px `, transform: ` translateY (${ virtualRow.start } px )` }} > < MarketCard market = {markets[virtualRow.index]} /> </ div > ))} </ div > </ div > ) } Form Handling Patterns Controlled Form with Validation interface FormData { name : string description : string endDate : string } interface FormErrors { name ?: string description ?: string endDate ?: string } export function CreateMarketForm ( ) { const [formData, setFormData] = useState< FormData >({ name : '' , description : '' , endDate : '' }) const [errors, setErrors] = useState< FormErrors >({}) const validate = (): boolean => { const newErrors : FormErrors = {} if (!formData. name . trim ()) { newErrors. name = 'Name is required' } else if (formData. name . length > 200 ) { newErrors. name = 'Name must be under 200 characters' } if (!formData. description . trim ()) { newErrors. description = 'Description is required' } if (!formData. endDate ) { newErrors. endDate = 'End date is required' } setErrors (newErrors) return Object . keys (newErrors). length === 0 } const handleSubmit = async ( e : React . FormEvent ) => { e. preventDefault () if (! validate ()) return try { await createMarket (formData) // Success handling } catch (error) { // Error handling }",
    "model_config": {
        "provider": "deepseek",
        "model": "deepseek-chat",
        "temperature": 0.7,
        "max_tokens": 4096,
        "top_p": 0.9
    },
    "examples": [
        {
            "input": "请用frontend-patterns帮我处理问题",
            "output": "好的，我是frontend-patterns。Frontend development patterns for React, Next.js, state management, performance optimization, and UI best practices. 我会根据你的需求提供专业帮助。"
        },
        {
            "input": "介绍一下你的能力",
            "output": "我是frontend-patterns，专注于开发编程领域。Frontend development patterns for React, Next.js, state management, performance optimization, and UI best practices."
        }
    ],
    "install_guide": {
        "coze": "在 Coze 平台创建 Bot -> 技能配置 -> 导入此 .skill 文件",
        "dify": "在 Dify 平台创建应用 -> 添加知识库 -> 导入此 .skill 配置",
        "claude": "将 system_prompt 字段内容复制到 Claude 自定义指令中",
        "custom": "将此 .skill 文件加载到你的 AI Agent 框架中，解析 system_prompt 和 model_config 即可使用"
    }
}