TanStack / query

🤖 Powerful asynchronous state management, server-state utilities and data fetching for the web. TS/JS, React Query, Solid Query, Svelte Query and Vue Query.
https://tanstack.com/query
MIT License
40.09k stars 2.69k forks source link

eslint plugin: false positive for function calls #7340

Open TkDodo opened 2 weeks ago

TkDodo commented 2 weeks ago

Describe the bug

The following yields a false-positive eslint violation:

useQuery({
  queryKey: [{ path: path.split('/') }],
  queryFn: () => api.get(path),
})

error with:

ESLint: The following dependencies are missing in your queryKey: path(@tanstack/query/exhaustive-deps)

Your minimal, reproducible example

failing test case attached

Steps to reproduce

Here's a failing test case:

{
  name: 'should work with function calls',
  code: `useQuery({ queryKey: [{ path: path.split('/') }], queryFn: () => api.get(path) })`,
},

Expected behavior

Ideally, I would like to see no error here, because path winds up in the queryKey. Not sure if it's possible though

How often does this bug happen?

None

Screenshots or Videos

No response

Platform

all

Tanstack Query adapter

None

TanStack Query version

5.29.2

TypeScript version

5.3.3

Additional context

No response

TkDodo commented 2 weeks ago

@Newbie012 is there a way to make this work ?

Newbie012 commented 2 weeks ago

Yes (Stackblitz). I had a similar issue where I had to cache signed S3 (AWS) URLs. I ended up doing something (roughly) like:

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

class QueryableValue<T> {
  constructor(private value: T, private map: (v: T) => string) {}
  toJSON = () => this.map(this.value);
  toString = () => this.value;
  valueOf = () => this.value;
}

const path = new QueryableValue(
  'https://signed-url.com?Expiration=123',
  (x) => x.split('?Expiration')[0]
);

export const Test = () => {
  const query = useQuery({
    queryKey: [path],
    queryFn: () => path.toString(),
  });

  return <div>{query.data}</div>;
};

image

TkDodo commented 2 weeks ago

so toJSON will be called by query?

Newbie012 commented 2 weeks ago

Correct, since query uses JSON.stringify which uses .toJSON.