jotaijs / jotai-tanstack-query

Jotai integration library for TanStack Query
MIT License
214 stars 14 forks source link

atomsWithQuery wrap by atom(async) will trigger unnecessary loading #50

Open Landon-CN opened 1 year ago

Landon-CN commented 1 year ago

code example: https://codesandbox.io/p/sandbox/small-brook-7vmvwd?file=%2Fsrc%2FApp.tsx%3A32%2C27

first use fetch data directly const data = useAtomValue(userAtom); the console will not has loading image

two wrap by atom(async) const data = useAtomValue(asyncToJsonAtom); the console will has loading image

in example two, even if use query cache data, the loading will show again so screen will flash: content->loaindg->content. because time is short

expect: not trigger loading

dai-shi commented 1 year ago

Interesting. It seems like a bug, but I don't have any idea how it happens. Thanks for reporting. Hope someone can investigate it further.

Landon-CN commented 1 year ago

Interesting. It seems like a bug, but I don't have any idea how it happens. Thanks for reporting. Hope someone can investigate it further.

i try to debug it. in example one whe use cache,it will not use promise https://github.com/jotaijs/jotai-tanstack-query/blob/main/src/common.ts#L331 ,will triiger like sync atom. but if you wrap with atom(async) . useAtomValue will treat it as promiseLike https://github.com/pmndrs/jotai/blob/main/src/react/useAtomValue.ts#L106 so it will trigger suspense

dai-shi commented 1 year ago

I would like to make sure if it's a jotai-tanstack-query issue. If it can be reproduced with bare Jotai, it's more unexpected.

Landon-CN commented 1 year ago

I would like to make sure if it's a jotai-tanstack-query issue. If it can be reproduced with bare Jotai, it's more unexpected.

i try anthor example, async wrap with a new query image i think this bug is caused by:

  1. const data = useAtomValue(asyncToJsonAtom); throw Promise. block blow useAtomValue(asyncTwiceAtom)
  2. promise resloved. execute useAtomValue(asyncTwiceAtom), throw promise
  3. promise resloved rendering

tanstack query solve this case is use https://tanstack.com/query/v5/docs/react/reference/useSuspenseQueries

https://codesandbox.io/p/sandbox/elated-dust-57sk3m?file=%2Fsrc%2FApp.tsx%3A42%2C25

dai-shi commented 1 year ago

Does Promise.all help? ref: https://twitter.com/dai_shi/status/1699553010245067022

Landon-CN commented 1 year ago

it try to combie two async atom -> one async atom

const combineAtom = atom(async (get) => {
  const data1 = await get(asyncToJsonAtom);
  const data2 = await get(asyncTwiceAtom);

  return [data1, data2];
});

image

Seems to have solved the problem