Hone logo
Hone
Problems

Implementing a useVibration Hook in React for Haptic Feedback

Haptic feedback, or vibration, can significantly enhance the user experience in mobile applications. This challenge asks you to implement a custom React hook, useVibration, that provides a simple and consistent interface for triggering device vibrations. This hook will abstract away the platform-specific APIs for vibration, making it easier to add haptic feedback to your React components.

Problem Description

You need to create a React hook called useVibration. This hook should manage the vibration functionality and provide a single function, vibrate, that can be called to initiate a vibration. The vibrate function should accept a duration in milliseconds as an argument, specifying how long the vibration should last. The hook should handle the platform-specific differences in vibration APIs (e.g., navigator.vibrate in web browsers, HapticFeedback in React Native) and gracefully handle cases where vibration is not supported.

Key Requirements:

  • Platform Detection: The hook should detect the environment (browser, React Native, etc.) and use the appropriate vibration API.
  • Duration Control: The vibrate function should accept a duration in milliseconds and vibrate for that specified time.
  • Error Handling: The hook should handle cases where the device does not support vibration. It should log a warning to the console in such cases, but not throw an error that would crash the application.
  • Clean-up: If a vibration is already active, the hook should attempt to stop it before starting a new one. This prevents overlapping vibrations.
  • Typescript: The code must be written in Typescript.

Expected Behavior:

  • When vibrate(duration) is called, the device should vibrate for the specified duration (in milliseconds).
  • If vibration is not supported, a warning message should be logged to the console.
  • Calling vibrate(duration) while a vibration is already active should stop the existing vibration before starting the new one.
  • The hook should not cause any memory leaks or performance issues.

Edge Cases to Consider:

  • Device does not support vibration.
  • User has disabled vibration in device settings.
  • Vibration API throws an error (e.g., invalid duration).
  • Calling vibrate multiple times in quick succession.

Examples

Example 1:

Input: vibrate(500); // Called in a React component
Output: Device vibrates for 500 milliseconds.
Explanation: The hook detects the platform and uses the appropriate API to vibrate the device for half a second.

Example 2:

Input: vibrate(100); vibrate(200); // Called in quick succession
Output: Device vibrates for 100 milliseconds, then immediately vibrates for 200 milliseconds.
Explanation: The hook stops the previous vibration before starting the next one.

Example 3: (Edge Case - No Vibration Support)

Input: vibrate(300); // Called on a device without vibration support
Output: A warning message is logged to the console: "Vibration not supported on this device."
Explanation: The hook detects the lack of vibration support and logs a warning instead of attempting to vibrate.

Constraints

  • Duration: The duration argument to vibrate must be a non-negative number. The hook should handle invalid durations gracefully (e.g., by logging a warning and not vibrating).
  • Performance: The hook should be performant and not introduce any noticeable delays or lag in the application.
  • Platform Compatibility: The hook should be compatible with modern web browsers and React Native (at least versions 0.60+).
  • Typescript: The code must be written in Typescript.

Notes

  • You can use navigator.vibrate for web browsers.
  • For React Native, you can use HapticFeedback from react-native. You may need to install this dependency: npm install react-native-haptic-feedback.
  • Consider using a useEffect hook to manage the vibration lifecycle.
  • Think about how to handle potential errors from the vibration API.
  • Focus on creating a clean, reusable, and well-documented hook.
  • The hook should return only the vibrate function. No other values are needed.
Loading editor...
typescript