React类组件调用useSpeechRecognition钩子报错如何解决
问题根因
你遇到的报错是因为违反了React Hooks的使用规则:所有Hook只能在React函数组件或者自定义Hook函数中调用,不能在类组件的内部方法、普通JS函数中调用。你当前在App类组件的Dictaphone方法里调用useSpeechRecognition Hook,自然触发编译报错。另外你调用Dictaphone相关属性的写法也不符合规范:你定义的Dictaphone是一个组件,不是普通对象,不能直接用this.Dictaphone.xxx的方式读取内部的状态和方法。
可行解决方案
方案1:将App类组件重构为函数组件(最简便)
这是改动最小的方案,直接把类组件改成函数组件,就可以正常使用useSpeechRecognition Hook了,示例代码如下:
import { useSpeechRecognition } from 'react-speech-recognition'; function App() { const { transcript, listening, resetTranscript, browserSupportsSpeechRecognition, startListening, stopListening } = useSpeechRecognition(); if (!browserSupportsSpeechRecognition) { return <span>Browser doesn't support speech recognition.</span>; } return ( <div> <p>Microphone: {listening ? 'on' : 'off'}</p> <button onClick={startListening}>Start</button> <button onClick={stopListening}>Stop</button> <button onClick={resetTranscript}>Reset</button> <p>{transcript}</p> </div> ); } export default App;
方案2:保留App类组件,封装独立的语音识别函数子组件
如果你的App组件已经有很多类组件的逻辑,不想重构为函数组件,可以把语音识别相关的逻辑单独封装成一个函数子组件,在App类组件的render方法里直接引入使用即可:
首先封装子组件Dictaphone.jsx:
import { useSpeechRecognition } from 'react-speech-recognition'; const Dictaphone = () => { const { transcript, listening, resetTranscript, browserSupportsSpeechRecognition, startListening, stopListening } = useSpeechRecognition(); if (!browserSupportsSpeechRecognition) { return <span>Browser doesn't support speech recognition.</span>; } return ( <div> <p>Microphone: {listening ? 'on' : 'off'}</p> <button onClick={startListening}>Start</button> <button onClick={stopListening}>Stop</button> <button onClick={resetTranscript}>Reset</button> <p>{transcript}</p> </div> ); }; export default Dictaphone;
然后在App类组件的render方法里直接使用:
import Dictaphone from './Dictaphone'; class App extends React.Component { // 你原来的其他类组件逻辑 render() { return ( <div> {/* 你原来的其他渲染内容 */} <Dictaphone /> </div> ); } }
方案3:不使用第三方Hook,直接调用原生Web Speech API在类组件实现
如果你不想用react-speech-recognition这个库,也可以直接在类组件里调用原生的SpeechRecognition API实现功能,核心逻辑如下:
class App extends React.Component { state = { transcript: '', listening: false, browserSupports: false }; recognition = null; componentDidMount() { // 兼容不同浏览器的前缀 const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition; if (SpeechRecognition) { this.setState({ browserSupports: true }); this.recognition = new SpeechRecognition(); this.recognition.continuous = true; this.recognition.interimResults = true; this.recognition.lang = 'zh-CN'; // 可改成你需要的语言 this.recognition.onresult = (event) => { let text = ''; for (let i = event.resultIndex; i < event.results.length; i++) { text += event.results[i][0].transcript; } this.setState({ transcript: text }); }; } } startListening = () => { this.recognition.start(); this.setState({ listening: true }); }; stopListening = () => { this.recognition.stop(); this.setState({ listening: false }); }; resetTranscript = () => { this.setState({ transcript: '' }); }; render() { if (!this.state.browserSupports) { return <span>Browser doesn't support speech recognition.</span>; } return ( <div> <p>Microphone: {this.state.listening ? 'on' : 'off'}</p> <button onClick={this.startListening}>Start</button> <button onClick={this.stopListening}>Stop</button> <button onClick={this.resetTranscript}>Reset</button> <p>{this.state.transcript}</p> </div> ); } }
内容的提问来源于stack exchange,提问作者Soccerball123
相关产品推荐
相关产品推荐

