Source profileQuality 66/100

affaan-m/ECC/docs/tr/skills/frontend-patterns/SKILL.md

frontend-patterns

React, Next.js, state yönetimi, performans optimizasyonu ve UI en iyi uygulamaları için frontend geliştirme kalıpları.

Source repository stars
234,327
Declared platforms
0
Static risk flags
1
Last source update
2026-07-27
Source checked
2026-07-28

Decision brief

What it does—and where it fits

React, Next.js ve performanslı kullanıcı arayüzleri için modern frontend kalıpları.

Best for

    Not for

    • Tasks that require unconfirmed production actions or broad system permissions.
    • Environments where the pinned source and install steps cannot be inspected.

    Compatibility matrix

    Platform support, with evidence labels

    PlatformStatusEvidenceWhat to check
    CodexNot declaredNo explicit evidencePortability before use
    Claude CodeNot declaredNo explicit evidencePortability before use
    CursorNot declaredNo explicit evidencePortability before use
    Gemini CLINot declaredNo explicit evidencePortability before use
    Open the compatibility checker

    Installation

    Inspect first. Install second.

    The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.

    Source-detected install commandSource
    npx skills add https://github.com/affaan-m/ECC --skill "docs/tr/skills/frontend-patterns"
    Safe inspection promptEditorial

    Inspect the Agent Skill "frontend-patterns" from https://github.com/affaan-m/ECC/blob/4e973d3eaf92d97f8d2e2d8abb39d8bdc8711b38/docs/tr/skills/frontend-patterns/SKILL.md at commit 4e973d3eaf92d97f8d2e2d8abb39d8bdc8711b38. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.

    Workflow

    What the source asks the agent to do

    1. 01

      Ne Zaman Aktifleştirmelisiniz

      React bileşenleri oluştururken (composition, props, rendering)

      React bileşenleri oluştururken (composition, props, rendering)State yönetirken (useState, useReducer, Zustand, Context)Veri çekme implementasyonu (SWR, React Query, server components)
    2. 02

      Bileşen Kalıpları

      Review the “Bileşen Kalıpları” section in the pinned source before continuing.

      Review and apply the “Bileşen Kalıpları” source section.
    3. 03

      Kalıtım Yerine Composition

      Review the “Kalıtım Yerine Composition” section in the pinned source before continuing.

      Review and apply the “Kalıtım Yerine Composition” source section.
    4. 04

      Compound Components

      Review the “Compound Components” section in the pinned source before continuing.

      Review and apply the “Compound Components” source section.
    5. 05

      Render Props Kalıbı

      Review the “Render Props Kalıbı” section in the pinned source before continuing.

      Review and apply the “Render Props Kalıbı” source section.

    Permission review

    Static risk signals and limitations

    Network access

    medium · line 109

    The documentation includes network, browsing, or remote request actions.

    fetch(url)

    Network access

    medium · line 209

    The documentation includes network, browsing, or remote request actions.

    () => fetch('/api/markets').then(r => r.json()),

    Evidence record

    Why each signal appears

    EvidenceSourceComputedTestedEditorial
    SignalValueEvidence typeMeaning
    Quality score66/100ComputedDocumentation, specificity, maintenance, and trust rules
    Repository stars234,327SourceRepository attention, not individual Skill quality
    Compatibility0 platformsSourceDeclared in the catalog source record
    Usage guideautomated source guideEditorialGenerated or reviewed according to the visible evidence level

    Pinned source

    Provenance and original SKILL.md

    Repository
    affaan-m/ECC
    Skill path
    docs/tr/skills/frontend-patterns/SKILL.md
    Commit
    4e973d3eaf92d97f8d2e2d8abb39d8bdc8711b38
    License
    MIT
    Collected
    2026-07-28
    Default branch
    main
    View the original SKILL.md

    Frontend Geliştirme Kalıpları

    React, Next.js ve performanslı kullanıcı arayüzleri için modern frontend kalıpları.

    Ne Zaman Aktifleştirmelisiniz

    • React bileşenleri oluştururken (composition, props, rendering)
    • State yönetirken (useState, useReducer, Zustand, Context)
    • Veri çekme implementasyonu (SWR, React Query, server components)
    • Performans optimize ederken (memoization, virtualization, code splitting)
    • Formlarla çalışırken (validation, controlled inputs, Zod schemas)
    • Client-side routing ve navigasyon işlerken
    • Erişilebilir, responsive UI kalıpları oluştururken

    Bileşen Kalıpları

    Kalıtım Yerine Composition

    // PASS: İYİ: Bileşen 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>
    }
    
    // Kullanım
    <Card>
      <CardHeader>Başlık</CardHeader>
      <CardBody>İçerik</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>
      )
    }
    
    // Kullanım
    <Tabs defaultTab="overview">
      <TabList>
        <Tab id="overview">Genel Bakış</Tab>
        <Tab id="details">Detaylar</Tab>
      </TabList>
    </Tabs>
    

    Render Props Kalıbı

    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)}</>
    }
    
    // Kullanım
    <DataLoader<Market[]> url="/api/markets">
      {(markets, loading, error) => {
        if (loading) return <Spinner />
        if (error) return <Error error={error} />
        return <MarketList markets={markets!} />
      }}
    </DataLoader>
    

    Özel Hook Kalıpları

    State Yönetimi Hook'u

    export function useToggle(initialValue = false): [boolean, () => void] {
      const [value, setValue] = useState(initialValue)
    
      const toggle = useCallback(() => {
        setValue(v => !v)
      }, [])
    
      return [value, toggle]
    }
    
    // Kullanım
    const [isOpen, toggleOpen] = useToggle()
    

    Async Veri Çekme Hook'u

    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)
    
      // Çağıranlar satır içi fonksiyonlar ve nesne literalleri geçirse bile
      // refetch'in referans olarak kararlı kalması için en güncel fetcher/options
      // değerlerini ref'lerde tutun. Bu olmadan her render yeni bir refetch
      // oluşturur ve aşağıdaki effect her state güncellemesinden sonra yeniden
      // çalışır - sonsuz bir fetch döngüsü.
      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 }
    }
    
    // Kullanım
    const { data: markets, loading, error, refetch } = useQuery(
      'markets',
      () => fetch('/api/markets').then(r => r.json()),
      {
        onSuccess: data => console.log('Getirilen', data.length, 'market'),
        onError: err => console.error('Başarısız:', err)
      }
    )
    

    Debounce Hook'u

    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
    }
    
    // Kullanım
    const [searchQuery, setSearchQuery] = useState('')
    const debouncedQuery = useDebounce(searchQuery, 500)
    
    useEffect(() => {
      if (debouncedQuery) {
        performSearch(debouncedQuery)
      }
    }, [debouncedQuery])
    

    State Yönetimi Kalıpları

    Context + Reducer Kalıbı

    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
    }
    

    Performans Optimizasyonu

    Memoization

    // PASS: Pahalı hesaplamalar için useMemo
    // Sıralamadan önce kopyalayın - Array.prototype.sort yerinde değiştirir
    const sortedMarkets = useMemo(() => {
      return [...markets].sort((a, b) => b.volume - a.volume)
    }, [markets])
    
    // PASS: Alt bileşenlere geçirilen fonksiyonlar için useCallback
    const handleSearch = useCallback((query: string) => {
      setSearchQuery(query)
    }, [])
    
    // PASS: Pure bileşenler için React.memo
    export const MarketCard = React.memo<MarketCardProps>(({ market }) => {
      return (
        <div className="market-card">
          <h3>{market.name}</h3>
          <p>{market.description}</p>
        </div>
      )
    })
    

    Code Splitting ve Lazy Loading

    import { lazy, Suspense } from 'react'
    
    // PASS: Ağır bileşenleri lazy yükle
    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>
      )
    }
    

    Uzun Listeler için Virtualization

    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,  // Tahmini satır yüksekliği
        overscan: 5  // Ekstra render edilecek öğeler
      })
    
      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 İşleme Kalıpları

    Doğrulamalı Controlled Form

    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 = 'İsim gereklidir'
        } else if (formData.name.length > 200) {
          newErrors.name = 'İsim 200 karakterden az olmalıdır'
        }
    
        if (!formData.description.trim()) {
          newErrors.description = 'Açıklama gereklidir'
        }
    
        if (!formData.endDate) {
          newErrors.endDate = 'Bitiş tarihi gereklidir'
        }
    
        setErrors(newErrors)
        return Object.keys(newErrors).length === 0
      }
    
      const handleSubmit = async (e: React.FormEvent) => {
        e.preventDefault()
    
        if (!validate()) return
    
        try {
          await createMarket(formData)
          // Başarı işleme
        } catch (error) {
          // Hata işleme
        }
      }
    
      return (
        <form onSubmit={handleSubmit}>
          <input
            value={formData.name}
            onChange={e => setFormData(prev => ({ ...prev, name: e.target.value }))}
            placeholder="Market ismi"
          />
          {errors.name && <span className="error">{errors.name}</span>}
    
          {/* Diğer alanlar */}
    
          <button type="submit">Market Oluştur</button>
        </form>
      )
    }
    

    Error Boundary Kalıbı

    interface ErrorBoundaryState {
      hasError: boolean
      error: Error | null
    }
    
    export class ErrorBoundary extends React.Component<
      { children: React.ReactNode },
      ErrorBoundaryState
    > {
      state: ErrorBoundaryState = {
        hasError: false,
        error: null
      }
    
      static getDerivedStateFromError(error: Error): ErrorBoundaryState {
        return { hasError: true, error }
      }
    
      componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
        console.error('Error boundary caught:', error, errorInfo)
      }
    
      render() {
        if (this.state.hasError) {
          return (
            <div className="error-fallback">
              <h2>Bir şeyler yanlış gitti</h2>
              <p>{this.state.error?.message}</p>
              <button onClick={() => this.setState({ hasError: false })}>
                Tekrar dene
              </button>
            </div>
          )
        }
    
        return this.props.children
      }
    }
    
    // Kullanım
    <ErrorBoundary>
      <App />
    </ErrorBoundary>
    

    Animasyon Kalıpları

    Framer Motion Animasyonları

    import { motion, AnimatePresence } from 'framer-motion'
    
    // PASS: Liste animasyonları
    export function AnimatedMarketList({ markets }: { markets: Market[] }) {
      return (
        <AnimatePresence>
          {markets.map(market => (
            <motion.div
              key={market.id}
              initial={{ opacity: 0, y: 20 }}
              animate={{ opacity: 1, y: 0 }}
              exit={{ opacity: 0, y: -20 }}
              transition={{ duration: 0.3 }}
            >
              <MarketCard market={market} />
            </motion.div>
          ))}
        </AnimatePresence>
      )
    }
    
    // PASS: Modal animasyonları
    export function Modal({ isOpen, onClose, children }: ModalProps) {
      return (
        <AnimatePresence>
          {isOpen && (
            <>
              <motion.div
                className="modal-overlay"
                initial={{ opacity: 0 }}
                animate={{ opacity: 1 }}
                exit={{ opacity: 0 }}
                onClick={onClose}
              />
              <motion.div
                className="modal-content"
                initial={{ opacity: 0, scale: 0.9, y: 20 }}
                animate={{ opacity: 1, scale: 1, y: 0 }}
                exit={{ opacity: 0, scale: 0.9, y: 20 }}
              >
                {children}
              </motion.div>
            </>
          )}
        </AnimatePresence>
      )
    }
    

    Erişilebilirlik Kalıpları

    Klavye Navigasyonu

    export function Dropdown({ options, onSelect }: DropdownProps) {
      const [isOpen, setIsOpen] = useState(false)
      const [activeIndex, setActiveIndex] = useState(0)
    
      const handleKeyDown = (e: React.KeyboardEvent) => {
        switch (e.key) {
          case 'ArrowDown':
            e.preventDefault()
            setActiveIndex(i => Math.min(i + 1, options.length - 1))
            break
          case 'ArrowUp':
            e.preventDefault()
            setActiveIndex(i => Math.max(i - 1, 0))
            break
          case 'Enter':
            e.preventDefault()
            onSelect(options[activeIndex])
            setIsOpen(false)
            break
          case 'Escape':
            setIsOpen(false)
            break
        }
      }
    
      return (
        <div
          role="combobox"
          aria-expanded={isOpen}
          aria-haspopup="listbox"
          onKeyDown={handleKeyDown}
        >
          {/* Dropdown implementasyonu */}
        </div>
      )
    }
    

    Focus Yönetimi

    export function Modal({ isOpen, onClose, children }: ModalProps) {
      const modalRef = useRef<HTMLDivElement>(null)
      const previousFocusRef = useRef<HTMLElement | null>(null)
    
      useEffect(() => {
        if (isOpen) {
          // Şu anki focus'lanmış elementi kaydet
          previousFocusRef.current = document.activeElement as HTMLElement
    
          // Modal'a focus yap
          modalRef.current?.focus()
        } else {
          // Kapatırken focus'u geri yükle
          previousFocusRef.current?.focus()
        }
      }, [isOpen])
    
      return isOpen ? (
        <div
          ref={modalRef}
          role="dialog"
          aria-modal="true"
          tabIndex={-1}
          onKeyDown={e => e.key === 'Escape' && onClose()}
        >
          {children}
        </div>
      ) : null
    }
    

    Unutmayın: Modern frontend kalıpları sürdürülebilir, performanslı kullanıcı arayüzleri sağlar. Proje karmaşıklığınıza uyan kalıpları seçin.

    Alternatives

    Compare before choosing