AgentSkillsCN

client_event_listeners

从Vercel导入技能:client_event_listeners

SKILL.md
--- frontmatter
description: Imported skill client_event_listeners from vercel
name: client_event_listeners
signature: 242a873349febc1ce685e85617994784dbab92c2eaa68aed7fed5a83e7680e93
source: /a0/tmp/skills_research/vercel/skills/react-best-practices/rules/client-event-listeners.md

title: Deduplicate Global Event Listeners impact: LOW impactDescription: single listener for N components tags: client, swr, event-listeners, subscription

Deduplicate Global Event Listeners

Use useSWRSubscription() to share global event listeners across component instances.

Incorrect (N instances = N listeners):

tsx
function useKeyboardShortcut(key: string, callback: () => void) {
  useEffect(() => {
    const handler = (e: KeyboardEvent) => {
      if (e.metaKey && e.key === key) {
        callback()
      }
    }
    window.addEventListener('keydown', handler)
    return () => window.removeEventListener('keydown', handler)
  }, [key, callback])
}

When using the useKeyboardShortcut hook multiple times, each instance will register a new listener.

Correct (N instances = 1 listener):

tsx
import useSWRSubscription from 'swr/subscription'

// Module-level Map to track callbacks per key
const keyCallbacks = new Map<string, Set<() => void>>()

function useKeyboardShortcut(key: string, callback: () => void) {
  // Register this callback in the Map
  useEffect(() => {
    if (!keyCallbacks.has(key)) {
      keyCallbacks.set(key, new Set())
    }
    keyCallbacks.get(key)!.add(callback)

    return () => {
      const set = keyCallbacks.get(key)
      if (set) {
        set.delete(callback)
        if (set.size === 0) {
          keyCallbacks.delete(key)
        }
      }
    }
  }, [key, callback])

  useSWRSubscription('global-keydown', () => {
    const handler = (e: KeyboardEvent) => {
      if (e.metaKey && keyCallbacks.has(e.key)) {
        keyCallbacks.get(e.key)!.forEach(cb => cb())
      }
    }
    window.addEventListener('keydown', handler)
    return () => window.removeEventListener('keydown', handler)
  })
}

function Profile() {
  // Multiple shortcuts will share the same listener
  useKeyboardShortcut('p', () => { /* ... */ }) 
  useKeyboardShortcut('k', () => { /* ... */ })
  // ...
}