Tanstack's React Query Kicked `onSuccess`, `onError`, and `onSettled` Out of `useQuery`: Now What?!

Barry Michael Doyle - Oct 25 '23 - - Dev Community

Well, knock me over with a feather! My usually quiet Slack bot, Patch Pulse, got all chatty recently, gossiping about the @tanstack/react-query package prancing up to version 5.

Like any self-respecting developer with a fear of missing out, I dove head-first into the upgrade. Sitting in my fancy chair (it spins), I’m fortunate that my day job has a big, shiny "No Technical Debt Allowed" sign hanging up. So, I jumped from v4 to v5, fully expecting a few surprises. And boy, TypeScript sure delivered on the confetti – or should I say error messages?

To all you daredevil JavaScript purists, I don't understand you. I need my TypeScript safety net! Brushing off my pride, I took a gander at the Migrating to TanStack Query v5 docs. Most of the hiccups? Child’s play. But then, the plot thickened.

Those pesky onError statements in my useQuery hooks were throwing a tantrum. They were my go-to for those dramatic toast notifications whenever a fetch query played hard to get. But the cryptic message I found had me raising an eyebrow:

onSuccess, onError and onSettled have been removed from Queries. They haven't been touched for Mutations. Please see this RFC for motivations behind this change and what to do instead.

The RFC seemed to have its own fan club.

RFC posts about removing callbacks from  raw `useQuery` endraw  with lots of upvotes

But where’s the easy-peasy switcheroo? All I got was a fellow coder's rant about this being a sneaky trap he'd been warding off during code reviews. Thankfully, the guy wasn’t just there to complain; he handed out a lifeline.

V4's Way - That's So Yesterday 😢

Here's the v4 relic that's now gathering dust:



function TodoList() {
  const toast = useToast();

  const { data: todos } = useQuery({
    queryFn: () => getTodos(),
    queryKey: ['getTodos'],
    onError(error) {
      toast({
        title: 'Error getting todos',
        description: error.message,
        status: 'error',
      });
    },
  });

  return todos; // too lazy to write UI stuff here
}


Enter fullscreen mode Exit fullscreen mode

It was smooth sailing, minus the try-catch juggling act that React Query graciously spared us from. But v5 had other plans.

V5's Swagger - A New Groove 🥳

Rolling up my sleeves, I tackled the changes:



function TodoList() {
  const toast = useToast();

  const { data: todos, isError, error } = useQuery({
    queryFn: () => getTodos(),
    queryKey: ['getTodos'],
  });

  useEffect(() => {
    if (isError) {
      toast({
        title: 'Error getting todos',
        description: error.message,
        status: 'error',
      });
    }
  }, [isError]);

  return todos; // too lazy to write UI stuff here
}


Enter fullscreen mode Exit fullscreen mode

It's a tad different, but hey, adapt and thrive, right? And for those detail-oriented folks, yes, isSuccess and isSettled can join the party. Just wasn’t my scene.

Sprucing Things Up

Since I'm all about that toast life, I crafted a slick hook that gave my components a fresh facelift:



function useErrorNotification({
  isError,
  title,
  description,
  status = 'error'
}) {
  const toast = useToast();

  useEffect(() => {
    if (isError) {
      toast({ title, description, status });
    }
  }, [isError]);
}


Enter fullscreen mode Exit fullscreen mode

And then we bring it all together like this:



function TodoList() {
  const { data: todos, isError, error } = useQuery({
    queryFn: () => getTodos(),
    queryKey: ['getTodos'],
  });

  useErrorNotification({
    isError,
    title: 'Error getting todos',
    description: error.message,
  })  

  return todos; // too lazy to write UI stuff here
}


Enter fullscreen mode Exit fullscreen mode

Who said change wasn’t fabulous?

Curtain Call

Kudos to the React Query team for the nudge (or push) towards cleaner code realms!

Anyone else made the leap to Tanstack's React Query v5? Let me know what you think!

. . . . . . . . . . .