skip to Main Content

Trying to build my first project using React and firebase. I have a Header.jsx component where I’m mapping names of all added categories like shown below:

const [data, setData] = useState([]);

// Getting all categories from firebase.
useEffect(() => {
    const fetchData = async () => {
        let list = []
        try{
            const categories = collection(db, 'category')
            let mquery = query(categories, orderBy('timeStamp', "desc"))
            const querySnapshot = await getDocs(mquery);
            querySnapshot.forEach((doc) => {
                list.push({ id: doc.id, ...doc.data()});
            });
            setData(list);
        } catch (err) {
            console.log(err)
        }
    };
    fetchData()
}, []);

// Mapping category names in the header
<ul className="absolute hidden text-white pt-1 group-hover:block items-center">
  {data.map((category, index) => {
    return (
     <Link to={`/categories/${category.name}`} key={category.id}>
       <li className='rounded-lg p-2 hover:text-white/80 hover:-translate-y-1 hover:scale-110 duration-300 transition ease-in-out delay-150'>
        <span>{category.name}</span>
       <li>
     </Link>
    )
  })}

When I’m adding a new category, the new category name is not displayed, it’s only displayed if I refresh the page.

I suppose that this is due to not updating the state, [data], right? How can I update the state and add a new category name without refreshing?

2

Answers


  1. Chosen as BEST ANSWER

    I've managed to solve it by implementing an onSnapshot listener. You can check firebase docs https://firebase.google.com/docs/firestore/query-data/listen#listen_to_multiple_documents_in_a_collection.

    Also helpful link useEffect rendering multiple times even when data is not changing

    useEffect(() => {
       const categories = collection(db, 'category')
       let mquery = query(categories, orderBy('timeStamp', "desc"))
       const unsubscribe = onSnapshot((mquery), (querySnapshot) => {
       const list = [];
       querySnapshot.forEach((doc) => {
         list.push({ id: doc.id, ...doc.data()});
        });
        setData(list);
       }); 
    }, []);
    

  2. Try this instead.

    // Getting all categories from firebase.
    useEffect(() => {
      const fetchData = async() => {
        try {
          const categories = collection(db, 'category')
          let mquery = query(categories, orderBy('timeStamp', "desc"))
          const querySnapshot = await getDocs(mquery);
          const list = querySnapshot.docs.map((doc) => {
            return {
              id: doc.id,
              ...doc.data()
            };
          });
          setData(list);
        } catch (err) {
          console.log(err)
        }
      };
      fetchData()
    }, []);
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search