Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TanStack Query doesn't properly hash promises #8608

Open
lcswillems opened this issue Feb 5, 2025 · 1 comment
Open

TanStack Query doesn't properly hash promises #8608

lcswillems opened this issue Feb 5, 2025 · 1 comment

Comments

@lcswillems
Copy link

lcswillems commented Feb 5, 2025

Describe the bug

I've this hook:

import { useQuery } from "@tanstack/react-query";

export const usePromise = <T>(promise: Promise<T>) => {
  return useQuery({
    queryKey: ["promise", promise],
    queryFn: () => promise,
  }).data;
};

Whatever the promise the final key stored by TanStack Query is {}. So it means that the value of the first promise to resolve will be cached and used for all the other promises.

I anticipate that one would say "don't use promises in the key" but honestly it would be a big flaw of TanStack Query as conceptually there is really nothing wrong in doing this. For example, it is possible to use a promise in the deps of a useEffect.

It would also be great to have in the documentation an explanation of how the query hashing / serialization works.

Your minimal, reproducible example

https://stackblitz.com/edit/github-4dza7jb5?file=src%2Findex.tsx&preset=node&theme=light

Steps to reproduce

Open the repro and observe that "promise1 / promise1" is displayed instead of "promise1 / promise2".

Expected behavior

Should be "promise1 / promise2".

Platform

Linux

TanStack Query version

5.66.0

@lcswillems
Copy link
Author

The correct way of doing to my opinion would be to have such a function:

export const id = (() => {
  let oldI = 0;
  const map = new WeakMap<WeakKey, number>();

  return (object: WeakKey) => {
    let i = map.get(object);
    if (i === undefined) {
      i = ++oldI;
      map.set(object, i);
    }
    return i;
  };
})();

And use it in order to generate the keys.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant