我正在制作一个输入表单,我想使用React语音识别包来让用户选择记录他们的输入,而不是在表单中的两个字段中输入- "review“和"order”。我创建了两个版本的口述电话,分别为ReviewDict和OrderDict,并分别向它们传递了一个"changeReview/changeOrder“属性来更新字段。
但是,每当我单击其中一个开始录制时,它就会启动这两个字段,并将我所说的文字记录拉到两个输入字段中。
有没有一种简单的方法可以让每个按钮只影响包的实例?
以下是我的代码的相关部分:
输入表单:
<TextField
value={postData.review}
onInput={(e) =>
setPostData({ ...postData, review: e.target.value })
}
/>
</div>
<ReviewDict changeReview={dictUpdate} />
<div>
<TextField
value={postData.order}
onInput={(e) =>
setPostData({ ...postData, order: e.target.value })
}
/>
</div>
<OrderDict changeOrder={orderUpdate} />然后我的口述录音机是这样的:
import React, { useState } from "react";
import { CardContent } from "@mui/material";
import { useEffect } from "react";
import MicIcon from "@mui/icons-material/Mic";
import MicOffIcon from "@mui/icons-material/MicOff";
import SpeechRecognition, {useSpeechRecognition} from "react-speech-recognition";
export const ReviewDict = ({ changeText, changeOrder, changeReview }) => {
const [reviewText, setReviewText] = useState("");
const {
transcript,
listening,
resetTranscript,
browserSupportsSpeechRecognition,
} = useSpeechRecognition();
useEffect(() => {
setReviewText(" ");
changeReview(transcript)
}, [transcript]);
if (!browserSupportsSpeechRecognition) {
return <span>Browser doesn't support speech recognition.</span>;
}
return (
<div>
<CardContent sx={{ paddingTop: 5, fontSize: 25 }}>
<center>
{!listening ? (
<>
{" "}
<span onClick={SpeechRecognition.startListening}>
<MicIcon fontSize="normal" /> review
</span>
</>
) : (
<>
<span onClick={SpeechRecognition.stopListening}>
<MicOffIcon fontSize="normal" />
</span>
</>
)}
</center>
</CardContent>
</div>
);
};和
import React, { useState } from "react";
import { CardContent } from "@mui/material";
import { useEffect } from "react";
import MicIcon from "@mui/icons-material/Mic";
import MicOffIcon from "@mui/icons-material/MicOff";
import RestartAltIcon from "@mui/icons-material/RestartAlt";
import { Card, Rating, TextField, Box } from "@mui/material";
import SpeechRecognition, {
useSpeechRecognition,
} from "react-speech-recognition";
export const OrderDict = ({ changeText, changeOrder, changeReview }) => {
const [reviewText, setReviewText] = useState("");
const {
transcript,
listening,
resetTranscript,
browserSupportsSpeechRecognition,
} = useSpeechRecognition();
useEffect(() => {
setReviewText(" ");
changeOrder(transcript);
}, [transcript]);
if (!browserSupportsSpeechRecognition) {
return <span>Browser doesn't support speech recognition.</span>;
}
return (
<div>
<CardContent sx={{ paddingTop: 5, fontSize: 25 }}>
<center>
{!listening ? (
<>
{" "}
<span onClick={SpeechRecognition.startListening}>
<MicIcon fontSize="normal" /> order
</span>
</>
) : (
<>
<span onClick={SpeechRecognition.stopListening}>
<MicOffIcon fontSize="normal" />
</span>
</>
)}
{/*
<br />
{transcript && (
<>
<span onClick={resetTranscript}>
<RestartAltIcon fontSize="large" />
Re-record
</span>
</>
)}
*/}
</center>
</CardContent>
</div>
);
};任何帮助都非常感谢!
发布于 2021-10-10 16:18:22
好的,当我洗澡的时候,我想到了解决这个问题的办法!
问题是语音识别工具的控件是全局的,所以在一个实例上调用startListening就是在所有实例上调用它,而且因为我的组件都呈现在页面上,所以我不能在没有另一个的情况下完成一个-所以我只需要一次最多呈现一个。
所以我只是用如下的状态初始化了一个fieldDict变量:
const [fieldDict, setFieldDict] = useState(null);然后根据当前的fieldDict值,有条件地将开始录制按钮或外观相同的按钮呈现为setFieldDict到右侧字段,如下所示:
{fieldDict === "review" ? (
<ReviewDict changeReview={dictUpdate} />
) : (
<center>
<MicIcon onClick={() => setFieldDict("review")} />
</center>
)}在speech- to -text组件中,一旦呈现组件,我就使用useEffect开始录制,如下所示:
useEffect(() => {
SpeechRecognition.startListening()
}, []);这意味着从用户的角度来看,它与我想要做的事情是一样的--有一个录音按钮,当你点击它时,它会开始录音,并将你的文本转录到正确的字段,但在幕后,我一次只渲染语音到文本组件的一个实例,所以我避免了在我不想要的时候意外地触发它的实例。
https://stackoverflow.com/questions/69509721
复制相似问题