Tengo una pregunta sobre cómo actualizar un campo numérico en Cloud Firestore. Seguí un documento oficial y no fue tan difícil escribir código. Pero no funcionó como yo quería. Parece que no usé async y esperé correctamente. No he entendido perfectamente async y espero ahora, así que no tengo idea de dónde me perdí.
import { useState } from 'react'; import { FaHeart, FaRegHeart } from 'react-icons/fa'; // import { FaThumbsUp, FaRegThumbsUp } from "react-icons/fa"; import {updateDoc, getDoc, doc } from 'firebase/firestore'; import db from '../config/firebase'; const GoodBad = ({ quiz }) => { const [goodClicked, setGoodClicked] = useState(false); const [goodCounter, setGoodCounter] = useState(quiz.likes); // console.log(quiz.id, quiz.likes) const handleLikesUI = async (e) => { if (goodClicked === false) { setGoodClicked(true); setGoodCounter(prevState => prevState + 1); } else { setGoodClicked(false); setGoodCounter(prevState => prevState - 1); } const docRef = doc(db, "quizzes", quiz.id) const payload = {likes: goodCounter} await updateDoc(docRef, payload); }; return ( <div className='quizFooter'> <div className={ goodClicked ? 'likesCounterContainer checked' : 'likesCounterContainer' } onClick={() => handleLikesUI(quiz)} > <span className='heartIcon'> {goodClicked ? <FaHeart /> : <FaRegHeart />}{' '} </span> <span className='likesNumber'>{goodCounter}</span> {/* <span onClick={handleDislikes}>{goodClicked ? <FontAwesomeIcon icon="fa-regular fa-thumbs-down" /> : <FontAwesomeIcon icon="fa-solid fa-thumbs-down" />}bad: {badCounter}, {badClicked}</span> */} </div> </div> ); }; export default GoodBad;Sugeriría usar useEffect() para su caso de uso.
useEffect(() => { const payload = {likes: goodCounter} updateDoc(docRef, payload) }, [goodCounter]); const handleLikesUI = async (e) => { if (goodClicked === false) { setGoodClicked(true); setGoodCounter(prevState => prevState + 1); } else { setGoodClicked(false); setGoodCounter(prevState => prevState - 1); } }; En el código anterior, escuchará los cambios de goodCounter en tiempo real y, si hay un cambio en el valor de goodCounter , ahora procederá a actualizar su documento. Si no usa useEffect, habrá un retraso al configurar setGoodCounter .
Como dijo @mocherfaoui, si solo desea incrementar (o disminuir) el valor existente de un campo, debe usar increment . Vea el código de muestra a continuación:
if (goodClicked) { const n = 1 } else { const n = -1 } updateDoc(docRef, { // `n` would be the number of increments (1 or -1). likes: increment(n) });Para más información, puede consultar esta documentación .