skip to Main Content

I’m trying to create a component that users can add or remove galleries to using Firebase as my store inside a next.js 13 project.

As I’m using React hooks I’ve set ‘use client’ at the top level of the file.

I am setting the value of the galleries present by making a call to a Firebase collection. Inside my React functional component, I have the following

const [galleries, setGalleries] = useState<any[]>([]);

useEffect(() => {
  const getFirebaseGalleries = async () => {
    const collectionRef = collection(db, "galleries");
    const querySnapshot = await getDocs(collectionRef);

    const documents = querySnapshot.docs.map((doc) => ({
      id: doc.id,
      ...doc.data(),
    }));

    console.log("useffect ran");

    setGalleries(documents);
  };

  getFirebaseGalleries();
}, [galleries]);

Inside my functional component I am displaying the galleries with a grid by doing the following

<CreateGalleryComponent />
  <Grid>
      {galleries.map((item) => (
        <>
           // logic and functionality for deleting an item in the GalleryItem component
          <GalleryItem key={item.id} {...item} />
        </>
      ))}
    </Grid>

In its current form. updates will display only as the useEffect loops continuously. If I remove the galleries from the dependency array, the component does not re-render.

Please could you point out where I am going wrong in my implementation?

Could it be my separation of functionality for adding/removing galleries from the Firebase collection?

3

Answers


  1. You have to remove the galleries from dependency array.

    useEffect(() => {
    const getFirebaseGalleries = async () => {
      const collectionRef = collection(db, "galleries");
      const querySnapshot = await getDocs(collectionRef);
    
      const documents = querySnapshot.docs.map((doc) => ({
        id: doc.id,
        ...doc.data(),
      }));
    
      console.log("useffect ran");
    
      setGalleries(documents);
    };
    
      getFirebaseGalleries();
    }, []); //<----
    

    By removing the galleries dependency, the effect will only be called once when the component mounts, and will not cause an infinite loop of updates.

    Login or Signup to reply.
  2. Your effect will be called every time the galleries value changes. Since you are calling setGalleries at the end of your effect, the value is changing after that. That’s why you have the cycle.
    It seems that the galleries should be fetched after some user interaction, so you can move this fetch logic to some callback that is called when a user clicks on some button or something.

    Login or Signup to reply.
  3. I don’t see you have shared code for updating firebase gallery anywhere. You’re only reading same gallery from firebase.

    As far as I think, you need to do below steps.

    1. Make your useEffect dependency array empty to get firebase data on initial rendering as shown by @fly_sprig117
    2. Inside <CreateGalleryComponent />, on create event click, post gallery to firebase store. Now firebase will have updated data.
    3. Fetch from firebase again to get updated gallery.
    4. Once above fetch is successful, update your gallery state to show newly added gallery in the UI.

    Here is how the code should look like –

    const onAddGalleryClick = async (event) => {
    
    // Send gallery object to firebase
    const successPostingGallery = await collectionRef.insert(newGalleryObj);
    
    // fetch from firebase
    const querySnapshot = await getDocs(collectionRef);
    const documents = querySnapshot.docs.map((doc) => ({
        id: doc.id,
        ...doc.data(),
      }));
    
    
    // update the gallery
      setGalleries(documents);
    
    };
    

    Tip: Write a function to get gallery from firebase and setting gallery to local state so that you can use this inside useEffect and create event handler, at both places.

    Also, I think you need to pass galleries, setGalleries to <CreateGalleryComponent /> component.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search