You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

react-speech-recognition多表单字段语音录入同时触发所有实例如何解决

问题原因

react-speech-recognition 全局共享单例状态:默认所有调用useSpeechRecognition的组件都订阅同一个全局录音实例的状态,调用全局的startListening方法会触发所有组件同步更新录音状态和转写结果,就会出现两个组件同时启动、文本同步填充的问题。


最简解决方法

给每个语音组件分配唯一的id隔离实例,所有录音操作都指定对应id即可,不需要改动现有业务逻辑:

1. 修改ReviewDict组件

import React, { useEffect } from "react";
import { CardContent } from "@mui/material";
import MicIcon from "@mui/icons-material/Mic";
import MicOffIcon from "@mui/icons-material/MicOff";
import SpeechRecognition, {useSpeechRecognition} from "react-speech-recognition";

export const ReviewDict = ({ changeReview }) => {
  const {
    transcript,
    listening,
    browserSupportsSpeechRecognition,
  } = useSpeechRecognition({ id: 'review' }); // 分配唯一id

  useEffect(() => {
    changeReview(transcript)
  }, [transcript, changeReview]);

  if (!browserSupportsSpeechRecognition) {
    return <span>浏览器不支持语音识别功能。</span>;
  }

  return (
    <div>
      <CardContent sx={{ paddingTop: 5, fontSize: 25 }}>
        <center>
          {!listening ? (
            <span onClick={() => SpeechRecognition.startListening({ id: 'review' })}>
              <MicIcon fontSize="normal" /> review
            </span>
          ) : (
            <span onClick={() => SpeechRecognition.stopListening({ id: 'review' })}>
              <MicOffIcon fontSize="normal" />
            </span>
          )}
        </center>
      </CardContent>
    </div>
  );
};

2. 修改OrderDict组件

import React, { useEffect } from "react";
import { CardContent } from "@mui/material";
import MicIcon from "@mui/icons-material/Mic";
import MicOffIcon from "@mui/icons-material/MicOff";
import SpeechRecognition, {useSpeechRecognition} from "react-speech-recognition";

export const OrderDict = ({ changeOrder }) => {
  const {
    transcript,
    listening,
    browserSupportsSpeechRecognition,
  } = useSpeechRecognition({ id: 'order' }); // 分配和review不同的唯一id

  useEffect(() => {
    changeOrder(transcript);
  }, [transcript, changeOrder]);

  if (!browserSupportsSpeechRecognition) {
    return <span>浏览器不支持语音识别功能。</span>;
  }

  return (
    <div>
      <CardContent sx={{ paddingTop: 5, fontSize: 25 }}>
        <center>
          {!listening ? (
            <span onClick={() => SpeechRecognition.startListening({ id: 'order' })}>
              <MicIcon fontSize="normal" /> order
            </span>
          ) : (
            <span onClick={() => SpeechRecognition.stopListening({ id: 'order' })}>
              <MicOffIcon fontSize="normal" />
            </span>
          )}
        </center>
      </CardContent>
    </div>
  );
};

可选优化(代码复用)

两个语音组件逻辑完全一致,可以封装为通用组件减少重复代码:

// 通用语音录入组件 Dictaphone.jsx
import React, { useEffect } from "react";
import { CardContent } from "@mui/material";
import MicIcon from "@mui/icons-material/Mic";
import MicOffIcon from "@mui/icons-material/MicOff";
import SpeechRecognition, {useSpeechRecognition} from "react-speech-recognition";

export const Dictaphone = ({ fieldId, label, onChange }) => {
  const {
    transcript,
    listening,
    browserSupportsSpeechRecognition,
  } = useSpeechRecognition({ id: fieldId });

  useEffect(() => {
    onChange(transcript);
  }, [transcript, onChange]);

  if (!browserSupportsSpeechRecognition) {
    return <span>浏览器不支持语音识别功能。</span>;
  }

  return (
    <div>
      <CardContent sx={{ paddingTop: 5, fontSize: 25 }}>
        <center>
          {!listening ? (
            <span onClick={() => SpeechRecognition.startListening({ id: fieldId })}>
              <MicIcon fontSize="normal" /> {label}
            </span>
          ) : (
            <span onClick={() => SpeechRecognition.stopListening({ id: fieldId })}>
              <MicOffIcon fontSize="normal" />
            </span>
          )}
        </center>
      </CardContent>
    </div>
  )
}

表单中调用方式:

<Dictaphone fieldId="review" label="review" onChange={dictUpdate} />
<Dictaphone fieldId="order" label="order" onChange={orderUpdate} />

内容的提问来源于stack exchange,提问作者Gordon Maloney

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 16:30:04