frontend-react

star 0

Load when editing .tsx, .jsx files or working in components/, pages/, store/, hooks/. Provides React, TypeScript, Zustand state management, and WebSocket client patterns.

goranjovic55 By goranjovic55 schedule Updated 1/30/2026

name: frontend-react description: Load when editing .tsx, .jsx files or working in components/, pages/, store/, hooks/. Provides React, TypeScript, Zustand state management, and WebSocket client patterns.

Frontend React

Merged Skills

  • state-management: Zustand stores, selectors, subscriptions
  • internationalization: i18n, translation, locale patterns
  • performance: React.memo, useMemo, useCallback optimization
  • authentication: Login flows, token storage, auth guards
  • websocket-realtime: WebSocket client, reconnection, message handling

⚠️ Critical Gotchas

Category Pattern Solution
Auth 401 errors Call logout() from authStore, don't show page-level error
JSX Comment syntax error Use {/* comment */} not //
Hooks Stale closures Add all deps to useEffect dependency array
State Settings lost on refresh Use localStorage for persistent settings
Zustand Memory leaks Clean up selectors/subscriptions
Auth Wrong storage key Use localStorage.getItem('nop-auth') not 'token'
Async State stale in callback Capture with { ...localState } BEFORE async calls
ConfigPanel Save lost Call saveCurrentWorkflow() after updateNode()

Rules

Rule Pattern
Keys in lists Always key={item.id}
Dependency arrays Include all dependencies
Async in effects Use wrapper function, never async callback
State management Zustand for global, useState for local
Auth handling Redirect on 401, don't show error page

Avoid

❌ Bad ✅ Good
Prop drilling Context or Zustand
useEffect(async () => ...) Wrapper function inside
Missing keys key={id}
Page-level 401 UI logout() redirect
// comment in JSX {/* comment */}

Patterns

// Pattern 1: Component with Zustand selector
const items = useStore((s) => s.items);
const Card: FC<{item: Item}> = ({ item }) => (
  <div key={item.id}>{item.name}</div>
);

// Pattern 2: Store with persistence
export const useStore = create<State>()(
  persist(
    (set) => ({
      items: [],
      addItem: (i) => set((s) => ({ items: [...s.items, i] }))
    }),
    { name: 'store-key' }
  )
);

// Pattern 3: Async state capture (CRITICAL)
const handleSave = async () => {
  const capturedParams = { ...localParams };  // Capture BEFORE async
  await updateNode(nodeId, { data: { ...node.data, ...capturedParams }});
  await saveCurrentWorkflow();  // Persist to backend
};

// Pattern 4: Execution visualization in BlockNode
const executionStatus = (data as any).executionStatus as NodeExecutionStatus;
const borderColor = executionStatus ? statusColors[executionStatus] : categoryColor;
const isExecuting = executionStatus === 'running';

// Pattern 5: Auth-aware API call
const fetchData = async () => {
  try {
    const response = await api.get('/resource');
    return response.data;
  } catch (error) {
    if (error.response?.status === 401) {
      logout();  // Redirect, don't show error
      return;
    }
    throw error;
  }
};

Execution Visualization

Status Border Color Effect
running cyan animate-pulse + glow
completed green static glow
failed red static glow
pending gray default

Commands

Task Command
Start dev cd frontend && npm start
Run tests cd frontend && npm test
Build cd frontend && npm run build
Type check cd frontend && npx tsc --noEmit
Lint cd frontend && npm run lint
Install via CLI
npx skills add https://github.com/goranjovic55/NOP --skill frontend-react
Repository Details
star Stars 0
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator
goranjovic55
goranjovic55 Explore all skills →