簡體   English   中英

避免將 ref 傳遞給父組件:ReactJS

[英]Avoiding ref to be passed to the parent component: ReactJS

我有一個文件上傳器,它是一個子組件。 文件的 state 正在應用程序組件中維護。 我正在嘗試使用setInterval模擬 App 組件本身內部的上傳和失敗案例。 但是我正在使用將子組件中的 ref 傳遞給父回調,以便在 setTimeout 中獲得文件的最新上傳狀態。 實現工作得很好,有沒有什么方法可以做到這一切,而無需在回調中將任何 ref 傳遞給父組件?

我能夠成功地模擬完成和失敗。 在下面的沙箱中,我將文件名硬編碼為“1.txt”,以便上傳失敗。

注意:如果我必須在 App 內創建任何 ref 也沒關系,我只是不希望 ref 在傳遞給 App 組件時成為onFileUpload回調的一部分

沙盒: https://codesandbox.io/s/updated-file-upload-forked-k59xgo

內部文件上傳

 const timerRef = useRef<ReturnType<typeof setInterval> | undefined>();

  useEffect(() => {
    if (file.active && !file.uploadError) {
      onFileUpload(file, timerRef);
    }
  }, [file.active, file, onFileUpload]);

內部應用

 const onFileUpload = (
    selectedFile: FileType,
    uploadRef: React.MutableRefObject<
      ReturnType<typeof setInterval> | undefined
    >
  ) => {
    pollRef.current = selectedFile;
    if (!uploadRef.current) {
      uploadRef.current = setInterval(() => {
        if (
          pollRef.current?.uploadStatus === 100 ||
          pollRef.current?.uploadError
        ) {
          clearInterval(uploadRef.current);
        }
        const diff: number = Math.random() * 15;
        let currentProgess: number = pollRef.current?.uploadStatus as number;
        setSelectedFiles((prevState: FileType[]) => {
          return prevState.map((currentFile: FileType) => {
            const {
              file: { name: currentFileName },
              uploadStatus: currentFileUploadStatus
            } = currentFile;
            if (currentFileName === selectedFile.file.name) {
              if (
                selectedFile.file.name === "1.pdf" &&
                currentFileUploadStatus > 40
              ) {
                clearInterval(uploadRef.current);
                return {
                  ...currentFile,
                  uploadStatus: 0,
                  isActive: true,
                  uploadError: "Upload Error"
                };
              }
              currentProgess = Math.min(currentFileUploadStatus + diff, 100);
              return {
                ...currentFile,
                uploadStatus: currentProgess
              };
            } else return currentFile;
          });
        });
        return currentProgess;
      }, 60 * Math.floor(Math.random() * 6) + 100);
    }
  };

您已經使用文件名作為 React 的鍵。

<ListItem key={file.file.name} className={"file-name"}>

您也可以將其用作超時的鍵。

實際上,這就是已經發生的事情。 您依靠 React 渲染您的獨特組件來獲得正確的超時參考。

這允許您從UploadFile組件中刪除uploadRef ,因為它僅用於此超時。

const fileIntervals = useRef({});
const onFileUpload = ( selectedFile: FileType ) => {
  // ...
  const { name } = selectedFile;
  if (fileIntervals.current[name]) {
    return;
  }
  fileIntervals.current[name] = setInterval( // ...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM