mirror of https://github.com/usememos/memos.git
fix: react hooks order violation in MemoDetail when creating comments
Replace dynamic hook mapping with useMemoComments hook to fetch all comments via listMemoComments API, ensuring consistent hook order across renders and fixing page load failure after comment creation.
This commit is contained in:
parent
c4dfb85400
commit
6523891982
|
|
@ -118,10 +118,17 @@ const MemoEditorImpl: React.FC<MemoEditorProps> = ({
|
|||
cacheService.clear(cacheService.key(currentUser?.name ?? "", cacheKey));
|
||||
|
||||
// Invalidate React Query cache to refresh memo lists across the app
|
||||
await Promise.all([
|
||||
const invalidationPromises = [
|
||||
queryClient.invalidateQueries({ queryKey: memoKeys.lists() }),
|
||||
queryClient.invalidateQueries({ queryKey: userKeys.stats() }),
|
||||
]);
|
||||
];
|
||||
|
||||
// If this was a comment, also invalidate the comments query for the parent memo
|
||||
if (parentMemoName) {
|
||||
invalidationPromises.push(queryClient.invalidateQueries({ queryKey: memoKeys.comments(parentMemoName) }));
|
||||
}
|
||||
|
||||
await Promise.all(invalidationPromises);
|
||||
|
||||
// Reset editor state to initial values
|
||||
dispatch(actions.reset());
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ export const memoKeys = {
|
|||
list: (filters: Partial<ListMemosRequest>) => [...memoKeys.lists(), filters] as const,
|
||||
details: () => [...memoKeys.all, "detail"] as const,
|
||||
detail: (name: string) => [...memoKeys.details(), name] as const,
|
||||
comments: (name: string) => [...memoKeys.all, "comments", name] as const,
|
||||
};
|
||||
|
||||
export function useMemos(request: Partial<ListMemosRequest> = {}) {
|
||||
|
|
@ -139,3 +140,15 @@ export function useDeleteMemo() {
|
|||
},
|
||||
});
|
||||
}
|
||||
|
||||
export function useMemoComments(name: string, options?: { enabled?: boolean }) {
|
||||
return useQuery({
|
||||
queryKey: memoKeys.comments(name),
|
||||
queryFn: async () => {
|
||||
const response = await memoServiceClient.listMemoComments({ name });
|
||||
return response;
|
||||
},
|
||||
enabled: options?.enabled ?? true,
|
||||
staleTime: 1000 * 60, // 1 minute
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,11 +10,10 @@ import MobileHeader from "@/components/MobileHeader";
|
|||
import { Button } from "@/components/ui/button";
|
||||
import { memoNamePrefix } from "@/helpers/resource-names";
|
||||
import useCurrentUser from "@/hooks/useCurrentUser";
|
||||
import { useMemo as useMemoQuery } from "@/hooks/useMemoQueries";
|
||||
import { useMemo, useMemoComments } from "@/hooks/useMemoQueries";
|
||||
import useNavigateTo from "@/hooks/useNavigateTo";
|
||||
import useResponsiveWidth from "@/hooks/useResponsiveWidth";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { Memo, MemoRelation_Type } from "@/types/proto/api/v1/memo_service_pb";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
|
||||
const MemoDetail = () => {
|
||||
|
|
@ -29,7 +28,7 @@ const MemoDetail = () => {
|
|||
const [showCommentEditor, setShowCommentEditor] = useState(false);
|
||||
|
||||
// Fetch main memo with React Query
|
||||
const { data: memo, error, isLoading } = useMemoQuery(memoName, { enabled: !!memoName });
|
||||
const { data: memo, error, isLoading } = useMemo(memoName, { enabled: !!memoName });
|
||||
|
||||
// Handle errors
|
||||
if (error) {
|
||||
|
|
@ -38,18 +37,15 @@ const MemoDetail = () => {
|
|||
}
|
||||
|
||||
// Fetch parent memo if exists
|
||||
const { data: parentMemo } = useMemoQuery(memo?.parent || "", {
|
||||
const { data: parentMemo } = useMemo(memo?.parent || "", {
|
||||
enabled: !!memo?.parent,
|
||||
});
|
||||
|
||||
// Get comment relations and memo names
|
||||
const commentRelations =
|
||||
memo?.relations.filter((relation) => relation.relatedMemo?.name === memo.name && relation.type === MemoRelation_Type.COMMENT) || [];
|
||||
const commentMemoNames = commentRelations.map((relation) => relation.memo!.name);
|
||||
|
||||
// Fetch all comment memos
|
||||
const commentQueries = commentMemoNames.map((name) => useMemoQuery(name));
|
||||
const comments = commentQueries.map((q) => q.data).filter((memo): memo is Memo => !!memo);
|
||||
// Fetch all comments for this memo in a single query
|
||||
const { data: commentsResponse } = useMemoComments(memoName, {
|
||||
enabled: !!memo,
|
||||
});
|
||||
const comments = commentsResponse?.memos || [];
|
||||
|
||||
const showCreateCommentButton = currentUser && !showCommentEditor;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue