Firebase 存储 Web:uploadTask.cancel() 不工作 reactjs

Firebase Storage Web: uploadTask.cancel() is not working reactjs

我想一键取消上传任务。但它不起作用(returns false,我可以在 firebase 存储控制台中查看文件)下面是组件的完整代码

Upload.js

import React, { useState } from "react";
import { ref, uploadBytesResumable } from "firebase/storage";
import { storage } from "../../firebase";
import bookwall from "../../illustrations/bookwall.svg";

const Upload = () => {
  const [loading, setLoading] = useState(false);
  //used for cancel button
  const [cancel, setCancel] = useState(false);
  const formHandler = (e) => {
    e.preventDefault();
    const file = e.target[1].files[0];
    uploadFile(file);
  };

  const uploadFile = (file) => {
    if (!file) return;
    const storageRef = ref(storage, `files/${file.name}`);
    const uploadTask = uploadBytesResumable(storageRef, file);
    if(cancel === true){
      uploadTask.cancel();
      setLoading(false);
      setCancel(false);
      console.log('cancelled');
      console.log(`does upload task cancel work? ${uploadTask.cancel()}`);
    }
    
    //https://firebase.google.com/docs/reference/js/v8/firebase.storage.UploadTask
    uploadTask.on(
      "state_changed",
      //setting loading to true while the file upload is pending
      (snapshot) => {
        //to keep the upload button disabled till the upload is completed
        setLoading(true);
        console.log(snapshot.state)
        
      },
      //function for error
      (error) => {
        switch (error.code) {
          case 'storage/unauthorized':
            // User doesn't have permission to access the object
            alert('something went wrong while uploading this file :(')
            setLoading(false);
            break;
          case 'storage/canceled':
            // User canceled the upload
            console.log('the cancel method works')
            setLoading(false);
            setCancel(false);
            break;
          default:
            alert('something went wrong while uploading this file :(')
            setLoading(false);
        }
      },
      //function for successful completion
      () => {
        setLoading(false);
        console.log('the upload is successful');
      }
    );
    
    
  };
  return (
    <main className="upload">
      <form onSubmit={formHandler} className="upload-form">
        <h1>
          Add a new book for <br /> Everyone to read!
        </h1>
        <input
          type="text"
          className="gbooks-link"
          placeholder="Google Books Link"
          required
        />
        <label className="file-input-label">
          <input type="file" className="input" id="file-upload" required />
          Upload the book here
        </label>
        <div className="buttons-container">
          <button disabled={loading} type="submit" className="upload">
            Upload
          </button>
          {
            loading === true ?
            <button className="cancel" onClick={() => setCancel(true)}>
              Cancel
            </button>
            :
            null
          }
         
        </div>
      </form>
      <img src={bookwall} alt="a wall full of books" className="bookwall" />
    </main>
  );
};

export default Upload;

这是我点击取消后控制台中发生的事情(点击上传并设置文件(img,3.15mb)后)

如果我这样做

const uploadTask = uploadBytesResumable(storageRef, file);
console.log(`does upload task cancel work? ${uploadTask.cancel()}`);

它 returns 正确并且上传实际上被取消了

您无法设置 cancel 状态,然后期望您的 uploadFile() 响应该更改。

您或许可以尝试将上传任务另存为参考

例如

const uploadTaskRef = useRef();

const uploadFile = (file) => {
    .....
    const storageRef = ref(storage, `files/${file.name}`);
    //we save the reference of your upload here to be used later.
    uploadTaskRef.current = uploadBytesResumable(storageRef, file); 
    ......
}

取消时,调用下面的取消函数而不是使用 cancel 状态。

const onCancel = () => {
     //with the ref, we know which upload to cancel
     uploadTaskRef.current.cancel();
}

如果您有一组文件,您将学习如何使用

原来这是一个 scope-related 问题... 我必须通过使 uploadTask 成为反应状态以在我的代码中实现它来使其全局可用,并且我在我的按钮回调中调用了 uploadTask.cancel() ...我使用 useEffect 来监视我的 uploadTask 我是在按钮回调中执行 setLoading(false) 而不是错误回调