I have a page that have sidebar.sidebar item is render by fetching data and it works completely. After clicking the sidebar item it will send props to another component that also should fetch data, but it not fetching any data untill I click re-fetch button. For fetching and caching, I'm using tansatc react query:
This is my page //fetch is working in this:
"use client";
import { useSession } from "next-auth/react";
import { useQuery } from "@tanstack/react-query";
import React, { useState } from "react";
import StudentSubjects from "@/app/components/StudentSubjects"
import Link from "next/link";
interface SubjectData {
id: string;
name: string;
description: string;
}
const Student: React.FC = () => {
const { data: session, status } = useSession();
const { data: subjectsData, isLoading, error } = useQuery<
{ studentData: { whatsapp: string; name: string; grade: string; subjects: string[] } },
Error
>({
queryKey: ["subjects"],
queryFn: async () => {
if (status === "authenticated") {
const userEmail = session?.user?.email;
const res = await fetch(`/api/getStudent?email=${userEmail}`);
const data = await res.json();
return data;
} else {
return { studentData: { whatsapp: "", name: "", grade: "", subjects: [] } };
}
},
staleTime: Infinity,
gcTime: 60000,
enabled: status === "authenticated",
});
const [selectedSubject, setSelectedSubject] = useState<SubjectData | null>(null);
const subjectsList: SubjectData[] = subjectsData.studentData.subjects.map((subject) => {
const [id, name, description] = subject.split(",");
return { id, name, description };
});
return (
<div className="flex">
<div className="w-1/4 bg-gray-200 p-4">
<h2 className="text-lg font-bold mb-4">Subjects</h2>
<ul>
{subjectsList.map((subject) => (
<li
key={subject.id}
className="cursor-pointer hover:bg-gray-300 p-2"
onClick={() => setSelectedSubject(subject)}
>
{subject.name}
</li>
))}
<li className="cursor-pointer hover:bg-gray-300 p-2 text-blue-500">
<Link href="/student/add">Add a Subject</Link>
</li>
</ul>
</div>
<div className="w-3/4 p-4">
<StudentSubjects subject={selectedSubject} />
</div>
</div>
);
};
Export default Student;```
And this is my studentSubjects component
And this is my component.fetch is not working, but when I click re-fetch it working.
"use client";
import { useSession } from "next-auth/react";
import { useQuery } from "@tanstack/react-query";
interface SubjectData {
id: string;
name: string;
description: string;
}
interface Lesson {
id: string;
subject: string;
lessonName: string;
lessonDescription: string;
lessonFileUrl: string;
}
interface Assignment {
id: string;
subject: string;
assignmentName: string;
assigementDescription: string;
}
interface SubjectDataResponse {
lessons: Lesson[];
assignments: Assignment[];
}
const SubjectDetails: React.FC<{ subject: SubjectData | null }> = ({
subject,
}) => {
const { data: session, status } = useSession();
const {
data: subjectData,
isLoading,
error,
refetch
} = useQuery<SubjectDataResponse,Error>({
queryKey: ["subjectData"],
queryFn: async () => {
if (!subject) {
return null;
}
const res = await fetch(
`/api/getSubjectFullData?subjectId=${subject.id}`
);
const data = await res.json();
return data.subjectData;
},
staleTime: Infinity,
gcTime: 60000,
});
const handleRefetch = () => {
refetch();
};
if (isLoading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
if (!subject) {
return null;
}
return (
<div>
{subject.id && (
<div>
<button onClick={handleRefetch}>Refresh</button>
<p>id: {subject.id}</p>
<p>Name: {subject.name}</p>
<p>Description: {subject.description}</p>
<div className="mt-4">
<h3 className="text-md font-bold mb-2">Lessons</h3>
{isLoading ? (
<p>Loading lessons...</p>
) : subjectData?.lessons && subjectData.lessons.length > 0 ? (
<div className="grid grid-cols-3 gap-4">
{subjectData.lessons.map((lesson: any) => (
<div key={lesson.id} className="bg-gray-200 p-4 rounded">
<h4 className="font-bold">{lesson.lessonName}</h4>
<p>{lesson.lessonDescription}</p>
{lesson.lessonFileUrl && (
<a
href={lesson.lessonFileUrl}
target="_blank"
rel="noopener noreferrer"
>
View File
</a>
)}
</div>
))}
</div>
) : (
<p>No lessons found.</p>
)}
</div>
<div className="mt-4">
<h3 className="text-md font-bold mb-2">Assignments</h3>
{isLoading ? (
<p>Loading assignments...</p>
) : subjectData?.assignments &&
subjectData.assignments.length > 0 ? (
<div className="grid grid-cols-3 gap-4">
{subjectData.assignments.map((assignment: any) => (
<div key={assignment.id} className="bg-gray-200 p-4 rounded">
<h4 className="font-bold">{assignment.assignmentName}</h4>
<p>{assignment.assigementDescription}</p>
</div>
))}
</div>
) : (
<p>No assignments found.</p>
)}
</div>
</div>
)}
</div>
);
};
export default SubjectDetails;
I need to know why this happening. I mean I don't see any fetch call happen in chrome dev tools.
im simply trying to fetch data but it dosent fetch untill i click refetch button .it should usually work and i cant think why this happence?can any person help me to understand the problem.and what should i do for to solve it.
As far as I can see, you are not fetching in the component anywhere except in the refetch function (which is not called anywhere except your button). In the first Page/Component, you have
which would populate the data. You don't have anything like this in the second. I would suggest adding a call. Either directly (not my first choice) or with
useEffect. Maybe something like:So it would be called when the
useQuerysets it.