React Hook to Manage Component Breakpoints in Tailwind

React Hook to Manage Component Breakpoints in Tailwind

Responsive design is an important aspect of web development, and Tailwind CSS makes it easy to achieve this with its built-in breakpoints. However, sometimes it's necessary to manage those breakpoints in a more dynamic manner, especially when you have a component with a specific layout and design. In this blog post, we'll explore a custom hook useTailwindBreakpoint to control breakpoints of a React Avatar component's child from its parent.

What are Tailwind CSS Breakpoints?

Tailwind CSS provides a set of predefined breakpoints that you can use to make your site responsive. You can define these breakpoints in your tailwind.config.js file and use them in your className attributes. For example, you can use the lg breakpoint for large screens like this:

This will cause the width of the div to be 100% for smaller screens, and 50% for larger screens.

<div className="w-full lg:w-1/2">...</div>

However, sometimes you might want to change the layout of a component dynamically based on the size of its parent container or viewport. In these cases, managing breakpoints can become difficult if we hardcode the breakpoints using className attributes.

Introducing the useTailwindBreakpoint Hook

The useTailwindBreakpoint hook is a custom React Hook that uses the window.matchMedia API to detect screen sizes and manage breakpoints dynamically. By using this hook, the parent component can control the size prop of its child component (in this case, an Avatar component).

Here's an implementation of the useTailwindBreakpoint hook:

import { useState, useEffect } from 'react';

export const useTailwindBreakpoint = () => {
  const [size, setSize] = useState<'xs' | 'sm' | 'md' | 'lg'>('xs');

  useEffect(() => {
    const handleBreakpointChange = () => {
      if (window.innerWidth >= 1200) { 
        setSize('lg');
      } else if (window.innerWidth >= 768) { 
        setSize('md');
      } else if (window.innerWidth >= 640) { 
        setSize('sm');
      } else {
        setSize('xs');
      }
    };

    window.addEventListener('resize', handleBreakpointChange);
    handleBreakpointChange();

    return () => {
      window.removeEventListener('resize', handleBreakpointChange);
    };
  }, []);

  return size;
};

In this implementation:

  • We define a useTailwindBreakpoint hook that manages breakpoints dynamically using window.matchMedia.

  • We use useState to manage the size state of the Avatar component. By default, it's set to xs.

  • We useEffect to add an event listener for the resize event and to call the handleBreakpointChange function, which updates the size state based on the screen size.

  • We return the current size value.

Using the useTailwindBreakpoint Hook

Now, we can use the useTailwindBreakpoint hook in the parent component to update the size prop of the Avatar component dynamically. Here's how:

import { Avatar } from './Avatar';
import { useTailwindBreakpoint } from './useTailwindBreakpoint';

const ParentComponent = () => {
  const size = useTailwindBreakpoint();

  return <Avatar size={size} src="..." alt="..." />;
};

In this implementation:

  • We import Avatar and useTailwindBreakpoint

  • We use the useTailwindBreakpoint hook to get the current size value.

  • We pass the size value to the Avatar component as a prop.

The Avatar component now has a dynamic size that depends on the screen size.

Conclusion

Creating a custom useTailwindBreakpoint hook is a powerful tool for managing breakpoints dynamically in React components. By using this hook, we can achieve dynamic and responsive designs that adapt to various screen sizes.