react-speech-kit语音转文字后自动调用speak方法重复触发问题求助
解决方案
重复调用问题修复方法
- 根因1:
onEnd回调被重复绑定/多次触发,没有做并发控制
修复:新增执行锁标记运行状态,避免同一时间重复发起请求和调用speak - 根因2:回调函数未用
useCallback包裹,组件重渲染时重复向语音识别实例注册新的onEnd回调,导致同一次识别结束触发多次逻辑
修复:用useCallback包裹onEnd函数,明确标注依赖项 - 根因3:未清空之前的语音播放队列,多次调用
speak会叠加播放任务,看起来像重复播放同一段文本
修复:调用speak前先执行cancel方法清空现有播放队列
完整修复代码示例
import { useCallback, useRef, useState } from 'react'; import { useSpeechRecognition, useSpeechSynthesis } from 'react-speech-kit'; function VoiceComponent() { const [value, setValue] = useState(''); const [response, setResponse] = useState(''); // 执行锁:true表示正在处理请求/播放,阻止重复触发 const isProcessingRef = useRef(false); const { speak, cancel } = useSpeechSynthesis(); const { listen, stop } = useSpeechRecognition({ onResult: (result) => { setValue(result); }, // 用useCallback包裹避免重复绑定回调 onEnd: useCallback(() => { if (isProcessingRef.current) return; isProcessingRef.current = true; fetch(`http://api/Main?id=test&lang=kor&req=${encodeURIComponent(value)}`, {}) .then((res) => res.json()) .then( (result) => { setResponse(result.res); // 先清空历史播放队列再播放新内容 cancel(); speak({ text: result.res }); }, (error) => { console.log(error); } ) .finally(() => { // 处理完成后释放锁 isProcessingRef.current = false; }); }, [value, cancel, speak]) }); // 其余组件业务逻辑 return <div>你的组件UI</div> }
补充说明
上述代码对请求参数加了encodeURIComponent转义,避免语音识别结果包含特殊字符时请求参数异常。
内容的提问来源于stack exchange,提问作者naoval luthfi
相关产品推荐
相关产品推荐

