Hone logo
Hone
Problems

React Speech Recognition Hook Challenge

This challenge requires you to build a custom React hook, useSpeechRecognition, that leverages the browser's Web Speech API to enable speech recognition within your React applications. This hook will allow developers to easily integrate voice input capabilities into their components, opening up possibilities for more accessible and interactive user experiences.

Problem Description

You need to create a reusable React hook named useSpeechRecognition that encapsulates the functionality for speech recognition. The hook should manage the state of the recognition process, including whether it's currently listening, the recognized text, and any potential errors.

Key Requirements:

  1. Initialization: The hook should accept an optional configuration object. This object might include properties like lang (e.g., 'en-US', 'es-ES') to specify the language for recognition.
  2. Start/Stop Recognition: The hook must expose functions to start and stop the speech recognition process.
  3. Recognized Text: The hook should provide a way to access the latest recognized text. This could be a single string representing the most recent utterance or an array of alternative transcriptions.
  4. Listening State: The hook should expose a boolean state indicating whether the microphone is currently active and listening.
  5. Error Handling: The hook should provide a mechanism to report any errors that occur during the speech recognition process.
  6. Cleanup: The hook should handle the cleanup of any resources (like event listeners) when the component unmounts.

Expected Behavior:

  • When the startListening function is called, the browser's Speech Recognition API should be activated.
  • As the user speaks, the recognizedText state should be updated with the transcribed words.
  • The isListening state should be true while the microphone is active and false otherwise.
  • If an error occurs (e.g., microphone denied, no speech detected), the error state should be populated with a descriptive error message.
  • Calling stopListening should gracefully end the recognition session.

Edge Cases to Consider:

  • Browser support for the Web Speech API.
  • User denying microphone permissions.
  • No speech being detected within a certain timeframe.
  • Handling multiple interim and final results from the API.

Examples

Example 1: Basic Usage

// Assume a component uses the hook like this:
function SpeechComponent() {
  const {
    recognizedText,
    isListening,
    startListening,
    stopListening,
    error
  } = useSpeechRecognition({ lang: 'en-US' });

  return (
    <div>
      <p>Status: {isListening ? 'Listening...' : 'Not Listening'}</p>
      <p>Recognized: {recognizedText}</p>
      {error && <p style={{ color: 'red' }}>Error: {error}</p>}
      <button onClick={startListening} disabled={isListening}>Start Listening</button>
      <button onClick={stopListening} disabled={!isListening}>Stop Listening</button>
    </div>
  );
}

Output:

  • Initially, isListening is false, recognizedText is '', and error is null.
  • Upon clicking "Start Listening", isListening becomes true.
  • As the user speaks "Hello world", recognizedText might update to "Hello world".
  • Upon clicking "Stop Listening", isListening becomes false.
  • If microphone access is denied, error would be populated with an appropriate message.

Example 2: Handling Multiple Languages

// Using the hook with a different language
function SpanishSpeechComponent() {
  const {
    recognizedText,
    isListening,
    startListening,
    stopListening
  } = useSpeechRecognition({ lang: 'es-ES' });

  return (
    <div>
      <p>Estado: {isListening ? 'Escuchando...' : 'No escuchando'}</p>
      <p>Reconocido: {recognizedText}</p>
      <button onClick={startListening} disabled={isListening}>Empezar a escuchar</button>
      <button onClick={stopListening} disabled={!isListening}>Dejar de escuchar</button>
    </div>
  );
}

Output:

  • The hook will attempt to use Spanish language models for recognition. If the user speaks "Hola mundo", recognizedText will be updated accordingly.

Constraints

  • The solution must be implemented in TypeScript.
  • The hook should gracefully handle cases where the Web Speech API is not supported by the browser.
  • Avoid direct DOM manipulation; rely on React's declarative nature.
  • The hook should be performant, minimizing unnecessary re-renders.

Notes

  • The Web Speech API is primarily supported in Chrome and some other Chromium-based browsers. You might need to polyfill or provide fallback mechanisms for broader compatibility if required in a real-world application (though not strictly required for this challenge).
  • The SpeechRecognition API can provide interim results before a final transcription. Consider how you want to handle these. For simplicity, you can focus on final results.
  • Think about how you'll manage the lifecycle of the SpeechRecognition instance.
  • The SpeechRecognition object emits various events (onresult, onerror, onend, onstart). Your hook will need to subscribe to these.
  • Consider the return type of your hook. It should be a clear object containing all the necessary state and control functions.
Loading editor...
typescript