TkDodo / blog-comments

6 stars 1 forks source link

blog/leveraging-the-query-function-context #32

Closed utterances-bot closed 2 years ago

utterances-bot commented 3 years ago

Leveraging the Query Function Context | TkDodo's blog

Use what React Query provides for optimal type safety

https://tkdodo.eu/blog/leveraging-the-query-function-context

rchubatov commented 3 years ago

Great post as always! 👍 Your articles help me a lot, thanks for it!

I may be wrong, but it seems to me that I found typos in the examples.

In all examples

... fetchTodo(...)

should be replaced (?) with:

... fetchTodos(...)

and in the Object Query Keys example:

const todoKeys = {
  // ✅ all keys are arrays with exactly one object
  all: [{ scope: 'todos' }] as const,
  lists: () => ({ ...todoKeys.all[0], entity: 'list' } as const),
  list: (state: State, sorting: Sorting) =>
    ({ ...todoKeys.lists()[0], state, sorting } as const),
}

missing extra square brackets for the lists key:

const todoKeys = {
  // ✅ all keys are arrays with exactly one object
  all: [{ scope: 'todos' }] as const,
  lists: () => ([{ ...todoKeys.all[0], entity: 'list' }] as const),
  list: (state: State, sorting: Sorting) =>
    ({ ...todoKeys.lists()[0], state, sorting } as const),
}
rchubatov commented 3 years ago

And if I understand correctly the list also must be described as an array with only one object element.

const todoKeys = {
 ...
 ...
  list: (state: State, sorting: Sorting) =>
    ([{ ...todoKeys.lists(), state, sorting }] as const),
}
joshwilsonvu commented 3 years ago

I thought query key arrays must begin with strings, is that rule obsolete?

TkDodo commented 3 years ago

@rchubatov you are of course right on both accounts. I guess I was rushing the publishing a bit this time 😅. If you want, I’d accept a PR to fix it (https://github.com/tkdodo/blog), otherwise I’ll do it later 😊

TkDodo commented 3 years ago

@joshwilsonvu the query key must be a string or an array. There is no restriction of what can go in the array. The type is defined here: https://github.com/tannerlinsley/react-query/blob/4d762a4ffe16ea126c432460699f04bf73463f23/src/core/types.ts#L6

rchubatov commented 3 years ago

@TkDodo , done PR

AtticusCMBM commented 2 years ago

Cool!

abhibhaw commented 2 years ago

wow awesome

riteshsp2000 commented 2 years ago

This is amazing

Katli95 commented 2 years ago

Awesome work! Loving the blog, I'm just getting started with react-query and this has been great for finding some baseline best practices.

I don't know if this will help anyone but I created a small utility to help type the context:

type QueryContext<
    keys extends { [K: string]: QueryKey | ((...params: any[]) => QueryKey) },
    mode extends keyof keys
> = keys[mode] extends (...params: any[]) => QueryKey
    ? QueryFunctionContext<ReturnType<keys[mode]>>
    : keys[mode] extends QueryKey
    ? QueryFunctionContext<keys[mode]>
    : never;

// Can then be used like this:
    const fetchTodos = async ({ queryKey: [{ state, sorting }] }: QueryContext<typeof todoKeys, "list">) => {
    ...
}
Faithfinder commented 2 years ago

Feels like entity and scope should be reversed? "Todo" is an "Entity" and "List" is a scope?

TkDodo commented 2 years ago

@Faithfinder yes, possibly. It's just an example 😅