为什么我的代码使用 onDoubleClick 发送服务器数据时触发不一致?



我一辈子都不明白为什么第一对onDoubleClick会触发500服务器错误,但在所有后续的onDoubleClick上,它会正确地触发200,但行为不一致,如下所示。

为了便于说明,这就是正在发生的事情:

  1. 双击用户ID1->的图像A;500错误
  2. 双击图像A上的用户ID1->200成功(成功更新用户ID1(
  3. 双击图像B上的用户ID2->200成功(成功更新用户ID1,而本应更新用户ID2(
  4. 等等

我检查了SO的所有内容,甚至尝试了SO上关于这个主题的最受欢迎的问题的所有建议,但都无济于事。我撞到了砖墙。

我相信这与钩子的异步性质以及我如何定义它们有关,但我不完全确定。

我如何才能在双击任何图像时,在第一对双击以及随后的任何一对双击(即在不同的图像上(将相应的数据正确发送到服务器?

为了便于说明,我希望它的行为方式是:

  1. 双击用户ID1->的图像A;200成功(成功更新用户ID1(
  2. 双击图像b上的用户ID2->200成功(成功更新用户ID2(
  3. 等等
const Images = () => {
let authToken = localStorage.getItem("token");
const [uploadsData, setUploadsData] = useState([]);
const [likedPhotoUserId, setLikedPhotoUsedId] = useState("");
const [like, setLike] = useState(0);
useEffect(() => {
getUploads();
}, []);
useEffect(() => {}, [uploadsData]);
const getUploads = () => {
const headers = {
Accept: "application/json",
Authorization: `Bearer ${authToken}`,
};
axios
.get("http://localhost:8005/api/get-user-uploads-data", { headers })
.then((resp) => {
console.log(resp.data);
setUploadsData(resp.data);
})
.catch((error) => {
console.log(error);
});
};
const handleLikesBasedOnUserId = (e) => {
setLikedPhotoUsedId(e);
sendUserLikePost();
};
const sendUserLikePost = () => {
const url = "http://localhost:8005/api/post-user-like";
const headers = {
Accept: "application/json",
Authorization: `Bearer ${authToken}`,
};
let data = {
like: like,
UserID: likedPhotoUserId,
};
console.log(data);
axios
.post(url, data, { headers })
.then((resp) => {
console.log(resp.data);
})
.catch((error) => {
console.log(error);
});
};
const displayUploadsData = () => {
return uploadsData.map((photos, index) => {
return (
<ImagesGrid
src={photos.url}
likes={photos.likes}
userName={photos.name}
key={index}
doubleClick={handleLikesBasedOnUserId}
value={photos.UserID}
/>
);
});
};
return <>{displayUploadsData()}</>;
};
const ImagesGrid = (props) => {
const createUserPhotoNodes = () => {
return (
<section className="gallery">
<div className="container">
<form method="POST" name="likes">
<div className="img-container">
<img
src={props.src}
alt="Photo"
className="gallery-img"
onDoubleClick={() => props.doubleClick(props.value)}
/>
<h2 className="userName">{props.userName}</h2>
<h2 className="likes" onChange={props.onChange}>
Likes {props.likes}
</h2>
</div>
</form>
</div>
</section>
);
};
return <>{createUserPhotoNodes()}</>;
};

您已经一针见血了——这是因为setState是异步的,您看到的是过时的道具或要启动的状态。

const handleLikesBasedOnUserId = (e) => {
setLikedPhotoUsedId(e);
sendUserLikePost();
};
const sendUserLikePost = () => {
// ...
let data = {
'like': like,
'UserID': likedPhotoUserId
};
// ...

在调用sendUserLikePost之前,likedPhotoUserId不会更新,因此likedPhotoUserId就是''。(当您再次调用handleLikes...时,它将具有"以前"的值。(

无论如何,我看不出likedPhotoUserId应该是一个状态原子的原因,因为你所使用的只是sendUserLikePost——只是让它成为一个常规的ol'参数:

const handleLikesBasedOnUserId = (e) => {
sendUserLikePost(e);
};
const sendUserLikePost = (likedPhotoUserId) => {
// ...
let data = {
'like': like,
'UserID': likedPhotoUserId
};
// ...