I built a react-app using react-hook-speech-to-text. It converts speech to text and sends this text to a mongodb database via a backend node server. If a user says "hello world", then it will convert this to a string and store it in an array called results. The I app built was supposed to send each string once to the database but it sends multiple fetch requests and fills up the database with unnecessary copies of the same string. Below is the code I have written in the App.js file. I want it to only send one fetch request per new string converted to text.
import React from 'react';
import useSpeechToText from 'react-hook-speech-to-text';
export default function App() {
const {
error,
interimResult,
isRecording,
results,
startSpeechToText,
stopSpeechToText,
} = useSpeechToText({
continuous: true,
useLegacyResults: false,
});
if (error) return <p>Web Speech API is not available in this browser 🤷</p>;
return (
<div className='min-h-screen flex justify-center items-center bg-indigo-400'>
<div className='flex flex-col justify-center'>
<h1 className='uppercase text-3xl bold text-white text-center'>
Recording: {isRecording.toString()}
</h1>
<button
className='bg-white text-indigo-400 px-4 py-2 rounded border-white border-2 transition hover:bg-indigo-400 hover:text-white'
onClick={isRecording ? stopSpeechToText : startSpeechToText}
>
{isRecording ? 'Stop Recording' : 'Start Recording'}
</button>
<ul>
{results.map((result) => {
try {
fetch('http://localhost:8000/api/commands', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ command: result.transcript }),
})
.then((res) => res.json())
.then((myRes) => console.log(myRes));
} catch (error) {
console.log('Error posting data: ' + error);
}
return <li key={result.timestamp}>{result.transcript}</li>;
})}
{interimResult && <li>{interimResult}</li>}
</ul>
</div>
</div>
);
}
I recommend to create a separate component for one result item. There you can add a useEffect hook.
The dependency of the useEffect should basically the thing that would make a re-fetch necessary if it changes, i.e. probably your result.transcript.
That is easy if result.transcript is just a string, then you could just pass transcript to the component, put it into the dependencies and the fetch parameters.
The result of the fetch then needs to be passed back by some kind of callback instead of just returned.