Я изучаю MERN, и мой преподаватель дал мне задание: Сохраните изображение, предоставленное пользователем, в «общедоступной» папке без использования серверной части или базы данных, просто отреагируйте. У меня есть:
import { useEffect, useState } from "react";
export default function App() {
const [image, setImage] = useState(null);
const [file, setFile] = useState(null);
useEffect(() => {
if (file) {
var src = URL.createObjectURL(file[0]);
setImage(
<img src = {src} />
);
}
}, [file])
return (
<div>
<input type = "file" onChange = {(e) => setFile(e.target.files)} />
{ image }
</div>
);
}
Кажется, я не могу придумать, как сохранить изображение так, как этого хочет мой наставник.
Я тоже так предполагал, @Phil, но может быть, это возможно?
@sallf тот пост, на который вы ссылаетесь, буквально использует Node.js
Разрешено ли использовать localStorage? Я думаю, что в React прямое сохранение файлов в общую папку обычно невозможно, поскольку общая папка является статической и не допускает динамических изменений во время выполнения без взаимодействия с серверной частью.
export default function App() {
const [image, setImage] = useState(null);
const [file, setFile] = useState(null);
useEffect(() => {
if (file) {
const src = URL.createObjectURL(file[0]);
setImage(
<img src = {src} alt = "Uploaded" />
);
const reader = new FileReader();
reader.onloadend = () => {
const base64data = reader.result;
localStorage.setItem("savedImage", base64data);
};
reader.readAsDataURL(file[0]);
}
}, [file]);
useEffect(() => {
const savedImage = localStorage.getItem("savedImage");
if (savedImage) {
setImage(
<img src = {savedImage} alt = "Saved" />
);
}
}, []);
return (
<div>
<input type = "file" onChange = {(e) => setFile(e.target.files)} />
{image}
</div>
);
}
В противном случае, если использование localStorage также не разрешено, этот код ниже с использованием памяти браузера может работать.
export default function App() {
const [image, setImage] = useState(null);
const [file, setFile] = useState(null);
useEffect(() => {
if (file && file.length > 0) {
var src = URL.createObjectURL(file[0]);
setImage(src);
}
}, [file]);
return (
<div>
<input type = "file" onChange = {(e) => setFile(e.target.files)} />
{image && <img src = {image} alt = "Uploaded" />}
</div>
);
}
Надеюсь, я смогу чем-то помочь.
Как localStorage
эквивалентно «в общедоступной папке»?
Я так понимаю, вы имеете в виду Create-React-App (CRA) и его соглашение об использовании "%PUBLIC_URL%"
для доступа к общедоступной папке, о которой вы говорите.
Все эти файлы отправляются в браузер, и браузер не предлагает удобную файловую систему, в которую можно было бы писать. Он предоставляет только API, который можно использовать для записи в файловую систему ОС (имейте в виду, что для этого вам нужно разрешение пользователя).
Когда вы запускаете серверные предложения CRA, CRA объединяет сборку этих файлов для разработки и отправляет их в браузер. [1] Когда в любом из файлов происходят какие-либо изменения, он все перестраивает и сообщает браузеру через Websocket о наличии новых изменений. Затем клиент запрашивает новые файлы, которые отправляются клиенту через HTTP. [2] CRA на этом этапе поддерживает соединение WebSocket с браузером, чтобы передача файлов могла эффективно обрабатываться.
Теперь вы можете увидеть проблему в обосновании вопроса. Когда вы создадите статическую сборку этого приложения, она объединит все файлы, и функция горячей перезагрузки больше не будет. Вы можете обслуживать его с помощью любого статического файлового сервера, и файлы в конечном итоге останутся в браузере клиента. Общей папки больше не будет. [3]
Вопрос основан на фундаментальном непонимании того, как работает CRA.
[1] Static resource importing, tree-shaking e.t.c are done by Webpack under the hood.
[2] This feature is called hot-reloading.
[3] You can try this for yourself to see what I’m talking about.
Я думаю, вы неправильно истолковали то, что спрашивает ОП. Они хотят принять загрузку файла и сохранить его в общей папке, используя только клиентский код. Простой ответ: это невозможно.
Я почувствовал необходимость объяснить весь механизм ФП, прежде чем говорить о неизбежном невозможном.
«без использования серверной части или базы данных просто реагировать»… просто невозможно. Скажи своему преподавателю, что Фил сказал, что они полны ерунды.