Skip to content

🏝️ TanStack Query DevTools for Expo/React Native! 🚀 #8846

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

Merged
merged 24 commits into from
May 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
4b3e884
test
LovesWorking Mar 22, 2025
f7b02b4
feat(devtools): add action event types and notify functionality for q…
LovesWorking Mar 23, 2025
16b0e7d
cleanup commeny
LovesWorking Mar 23, 2025
10074bf
fix(devtools): update notifyDevtools to use queryClient for all actio…
LovesWorking Mar 23, 2025
33cabd4
remove dup call
LovesWorking Mar 23, 2025
e7150fc
Fix online manager bug not syncing correctly
LovesWorking Mar 23, 2025
2ec65f3
Update docs
LovesWorking Mar 24, 2025
cff1c33
Merge branch 'main' into main
LovesWorking Mar 25, 2025
89ffabe
Merge branch 'main' into main
TkDodo Mar 26, 2025
874bb10
Fix default case error due to additional events from dev tools.
LovesWorking Mar 30, 2025
452bf71
Merge branch 'main' into main
LovesWorking Apr 6, 2025
3aba238
Merge branch 'main' into main
LovesWorking Apr 8, 2025
5cae570
Merge branch 'TanStack:main' into main
LovesWorking Apr 18, 2025
43bab78
Merge branch 'TanStack:main' into main
LovesWorking May 11, 2025
fc1652b
Add events
LovesWorking May 11, 2025
28cafec
ci: apply automated fixes
autofix-ci[bot] May 11, 2025
504f598
Remove no longer needed code
LovesWorking May 11, 2025
4d087a6
ci: apply automated fixes
autofix-ci[bot] May 11, 2025
83d815e
revert previous change
LovesWorking May 11, 2025
1cc4752
undo minor text change
LovesWorking May 11, 2025
f242647
ci: apply automated fixes
autofix-ci[bot] May 11, 2025
74bef6e
Merge branch 'main' into main
TkDodo May 12, 2025
7b11c9f
Update packages/query-devtools/src/Devtools.tsx
TkDodo May 12, 2025
daf0da1
Apply suggestions from code review
TkDodo May 12, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions docs/framework/react/devtools.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,7 @@ Wave your hands in the air and shout hooray because React Query comes with dedic

When you begin your React Query journey, you'll want these devtools by your side. They help visualize all the inner workings of React Query and will likely save you hours of debugging if you find yourself in a pinch!

> Please note that for now, the devtools **do not support React Native**. If you would like to help us make the devtools platform-agnostic, please let us know!

> Exciting News: We now have a separate package for React Native React Query DevTools! This new addition brings native support, allowing you to integrate DevTools directly into your React Native projects. Check it out and contribute here: [react-native-react-query-devtools](https://github.com/LovesWorking/react-native-react-query-devtools)

> An external tool is also available that enables the use of React Query DevTools via an external dashboard. Find out more and contribute on [react-query-external-sync](https://github.com/LovesWorking/react-query-external-sync)
> For React Native users: A third-party native macOS app is available for debugging React Query in ANY js-based application. Monitor queries across devices in real-time. Check it out here: [rn-better-dev-tools](https://github.com/LovesWorking/rn-better-dev-tools)

> Note that since version 5, the dev tools support observing mutations as well.

Expand Down
15 changes: 10 additions & 5 deletions docs/framework/react/react-native.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,20 @@ id: react-native
title: React Native
---

React Query is designed to work out of the box with React Native, with the exception of the devtools, which are only supported with React DOM at this time.
React Query is designed to work out of the box with React Native.

There is a 3rd party [Expo](https://docs.expo.dev/) plugin which you can try: https://github.com/expo/dev-plugins/tree/main/packages/react-query
## DevTools Support

There is a 3rd party [Flipper](https://fbflipper.com/docs/getting-started/react-native/) plugin which you can try: https://github.com/bgaleotti/react-query-native-devtools
There are several options available for React Native DevTools integration:

There is a 3rd party [Reactotron](https://github.com/infinitered/reactotron/) plugin which you can try: https://github.com/hsndmr/reactotron-react-query
1. **Native macOS App**: A 3rd party app for debugging React Query in any js-based application:
https://github.com/LovesWorking/rn-better-dev-tools

If you would like to help us make the built-in devtools platform agnostic, please let us know!
2. **Flipper Plugin**: A 3rd party plugin for Flipper users:
https://github.com/bgaleotti/react-query-native-devtools

3. **Reactotron Plugin**: A 3rd party plugin for Reactotron users:
https://github.com/hsndmr/reactotron-react-query

## Online status management

Expand Down
105 changes: 91 additions & 14 deletions packages/query-devtools/src/Devtools.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,18 @@
const styles = createMemo(() => {
return theme() === 'dark' ? darkStyles(css) : lightStyles(css)
})
const onlineManager = createMemo(
() => useQueryDevtoolsContext().onlineManager,

Check warning on line 124 in packages/query-devtools/src/Devtools.tsx

View check run for this annotation

Codecov / codecov/patch

packages/query-devtools/src/Devtools.tsx#L123-L124

Added lines #L123 - L124 were not covered by tests
)
onMount(() => {
const unsubscribe = onlineManager().subscribe((online) => {
setOffline(!online)

Check warning on line 128 in packages/query-devtools/src/Devtools.tsx

View check run for this annotation

Codecov / codecov/patch

packages/query-devtools/src/Devtools.tsx#L126-L128

Added lines #L126 - L128 were not covered by tests
})

onCleanup(() => {
unsubscribe()

Check warning on line 132 in packages/query-devtools/src/Devtools.tsx

View check run for this annotation

Codecov / codecov/patch

packages/query-devtools/src/Devtools.tsx#L131-L132

Added lines #L131 - L132 were not covered by tests
})
})

const pip = usePiPWindow()

Expand Down Expand Up @@ -922,8 +934,10 @@
<button
onClick={() => {
if (selectedView() === 'queries') {
sendDevToolsEvent({ type: 'CLEAR_QUERY_CACHE' })

Check warning on line 937 in packages/query-devtools/src/Devtools.tsx

View check run for this annotation

Codecov / codecov/patch

packages/query-devtools/src/Devtools.tsx#L937

Added line #L937 was not covered by tests
query_cache().clear()
} else {
sendDevToolsEvent({ type: 'CLEAR_MUTATION_CACHE' })

Check warning on line 940 in packages/query-devtools/src/Devtools.tsx

View check run for this annotation

Codecov / codecov/patch

packages/query-devtools/src/Devtools.tsx#L940

Added line #L940 was not covered by tests
mutation_cache().clear()
}
}}
Expand All @@ -939,13 +953,7 @@
</button>
<button
onClick={() => {
if (offline()) {
onlineManager().setOnline(true)
setOffline(false)
} else {
onlineManager().setOnline(false)
setOffline(true)
}
onlineManager().setOnline(!onlineManager().isOnline())

Check warning on line 956 in packages/query-devtools/src/Devtools.tsx

View check run for this annotation

Codecov / codecov/patch

packages/query-devtools/src/Devtools.tsx#L956

Added line #L956 was not covered by tests
}}
class={cx(
styles().actionsBtn,
Expand Down Expand Up @@ -1768,29 +1776,43 @@
const color = createMemo(() => getQueryStatusColorByLabel(statusLabel()))

const handleRefetch = () => {
sendDevToolsEvent({ type: 'REFETCH', queryHash: activeQuery()?.queryHash })

Check warning on line 1779 in packages/query-devtools/src/Devtools.tsx

View check run for this annotation

Codecov / codecov/patch

packages/query-devtools/src/Devtools.tsx#L1779

Added line #L1779 was not covered by tests
const promise = activeQuery()?.fetch()
promise?.catch(() => {})
}

const triggerError = (errorType?: DevtoolsErrorType) => {
const activeQueryVal = activeQuery()

Check warning on line 1785 in packages/query-devtools/src/Devtools.tsx

View check run for this annotation

Codecov / codecov/patch

packages/query-devtools/src/Devtools.tsx#L1785

Added line #L1785 was not covered by tests
if (!activeQueryVal) return
sendDevToolsEvent({

Check warning on line 1787 in packages/query-devtools/src/Devtools.tsx

View check run for this annotation

Codecov / codecov/patch

packages/query-devtools/src/Devtools.tsx#L1787

Added line #L1787 was not covered by tests
type: 'TRIGGER_ERROR',
queryHash: activeQueryVal.queryHash,
metadata: { error: errorType?.name },
})
const error =
errorType?.initializer(activeQuery()!) ??
errorType?.initializer(activeQueryVal) ??
new Error('Unknown error from devtools')

const __previousQueryOptions = activeQuery()!.options
const __previousQueryOptions = activeQueryVal.options

Check warning on line 1796 in packages/query-devtools/src/Devtools.tsx

View check run for this annotation

Codecov / codecov/patch

packages/query-devtools/src/Devtools.tsx#L1796

Added line #L1796 was not covered by tests

activeQuery()!.setState({
activeQueryVal.setState({

Check warning on line 1798 in packages/query-devtools/src/Devtools.tsx

View check run for this annotation

Codecov / codecov/patch

packages/query-devtools/src/Devtools.tsx#L1798

Added line #L1798 was not covered by tests
status: 'error',
error,
fetchMeta: {
...activeQuery()!.state.fetchMeta,
...activeQueryVal.state.fetchMeta,
__previousQueryOptions,
} as any,
} as QueryState<unknown, Error>)
}

const restoreQueryAfterLoadingOrError = () => {
const activeQueryVal = activeQuery()!
const activeQueryVal = activeQuery()

Check warning on line 1809 in packages/query-devtools/src/Devtools.tsx

View check run for this annotation

Codecov / codecov/patch

packages/query-devtools/src/Devtools.tsx#L1809

Added line #L1809 was not covered by tests
if (!activeQueryVal) return

sendDevToolsEvent({

Check warning on line 1812 in packages/query-devtools/src/Devtools.tsx

View check run for this annotation

Codecov / codecov/patch

packages/query-devtools/src/Devtools.tsx#L1812

Added line #L1812 was not covered by tests
type: 'RESTORE_LOADING',
queryHash: activeQueryVal.queryHash,
})
const previousState = activeQueryVal.state
const previousOptions = activeQueryVal.state.fetchMeta
? (activeQueryVal.state.fetchMeta as any).__previousQueryOptions
Expand Down Expand Up @@ -1899,7 +1921,13 @@
'tsqd-query-details-actions-btn',
'tsqd-query-details-action-invalidate',
)}
onClick={() => queryClient.invalidateQueries(activeQuery())}
onClick={() => {
sendDevToolsEvent({

Check warning on line 1925 in packages/query-devtools/src/Devtools.tsx

View check run for this annotation

Codecov / codecov/patch

packages/query-devtools/src/Devtools.tsx#L1924-L1925

Added lines #L1924 - L1925 were not covered by tests
type: 'INVALIDATE',
queryHash: activeQuery()?.queryHash,
})
queryClient.invalidateQueries(activeQuery())
}}

Check warning on line 1930 in packages/query-devtools/src/Devtools.tsx

View check run for this annotation

Codecov / codecov/patch

packages/query-devtools/src/Devtools.tsx#L1929-L1930

Added lines #L1929 - L1930 were not covered by tests
disabled={queryStatus() === 'pending'}
>
<span
Expand All @@ -1917,7 +1945,13 @@
'tsqd-query-details-actions-btn',
'tsqd-query-details-action-reset',
)}
onClick={() => queryClient.resetQueries(activeQuery())}
onClick={() => {
sendDevToolsEvent({

Check warning on line 1949 in packages/query-devtools/src/Devtools.tsx

View check run for this annotation

Codecov / codecov/patch

packages/query-devtools/src/Devtools.tsx#L1948-L1949

Added lines #L1948 - L1949 were not covered by tests
type: 'RESET',
queryHash: activeQuery()?.queryHash,
})
queryClient.resetQueries(activeQuery())
}}

Check warning on line 1954 in packages/query-devtools/src/Devtools.tsx

View check run for this annotation

Codecov / codecov/patch

packages/query-devtools/src/Devtools.tsx#L1953-L1954

Added lines #L1953 - L1954 were not covered by tests
disabled={queryStatus() === 'pending'}
>
<span
Expand All @@ -1936,6 +1970,10 @@
'tsqd-query-details-action-remove',
)}
onClick={() => {
sendDevToolsEvent({

Check warning on line 1973 in packages/query-devtools/src/Devtools.tsx

View check run for this annotation

Codecov / codecov/patch

packages/query-devtools/src/Devtools.tsx#L1973

Added line #L1973 was not covered by tests
type: 'REMOVE',
queryHash: activeQuery()?.queryHash,
})
queryClient.removeQueries(activeQuery())
setSelectedQueryHash(null)
}}
Expand Down Expand Up @@ -1964,6 +2002,10 @@
} else {
const activeQueryVal = activeQuery()
if (!activeQueryVal) return
sendDevToolsEvent({

Check warning on line 2005 in packages/query-devtools/src/Devtools.tsx

View check run for this annotation

Codecov / codecov/patch

packages/query-devtools/src/Devtools.tsx#L2005

Added line #L2005 was not covered by tests
type: 'TRIGGER_LOADING',
queryHash: activeQueryVal.queryHash,
})
const __previousQueryOptions = activeQueryVal.options
// Trigger a fetch in order to trigger suspense as well.
activeQueryVal.fetch({
Expand Down Expand Up @@ -2006,6 +2048,10 @@
if (!activeQuery()!.state.error) {
triggerError()
} else {
sendDevToolsEvent({

Check warning on line 2051 in packages/query-devtools/src/Devtools.tsx

View check run for this annotation

Codecov / codecov/patch

packages/query-devtools/src/Devtools.tsx#L2051

Added line #L2051 was not covered by tests
type: 'RESTORE_ERROR',
queryHash: activeQuery()?.queryHash,
})
queryClient.resetQueries(activeQuery())
}
}}
Expand Down Expand Up @@ -2438,6 +2484,37 @@
return value
}

type DevToolsActionType =
| 'REFETCH'
| 'INVALIDATE'
| 'RESET'
| 'REMOVE'
| 'TRIGGER_ERROR'
| 'RESTORE_ERROR'
| 'TRIGGER_LOADING'
| 'RESTORE_LOADING'
| 'CLEAR_MUTATION_CACHE'
| 'CLEAR_QUERY_CACHE'

const DEV_TOOLS_EVENT = '@tanstack/query-devtools-event'

Check warning on line 2499 in packages/query-devtools/src/Devtools.tsx

View check run for this annotation

Codecov / codecov/patch

packages/query-devtools/src/Devtools.tsx#L2499

Added line #L2499 was not covered by tests

const sendDevToolsEvent = ({

Check warning on line 2501 in packages/query-devtools/src/Devtools.tsx

View check run for this annotation

Codecov / codecov/patch

packages/query-devtools/src/Devtools.tsx#L2501

Added line #L2501 was not covered by tests
type,
queryHash,
metadata,
}: {
type: DevToolsActionType
queryHash?: string
metadata?: Record<string, unknown>
}) => {
const event = new CustomEvent(DEV_TOOLS_EVENT, {

Check warning on line 2510 in packages/query-devtools/src/Devtools.tsx

View check run for this annotation

Codecov / codecov/patch

packages/query-devtools/src/Devtools.tsx#L2509-L2510

Added lines #L2509 - L2510 were not covered by tests
detail: { type, queryHash, metadata },
bubbles: true,
cancelable: true,
})
window.dispatchEvent(event)

Check warning on line 2515 in packages/query-devtools/src/Devtools.tsx

View check run for this annotation

Codecov / codecov/patch

packages/query-devtools/src/Devtools.tsx#L2515

Added line #L2515 was not covered by tests
}

const stylesFactory = (
theme: 'light' | 'dark',
css: (typeof goober)['css'],
Expand Down
Loading