Hone logo
Hone
Problems

React Custom Hook: useOrientation

This challenge asks you to build a custom React hook, useOrientation, that elegantly detects and reports the current screen orientation (portrait or landscape) of a user's device. This is incredibly useful for creating responsive UIs that adapt their layout and behavior based on how a user is holding their device, enhancing user experience across various screen sizes and orientations.

Problem Description

You need to create a custom React hook named useOrientation that exposes the current screen orientation. This hook should:

  • Detect Orientation: Accurately determine if the device is in "portrait" or "landscape" mode.
  • Provide State: Return the current orientation as a string ("portrait" or "landscape").
  • Update Dynamically: Automatically update the orientation state when the device's orientation changes.
  • Handle Initial State: Set the initial orientation correctly when the component using the hook mounts.

Key Requirements:

  1. Hook Signature: The hook should have the signature useOrientation(): Orientation.
  2. Return Type: The Orientation type should be a union of "portrait" and "landscape".
  3. Event Listener: You will need to listen to the resize event on the window object to detect orientation changes.
  4. Orientation Logic: Determine orientation based on window.innerWidth and window.innerHeight.

Expected Behavior:

  • When the hook is first used, it should return the current orientation.
  • If the user rotates their device from portrait to landscape, the hook's returned value should update from "portrait" to "landscape".
  • If the user rotates their device from landscape to portrait, the hook's returned value should update from "landscape" to "portrait".

Edge Cases:

  • Server-Side Rendering (SSR): The hook should gracefully handle environments where window is not available (e.g., during SSR). In such cases, it should return a default orientation (e.g., "portrait" or undefined if you prefer to signal that orientation cannot be determined).
  • Initial Measurement: Ensure the initial measurement of width and height is correct.

Examples

Example 1:

// Assume the device is wider than it is tall initially
const currentOrientation = useOrientation();

// currentOrientation would be "landscape"

Explanation: In this scenario, window.innerWidth is greater than window.innerHeight, indicating a landscape orientation.

Example 2:

// Assume the device is taller than it is wide initially
const currentOrientation = useOrientation();

// currentOrientation would be "portrait"

Explanation: Here, window.innerHeight is greater than window.innerWidth, indicating a portrait orientation.

Example 3:

// Imagine the user rotates their device from portrait to landscape

// Initially:
// const orientation1 = useOrientation(); // orientation1 === "portrait"

// After rotation:
// const orientation2 = useOrientation(); // orientation2 === "landscape"

Explanation: The hook correctly updates its state upon the resize event triggered by the device rotation.

Constraints

  • The hook must be implemented in TypeScript.
  • It should not rely on any external libraries.
  • Performance: The event listener should be cleaned up when the component unmounts to prevent memory leaks.

Notes

  • Consider using useState to manage the orientation state within the hook.
  • Remember to use useEffect to set up and clean up the event listener.
  • The logic for determining portrait vs. landscape is typically:
    • Portrait: window.innerHeight > window.innerWidth
    • Landscape: window.innerWidth >= window.innerHeight
  • You'll need to define a type for the orientation string.
Loading editor...
typescript