【发布时间】:2021-05-21 19:15:32
【问题描述】:
我正在为我的网络应用开发类似的功能。这里的问题是即使在使用 setLike(!like) 之后我的 setLike 也没有改变状态。我通过在 setlike() 之前和之后使用 console.log() 进行了检查,但是两个 console.log() 语句都给了我相同的值。这是我的 Post 组件。
import React , {useState,useEffect} from 'react'
import './Post.css'
import Avatar from '@material-ui/core/Avatar';
import {Button, IconButton, Input, Typography } from '@material-ui/core';
import {DataBase} from './firebase'
import firebase from 'firebase';
import FavoriteIcon from '@material-ui/icons/Favorite';
import {useStateValue} from '../contexts/StateProvider'
function Post({postId}) {
//get the user from the provider
const [{user}, dispatch] = useStateValue();
//number of likes
const [likeCount,setLikeCount] = useState(likesCount)
//if like=true or not
const [like, setLike] = useState(false);
我正在使用 firebase firestore 数据库作为后端。当用户第一次与它交互时,like 文档仅存在于数据库集合中(喜欢它或先喜欢它然后撤消喜欢)。所以首先检查用户以前是否喜欢该文档。如果用户以前喜欢该文档,则获取该特定用户的 like 值(true/false)并使用 setLike(like) 设置它。同时获取集合中具有like==true 的文档数,并将其设置为等于setLikeCount(likeCount)。
//=======Get likes from the database ===========================
useEffect(() => {
//check if the user already liked the doc or not (first time or not)
DataBase.collection('posts').doc(postId).collection('postLikes')
.doc(user.uid).get().then((doc) => {
if (doc.exists) {
console.log(doc.data().like)
//set like to value of like from database
setLike(doc.data().like)
} else {
// doc.data() will be undefined in this case
console.log("Not liked");
}
}).catch((error) => {
console.log("Error getting document:", error);
});
//grab the docs which have like=true
DataBase.collection('posts').doc(postId).collection('postLikes').where("like", "==",
true).get()
.then((querySnapshot) => {
setLikeCount((querySnapshot.docs.map(doc =>doc.data())).length)
console.log(likeCount +" likes count")
})
.catch((error) => {
console.log("Error getting documents: ", error);
});
}
//when postId changes or page loads fire the code above
},[postId])
这是我的 postLike 函数。 setLike(!like) 应该切换用户从 firebase 获得的文档的前一个 like 值。我猜这不是更新。
//=============Post likes to the database=======
const postLike = (e) => {
//if already liked i.e. doc exists
console.log(like+"like before")
setLike(!like)
console.log(like+"like after")
like?(setLikeCount(likeCount+1)):(setLikeCount(likeCount-1))
console.log("likeCount"+likeCount)
DataBase.collection('posts').doc(postId).collection('postLikes').doc(user.uid).set(
{
like:like,
username:user.displayName,
timestamp:firebase.firestore.FieldValue.serverTimestamp(),
}
).catch((err)=>{console.log("something wrong happened "+err.message)})
}
return (
<div className="post">
<div className="post__likes">
{/*like button*/}
{
like?
(<Button onClick={postLike} ><FavoriteIcon fontsize="small" cursor="pointer" onClick=.
{postLike} style={{color:'red'}}/></Button> ):
(<Button onClick={postLike} ><FavoriteIcon fontsize="small" cursor="pointer" />
</Button>)
}
<Typography style={{color:'aliceblue'}}>Liked by {likeCount}</Typography>
</div>
</div>
)
}
export default Post
【问题讨论】:
-
不清楚可能是什么所有问题,但
setLike与任何其他状态修改一样,是异步的:like不会立即更新。postLike的其余部分应使用like的本地否定副本,而不是依赖状态的like,它将在未来的任意时间进行修改。 -
问题是当我的组件最初加载并使用用户从数据库中选择的类似选项时,它应该否定本地副本并设置全局状态并根据否定状态。但是因为 setLike 没有更新,所以它采用相同的值并使用相同的值增加/减少它。例如,假设用户已经喜欢该文档并且 likeCount 现在为 1,然后刷新页面,因此用户的喜欢是真实的并且基于如果用户再次按下按钮而不是减少它仍然会增加,使得 likeCount=2
标签: javascript reactjs firebase material-ui