I'm trying to learn how typescript, react and tRPC behaves together, I've this page questions.tsx
:
import { NextPage } from 'next';
import { useRouter } from 'next/router';
import { QuestionCard } from '~/components/questionCard';
import { api } from '~/utils/api';
const QuestionFlow: NextPage = () => {
const router = useRouter();
const { subjectId, chapterId } = router.query;
const subId = typeof subjectId === 'string' ? parseInt(subjectId) : 0;
const chapId = typeof chapterId === 'string' ? parseInt(chapterId) : 0;
//Get All questions from Chapter
const { data: allChapterQuestions } = api.chapterQuestions.getAllChapterQuestionsFromSubjectChapter.useQuery({ subjectId: subId, chapterId: chapId });
if (allChapterQuestions && allChapterQuestions.length > 0) {
const { data: questionInfo } = api.chapterQuestions.getById.useQuery({ chapterQuestionId: allChapterQuestions[0]!.id });
const { data: questionOptions } = api.questionOptions.getAllOptionsFromQuestionId.useQuery({ questionId: allChapterQuestions[0]!.id });
// Check if both questionInfo and questionOptions are available before rendering the QuestionCard
const isDataAvailable = questionInfo && questionOptions;
return (
<>
<p>Question Flow</p>
<p>subjectId: {subId}</p>
<p>chapterId: {chapId}</p>
{isDataAvailable ?
<QuestionCard questionInfo={questionInfo} questionOptions={questionOptions} /> :
<p>ERROR WITH SOME DATA</p>
}
</>
);
} else {
return (
<>
<p>Question Flow</p>
<p>subjectId: {subId}</p>
<p>chapterId: {chapId}</p>
<p>ERROR WITH THE DATA</p>
</>
);
}
};
export default QuestionFlow;
As you may guess this renders first the "else" return, to then throw the error:
Unhandled Runtime Error
Error: Rendered more hooks than during the previous render.
I understand that this is caused to call my api.
inside a conditional that will change on the next re-frame if the conditional change.
I know that one work around will be to put all those 3 api calls inside just one that retrieves the info at once, BUT:
There are a lot of cases that I won't be able to do that, and I don't know how to work around it when the moment arrives, there are a lot of cases that I want to check the response from the api and make another api call depending on that.
How should I tackle this issue?
As it was recommended in the comment, you cannot use hook with conditions, it's a general React rule, not trpc.
What you can do here is roughly this:
enabled
option to the hooksconst hasChapters = allChapterQuestions && allChapterQuestions.length > 0
const { data: questionInfo } = api
.chapterQuestions
.getById
// add `enabled` option
.useQuery({ chapterQuestionId: allChapterQuestions[0]!.id }, { enabled: hasChapters});
// and now you can have your if clause here:
if (questionInfo) {
// ...
} else {
// ...
}