我有一个包含侧边栏的页面。侧边栏项目是通过获取数据来渲染的,并且它完全可以工作。单击侧边栏项目后,它将向另一个组件发送道具,该组件也应该获取数据,但直到我单击重新获取按钮为止,它不会获取任何数据。使用 tansatc React 查询获取和缓存即时消息:
这是我的页面//fetch 正在其中工作
"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 compoentn
这是我的 compoent.fetch 不起作用,但是当我单击 refetch 时它起作用了。
"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;
我需要知道为什么会发生这种情况。我的意思是我在 Chrome 开发工具中没有看到任何 fetch 调用 hapeen
我只是想获取数据,但直到我点击重新获取按钮才获取数据。它通常应该可以工作,但我不知道为什么会发生这种情况?任何人都可以帮助我理解这个问题。我应该做什么来解决它。
据我所知,除了重新获取函数(除了按钮之外,不会在任何地方调用)之外,您不会在组件中的任何地方进行获取。在第一个页面/组件中,您有
const subjectsList: SubjectData[] = subjectsData.studentData.subjects.map((subject) => {
const [id, name, description] = subject.split(",");
return { id, name, description };
});
这将填充数据。第二次你就没有这样的事情了。我建议添加一个电话。要么直接(不是我的第一选择),要么用
useEffect
。也许是这样的:
useEffect(() => {
if (refetch) {
refetch()
}
}, [refetch]);
所以当
useQuery
设置它时就会调用它。