kererū
kererū
TtRPC
Created by kererū on 9/26/2023 in #❓-help
How to type a helper function to standardise loading and error states with a useQuery call?
I am trying to standardize handling of error and loading states. I'd like to have one function/component that can handle what to do in those cases, and otherwise passes data to a function to render whatever is the happy path. So something like this:
function RenderHelper({useQueryOutput, renderData}) {
const {data, error, isFetching, isSuccess, isError} = useQueryOutput;
if (isError) { /* ... render `error` UI */ }
if (isLoading) { /* ... render loading UI */}
if (isSuccess) {
return renderData(data);
}
}

const SomeComponent = () => {
const userQuery = trpc.user.myInfo.useQuery();
return <RenderHelper useQueryOutput={userQuery} renderData={(data) => {
return <div>{data.userName}</div>; // structure of `data` should be inferred
}
} />
}
function RenderHelper({useQueryOutput, renderData}) {
const {data, error, isFetching, isSuccess, isError} = useQueryOutput;
if (isError) { /* ... render `error` UI */ }
if (isLoading) { /* ... render loading UI */}
if (isSuccess) {
return renderData(data);
}
}

const SomeComponent = () => {
const userQuery = trpc.user.myInfo.useQuery();
return <RenderHelper useQueryOutput={userQuery} renderData={(data) => {
return <div>{data.userName}</div>; // structure of `data` should be inferred
}
} />
}
I'm struggling to type this in a way that the renderData function has the structure of data inferred by Typescript. I have looked at AppRouterLike, QueryLike and friends but can't get it to work. Would love some assistance, in the meantime I'll keep bashing my head against it. Here's a not-working example, in which data is typed as any and in the render function TS thinks data could be undefined
export function RenderQuery<T extends ReturnType<QueryLike["useQuery"]>>({
useQueryResponse,
render,
}: {
useQueryResponse: T;
render: (data: T["data"]) => ReactElement;
}) {
const { data, error, isFetching, isError, isSuccess } = useQueryResponse;
if (isFetching) {
return <LoadingSpinner />;
}
if (isError) {
return (
<Typography>Sorry, something went wrong.</Typography>
);
}
if (isSuccess) {
if (data === undefined) {
throw new Error("How does TS still think data might be undefined in `render`?");
}
return render(data);
}
throw new Error("Shouldn't be possible to reach this point");
}
export function RenderQuery<T extends ReturnType<QueryLike["useQuery"]>>({
useQueryResponse,
render,
}: {
useQueryResponse: T;
render: (data: T["data"]) => ReactElement;
}) {
const { data, error, isFetching, isError, isSuccess } = useQueryResponse;
if (isFetching) {
return <LoadingSpinner />;
}
if (isError) {
return (
<Typography>Sorry, something went wrong.</Typography>
);
}
if (isSuccess) {
if (data === undefined) {
throw new Error("How does TS still think data might be undefined in `render`?");
}
return render(data);
}
throw new Error("Shouldn't be possible to reach this point");
}
4 replies
TtRPC
Created by kererū on 7/12/2023 in #❓-help
Upgrading from tRPC v9 and NextJS v12. Should I upgrade NextJS first or tRPC?
I have an app built from the tRPC + NextJS + Prisma starter, and I'd like to upgrade from tRPC v9 and NextJS v12 to the respective latest versions. Does it make any different whether I upgrade Next or tRPC first?
5 replies