I want to count view every time the user visits the page using react-router-dom and Firebase, I have this Code:
//useHistory is the react-router-dom dependency
const history = useHistory();
const handleClick = () => history.push('/post');
if(handleClick){
db.collection("posts").doc(postId).update({
views: increment,
})
}
Its works But its give an Infinite Loop I tried useEffect Like:
useEffect(() => {
if(handleClick){
db.collection("posts").doc(postId).update({
views: increment,
})
}
}, [handleClick])
and it still gave the infinite increments, is there a way to count views without running in this type of problem?
CodePudding user response:
Issue
It's not clear how the first snippet creates a render loop, but it certainly isn't correct. Each render/rerender of the component reruns the function component body, which means each render handleClick
is redeclared, and OFC the if (handleClick)
condition will always be true (since it was defined just above) and the "posts" collection will be updated each time.
Indeed, in the second snippet the issue is very nearly the same, each render/rerender of the component redeclares the handleClick
function and this is a new reference in the dependency array it triggers the useEffect
callback.
Solutions
Use a mounting (empty dependency array) useEffect
to trigger the db collection update.
useEffect(() => {
db.collection("posts")
.doc(postId)
.update({
views: increment,
});
}, []);
It's not clear where the postId
and increment
values comes from, but I assume somewhere previously in the component code you've accessed the same collection and retrieved an "initial" views
value from the DB.