如何在JS类中派发自定义事件并在React组件中监听
实现方法
1. 修改WordGame类,集成事件派发能力
直接让类继承浏览器原生的EventTarget,就可以直接用标准的事件派发、监听API,不需要引入额外依赖。修改后的代码如下:
// 定义事件名常量,避免拼写错误 const ACTIVE_WORD_CHANGE = 'activewordchange' class WordGame extends EventTarget { words: string[] gameOver: boolean usedWords: string[] whoseTurn: 'player' | 'computer' | 'none' activeWord: string constructor(wordList: string[]) { super() // 继承EventTarget必须先调用父类构造 this.words = wordList this.gameOver = false this.usedWords = [] this.whoseTurn = 'none' this.activeWord = '' } private updateActiveWord(word: string) { this.activeWord = word.toLowerCase() // 属性更新后派发自定义事件,通过detail传递最新值 this.dispatchEvent(new CustomEvent(ACTIVE_WORD_CHANGE, { detail: this.activeWord })) } // 其他游戏逻辑方法... }
如果你不想继承EventTarget,也可以在类里自己维护一个监听回调的映射表,手动实现on/off/emit逻辑,但原生EventTarget已经足够稳定好用,不需要重复实现。
2. 在React组件中监听事件
在函数组件中,把事件监听的逻辑放在useEffect里,组件卸载时一定要移除监听,避免内存泄漏。示例代码:
import { useEffect, useState } from 'react' // 实际场景下game实例可通过props/context获取,或在组件内初始化 const game = new WordGame(['apple', 'egg', 'game']) function GameBoard() { const [currentActiveWord, setCurrentActiveWord] = useState(game.activeWord) useEffect(() => { // 定义事件回调 const handleActiveWordChange = (e: Event) => { // 转成CustomEvent拿到传递的新值 const newWord = (e as CustomEvent<string>).detail setCurrentActiveWord(newWord) } // 绑定监听 game.addEventListener(ACTIVE_WORD_CHANGE, handleActiveWordChange) // 组件卸载时移除监听 return () => { game.removeEventListener(ACTIVE_WORD_CHANGE, handleActiveWordChange) } }, []) return ( <div className="game-board"> <p>当前激活单词:<strong>{currentActiveWord}</strong></p> {/* 其他游戏UI */} </div> ) }
注意事项
- 派发和监听的事件名必须完全一致,建议抽成常量统一管理,避免拼写错误导致监听失效
- 如果是TypeScript项目,可以给事件加类型声明,获得更完善的类型提示,不需要手动做类型断言
- 如果WordGame实例是在组件内动态创建的,要把实例加到useEffect的依赖数组里,保证监听绑定到正确的实例上
- 如果使用类组件,在
componentDidMount生命周期绑定监听、componentWillUnmount生命周期移除监听即可
内容的提问来源于stack exchange,提问作者Bilal Koçak
相关产品推荐
相关产品推荐

