smit agravat
smit agravat

Reputation: 295

React Gallary app uploads image two times

I am trying to create React image gallery app everything is working perfectly but every time I upload image it gets uploaded two times and I can't figure out why.....

Here is my useStorage hook that is responsible for uploading images

import { useState, useEffect } from "react";
import { fireStorage, fireStore } from "../firebase/firebase-config";
import { ref, getDownloadURL, uploadBytesResumable } from "firebase/storage";
import { collection, addDoc, serverTimestamp } from "firebase/firestore";

export default function useStorage(file) {
  const [progresspercent, setProgresspercent] = useState(0);
  const [error, setError] = useState(null);
  const [url, setUrl] = useState(null);
  const db = fireStore;

  useEffect(() => {
    const storageRef = ref(fireStorage, `Images/${file.name}`);
    const uploadTask = uploadBytesResumable(storageRef, file);


    uploadTask.on("state_changed",
      (snapshot) => {
        const progress =
          (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
        setProgresspercent(progress);
      },
      (error) => {
        setError(error);
      },
      async () => {
        const imageUrl = await getDownloadURL(uploadTask.snapshot.ref).then((downloadUrl) => {
          addDoc(collection(db, 'Images'),{
            url: downloadUrl,
            createdAt: serverTimestamp()
          })
          setUrl(downloadUrl)
        });
      }
    );
  },[file]);

  return { progresspercent, url, error };
}

Here is uploadform

import React, { useState } from "react";
import ProgressBar from "./ProgressBar";

export default function UploadForm() {
  const [file, setFile] = useState(null);
  const [error, setError] = useState("");
  const allowedType = ["image/png", "image/jpg", "image/jpeg"];

  function changeHandler(e) {
    let selectedFile = e.target.files[0];

    if (selectedFile && allowedType.includes(selectedFile.type)) {
      setFile(selectedFile);
      setError("");
    } else {
      setFile(null);
      setError("Please select an image file");
    }
  }

  return (
    <form>
      <label>
        <input type="file" onChange={changeHandler} />
        <span>+</span>
      </label>
      <div className="output">
        {error && <div className="error">{error}</div>}
        {file && <div>{file.name}</div>}
        {file && <ProgressBar file={file} setFile={setFile} />}
      </div>
    </form>
  );
}

This is my useFirestore hook

import { useState, useEffect } from "react";
import { fireStorage, firestore } from '../firebase-config'
import { ref, getDownloadURL, uploadBytesResumable } from "firebase/storage";
import { collection, addDoc, serverTimestamp } from "firebase/firestore";

export default function useStorage(file) {
  const [progresspercent, setProgresspercent] = useState(0);
  const [error, setError] = useState(null);
  const [url, setUrl] = useState(null);
  const db = firestore;

  useEffect(() => {
    const storageRef = ref(fireStorage, `Images/${file.name}`);
    const uploadTask = uploadBytesResumable(storageRef, file);


    uploadTask.on("state_changed",
      (snapshot) => {
        const progress =
          (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
        setProgresspercent(progress);
      },
      (error) => {
        setError(error);
      },
      async () => {
        const imageUrl = await getDownloadURL(uploadTask.snapshot.ref).then((downloadUrl) => {
          addDoc(collection(db, 'Images'),{
            url: downloadUrl,
            createdAt: serverTimestamp()
          })
          setUrl(downloadUrl)
        });
      }
    );
  },[file]);

  return { progresspercent, url, error };
}

Also here is git repo if error is in any other comp

Upvotes: 2

Views: 140

Answers (1)

smit agravat
smit agravat

Reputation: 295

I figure out this one it is related to react 18 just a simple solution remove <React.StrictMode> from main component file or use conditional function in use Effect

Upvotes: 1

Related Questions