Я написал код, который работает, но это не шедевр. У него огромные проблемы с производительностью. Как бы я с этим справился?
Проблемы
У меня проблемы с производительностью моего компонента:
Вопросы
Было бы неплохо отключить кнопку добавления альбома при передаче файлов в Cloudinary?
Пожалуйста, помогите мне решить эти две проблемы, и я хочу убедиться, что приложение работает без сбоев. Большое спасибо.
const AddAlbum = () => {
const [fileUrl, setFileUrl] = useState();
// MultipleFiles
const [multipleFileUrl, setMultipleFileUrl] = useState([]);
// cloudnary upload api endpoint
const api_cloudinary =
"https://api.cloudinary.com/v1_1/cloudinary_name/image/upload";
// file upload
const handleSingleFileUpload = async (files) => {
const formData = new FormData();
formData.append("file", files[0]);
formData.append("upload_preset", "preset_number");
// send cloudinary image and presets info
const res = await fetch(api_cloudinary, {
method: "POST",
body: formData,
});
const file = await res.json();
console.info(file);
const fileUrl = await file.eager[0].url;
setFileUrl(fileUrl);
};
console.info(fileUrl);
// upload many files cloudnary
// For now max amount of files is 20
const handleMultipleFileUpload = async (files, amount) => {
const formData = new FormData();
for (let i = 0; i <= files.length; i++) {
let file = files[i];
formData.append("file", file);
formData.append("upload_preset", ""preset_number"");
const res = await fetch(api_cloudinary, {
method: "POST",
body: formData,
});
const cloudinaryFiles = await res.json();
console.info(cloudinaryFiles);
setMultipleFileUrl(cloudinaryFiles);
}
};
const handleSubmit = async (e) => {
e.preventDefault();
console.info(
`
Album name:${albumName}
color:${color}
Background Image: ${fileUrl}
files:${multipleFileUrl}
`
);
};
И формы
return (
<Wrapper>
<form onSubmit = {handleSubmit}>
<div>
<StyledLabel>Upload background image</StyledLabel>
<DefaultInput
type = "file"
onChange = {(e) => handleSingleFileUpload(e.target.files)}
/>
</div>
<div>
<StyledLabel>Upload background image</StyledLabel>
<DefaultInput
type = "file"
onChange = {(e) => handleMultipleFileUpload(e.target.files)}
multiple
/>
</div>
<StyledButton type = "submit">Submit</StyledButton>
</form>
</Wrapper>
);
};
Вам нужна только 1 функция для обработки 1 или более файлов изображений. Вам нужно получить содержимое каждого файла и загрузить содержимое файла в данные формы. Пример кода использует API FileReader браузера для чтения содержимого локальных файлов изображений. Посмотрите на этот код в repl.it, который использует vanilla JS. Если это имеет смысл, вы можете вписать его в свою структуру. Дайте мне знать, если есть вопросы. https://repl.it/@rpeltz/fe-upload#script.js
reader.addEventListener(
"load", function () {
const fileContents = reader.result;
Я рекомендую использовать библиотеку, которая сделает это за вас. Есть много пограничных случаев, о которых вам нужно позаботиться при загрузке файлов.
Например, react-uploady делает это за вас. так что это просто:
import React from "react";
import Uploady from "@rpldy/uploady";
import UploadButton from "@rpldy/upload-button";
const CLOUD_NAME = "<your-cloud-name>";
const UPLOAD_PRESET = "<your-upload-preset>";
const App = () => (<Uploady
destination = {{
url: `https://api.cloudinary.com/v1_1/${CLOUD_NAME}/upload`,
params: {
upload_preset: UPLOAD_PRESET,
}
}}>
<UploadButton/>
</Uploady>);
Для производственного кода, где вы не хотите разрешать неподписанные загрузки, я рекомендую посмотреть это руководство