[英]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.