算法艺术创作
algorithmic-art
通过代码和可调参数创作生成艺术与交互式视觉效果。
frontend-patterns【设计与创意】Use this skill when the user asks about frontend design patterns, component patterns, Container/Presentational, Compound Components, HOC, Render Props, Hooks patterns, Provider, or State Reducer.
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
Select and implement frontend component patterns that solve specific architectural problems with idiomatic framework code.
User request includes: frontend pattern, component pattern, react pattern, vue pattern, container pattern, hoc, render prop, compound component, hooks pattern, provider pattern, composable.
A markdown document containing:
Produce the artifact directly. No preamble. No postamble. No explanations. No filler/hedging/transitions. Compress output — why use many token when few do trick. If no pattern applies, output No pattern required. Current approach is sufficient. and stop.
——
4096 tokens
What problem are you solving?
|-- Logic scattered across lifecycle methods? -->
| |-- React: Custom Hooks (preferred) or HOC (legacy only)
| |-- Vue: Composables
| |-- Angular: Services + RxJS
| |-- Svelte: Store + reactive statements
|
|-- Prop drilling (>3 levels)? -->
| |-- React/Vue: Provider/Context pattern
| |-- Angular: DI + services
| |-- Alternative: Component composition (restructure tree)
|
|-- Complex multi-part UI (Tabs, Accordion, Select)? -->
| |-- Compound Components with context-based state
| |-- Each sub-component shares state via parent context
|
|-- Cross-cutting concern across many components? -->
| |-- HOC (for pre-render wrapping like auth guards)
| |-- Hooks (for functional composition)
| |-- Provider (for global state like theme, locale)
|
|-- Dynamic rendering logic sharing? -->
| |-- Render Props (when consumer needs rendering control)
| |-- Slots (Vue/Svelte native slot pattern)
|
|-- Need to override internal component behavior? -->
|-- State Reducer pattern (for reusable component libraries)
|-- Strategy pattern (pass behavior as prop)
How many variations does the component have?
|-- Few variations (2-3) -->
| Props-based configuration is fine
| Example: <Button variant="primary" size="md" />
|
|-- Many variations (4+), composable parts -->
| Composition preferred
| Example: <Card><Card.Header><Card.Body><Card.Footer>
|
|-- Consumer needs full rendering control -->
Render props / slots
Example: <DataTable columns={...} renderRow={(row) => ...} />
Analyze component hierarchy, data flow, and current pain points (prop drilling, re-renders, complex state logic).
Use the pattern selection table to match the problem to the appropriate pattern.
Write idiomatic framework code following the pattern catalog examples.
Implement tests per pattern type using the testing strategy table.
Cover loading, error, and empty states for every component.
Intent: Separate logic (container) from rendering (presentational).
// Container (handles data, state, events)
function OrderListContainer() {
const { data, isLoading, error } = useOrders();
if (isLoading) return <Loading />;
if (error) return <ErrorState message={error.message} />;
return <OrderListPresentation orders={data} onSelect={handleSelect} />;
}
// Presentational (pure rendering, no side effects)
function OrderListPresentation({ orders, onSelect }: Props) {
return (
<ul>
{orders.map(order => (
<li key={order.id} onClick={() => onSelect(order.id)}>
{order.name} - ${order.total}
</li>
))}
</ul>
);
}
When: Complex pages with data fetching, loading/error states, multiple data sources. Avoid for simple static components. Selection rule: Component has 3+ state variables or data sources? Use Container/Presentational. Otherwise, keep single component.
Intent: Expressive, declarative API for multi-part components.
// Select with context-based state sharing
function OrderActions({ children }: { children: ReactNode }) {
const [state, dispatch] = useReducer(orderActionsReducer, initialState);
return (
<OrderActionsContext.Provider value={{ state, dispatch }}>
<div className="order-actions">{children}</div>
</OrderActionsContext.Provider>
);
}
OrderActions.Approve = function Approve() {
const { dispatch } = useOrderActionsContext();
return <button onClick={() => dispatch({ type: 'APPROVE' })}>Approve</button>;
};
OrderActions.Reject = function Reject() {
const { dispatch } = useOrderActionsContext();
return <button onClick={() => dispatch({ type: 'REJECT' })}>Reject</button>;
};
// Usage
<OrderActions>
<OrderActions.Approve />
<OrderActions.Reject />
</OrderActions>
When: Multi-part UI with shared state (Select, Tabs, Accordion, Stepper). Avoid for single-element components.
Intent: Reuse component logic by wrapping.
function withAuth<P>(Component: React.ComponentType<P>) {
return function AuthenticatedComponent(props: P) {
const { user } = useAuth();
if (!user) return <Navigate to="/login" />;
return <Component {...props} user={user} />;
};
}
const ProtectedOrders = withAuth(OrderList);
When: Cross-cutting concerns (auth, logging, permissions) applied to multiple components. Prefer: Hooks over HOC since React 16.8. Use HOC only when wrapping legacy components or when conditional rendering before hook execution is needed. Selection rule: Can the behavior be a hook? Yes → use hook. No → use HOC.
Intent: Share logic via function-as-child prop.
function OrderFetcher({ orderId, children }: {
orderId: string;
children: (state: { order: Order | null; loading: boolean }) => ReactNode;
}) {
const [order, setOrder] = useState<Order | null>(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetchOrder(orderId).then(o => { setOrder(o); setLoading(false); });
}, [orderId]);
return <>{children({ order, loading })}</>;
}
// Usage
<OrderFetcher orderId="123">
{({ order, loading }) => loading ? <Loading /> : <OrderView order={order} />}
</OrderFetcher>
When: Component needs to expose state to consumers without dictating rendering. Prefer: Hooks over Render Props since React 16.8. Use for complex render-props-only libraries (React Motion, Formik).
Intent: Encapsulate stateful logic in composable functions.
function useOrders(filters: OrderFilters) {
const [orders, setOrders] = useState<Order[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<Error | null>(null);
useEffect(() => {
setLoading(true);
api.getOrders(filters)
.then(setOrders)
.catch(setError)
.finally(() => setLoading(false));
}, [filters]);
return { orders, loading, error };
}
// useOrders.ts
import { ref, watch, type Ref } from 'vue'
export function useOrders(filters: Ref<OrderFilters>) {
const orders = ref<Order[]>([])
const loading = ref(false)
const error = ref<Error | null>(null)
watch(filters, async (newFilters) => {
loading.value = true
try {
orders.value = await api.getOrders(newFilters)
} catch (e) {
error.value = e as Error
} finally {
loading.value = false
}
}, { immediate: true })
return { orders, loading, error }
}
| Rule | Rationale |
|---|---|
| One hook per concern | Single responsibility at hook level |
| Hooks call hooks only at top level | Rules of Hooks (React) / lifecycle consistency |
Prefix with use (React) or file scope (Vue) | Convention |
| Return stable references | Avoid infinite re-render loops |
| Parameterize eagerly | Accept primitive params, return stable callbacks |
Intent: Pass data deeply through component tree without prop drilling.
const OrderContext = createContext<OrderContextType | null>(null);
function OrderProvider({ children }: { children: ReactNode }) {
const [orders, setOrders] = useState<Order[]>([]);
const addOrder = useCallback((order: Order) => setOrders(prev => [...prev, order]), []);
return (
<OrderContext.Provider value={{ orders, addOrder }}>
{children}
</OrderContext.Provider>
);
}
function useOrdersContext() {
const ctx = useContext(OrderContext);
if (!ctx) throw new Error('OrderProvider missing');
return ctx;
}
When: Global or feature-level state (theme, auth, locale, feature flags, order state). Avoid wrapping entire app in single provider — split by domain. Selection rule: Data needed by 3+ levels of nesting? Use Provider. 2 levels only? Prop drilling is fine.
Intent: Expose internal state changes to consumers for overriding behavior.
type Action = { type: 'TOGGLE' } | { type: 'CLOSE' };
function useDropdown<T>(
userReducer?: (state: T, action: Action) => T,
initialOpen = false
) {
const defaultReducer = (state: boolean, action: Action) => {
switch (action.type) {
case 'TOGGLE': return !state;
case 'CLOSE': return false;
default: return state;
}
};
const reducer = userReducer || defaultReducer;
const [open, dispatch] = useReducer(reducer, initialOpen);
return { open, toggle: () => dispatch({ type: 'TOGGLE' }), close: () => dispatch({ type: 'CLOSE' }) };
}
// Consumer overrides behavior
const { open, toggle } = useDropdown(
(state, action) => action.type === 'TOGGLE' ? state : state, // never toggles
);
When: Building reusable component libraries where consumers need to customize behavior. Overkill for internal-only components.
| Problem | Pattern | Reason |
|---|---|---|
| Logic scattered across lifecycle | Custom hooks / Composables | Encapsulates stateful logic |
| Prop drilling >3 levels | Provider / Context | Avoids threading props |
| Complex multi-part UI | Compound Components | Declarative API, shared context |
| Cross-cutting concern across many components | HOC | Wrapping before render |
| Dynamic rendering logic sharing | Render Props | Flexible rendering control |
| Component library customization | State Reducer | Overridable internal state |
| Data fetching + rendering separation | Container / Presentational | Clear separation of concerns |
| Pattern | Test Focus | Example |
|---|---|---|
| Container | Mock data layer, test loading/error/success | render(<Container />) with mocked hooks |
| Presentational | Pure props → rendered output | Snapshot + behavior tests |
| Compound | Context provider + child interactions | render(<Component><ChildA/><ChildB/></>) |
| HOC | Wrapped component behavior | render(hoc(WrappedComponent)) |
| Hooks | Render hook via renderHook | renderHook(() => useOrders(filters)) |
| Provider | Consumer components render correctly | Wrap test with provider, assert children |
| Pattern | Re-render triggers | Optimization |
|---|---|---|
| Container/Presentational | Parent state changes | React.memo on presentational |
| Compound Components | Context value changes | Memoize context value with useMemo |
| HOC | Wrapper re-renders passed props | Avoid inline object props |
| Render Props | Parent re-renders → new function each time | useCallback on the render function |
| Provider | Context value changes → all consumers re-render | Split by domain, memoize value |
| Hooks | Hook internal state changes | Single responsibility, stable refs |
// BAD -- single provider for everything, any change re-renders all consumers
<AppProvider value={{ user, orders, theme, locale }}>
<App />
</AppProvider>
// GOOD -- split by domain, consumer only subscribes to what it needs
<UserProvider>
<OrdersProvider>
<ThemeProvider>
<LocaleProvider>
<App />
</LocaleProvider>
</ThemeProvider>
</OrdersProvider>
</UserProvider>
Hand off to frontend/universal/state-management/SKILL.md if state management pattern selection is needed. Hand off to frontend/universal/testing/SKILL.md for testing strategy.
` interface EventObserver { onEvent(event: T): Promise; }
class EventBus { private observers: Set<EventObserver> = new Set(); subscribe(observer: EventObserver): void { this.observers.add(observer); } unsubscribe(observer: EventObserver): void { this.observers.delete(observer); } async emit(event: T): Promise { const results = Array.from(this.observers).map(o => o.onEvent(event)); await Promise.allSettled(results); } } `
config: defaults: timeout: 30s retryCount: 3 overrides: production: timeout: 60s retryCount: 5 development: timeout: 300s retryCount: 1
| Metric | Threshold | Severity | Action |
|---|---|---|---|
| Error rate | > 1% over 5min | Critical | Page on-call |
| p99 latency | > 2s over 5min | Warning | Investigate |
| Throughput drop | > 50% over 1min | Critical | Check upstream |
| Queue depth | > 1000 over 1min | Warning | Scale consumers |
| Disk usage | > 85% | Warning | Clean or expand |
| Memory usage | > 90% heap | Critical | Restart or scale |
| Anti-Pattern | Symptom | Root Cause | Solution |
|---|---|---|---|
| Premature optimization | Complex code for no measured benefit | Guessing instead of profiling | Measure first, optimize based on data |
| Copy-paste reuse | Duplicate code across codebase | Lack of abstraction | Extract shared logic into libraries |
| Gold-plating | Features with no current requirement | Over-engineering | YAGNI — build what's needed now |
| Magical thinking | Assumptions without validation | Skipping error handling | Handle all failure modes explicitly |
Cache hierarchy: L1 (in-memory local) → L2 (distributed Redis/Memcached) → L3 (CDN/Edge). Cache invalidation: TTL-based (simple, stale), event-based (complex, fresh), write-through (consistent, higher write latency), write-behind (fast writes, eventual consistency).
Does the child component need to manage its own state? ├── No → Pure function component (props in, JSX out) └── Yes → Is the state derived from props? ├── Yes → useMemo or computed property └── No → useState/useReducer for local state Does the state need to persist across route changes? ├── Yes → URL state (search params) or global store └── No → Component-local state
How many components share the state? ├── 0-1 → Component-local state (useState/useReducer) ├── 2-5 → Prop drilling or React Context └── 5+ → Global state library (Zustand, Jotai, NgRx Signal Store) Is the state from server API? ├── Yes → TanStack Query/SWR/Apollo Client (server state) └── No → Client state library (Zustand, Context)