Merge pull request #21 from stevedylandev/chore/refactor-use-mutation f0059aa0
chore: updated templates to use refactored mutation
Steve Simkins · 2025-10-03 12:51 6 file(s) · +57 −99
src/templates/extras/client/src/App.tsx/App-with-rpc-shadcn-tailwind-tanstackquery.tsx +11 −20
1 -
import { useState } from "react";
2 1
import beaver from "./assets/beaver.svg";
3 2
import { Button } from "./components/ui/button";
4 3
import { hcWithType } from "server/dist/client";
11 10
type ResponseType = Awaited<ReturnType<typeof client.hello.$get>>;
12 11
13 12
function App() {
14 -
	const [data, setData] = useState<
15 -
		Awaited<ReturnType<ResponseType["json"]>> | undefined
16 -
	>();
17 -
18 -
	const { mutate: sendRequest } = useMutation({
13 +
	const apiRequestMutation = useMutation({
19 14
		mutationFn: async () => {
20 -
			try {
21 -
				const res = await client.hello.$get();
22 -
				if (!res.ok) {
23 -
					console.log("Error fetching data");
24 -
					return;
25 -
				}
26 -
				const data = await res.json();
27 -
				setData(data);
28 -
			} catch (error) {
29 -
				console.log(error);
15 +
			const res = await client.hello.$get();
16 +
			if (!res.ok) {
17 +
				throw new Error("Error fetching data");
30 18
			}
19 +
			const data = await res.json();
20 +
			return data;
31 21
		},
22 +
		onError: (err: any) => console.log(err),
32 23
	});
33 24
34 25
	return (
48 39
			<h2 className="text-2xl font-bold">Bun + Hono + Vite + React</h2>
49 40
			<p>A typesafe fullstack monorepo</p>
50 41
			<div className="flex items-center gap-4">
51 -
				<Button onClick={() => sendRequest()}>Call API</Button>
42 +
				<Button onClick={() => apiRequestMutation.mutate()}>Call API</Button>
52 43
				<Button variant="secondary" asChild>
53 44
					<a target="_blank" href="https://bhvr.dev" rel="noopener">
54 45
						Docs
55 46
					</a>
56 47
				</Button>
57 48
			</div>
58 -
			{data && (
49 +
			{apiRequestMutation.isSuccess && (
59 50
				<pre className="bg-gray-100 p-4 rounded-md">
60 51
					<code>
61 -
						Message: {data.message} <br />
62 -
						Success: {data.success.toString()}
52 +
						Message: {apiRequestMutation.data.message} <br />
53 +
						Success: {apiRequestMutation.data.success.toString()}
63 54
					</code>
64 55
				</pre>
65 56
			)}
src/templates/extras/client/src/App.tsx/App-with-rpc-tailwind-tanstackquery.tsx +11 −20
1 -
import { useState } from "react";
2 1
import beaver from "./assets/beaver.svg";
3 2
import { hcWithType } from "server/dist/client";
4 3
import { useMutation } from "@tanstack/react-query";
10 9
const client = hcWithType(SERVER_URL);
11 10
12 11
function App() {
13 -
	const [data, setData] = useState<
14 -
		Awaited<ReturnType<ResponseType["json"]>> | undefined
15 -
	>();
16 -
17 -
	const { mutate: sendRequest } = useMutation({
12 +
	const apiRequestMutation = useMutation({
18 13
		mutationFn: async () => {
19 -
			try {
20 -
				const res = await client.hello.$get();
21 -
				if (!res.ok) {
22 -
					console.log("Error fetching data");
23 -
					return;
24 -
				}
25 -
				const data = await res.json();
26 -
				setData(data);
27 -
			} catch (error) {
28 -
				console.log(error);
14 +
			const res = await client.hello.$get();
15 +
			if (!res.ok) {
16 +
				throw new Error("Error fetching data");
29 17
			}
18 +
			const data = await res.json();
19 +
			return data;
30 20
		},
21 +
		onError: (err: any) => console.log(err),
31 22
	});
32 23
33 24
	return (
49 40
			<div className="flex items-center gap-4">
50 41
				<button
51 42
					type="button"
52 -
					onClick={() => sendRequest()}
43 +
					onClick={() => apiRequestMutation.mutate()}
53 44
					className="bg-black text-white px-2.5 py-1.5 rounded-md"
54 45
				>
55 46
					Call API
63 54
					Docs
64 55
				</a>
65 56
			</div>
66 -
			{data && (
57 +
			{apiRequestMutation.isSuccess && (
67 58
				<pre className="bg-gray-100 p-4 rounded-md">
68 59
					<code>
69 -
						Message: {data.message} <br />
70 -
						Success: {data.success.toString()}
60 +
						Message: {apiRequestMutation.data.message} <br />
61 +
						Success: {apiRequestMutation.data.success.toString()}
71 62
					</code>
72 63
				</pre>
73 64
			)}
src/templates/extras/client/src/App.tsx/App-with-rpc-tanstackquery.tsx +11 −20
1 -
import { useState } from "react";
2 1
import beaver from "./assets/beaver.svg";
3 2
import { hcWithType } from "server/dist/client";
4 3
import { useMutation } from "@tanstack/react-query";
11 10
type ResponseType = Awaited<ReturnType<typeof client.hello.$get>>;
12 11
13 12
function App() {
14 -
	const [data, setData] = useState<
15 -
		Awaited<ReturnType<ResponseType["json"]>> | undefined
16 -
	>();
17 -
18 -
	const { mutate: sendRequest } = useMutation({
13 +
	const apiRequestMutation = useMutation({
19 14
		mutationFn: async () => {
20 -
			try {
21 -
				const res = await client.hello.$get();
22 -
				if (!res.ok) {
23 -
					console.log("Error fetching data");
24 -
					return;
25 -
				}
26 -
				const data = await res.json();
27 -
				setData(data);
28 -
			} catch (error) {
29 -
				console.log(error);
15 +
			const res = await client.hello.$get();
16 +
			if (!res.ok) {
17 +
				throw new Error("Error fetching data");
30 18
			}
19 +
			const data = await res.json();
20 +
			return data;
31 21
		},
22 +
		onError: (err: any) => console.log(err),
32 23
	});
33 24
34 25
	return (
47 38
			<p>A typesafe fullstack monorepo</p>
48 39
			<div className="card">
49 40
				<div className="button-container">
50 -
					<button type="button" onClick={() => sendRequest()}>
41 +
					<button type="button" onClick={() => apiRequestMutation.mutate()}>
51 42
						Call API
52 43
					</button>
53 44
					<a
59 50
						Docs
60 51
					</a>
61 52
				</div>
62 -
				{data && (
53 +
				{apiRequestMutation.isSuccess && (
63 54
					<pre className="response">
64 55
						<code>
65 -
							Message: {data.message} <br />
66 -
							Success: {data.success.toString()}
56 +
							Message: {apiRequestMutation.data.message} <br />
57 +
							Success: {apiRequestMutation.data.success.toString()}
67 58
						</code>
68 59
					</pre>
69 60
				)}
src/templates/extras/client/src/App.tsx/App-with-shadcn-tailwind-tanstackquery.tsx +9 −15
1 -
import { useState } from "react";
2 1
import beaver from "./assets/beaver.svg";
3 2
import type { ApiResponse } from "shared";
4 3
import { Button } from "./components/ui/button";
7 6
const SERVER_URL = import.meta.env.VITE_SERVER_URL || "http://localhost:3000";
8 7
9 8
function App() {
10 -
	const [data, setData] = useState<ApiResponse | undefined>();
11 -
12 -
	const { mutate: sendRequest } = useMutation({
9 +
	const apiRequestMutation = useMutation({
13 10
		mutationFn: async () => {
14 -
			try {
15 -
				const req = await fetch(`${SERVER_URL}/hello`);
16 -
				const res: ApiResponse = await req.json();
17 -
				setData(res);
18 -
			} catch (error) {
19 -
				console.log(error);
20 -
			}
11 +
			const req = await fetch(`${SERVER_URL}/hello`);
12 +
			const res: ApiResponse = await req.json();
13 +
			return res;
21 14
		},
15 +
		onError: (err: any) => console.log(err),
22 16
	});
23 17
24 18
	return (
38 32
			<h2 className="text-2xl font-bold">Bun + Hono + Vite + React</h2>
39 33
			<p>A typesafe fullstack monorepo</p>
40 34
			<div className="flex items-center gap-4">
41 -
				<Button onClick={() => sendRequest()}>Call API</Button>
35 +
				<Button onClick={() => apiRequestMutation.mutate()}>Call API</Button>
42 36
				<Button variant="secondary" asChild>
43 37
					<a target="_blank" href="https://bhvr.dev" rel="noopener">
44 38
						Docs
45 39
					</a>
46 40
				</Button>
47 41
			</div>
48 -
			{data && (
42 +
			{apiRequestMutation.isSuccess && (
49 43
				<pre className="bg-gray-100 p-4 rounded-md">
50 44
					<code>
51 -
						Message: {data.message} <br />
52 -
						Success: {data.success.toString()}
45 +
						Message: {apiRequestMutation.data.message} <br />
46 +
						Success: {apiRequestMutation.data.success.toString()}
53 47
					</code>
54 48
				</pre>
55 49
			)}
src/templates/extras/client/src/App.tsx/App-with-tailwind-tanstackquery.tsx +9 −15
1 -
import { useState } from "react";
2 1
import beaver from "./assets/beaver.svg";
3 2
import type { ApiResponse } from "shared";
4 3
import { useMutation } from "@tanstack/react-query";
6 5
const SERVER_URL = import.meta.env.VITE_SERVER_URL || "http://localhost:3000";
7 6
8 7
function App() {
9 -
	const [data, setData] = useState<ApiResponse | undefined>();
10 -
11 -
	const { mutate: sendRequest } = useMutation({
8 +
	const apiRequestMutation = useMutation({
12 9
		mutationFn: async () => {
13 -
			try {
14 -
				const req = await fetch(`${SERVER_URL}/hello`);
15 -
				const res: ApiResponse = await req.json();
16 -
				setData(res);
17 -
			} catch (error) {
18 -
				console.log(error);
19 -
			}
10 +
			const req = await fetch(`${SERVER_URL}/hello`);
11 +
			const res: ApiResponse = await req.json();
12 +
			return res;
20 13
		},
14 +
		onError: (err) => console.log(err),
21 15
	});
22 16
23 17
	return (
39 33
			<div className="flex items-center gap-4">
40 34
				<button
41 35
					type="button"
42 -
					onClick={() => sendRequest()}
36 +
					onClick={() => apiRequestMutation.mutate()}
43 37
					className="bg-black text-white px-2.5 py-1.5 rounded-md"
44 38
				>
45 39
					Call API
53 47
					Docs
54 48
				</a>
55 49
			</div>
56 -
			{data && (
50 +
			{apiRequestMutation.isSuccess && (
57 51
				<pre className="bg-gray-100 p-4 rounded-md">
58 52
					<code>
59 -
						Message: {data.message} <br />
60 -
						Success: {data.success.toString()}
53 +
						Message: {apiRequestMutation.data.message} <br />
54 +
						Success: {apiRequestMutation.data.success.toString()}
61 55
					</code>
62 56
				</pre>
63 57
			)}
src/templates/extras/client/src/App.tsx/App-with-tanstackquery.tsx +6 −9
1 -
import { useState } from "react";
2 1
import beaver from "./assets/beaver.svg";
3 2
import { useMutation } from "@tanstack/react-query";
4 3
import type { ApiResponse } from "shared";
7 6
const SERVER_URL = import.meta.env.VITE_SERVER_URL || "http://localhost:3000";
8 7
9 8
function App() {
10 -
	const [data, setData] = useState<ApiResponse | undefined>();
11 -
12 -
	const { mutate: sendRequest } = useMutation({
9 +
	const apiRequestMutation = useMutation({
13 10
		mutationFn: async () => {
14 11
			const req = await fetch(`${SERVER_URL}/hello`);
15 12
			const res: ApiResponse = await req.json();
16 -
			setData(res);
13 +
			return res;
17 14
		},
18 15
		onError: (err) => console.log(err),
19 16
	});
34 31
			<p>A typesafe fullstack monorepo</p>
35 32
			<div className="card">
36 33
				<div className="button-container">
37 -
					<button type="button" onClick={() => sendRequest()}>
34 +
					<button type="button" onClick={() => apiRequestMutation.mutate()}>
38 35
						Call API
39 36
					</button>
40 37
					<a
46 43
						Docs
47 44
					</a>
48 45
				</div>
49 -
				{data && (
46 +
				{apiRequestMutation.isSuccess && (
50 47
					<pre className="response">
51 48
						<code>
52 -
							Message: {data.message} <br />
53 -
							Success: {data.success.toString()}
49 +
							Message: {apiRequestMutation.data.message} <br />
50 +
							Success: {apiRequestMutation.data.success.toString()}
54 51
						</code>
55 52
					</pre>
56 53
				)}