-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
feat(solid-query): Solid Query Adapter for TanStack Query #4211
Merged
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
26c0a3a
feat(solid-query): Solid Query Adapter for TanStack Query
lukesmurray 13b2c08
Fixed Tests and included changes from feedback
ardeora 3d4dc10
Prettier Format Code
ardeora 7542edd
Readme Update
ardeora c71d9ab
Fixing tsconfig for CI test runner
ardeora 206e440
(fix: ci) CI Test fix
ardeora 0224d6b
(fix: tests): Remove React 17 check
ardeora 234fd41
Update packages/solid-query/src/__tests__/createQuery.test.tsx
TkDodo de90e6b
Locking vite-plugin-solid version
ardeora File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
{ | ||
"installCommand": "install:csb", | ||
"sandboxes": ["/examples/react/basic", "/examples/react/basic-typescript"], | ||
"sandboxes": ["/examples/react/basic", "/examples/react/basic-typescript", "/examples/solid/basic-typescript"], | ||
"packages": ["packages/**"], | ||
"node": "16" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,205 @@ | ||
--- | ||
title: Solid Query (Coming Soon) | ||
title: Solid Query | ||
--- | ||
|
||
The `@tanstack/solid-query` package provides a 1st-class API for using TanStack Query with SolidJS. | ||
|
||
> ⚠️ This module has not yet been developed. It requires an adapter similar to `react-query` to work. We estimate the amount of code to do this is low-to-moderate, but does require familiarity with the SolidJS framework. If you would like to contribute this adapter, please open a PR! | ||
## Example | ||
|
||
The `@tanstack/solid-query` package offers a 1st-class API for using TanStack Query via Solid. However, all of the primitives you receive from this API are core APIs that are shared across all of the TanStack Adapters including the Query Client, query results, query subscriptions, etc. | ||
```tsx | ||
import { QueryClient, QueryClientProvider, createQuery } from '@tanstack/solid-query' | ||
import { Switch, Match, For } from 'solid-js' | ||
|
||
const queryClient = new QueryClient() | ||
|
||
function Example() { | ||
const query = createQuery(() => ['todos'], fetchTodos) | ||
|
||
return ( | ||
<div> | ||
<Switch> | ||
<Match when={query.isLoading}> | ||
<p>Loading...</p> | ||
</Match> | ||
<Match when={query.isError}> | ||
<p>Error: {query.error.message}</p> | ||
</Match> | ||
<Match when={query.isSuccess}> | ||
<For each={query.data}> | ||
{(todo) => <p>{todo.title}</p>} | ||
</For> | ||
</Match> | ||
</Switch> | ||
</div> | ||
) | ||
} | ||
|
||
function App() { | ||
return ( | ||
<QueryClientProvider client={queryClient}> | ||
<Example /> | ||
</QueryClientProvider> | ||
) | ||
} | ||
|
||
``` | ||
|
||
## Available Functions | ||
|
||
Solid Query offers useful primitives and functions that will make managing server state in SolidJS apps easier. | ||
|
||
- `createQuery` | ||
- `createQueries` | ||
- `createInfiniteQueries` | ||
- `createMutation` | ||
- `useIsFetching` | ||
- `useIsMutating` | ||
- `useQueryClient` | ||
- `QueryClient` | ||
- `QueryClientProvider` | ||
|
||
|
||
|
||
|
||
## Important Differences between Solid Query & React Query | ||
|
||
Solid Query offers an API similar to React Query, but there are some key differences to be mindful of. | ||
|
||
- To maintain their reactivity, Query keys need to be wrapped inside a function while using `createQuery`, `createQueries`, `createInfiniteQuery` and `useIsFetching`. | ||
|
||
```tsx | ||
// ❌ react version | ||
useQuery(["todos", todo], fetchTodos) | ||
|
||
// ✅ solid version | ||
createQuery(() => ["todos", todo()], fetchTodos) | ||
``` | ||
|
||
- Suspense works for queries out of the box if you access the query data inside a `<Suspense>` boundary. | ||
|
||
```tsx | ||
import { For, Suspense } from 'solid-js' | ||
|
||
function Example() { | ||
const query = createQuery(() => ['todos'], fetchTodos) | ||
return ( | ||
<div> | ||
{/* ✅ Will trigger loading fallback, data accessed in a suspense context. */} | ||
<Suspense fallback={"Loading..."}> | ||
<For each={query.data}>{(todo) => <div>{todo.title}</div>}</For> | ||
</Suspense> | ||
{/* ❌ Will not trigger loading fallback, data not accessed in a suspense context. */} | ||
<For each={query.data}>{(todo) => <div>{todo.title}</div>}</For> | ||
</div> | ||
) | ||
} | ||
``` | ||
|
||
- Solid Query primitives (`createX`) do not support destructuring. The return value from these functions is a store, and their properties are only tracked in a reactive context. | ||
|
||
```tsx | ||
import { QueryClient, QueryClientProvider, createQuery } from '@tanstack/solid-query' | ||
import { Match, Switch } from 'solid-js' | ||
|
||
const queryClient = new QueryClient() | ||
|
||
export default function App() { | ||
return ( | ||
<QueryClientProvider client={queryClient}> | ||
<Example /> | ||
</QueryClientProvider> | ||
) | ||
} | ||
|
||
function Example() { | ||
// ❌ react version -- supports destructing outside reactive context | ||
// const { isLoading, error, data } = useQuery(['repoData'], () => | ||
// fetch('https://api.github.com/repos/tannerlinsley/react-query').then(res => | ||
// res.json() | ||
// ) | ||
// ) | ||
|
||
// ✅ solid version -- does not support destructuring outside reactive context | ||
const query = createQuery( | ||
() => ['repoData'], | ||
() => | ||
fetch('https://api.github.com/repos/tannerlinsley/react-query').then( | ||
(res) => res.json(), | ||
), | ||
) | ||
|
||
// ✅ access query properties in JSX reactive context | ||
return ( | ||
<Switch> | ||
<Match when={query.isLoading}>Loading...</Match> | ||
<Match when={query.isError}>Error: {query.error.message}</Match> | ||
<Match when={query.isSuccess}> | ||
<div> | ||
<h1>{query.data.name}</h1> | ||
<p>{query.data.description}</p> | ||
<strong>👀 {query.data.subscribers_count}</strong>{' '} | ||
<strong>✨ {query.data.stargazers_count}</strong>{' '} | ||
<strong>🍴 {query.data.forks_count}</strong> | ||
</div> | ||
</Match> | ||
</Switch> | ||
) | ||
} | ||
``` | ||
|
||
- If you want options to be reactive you need to pass them using object getter syntax. This may look strange at first but it leads to more idiomatic solid code. | ||
|
||
```tsx | ||
import { | ||
QueryClient, | ||
QueryClientProvider, | ||
createQuery, | ||
} from '@tanstack/solid-query' | ||
import { createSignal, For } from 'solid-js' | ||
|
||
const queryClient = new QueryClient() | ||
|
||
function Example() { | ||
const [enabled, setEnabled] = createSignal(false) | ||
const query = createQuery(() => ['todos'], fetchTodos, { | ||
// ❌ passing a signal directly is not reactive | ||
// enabled: enabled(), | ||
|
||
// ✅ passing a function that returns a signal is reactive | ||
get enabled() { | ||
return enabled() | ||
}, | ||
}) | ||
|
||
return ( | ||
<div> | ||
<Switch> | ||
<Match when={query.isLoading}> | ||
<p>Loading...</p> | ||
</Match> | ||
<Match when={query.isError}> | ||
<p>Error: {query.error.message}</p> | ||
</Match> | ||
<Match when={query.isSuccess}> | ||
<For each={query.data}> | ||
{(todo) => <p>{todo.title}</p>} | ||
</For> | ||
</Match> | ||
</Switch> | ||
<button onClick={() => setEnabled(!enabled())}>Toggle enabled</button> | ||
</div> | ||
) | ||
} | ||
|
||
function App() { | ||
return ( | ||
<QueryClientProvider client={queryClient}> | ||
<Example /> | ||
</QueryClientProvider> | ||
) | ||
} | ||
``` | ||
|
||
- Errors can be caught and reset using SolidJS' native `ErrorBoundary` component. `QueryErrorResetBoundary` is not needed with Solid Query | ||
|
||
- Since Property tracking is handled through Solid's fine grained reactivity, options like `notifyOnChangeProps` are not needed |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# Examples to Add | ||
|
||
- auto-refetching 🚫 nextjs (react only) | ||
- basic 🚫 javascript (only converting typescript) | ||
- basic-graphql-request 🟢 | ||
- basic-typescript 🟢 | ||
- custom-hooks 🚫 not implemented in react | ||
- default-query-function 🟡 (green styling for cached post not working) | ||
- focus-refetching 🚫 not implemented in react | ||
- load-more-infinite-scroll 🚫 nextjs (react only) | ||
- nextjs 🚫 nextjs (react only) | ||
- offline 🔴 | ||
- optimistic-updates 🚫 not implemented in react | ||
- optimistic-updates-typescript 🚫 nextjs (react only) | ||
- pagination 🚫 nextjs (react only) | ||
- playground 🔴 | ||
- prefetching 🚫 nextjs (react only) | ||
- react-native 🚫 react native (react only) | ||
- rick-morty 🔴 | ||
- simple 🟢 | ||
- star-wars 🔴 | ||
- suspense 🔴 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"parserOptions": { | ||
"project": "./tsconfig.json", | ||
"sourceType": "module" | ||
}, | ||
"rules": { | ||
"react/react-in-jsx-scope": "off", | ||
"jsx-a11y/anchor-is-valid": "off" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
node_modules | ||
dist | ||
.yalc | ||
yalc.lock |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# Example | ||
|
||
To run this example: | ||
|
||
- `npm install` | ||
- `npm run start` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="utf-8" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1" /> | ||
<meta name="theme-color" content="#000000" /> | ||
<link rel="shortcut icon" type="image/ico" href="/src/assets/favicon.ico" /> | ||
<title>Solid App</title> | ||
</head> | ||
<body> | ||
<noscript>You need to enable JavaScript to run this app.</noscript> | ||
<div id="root"></div> | ||
|
||
<script src="/src/index.tsx" type="module"></script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
{ | ||
"name": "@tanstack/query-example-solid-basic-graphql-request", | ||
"private": true, | ||
"version": "0.0.0", | ||
"description": "", | ||
"scripts": { | ||
"start": "vite", | ||
"dev": "vite", | ||
"build": "vite build", | ||
"serve": "vite preview" | ||
}, | ||
"license": "MIT", | ||
"dependencies": { | ||
"@tanstack/solid-query": "^4.3.9", | ||
"graphql": "^16.6.0", | ||
"graphql-request": "^5.0.0", | ||
"solid-js": "^1.5.1" | ||
}, | ||
"devDependencies": { | ||
"typescript": "^4.8.2", | ||
"vite": "^3.0.9", | ||
"vite-plugin-solid": "2.3.6" | ||
} | ||
} |
Binary file not shown.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm no babel expert, but I think it should be possible to also have one babel config per package? So we would only keep the shared things in top level and then move the framework specific things further down ?