javascript 如何在react JS中更新数组之前先运行一个函数?

dced5bon  于 2022-12-21  发布在  Java
关注(0)|答案(2)|浏览(126)
const handleItinerary = (e, type) => {
        
        var index = parseInt(e.target.name);
        let arr = [...itinerary];
        
        if (type === "imageUrl") {
            
            const date = new Date().getTime();
            const storageRef = ref(storage, `${date}`);

            uploadBytes(storageRef, e.target.files[0]).then((snapshot) => {
                
                getDownloadURL(storageRef).then((downloadURL) => {
                    arr[index]["imageUrl"] = downloadURL;
                    
                });
            });
                
        }
            

        setitinerary(arr);

    }

在上面的代码中,我尝试使用uploadBytes函数将图像上传到firebase存储器中,上传图像后,我获得了存储图像的downloadURL,我想将其值放入arr[index][“imageUrl”]中,但在获得downloadURL之前,arr[index][“imageUrl”]首先更新,我收到了downloadURL未定义的错误,那么如何解决这个问题呢?我使用的是react 18和firebase版本9。

rsl1atfo

rsl1atfo1#

当使用then()运行代码以响应正在完成的异步操作时,任何需要在完成时运行的代码都必须位于then()回调内部
所以

const handleItinerary = (e, type) => {
    var index = parseInt(e.target.name);
    let arr = [...itinerary];
    
    if (type === "imageUrl") {
        const date = new Date().getTime();
        const storageRef = ref(storage, `${date}`);

        uploadBytes(storageRef, e.target.files[0]).then((snapshot) => {
            getDownloadURL(storageRef).then((downloadURL) => {
                arr[index]["imageUrl"] = downloadURL;
                setitinerary(arr);                    
            });
        });                
    }
}

为了让这一点更加熟悉,您可以将''标记为async,并在其中使用await

const handleItinerary = async (e, type) => {
    var index = parseInt(e.target.name);
    let arr = [...itinerary];
    
    if (type === "imageUrl") {
        const date = new Date().getTime();
        const storageRef = ref(storage, `${date}`);

        const snapshot = await uploadBytes(storageRef, e.target.files[0]);
        const downloadURL = await getDownloadURL(storageRef);
        arr[index]["imageUrl"] = downloadURL;
        setitinerary(arr);                    
    }
}

注意,这并没有改变实际的行为,所有的异步调用仍然是异步执行的,这只是一种更熟悉的编写代码的方法。
如果您有要上载的图像列表,请确保使用use for of instead of forEachPromise.all来检测所有异步操作何时完成。

c8ib6hqw

c8ib6hqw2#

您可以将更新arr[index]["imageUrl"]值的代码移到then块中检索downloadURL。这将确保arr[index]["imageUrl"]值仅在检索downloadURL后更新。

const handleItinerary = (e, type) => {
  var index = parseInt(e.target.name);
  let arr = [...itinerary];

  if (type === "imageUrl") {
    const date = new Date().getTime();
    const storageRef = ref(storage, `${date}`);

    uploadBytes(storageRef, e.target.files[0]).then((snapshot) => {
      getDownloadURL(storageRef).then((downloadURL) => {
        arr[index]["imageUrl"] = downloadURL;
        setitinerary(arr);
      });
    });
  }
}

相关问题