React中使用useContext传递语音识别状态触发无效Hook调用错误
解决React语音识别中的Invalid hook call错误
错误原因
useContext是React钩子函数,必须满足以下使用规则:
- 只能在函数组件的顶层作用域中调用
- 只能在自定义钩子函数中调用
你当前把useContext放在普通工具函数runSpeechRecognition里,违反了钩子的使用规则,因此触发Invalid hook call错误。
解决方案
将setListening作为参数传入工具函数,不在函数内部调用React钩子,具体修改如下:
1. 修改语音识别工具函数
移除内部的useContext相关代码,接收外部传入的setListening:
function runSpeechRecognition(setListening) { var SpeechRecognition = SpeechRecognition || webkitSpeechRecognition var recognition = new SpeechRecognition() recognition.onstart = function () { console.log('We are listening. Try speaking into the microphone.') } recognition.onspeechend = function () { recognition.stop() setListening(false) } // 添加错误处理,避免异常时状态无法重置 recognition.onerror = function(event) { console.error('语音识别出错:', event.error) setListening(false) } recognition.start() setListening(true) return new Promise((resolve, reject) => { recognition.onresult = function (event) { var transcript = event.results[0][0].transcript resolve(transcript) } recognition.onerror = function(event) { reject(event.error) } }) } export default runSpeechRecognition
2. 在组件中调用工具函数
在函数组件中通过useContext获取setListening,并作为参数传给工具函数:
import { useContext } from 'react' import AppContext from './AppContext' import runSpeechRecognition from './runSpeechRecognition' function SpeechControlButton() { const { listening, setListening } = useContext(AppContext) const handleStartRecognition = async () => { try { const transcript = await runSpeechRecognition(setListening) // 处理识别得到的文本 console.log('识别结果:', transcript) } catch (err) { console.error('识别失败:', err) } } return ( <button onClick={handleStartRecognition} style={{ backgroundColor: listening ? '#e53935' : '#2196f3', color: '#fff', border: 'none', padding: '10px 20px', borderRadius: '4px', cursor: 'pointer' }} > {listening ? '正在监听...' : '开始语音识别'} </button> ) } export default SpeechControlButton
补充说明
通过这种方式,既遵守了React钩子的使用规范,又能正常更新listening状态来切换按钮样式,同时添加错误处理可以避免异常情况下按钮一直显示"正在监听"的状态。
内容的提问来源于stack exchange,提问作者JohnPix
相关产品推荐
相关产品推荐

