Logo

dev-resources.site

for different kinds of informations.

The Magic of useCallback โœจ

Published at
1/14/2025
Categories
usecallback
typescript
nextjs
react
Author
Joodi
The Magic of useCallback โœจ

Hey there, devs! ๐Ÿ‘‹

Today, I stumbled upon something that absolutely blew my mind: useCallback. It's a game-changer in React, and I canโ€™t wait to share how it saved me from a frustrating issue and made my code so much better. Let me walk you through my little adventure! ๐Ÿš€

Image description

The Problem ๐Ÿง

I had this function for handling submenu clicks:

const handleSubmenuClick = (submenuName: string) => {
  switch (submenuName) {
    case "add_user":
      router.push("/manage/users/add");
      break;
    case "update_user":
      if (!user_id) {
        alert("Please Select One Atleast!");
      }
      if (user_id) {
        router.push(`/manage/users/edit/${user_id}`);
      }
      break;
    default:
  }
};

Seems fine, right? But here's the catch: every time the component re-rendered, this function would be re-created. That meant unnecessary re-renders and even some weird UI behavior, like the page feeling like it was refreshing. ๐Ÿ˜ฉ Not what I wanted!

Enter useCallback ๐Ÿช„

I needed a way to prevent this function from being recreated unless its dependencies (like user_id or router) actually changed. That's where the useCallback hook came to the rescue! ๐Ÿฆธโ€โ™€๏ธ

Hereโ€™s how I rewrote the function:

const handleSubmenuClick = useCallback(
  (submenuName: string) => {
    const routes: { [key: string]: string } = {
      add_user: "/manage/users/add",
      update_user: user_id ? `/manage/users/edit/${user_id}` : "",
    };

    if (submenuName === "update_user" && !user_id) {
        alert("Please Select One Atleast!");
      return;
    }

    const route = routes[submenuName];
    if (route) {
      router.push(route);
    }
  },
  [router, user_id] // Dependencies
);

Why Is This So Cool? ๐Ÿ˜

  1. No more unnecessary re-creations!

    With useCallback, React remembers the function so it doesn't rebuild it unless the router or user_id changes. ๐Ÿ’พ

  2. Better performance.

    No wasted re-renders or resource usage. ๐ŸŽ๏ธ

  3. Cleaner code.

    By using an object (routes) and useCallback, the logic became easier to follow and extend. ๐Ÿ› ๏ธ

The Result ๐Ÿฅณ

Now, my routing works smoothly, and thereโ€™s no page "refresh" feeling. It's just like using the <Image> component in Next.js: fast, snappy, and delightful. โšก๏ธ

Here's a simplified version of the final function:

const handleSubmenuClick = useCallback(
  (submenuName: string) => {
    const routes = {
      add_user: "/manage/users/add",
      update_user: user_id ? `/manage/users/edit/${user_id}` : "",
    };

    if (submenuName === "update_user" && !user_id) {
      alert("Please select a user first!");
      return;
    }

    const route = routes[submenuName];
    route && router.push(route);
  },
  [router, user_id]
);

Final Thoughts ๐Ÿ’ก

useCallback is one of those hooks that feels like magic once you get it. It helps optimize performance, keeps your app running smoothly, and makes your code look much cleaner. ๐Ÿš€

If youโ€™re not already using it, I highly recommend giving it a try. Itโ€™s the kind of thing that makes you go, โ€œWow, React is amazing!โ€ ๐Ÿ’–

Happy coding! ๐Ÿ–ฅ๏ธโœจ

Featured ones: