发送第一个请求时,isVoting 将设置为“true”。在这种情况下,在 isVoting 设置为“false”之前,不应允许发送另一个请求。但不知何故,当我尝试快速多次点击否决时, isVoting 仍然是“假”。 并且投反对票请求发送了两次,这是不正确的。我该如何解决这个问题?
"use client";
import { downvoteAnswer } from "@/lib/actions/answer.action";
import Image from "next/image";
import { usePathname, useRouter } from "next/navigation";
import { useState } from "react";
interface Props {
type: string;
itemId: string;
userId: string;
upvotes: number;
hasupVoted: boolean;
downvotes: number;
hasdownVoted: boolean;
authorId: string;
hasSaved?: boolean;
}
const Votes = ({
type,
itemId,
userId,
upvotes,
hasupVoted,
authorId,
downvotes,
hasdownVoted,
hasSaved,
}: Props) => {
const [isVoting, setIsVoting] = useState(false);
const pathname = usePathname();
const router = useRouter();
const handleVote = async (action: string) => {
console.log("isVoting:", isVoting);
if (isVoting) {
console.log("Request denied");
return;
}
setIsVoting(true);
await downvoteAnswer({
answerId: JSON.parse(itemId),
userId: JSON.parse(userId),
hasupVoted,
hasdownVoted,
path: pathname,
});
setIsVoting(false);
}
};
return (
<div className="flex gap-5">
<div className="flex-center gap-1.5">
<Image
src={
hasdownVoted
? "/assets/icons/downvoted.svg"
: "/assets/icons/downvote.svg"
}
width={18}
height={18}
alt="downvote"
className="cursor-pointer"
onClick={() => handleVote("downvote")}
/>
</div>
</div>
);
};
export default Votes;
React 状态更新是异步的,并且跨渲染更新 isVoting 状态可能会有延迟。
就像 @hairyhandkerchief23 所说,你应该使用带有布尔值的 useRef() 。
你可以这样尝试:
const isVotingRef = useRef(false);
const handleVote = async (action: string) => {
console.log("isVoting:", isVotingRef.current);
if (isVotingRef.current) { // Use ref's current value
console.log("Request denied");
return;
}
isVotingRef.current = true; // this prevents multiple calling
try {
await downvoteAnswer({
answerId: JSON.parse(itemId),
userId: JSON.parse(userId),
hasupVoted,
hasdownVoted,
path: pathname,
});
} catch (error) {
console.error("Error in voting:", error);
} finally {
isVotingRef.current = false; // reset after finished
}
};
希望这有帮助