Skip to content

Commit 02a800c

Browse files
chore: use trpc queryOptions in example (#1153)
1 parent b2f3f87 commit 02a800c

7 files changed

Lines changed: 146 additions & 137 deletions

File tree

examples/minimal-expo/app/_layout.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import "./styles.css";
22

33
import FeatherIcon from "@expo/vector-icons/Feather";
44
import { BottomSheetModal, BottomSheetView } from "@gorhom/bottom-sheet";
5+
import { QueryClientProvider } from "@tanstack/react-query";
56
import { Image } from "expo-image";
67
import { Stack } from "expo-router";
78
import { StatusBar } from "expo-status-bar";
@@ -11,11 +12,11 @@ import {
1112
RectButton,
1213
} from "react-native-gesture-handler";
1314

14-
import { TRPCProvider } from "~/lib/trpc";
15+
import { queryClient } from "~/lib/trpc";
1516

1617
export default function RootLayout() {
1718
return (
18-
<TRPCProvider>
19+
<QueryClientProvider client={queryClient}>
1920
<GestureHandlerRootView style={{ flex: 1 }}>
2021
<Stack
2122
screenOptions={{
@@ -31,7 +32,7 @@ export default function RootLayout() {
3132
</GestureHandlerRootView>
3233

3334
<StatusBar />
34-
</TRPCProvider>
35+
</QueryClientProvider>
3536
);
3637
}
3738

examples/minimal-expo/app/index.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { useState } from "react";
22
import { FlashList } from "@shopify/flash-list";
3+
import { useQuery, useQueryClient } from "@tanstack/react-query";
34
import { Stack } from "expo-router";
45
import { ActivityIndicator, RefreshControl, Text, View } from "react-native";
56

@@ -8,8 +9,8 @@ import { UploadActionDrawer } from "~/components/upload-drawer";
89
import { trpc } from "~/lib/trpc";
910

1011
export default function HomeScreen() {
11-
const utils = trpc.useUtils();
12-
const { data: files, isPending } = trpc.getFiles.useQuery();
12+
const queryClient = useQueryClient();
13+
const { data: files, isPending } = useQuery(trpc.getFiles.queryOptions());
1314

1415
const [refreshing, setRefreshing] = useState(false);
1516
const [isScrolling, setIsScrolling] = useState(false);
@@ -34,7 +35,9 @@ export default function HomeScreen() {
3435
refreshing={refreshing}
3536
onRefresh={async () => {
3637
setRefreshing(true);
37-
await utils.getFiles.invalidate();
38+
await queryClient.invalidateQueries(
39+
trpc.getFiles.queryFilter(),
40+
);
3841
setRefreshing(false);
3942
}}
4043
tintColor={"#ccc"}

examples/minimal-expo/components/file-item.tsx

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { useRef } from "react";
22
import FeatherIcon from "@expo/vector-icons/Feather";
3+
import { useMutation, useQueryClient } from "@tanstack/react-query";
34
import * as Haptics from "expo-haptics";
45
import { Link } from "expo-router";
56
import { Animated, Text, View } from "react-native";
@@ -17,16 +18,20 @@ export function FileItem({
1718
}: {
1819
item: RouterOutputs["getFiles"][number];
1920
}) {
20-
const utils = trpc.useUtils();
21-
const { mutate: deleteFile } = trpc.deleteFile.useMutation({
22-
onMutate: () => {
23-
// Optimicially remove the file from the list
24-
const files = utils.getFiles.getData() ?? [];
25-
const newFiles = files.filter((f) => f.key !== item.key);
26-
utils.getFiles.setData(undefined, newFiles);
27-
},
28-
onSettled: () => utils.getFiles.invalidate(),
29-
});
21+
const queryClient = useQueryClient();
22+
const { mutate: deleteFile } = useMutation(
23+
trpc.deleteFile.mutationOptions({
24+
onMutate: () => {
25+
// Optimicially remove the file from the list
26+
const files = queryClient.getQueryData(trpc.getFiles.queryKey()) ?? [];
27+
const newFiles = files.filter((f) => f.key !== item.key);
28+
queryClient.setQueryData(trpc.getFiles.queryKey(), newFiles);
29+
},
30+
onSettled: async () => {
31+
await queryClient.invalidateQueries(trpc.getFiles.queryFilter());
32+
},
33+
}),
34+
);
3035

3136
const threshhold = 64;
3237
const height = useRef(new Animated.Value(threshhold)).current;

examples/minimal-expo/components/upload-drawer.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
BottomSheetModalProvider,
66
BottomSheetView,
77
} from "@gorhom/bottom-sheet";
8+
import { useQueryClient } from "@tanstack/react-query";
89
import { openSettings } from "expo-linking";
910
import { useRouter } from "expo-router";
1011
import { ActivityIndicator, Alert, Pressable, Text, View } from "react-native";
@@ -15,7 +16,7 @@ import { useDocumentUploader, useImageUploader } from "~/lib/uploadthing";
1516
export function UploadActionDrawer(props: { showTrigger: boolean }) {
1617
const bottomSheetModalRef = useRef<BottomSheetModal>(null);
1718

18-
const utils = trpc.useUtils();
19+
const queryClient = useQueryClient();
1920
const router = useRouter();
2021

2122
const imageUploader = useImageUploader("videoAndImage", {
@@ -26,7 +27,7 @@ export function UploadActionDrawer(props: { showTrigger: boolean }) {
2627
Alert.alert("Upload Error", e.data?.reason ?? e.message);
2728
},
2829
onClientUploadComplete: (files) => {
29-
utils.getFiles.invalidate();
30+
queryClient.invalidateQueries(trpc.getFiles.queryFilter());
3031

3132
if (files.length === 1) {
3233
// Auto-open the file if there's only one
@@ -46,7 +47,7 @@ export function UploadActionDrawer(props: { showTrigger: boolean }) {
4647
Alert.alert("Upload Error", e.data?.reason ?? e.message);
4748
},
4849
onClientUploadComplete: (files) => {
49-
utils.getFiles.invalidate();
50+
queryClient.invalidateQueries(trpc.getFiles.queryFilter());
5051

5152
if (files.length === 1) {
5253
// Auto-open the file if there's only one

examples/minimal-expo/lib/trpc.tsx

Lines changed: 27 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,44 @@
1-
import { useState } from "react";
2-
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
3-
import { httpBatchLink, loggerLink } from "@trpc/client";
4-
import { createTRPCReact } from "@trpc/react-query";
1+
import { QueryClient } from "@tanstack/react-query";
2+
import { createTRPCClient, httpBatchLink } from "@trpc/client";
53
import { inferRouterOutputs } from "@trpc/server";
4+
import { createTRPCOptionsProxy } from "@trpc/tanstack-react-query";
65
import Constants from "expo-constants";
76

87
import type { TRPCRouter } from "../app/api/trpc/[trpc]+api";
98

9+
export const queryClient = new QueryClient({
10+
defaultOptions: {
11+
queries: {
12+
// ...
13+
},
14+
},
15+
});
16+
1017
/**
11-
* A set of typesafe hooks for consuming your API.
18+
* A type-safe proxy for working with the React Query client.
1219
*/
13-
export const trpc = createTRPCReact<TRPCRouter>();
20+
export const trpc = createTRPCOptionsProxy<TRPCRouter>({
21+
client: createTRPCClient({
22+
links: [
23+
// loggerLink({
24+
// enabled: (opts) =>
25+
// process.env.NODE_ENV === "development" ||
26+
// (opts.direction === "down" && opts.result instanceof Error),
27+
// colorMode: "ansi",
28+
// }),
29+
httpBatchLink({ url: resolveUrl() }),
30+
],
31+
}),
32+
queryClient,
33+
});
1434

1535
export type RouterOutputs = inferRouterOutputs<TRPCRouter>;
1636

1737
/**
1838
* Extend this function when going to production by
1939
* setting the baseUrl to your production API URL.
2040
*/
21-
const resolveUrl = () => {
41+
function resolveUrl() {
2242
/**
2343
* Gets the IP address of your host-machine. If it cannot automatically find it,
2444
* you'll have to manually set it. NOTE: Port 3000 should work for most but confirm
@@ -41,33 +61,4 @@ const resolveUrl = () => {
4161
`Failed to resolve URL from ${process.env.EXPO_PUBLIC_SERVER_ORIGIN} or ${debuggerHost}`,
4262
);
4363
}
44-
};
45-
46-
/**
47-
* A wrapper for your app that provides the TRPC context.
48-
* Use only in _app.tsx
49-
*/
50-
export function TRPCProvider(props: { children: React.ReactNode }) {
51-
const [queryClient] = useState(() => new QueryClient());
52-
const [trpcClient] = useState(() =>
53-
trpc.createClient({
54-
links: [
55-
// loggerLink({
56-
// enabled: (opts) =>
57-
// process.env.NODE_ENV === "development" ||
58-
// (opts.direction === "down" && opts.result instanceof Error),
59-
// colorMode: "ansi",
60-
// }),
61-
httpBatchLink({ url: resolveUrl() }),
62-
],
63-
}),
64-
);
65-
66-
return (
67-
<trpc.Provider client={trpcClient} queryClient={queryClient}>
68-
<QueryClientProvider client={queryClient}>
69-
{props.children}
70-
</QueryClientProvider>
71-
</trpc.Provider>
72-
);
7364
}

examples/minimal-expo/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@
1616
"@gorhom/bottom-sheet": "^4.6.1",
1717
"@shopify/flash-list": "1.6.4",
1818
"@tanstack/react-query": "^5.29.2",
19-
"@trpc/client": "11.0.0-rc.452",
20-
"@trpc/react-query": "11.0.0-rc.452",
21-
"@trpc/server": "11.0.0-rc.452",
19+
"@trpc/client": "11.0.0-rc.772",
20+
"@trpc/server": "11.0.0-rc.772",
21+
"@trpc/tanstack-react-query": "11.0.0-rc.772",
2222
"@uploadthing/expo": "7.2.2",
2323
"expo": "~51.0.8",
2424
"expo-dev-client": "~4.0.10",

0 commit comments

Comments
 (0)