Writing

React Theme Hook for Toggling Images

07/04/24

A small thing I came across while building this website: I wanted to switch the map on my "where" section without using next-themes.

So, I wrote this small hook in TypeScript that handles this for me:

import { useState, useEffect } from "react";

export const useTheme = () => {
  if (typeof window === "undefined") return;

  const [theme, setTheme] = useState<string | undefined>(undefined);

  useEffect(() => {
    const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
    setTheme(mediaQuery.matches ? "dark" : "light");

    const handleThemeChange = (e: MediaQueryListEvent) => {
      setTheme(e.matches ? "dark" : "light");
    };

    mediaQuery.addEventListener("change", handleThemeChange);
    return () => mediaQuery.removeEventListener("change", handleThemeChange);
  }, []);

  return theme;
};

Usage

In your React component:

import useTheme from "./useTheme";

export default () => {
  const theme = useTheme();
  const src = theme === "dark" ? "img-dark.webp" : "img.webp";

  return <img src={src} />;
};
Contact