Skip to content

Conversation

@ThaddeusJiang
Copy link
Collaborator

Implement atomWithQueries for useQueries, resolve #97

@codesandbox-ci
Copy link

codesandbox-ci bot commented Jul 17, 2025

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

@ThaddeusJiang ThaddeusJiang self-assigned this Jul 17, 2025
@ThaddeusJiang ThaddeusJiang added the enhancement New feature or request label Jul 17, 2025
@dai-shi
Copy link
Member

dai-shi commented Jul 17, 2025

thanks for working on it. i leave the review for @himself65.

@himself65
Copy link
Member

sorry my changes doesnt work but I think we should have a way to make this

@ThaddeusJiang
Copy link
Collaborator Author

@himself65 Any other concerns? If there are no issues, I'm ready to complete this PR.

Comment on lines +118 to +130
const [userIds] = useAtom(userIdsAtom)

const userQueryAtoms = atomWithQueries({
queries: userIds.map((id) => () => ({
queryKey: ['user', id],
queryFn: async ({ queryKey: [, userId] }) => {
const res = await fetch(
`https://jsonplaceholder.typicode.com/users/${userId}`
)
return res.json()
},
})),
})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm concerning about the example here, seems like this atom is rely on react hook? can we change it?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@himself65 The atomWithQueries does not necessarily depend on React hooks; here it is used simply for convenient state management, same as useState.

Copy link
Member

@himself65 himself65 Jul 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we can change to

 const userQueryAtoms = atomWithQueries({
    queries: get(userIdsAtom).map(...)
  })

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understood

"@tanstack/query-core": "latest",
"jotai": "latest",
"jotai-tanstack-query": "latest",
"jotai-tanstack-query": "../../",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for the fix

const UsersData = () => {
const [userIds] = useAtom(userIdsAtom)

const userQueryAtoms = atomWithQueries<User>({
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same

queries,
combine,
}: {
queries: Array<(get: Getter) => AtomWithQueryOptions>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

again, do we have strong type hinting here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@himself65 What of strong type hinting is required?

In the examples, I provided type-safe samples for with and without the combine version.

const userQueryAtoms = atomWithQueries<User>({

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the ideal solution is user shouldn't annotate the result type but people can get the type hinting

const atoms = atomWithQueries({
  queries: get(userIdsAtom).map(d => ({ userId: '1' }))
})
const users = useAtomValue(atoms)
users[0].userId // <-- without type error

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@himself65 Understood.

Since atomWithQueries returns a compound type of Promise, it is necessary to handle pending and error states when writing code.

const atoms = atomWithQueries({
  queries: get(userIdsAtom).map(d => ({ userId: '1' }))
})

const userQueries = useAtomValue(atoms)

if (users[0].isPending) return <>Loading<>
if (users[0].isError) return <>Error<>

users[0].userId // <-- without type error

We provide a similar type system.

+ const atoms = atomWithQueries<User>({
const atoms = atomWithQueries({

const userQueryAtoms = atomWithQueries<User>({

queryAtom: Atom<AtomWithQueryResult<User>>

const UserDisplay = ({ user }: { user: User }) => {

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW
Since the project isn't using strong typing yet, I'd suggest making a separate PR just for that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, I think we can merge this first.

Copy link
Member

@himself65 himself65 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

feel free to merge when you re ready

@ThaddeusJiang ThaddeusJiang merged commit 8f5f569 into main Jul 23, 2025
3 checks passed
@ThaddeusJiang ThaddeusJiang deleted the feat/useQueries branch July 23, 2025 00:59
@kvnxiao
Copy link

kvnxiao commented Jul 23, 2025

Could we make a new stable release to include this addition? I'd like to take advantage of this ASAP without having to pin to a preview

@himself65
Copy link
Member

Could we make a new stable release to include this addition? I'd like to take advantage of this ASAP without having to pin to a preview

@ThaddeusJiang can you make that, I think I don't have npm access right now. Or you can add NPM_TOKEN in secret and I will try to release though CI

@ThaddeusJiang
Copy link
Collaborator Author

@kvnxiao
Done.
Hope you have fun. ❤️

cc @himself65

@kvnxiao
Copy link

kvnxiao commented Jul 23, 2025

Thanks everyone!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

atomWithQueries / useQueries equivalent with this integration plugin?

5 participants