console.log 未显示 useState 信息

console.log isn't showing useState info

我将 Firestorage 与 React 结合使用。基本上我想做的是在用户将多张图片上传到 Firestorage 后,它会将图片的 URL 添加到 Firestore 数据库中,如图所示

但是,当我尝试将它添加到字段值中时,它什么也没显示。所以我继续使用 console.log(urls) 来查看我的代码有什么问题,并且在 console.log 中它没有在数组中显示任何内容。

这是我的代码:

const [productImages, setProductImages] = useState([])
const [urls, setUrls] = useState([])

function handleSubmit(e) {
    e.preventDefault()

    const promises = []
    setLoading(true)
    setError("")

    // PRODUCT IMAGE UPDATE IF NOT NULL
    if (productImages !== null) {
        const promises = []
        productImages.map((image) => {
            const uploadTask = storage.ref(`products_images/${image.name}`).put(image);
            promises.push(uploadTask)
            uploadTask.on(
            "state_changed",
            snapshot => {},
            error => {
                console.log(error);
            },
            async () => {
                await storage
                    .ref("products_images")
                    .child(image.name)
                    .getDownloadURL()
                    .then(urls => {
                        setUrls((prevState) => [...prevState, urls])
                    })
            }
            )
        })
        Promise.all(promises)
            .then(() => console.log("Images > ", urls))
            .catch((err) => console.log(err));
      }

    Promise.all(promises)
      .then(() => {
        //history.push("/")
        //TRIED PUTTING HERE AS WELL BUT IT'S STILL SHOWING NOTHING
      })
      .catch(() => {
        setError("Failed to update account")
      })
      .finally(() => {
        setLoading(false)
      })
  }

const handleChange = (e) => {
      for (let i=0; i<e.target.files.length; i++) {
          const newProductImages = e.target.files[i]
          newProductImages["id"] = Math.random();
          setProductImages((prevState) => [...prevState, newProductImages]);
      
    }
  }

在我的代码中,您可以看到我把 console.log("Images >", urls) 放在哪里。它 return 什么都没有,而不是所有图像 URL。但是,当我将 console.log("Images >", urls) 放在所有函数的末尾时,在 return() 之前它将显示所有 URL。我该怎么做才能让它在提交按钮上显示图像 URLs?

---- 编辑 ----

我尝试使用 useEffect 将数据上传到 firestore 数据库,一旦它检测到 urls 状态有东西,这实现了我想要的,但它正在重复。它检测到状态已经改变了两次,因为它有两张图片正在上传。有没有什么办法可以修复成状态下存多张图片后只上传一次?

useEffect(() => {
    if (urls.length) {
        const newProduct = {
            product_category: productCategoryRef.current.value,
            product_name: productNameRef.current.value,
            product_images: urls,
            product_postedby: currentUser.email
        }
        db.collection("products").add(newProduct);
    }
  },[urls])

我建议使用 then()async/await,但不要在同一段代码中同时使用。虽然它们 可以 一起使用,但需要您对它们的功能有更多的了解。

如果您 使用 put returns 的承诺,然后将调用链接到 getDownloadURL那。据我所见,变成了这样:

if (productImages !== null) {
    const promises = productImages.map((image) => {
        const ref = storage.ref(`products_images/${image.name}`);
        return ref.put(image))
            .then(() => ref.getDownloadURL());
    });
    Promise.all(promises).then((urls) => {
        setUrls(urls)
    })
}