React Orientation Hook: useOrientation
This challenge asks you to create a custom React hook, useOrientation, that detects and tracks the device's orientation (portrait or landscape) using the screen.orientation API. This hook is useful for adapting your UI based on the device's orientation, providing a more responsive and user-friendly experience across different devices.
Problem Description
You need to implement a React hook called useOrientation that returns the current orientation of the device as a string: "portrait" or "landscape". The hook should:
- Initialize: On initial mount, determine the current orientation and store it.
- Listen for Changes: Listen for changes to the device's orientation using the
screen.orientationchangeevent. - Update State: Whenever the orientation changes, update the stored orientation value.
- Return Value: Return the current orientation as a string ("portrait" or "landscape").
- Handle Errors: Gracefully handle cases where the
screen.orientationAPI is not available (e.g., in server-side rendering environments). In such cases, return "unknown".
Key Requirements:
- The hook must be written in TypeScript.
- The hook must use the
screen.orientationAPI to detect orientation changes. - The hook must return a string representing the current orientation.
- The hook must handle the case where the
screen.orientationAPI is not available. - The hook should avoid memory leaks by properly cleaning up the event listener on unmount.
Expected Behavior:
- When the component using the hook mounts, the hook should immediately return the current orientation.
- When the device's orientation changes, the hook should update its state and return the new orientation.
- If the
screen.orientationAPI is not available, the hook should return "unknown".
Edge Cases to Consider:
- Server-side rendering (SSR): The
screen.orientationAPI is not available on the server. - Devices that do not support orientation changes.
- Initial orientation on mount.
Examples
Example 1:
Input: Device is initially in portrait mode.
Output: "portrait"
Explanation: The hook initializes and returns the initial orientation.
Example 2:
Input: Device is in landscape mode, then rotates to portrait mode.
Output: Initially "landscape", then "portrait"
Explanation: The hook updates its state and returns the new orientation after the rotation.
Example 3:
Input: Running in a server-side rendering environment.
Output: "unknown"
Explanation: The screen.orientation API is not available, so the hook returns "unknown".
Constraints
- The hook must be written in TypeScript.
- The hook must not introduce any memory leaks.
- The hook should be relatively performant; avoid unnecessary re-renders.
- The returned orientation string must be either "portrait", "landscape", or "unknown".
Notes
- Consider using
useEffectto manage the event listener and cleanup. - The
screen.orientationAPI provides anorientationproperty that can be used to determine the orientation. - Think about how to handle the case where the
screen.orientationAPI is not available. You might need to check for its existence before attempting to use it. - The
orientationchangeevent is fired when the device's orientation changes. - Remember to clean up the event listener when the component unmounts to prevent memory leaks. The
useEffectcleanup function is ideal for this.