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
vibratefunction 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 specifiedduration(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
vibratemultiple 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
vibratemust 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.vibratefor web browsers. - For React Native, you can use
HapticFeedbackfromreact-native. You may need to install this dependency:npm install react-native-haptic-feedback. - Consider using a
useEffecthook 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
vibratefunction. No other values are needed.