这是博客全栈网站。只有注册用户可以投票和评论。当用户注册时,他应该能够投票。但是当我运行应用程序并创建新用户时,按钮总是显示已被投票。
import { useState, useEffect } from 'react';
import {useParams} from 'react-router-dom';
import axios from 'axios';
import NotFoundPage from './NotFoundPage';
import CommentsList from '../components/CommentsList';
import articles from './article-content';
import useUser from '../hooks/useUser';
import AddCommentForm from '../components/AddCommentForm';
const ArticlePage = () => {
// using destructuring assignment to extract the articleId parameter value from the current route using the useParams()
const {articleId} = useParams();
const [articleInfo, setArticleInfo] = useState({ upvotes: 0, comments: [], canUpvote: false });
const { canUpvote } = articleInfo;
const { user, isLoading } = useUser();
useEffect(() => {
const loadArticleInfo = async () => {
const token = user && await user.getIdToken();
const headers = token ? { authToken: token } : {};
const response = await axios.get(`/api/articles/${articleId}`,{headers});
const newArticleInfo = response.data;
setArticleInfo(newArticleInfo)
};
if(isLoading){
loadArticleInfo();
}
}, [isLoading, user, articleId]);
// used the .find() method on the articles array, which returns the first element in the array that satisfies the provided testing function.
const article = articles.find(article => article.name === articleId);
const addUpvote = async () => {
const token = user && await user.getIdToken();
const headers = token ? { authToken: token } : {};
const response = await axios.put(`/api/articles/${articleId}/upvote`, null, {headers});
const updatedArticleInfo = response.data;
setArticleInfo(updatedArticleInfo);
};
if(!article) {
return <NotFoundPage />;
}
return (
<div>
<h1>{article.title}</h1>
<div className="upvotes-section">
{ user ? (
<button onClick={addUpvote}>
{canUpvote ? 'Upvote' : 'Already Upvoted'}
</button>
) : (
<button>Log in to upvote</button>
)}
<p> This article has {articleInfo.upvotes} upvote(s).</p>
</div>
{/* the .map() method is called on the article.content array, and for each paragraph in the array, it returns a <p> element with the paragraph as its content */}
{article.content.map((paragraph, i) => (
<p key={i}>{paragraph}</p>
))}
{user
?<AddCommentForm articleName={articleId} onArticleUpdate={updatedArticle => setArticleInfo(updatedArticle)} />
:<button>Log in to add a comment</button>
}
<CommentsList comments={articleInfo.comments} />
</div>
);
};
export default ArticlePage;
当我创建一个新用户,它显示已经Upvoted。但是它应该显示Upvote选项。
这是我的server.js文件import express from 'express';
import fs from 'fs'
import admin from 'firebase-admin';
import {db, connectDb} from './db.js';
const credentials = JSON.parse(
fs.readFileSync('./credentials.json')
);
admin.initializeApp({
credential: admin.credential.cert(credentials)
});
const app = express();
app.use(express.json());
app.use(async(req, res, next) => {
const {authToken} = req.headers;
if(authToken) {
try{
req.user = await admin.auth().verifyIdToken(authToken);
}catch(err) {
return res.sendStatus(400);
}
}
req.user = req.user || {};
next();
});
app.get('/api/articles/:name', async (req, res) => {
const {name} = req.params;
const {uid} = req.user;
const article = await db.collection('articles').findOne({ name });
if(article) {
const upvotesIds = article.upvotesIds || [];
article.canUpvote = uid && !upvotesIds.includes(uid);
res.json(article);
}else{
res.status(404).send('Article not found!');
}
});
app.use(( req, res, next) => {
if(req.user) {
next();
}else{
res.sendStatus(401);
}
});
app.put('/api/articles/:name/upvote',async (req, res) => {
const {name} = req.params;
const {uid} = req.user;
const article = await db.collection('articles').findOne({ name });
if(article) {
const upvotesIds = article.upvotesIds || [];
const canUpvote = uid && !upvotesIds.includes(uid);
if(canUpvote) {
await db.collection('articles').updateOne({ name }, {
'$inc': {
'upvotes': 1
},
'$push': {
'upvotesIds': uid
}
});
}
const updatedArticle = await db.collection('articles').findOne({ name });
res.json(updatedArticle);
} else{
res.status(404).send('The Article does not found!');
}
});
app.post('/api/articles/:name/comments', async (req, res) => {
const {name} = req.params;
const { comment } = req.body;
const {email} = req.user;
await db.collection('articles').updateOne({ name }, {
'$push': {
'comments': {
postedBy: email,
comment
}
}
});
const article = await db.collection('articles').findOne({ name });
if(article) {
res.json(article);
}else{
res.status(404).send('The Article not found!');
}
});
connectDb(() => {
console.log('Connected to Database!');
app.listen(8000, () => {
console.log('Server is listening on port 8000!');
});
});
我尝试改变loadArticleInfo在useEffect内,但仍然相同。
.canUpvote
在前端永远不会被更新为true
,因此三进制将始终为false。