At the moment the votes {count}
is not showing up on mount. I’m using useEffect
to get the article and useState
to set the count
to article.votes
. The votes go up after clicking the button twice as the first render doesn’t show the vote count.
const Article = () => {
const { article_id } = useParams();
const [article, setArticle] = useState({ title: "Not Found" });
useEffect(() => {
getArticle(article_id).then((article) => {
setArticle(article);
});
}, []);
const [count, setCount] = useState(article.votes);
function handleCountUp() {
updateArticleVotes(article_id, count, article.votes);
setCount(article.votes++);
}
function handleCountDown() {
setCount(article.votes--);
updateArticleVotes(article_id, count, article.votes);
}
const navigate = useNavigate();
function handleNavigate() {
navigate("./#form");
}
return (
<div>
<div className="one-article-div" id="top">
<h5>Votes: {count}</h5>
<button
onClick={handleCountUp}
name="Vote Up"
className="input-submit margin-left-right"
>
Vote Up
</button>
<button
onClick={handleCountDown}
name="Vote Down"
className="input-submit margin-left-right"
>
Vote Down
</button>
</div>
</div>
);
};
export default Article;
I’m expecting the <h5>votes: {count}</h5>
to show up on mount. At the moment it only shows up after clicking the up vote or down vote.
3
Answers
It would not show up, because here:
you have initialized
count
witharticle.votes
.Even if you change
article.votes
to something else afterwards, thecount
will not be re-initialized. From the docs:You have to update
count
too usingsetCount
, after you get newarticle
inuseEffect
.Inside the useEffect you need to add a setCount(article.votes).
In your case, it doesn’t work because the useEffect run after the mounting of your component. So at that time articles is undefined so votes is also undefined. And the initializer of the count state is set to undefined.
It does display/render on the initial render cycle, but the problem is that the initial
article
state has an undefinedvotes
property.I suggest you provide a default
votes
property value, and update the effect to also update thecount
state when it updates thearticle
state. Don’t forget to include thearticle_id
route path parameter as a dependency so the effect also runs if/when the article id parameter value changes.The vote handlers are also mutating the
article
state with the post-increment/decrement operators. You should avoid mutating React states. Add or subtract 1 from the currentarticle.votes
value and pass that result to thesetCount
state setter function.