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

Structural sharing doesn't check if dates are equal #6482

Closed
juanrgon opened this issue Dec 3, 2023 · 1 comment
Closed

Structural sharing doesn't check if dates are equal #6482

juanrgon opened this issue Dec 3, 2023 · 1 comment
Labels
wontfix This will not be worked on works as designed

Comments

@juanrgon
Copy link

juanrgon commented Dec 3, 2023

Describe the bug

Noticed in the past couple months that structural sharing in useQuery doesn't check if two date objects are equal to each other.

For my own project, I've had to create a custom structuralSharing function that does this check, since the majority of my query results include date objects (NOTE: not date strings).

For context, I use superjson with trpc to transform my API responses, which includes transforming date strings to Date objects. My assumption is that not that many people use trpc with superjson, but I also think this is a relatively simple thing to support, a problem that can occur outside of trpc and supersjson, and seems sensible to support

Your minimal, reproducible example

Code Sandbox

Steps to reproduce

You can reproduce this with this component that uses a useQuery hook that returns the same date object on every fetch.

What you will see with this component is that every second the render count will increment::

function DateComponent() {
  const renderCount = useRef(0);

  const { data, isLoading, error } = useQuery({
    queryKey: ["fooLastModified"],
    queryFn: async () => {
      return new Date("2023-12-03T16:58Z");
    },
    refetchInterval: 1000,
  });

  if (isLoading) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;

  renderCount.current += 1;

  return (
    <div>
      <div>Foo was last modified at: {data.toString()}</div>
      <em>Render count: {renderCount.current}</em>
    </div>
  );
}
Screen.Recording.2023-12-03.at.12.15.45.PM.mov

For comparison, when the useQuery hook returns a date string, the render count stays static

function DateComponent() {
  // Use a renderCount ref to keep track of the number of renders
  const renderCount = useRef(0);

  const { data, isLoading, error } = useQuery({
    queryKey: ["fooLastModified"],
    queryFn: async () => {
      return "2023-12-03T16:58Z";
    },
    refetchInterval: 1000,
  });

  if (isLoading) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;

  renderCount.current += 1;

  return (
    <div>
      <div>Foo was last modified at: {data.toString()}</div>
      <em>Render count: {renderCount.current}</em>
    </div>
  );
}
Screen.Recording.2023-12-03.at.12.18.51.PM.mov

Expected behavior

As a user I expected date objects with the same value to be treated as equal

How often does this bug happen?

Every time

Screenshots or Videos

Screen.Recording.2023-12-03.at.12.18.51.PM.mov

Platform

  • OS: Any OS
  • Browser: Any browser
  • Version: Any browser version

Tanstack Query adapter

None

TanStack Query version

v4.26.1

TypeScript version

No response

Additional context

No response

@TkDodo
Copy link
Collaborator

TkDodo commented Dec 4, 2023

@TkDodo TkDodo closed this as not planned Won't fix, can't repro, duplicate, stale Dec 4, 2023
@TkDodo TkDodo added wontfix This will not be worked on works as designed labels Dec 4, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
wontfix This will not be worked on works as designed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants