I am working on a Next.js application where I have implemented a commenting system. Users can post a review for a particular AI tool, reply to a review, and reply to a reply as well.
I have a component named <ReplyItemOperations />
that renders three buttons: like, dislike, and reply. Inside this component, I am using useSuspenseQuery
to fetch the status of whether the user has liked/disliked the reply or not.
Here is the code for the <ReplyItemOperations />
component:
import { useState } from "react"
import { useRouter } from "next/navigation"
import { Reply, Review } from "@/types"
import {
useMutation,
useQueryClient,
useSuspenseQuery,
} from "@tanstack/react-query"
import { useSession } from "next-auth/react"
type ReplyItemOperationsProps = {
review: Review
reply: Reply
}
export function ReplyItemOperations({
review,
reply,
}: ReplyItemOperationsProps) {
const router = useRouter()
const { data: session } = useSession()
const user = session?.user
const userEmail = session?.user?.email
const {
id: replyId,
likes_count: initialLikesCount,
dislikes_count: initialDislikesCount,
} = reply
const { id: reviewId, tool_name: toolName } = review
const { data: userReplyData } = useSuspenseQuery({
queryKey: ["userReplyData", toolName, userEmail],
queryFn: async () => {
if (!userEmail) {
return null
}
return await getUserReplyData(toolName, userEmail)
},
})
const [likesCount, setLikesCount] = useState(initialLikesCount)
const [dislikesCount, setDislikesCount] = useState(initialDislikesCount)
const [isLiked, setIsLiked] = useState(userReplyData?.is_liked || false)
const [isDisliked, setIsDisliked] = useState(
userReplyData?.is_disliked || false
)
// Other component logic
return (
<div>
{/* Component JSX */}
</div>
)
}
Here is the query code that fetches the data (an object with two keys: is_liked
and is_disliked
) regarding whether the current user has liked/disliked the reply or not:
const { data: userReplyData } = useSuspenseQuery({
queryKey: ["userReplyData", toolName, userEmail],
queryFn: async () => {
if (!userEmail) {
return null
}
return await getUserReplyData(toolName, userEmail)
},
})
And here is the code for the getUserReplyData()
function:
import { supabase } from "@/lib/clients"
export async function getUserReplyData(
toolName: string,
userEmail: string | null | undefined
) {
const { data, error } = await supabase
.from("user_replies")
.select("is_liked, is_disliked")
.match({ tool_name: toolName, user_email: userEmail })
.single()
if (error) {
console.error(`Error getting user replies data: ${error.message}`)
return
}
console.log("Get user reply data: ", data)
return data
}
The <ReplyItemOperations />
component is rendered inside the <ReplyItem />
component, and the <ReplyItem />
component is rendered inside the <Reviews />
component (where I display both the reviews and replies, including nested replies). The <Reviews />
component is rendered inside the <ToolPage />
component which display details regarding a particular AI tool (along with the reviews).
When I am NOT logged in, the <ToolPage />
component renders fine; I see the tool details, as well as the reviews and replies for that particular tool, as shoen below:
But when I am logged in, the <ToolPage />
does not render, and I get the following error:
Error: ["userReplyData","MakeAudio","user@gmail.com"] data is undefined
I suspect this error is related to the query key that I have set inside the query. Here is the query key for reference:
queryKey: ["userReplyData", toolName, userEmail],
So, why am I getting this error when I am logged in? Is it because the userEmail
has a value when I’m logged in and is undefined
when I’m not logged in, and this messes up the cache? If yes, how do I solve this problem?
Additional Information:
- Next.js version: 14.1.3
- Tanstack Query version: 5.40.1
- next-auth version: 4.24.5
Any help or insights would be greatly appreciated!