I'm trying to get a handle on the new tRPC version 10 with a basic shopping list CRUD Nextjs app. I have successfully set up the tRPC endpoint with "get all" and a "create" handlers and can confirm that they both work after testing from the front end. However, I can't seem to update my state with the data from the "get all" call. In older tRPC versions we would have updated the state as follows:
const data = trpc.useQuery(["items.getAll"], {
onSuccess(items) {
setItems(items);
},
});
In version 10 however, they've done away with the useQuery() arguments in favour of conditional status returns according to docs. I tried updating the state as follows:
const [items, setItems] = useState<ShoppingItem[]>([]);
const data = trpc.shoppingItem.getAll.useQuery();
if (data.isSuccess) {
setItems(data.data);
}
This understandably causes a "Too many re-renders" error since each time the state updates it re-renders the component, therefore triggering a new isSuccess and re-updating the state.
What is the proper way to update state from tRPCv10?
My full component follows for context:
import { useState, useEffect } from "react";
import { ShoppingItem } from "@prisma/client";
import type { NextPage } from "next";
import Head from "next/head";
import ItemModal from "../components/ItemModal";
import { trpc } from "../utils/trpc";
const Home: NextPage = () => {
const [items, setItems] = useState<ShoppingItem[]>([]);
const [modalOpen, setModalOpen] = useState<boolean>(false);
const data = trpc.shoppingItem.getAll.useQuery();
if (data.isSuccess) {
setItems(data.data);
}
return (
<>
<Head>
<title>Shopping List</title>
<meta name="description" content="Generated by create-t3-app" />
<link rel="icon" href="/favicon.ico" />
</Head>
{modalOpen && (
<ItemModal setModalOpen={setModalOpen} setItems={"hello"} />
)}
<main className="mx-auto my-12 max-w-3xl">
<div className="flex justify-between">
<h2 className="text-2xl font-semibold">My Shopping List</h2>
<button
className="rounded-md bg-violet-500 p-2 text-sm text-white transition hover:bg-violet-600"
type="button"
onClick={() => setModalOpen(true)}
>
Add Item
</button>
</div>
<ul className="mt-4">
{items.map((item) => (
<li key={item.id}>{item.name}</li>
))}
</ul>
</main>
</>
);
};
export default Home;