Hone logo
Hone
Problems

React Custom Hook: useWindowSize

This challenge asks you to create a custom React hook, useWindowSize, that efficiently tracks the current dimensions of the browser window. This is a fundamental utility for responsive web design, enabling components to adapt their layout or behavior based on the viewport size without manual event listeners in every component.

Problem Description

Your task is to implement a TypeScript React custom hook named useWindowSize. This hook should:

  • Track Window Dimensions: It needs to reliably report the current width and height of the browser viewport.
  • Update on Resize: The hook should automatically update the reported dimensions whenever the browser window is resized.
  • Initial State: The hook should provide an initial set of dimensions, ideally based on the window size at the time the hook is first mounted.
  • Clean Up: Ensure that any event listeners attached are properly removed when the component using the hook unmounts to prevent memory leaks.

Examples

Example 1:

Consider a component that uses useWindowSize like this:

import React from 'react';
import useWindowSize from './useWindowSize'; // Assuming your hook is in this file

function MyResponsiveComponent() {
  const { width, height } = useWindowSize();

  return (
    <div>
      <h1>Window Size</h1>
      <p>Width: {width}px</p>
      <p>Height: {height}px</p>
    </div>
  );
}

Input (Initial Load): Assume the browser window is initially 1280px wide and 720px tall.

Output (Rendered in JSX):

<div>
  <h1>Window Size</h1>
  <p>Width: 1280px</p>
  <p>Height: 720px</p>
</div>

Explanation: The useWindowSize hook is called. It reads the initial window dimensions (1280x720) and returns them. The component then displays these dimensions.

Example 2:

Input (After Resizing): The user resizes the browser window to 800px wide and 600px tall.

Output (Updated Rendered in JSX):

<div>
  <h1>Window Size</h1>
  <p>Width: 800px</p>
  <p>Height: 600px</p>
</div>

Explanation: The resize event listener within the useWindowSize hook is triggered. It updates its internal state with the new dimensions (800x600). React re-renders MyResponsiveComponent, which now receives and displays the updated width and height.

Example 3: (Edge Case: Server-Side Rendering)

Input: The application is being rendered on the server (e.g., using Next.js with SSR).

Output: The hook should gracefully handle the absence of a window object. It should likely return default or undefined values for width and height initially, and then correctly update them when the component mounts on the client-side and the window object becomes available.

Explanation: On the server, window is not defined. The hook should not throw an error. It might return an object like { width: undefined, height: undefined } or { width: 0, height: 0 } initially. Once the component mounts in the browser, the useEffect that attaches the event listener will run, and the window object will be available, allowing the hook to get the correct dimensions and start tracking.

Constraints

  • The hook must be implemented in TypeScript.
  • The hook should return an object with width and height properties, both of type number | undefined.
  • The hook should avoid unnecessary re-renders. Debouncing or throttling the resize event handler is a good practice, though not strictly mandatory for this basic implementation.
  • The hook must not leak memory by forgetting to remove the resize event listener.

Notes

  • Consider using useState to manage the window dimensions and useEffect to handle the event listener setup and cleanup.
  • The window.innerWidth and window.innerHeight properties are your primary tools here.
  • Pay close attention to how you handle the initial render and the absence of the window object in non-browser environments (SSR).
Loading editor...
typescript