I'm learning about ReactJS hooks and firebase, I'm getting users from the firestore and using the "Verify" button I set the user.status to "verified", This code works to verify the user in the firestore, however I don't know where exactly should I set the state of the user in order to make the component re-render!
I would appreciate your help !
/* some imports have been hidden for making the code readable */
import React, { useState, useEffect } from 'react'
import {db} from '../firebase'
import { collection, getDocs, query, where, updateDoc, doc } from 'firebase/firestore'
export default function Page() {
const [error, setError] = useState("")
const { currentUser, logout } = useAuth()
const[status, setStatus] = useState("notverified")
const history = useHistory()
// firestore
const [users, setUsers] = useState([])
const usersCollectionRef = collection(db, "users")
const queryInverified = query(usersCollectionRef, where("status","==", "notverified"))
const updateUser = async (id, status)=> {
const userDoc = doc(db, "users", id)
const newStatus = {status: status= "verified"}
setStatus("verified")
await updateDoc(userstDoc, newStatus)
/* Following AKX 's answer! */
setUsers((oldUsers) =>
oldUsers.map((user) =>
user.id === id? {...user, status} : user,
),
);
}
}
useEffect(() =>{
const getUsers = async () => {
const data = await getDocs(queryInverified)
setUsers(data.docs.map((doc)=>({...doc.data(), id: doc.id})))}
getUsers()
}, [])
return (
<>
<Container>
<Card>
<Card.Body>
<div>
{users.map((user) => {
return(
<div className="card mb-4" >
<div className="card-body">
<h5>User Name: {user.name}</h5>
<p>Verification status: {user.status}</p>}
<Button onClick={() =>{updateUser(user.id, user.status)>
Verify</Button>
</div>
</div>
)
})}
</div>
</Card.Body>
</Card>
</Container>
</>
)
}
CodePudding user response:
Well, you're not updating the users
state in any way after updating the user in Firebase.
You have about two options:
an optimistic update of the local state, i. e.
setUsers(...)
after the updateDoc await to update the just-updated user in the users array:setUsers((oldUsers) => oldUsers.map((user) => user.id === id ? { ...user, status } : user, ), );
simply reload the data from Firebase afterwards; refactor that fetching code to another function you can call both in the current
useEffect
and within the updateUser handler.
CodePudding user response:
Like @AKX mentioned, with the first option you can do this:
setUsers(...usersDoc.data, id)