В этом примере мы узнаем, как загружать файлы с помощью React Hook Form, который очень предпочтителен для управления формами с помощью React. Мы будем использовать FormData для загрузки файла и загрузим файл типа multipart/form-data.
Введение
Мы рассмотрим шаг за шагом, как использовать процесс загрузки файла Multipart, который обычно используется для загрузки изображения или файла на сервер, с помощью React Hook Form. Сначала создадим простой экспресс-сервер для загрузки файлов. Затем загрузим наши файлы на этот сервер с помощью формы React Hook. Давайте начнем!
Создайте экспресс-сервер
npm i express
Затем установим пакет cors, необходимый для разрешения загрузки файлов на сервер, и пакет express-fileupload для управления путями загруженных файлов.
npm i cors express-fileupload
Мы завершили наши установки для создания простого сервера. Этот сервер будет показывать, что файл был загружен успешно или неудачно, в ответ на вызов POST
к конечной точке, которую мы указали.
import express from "express";
import fileupload from "express-fileupload";
import cors from "cors";
const app = express();
app.use(
fileupload({
createParentPath: true,
}),
);
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.post("/upload-file", async (req, res) => {
try {
if (!req.files) {
res.send({
status: "failed",
message: "No file uploaded",
});
} else {
let file = req.files.file;
console.log(req.files);
file.mv("./uploads/" + file.name);
res.send({
status: "success",
message: "File is uploaded",
data: {
name: file.name,
mimetype: file.mimetype,
size: file.size,
},
});
}
} catch (err) {
res.status(500).send(err);
}
});
const port = process.env.PORT || 5000;
app.listen(port, () => console.log(`Server started on port ${port}`));
Мы создали сервер с помощью Express. Как вы можете видеть, мы успешно запустили наш сервер, теперь у нас есть конечная точка для обработки запросов к этому порту. Теперь давайте создадим проект React и отправим наши файлы на этот сервер с помощью React Hook Form.
Создание проекта React
Давайте создадим проект react с помощью Create React App, а затем установим необходимые пакеты для нашего проекта.
npx create-react-app react-hook-form-multipart-upload
После того как ваш проект готов, перейдем в каталог нашего проекта и установим пакет React Hook Form.
cd react-hook-form-multipart-upload
npm install react-hook-form
npm run start
Многосторонняя загрузка файлов с помощью React Hook Form
Мы создали наш проект React и установили пакет react hook form. Теперь давайте создадим форму и будем управлять ею с помощью react hook form.
import React from "react";
import { useForm } from "react-hook-form";
function App() {
const { register, handleSubmit } = useForm();
const onSubmit = () => {};
return (
<div className="App">
<form onSubmit={handleSubmit(onSubmit)}>
<input type="file" {...register("file")} />
<input type="submit" />
</form>
</div>
);
}
export default App;
Для управления нашей формой и ее элементами мы определили методы register и handleSubmit из react hook form. Теперь давайте загрузим файл, выбранный в методе onSubmit, на наш сервер, поместив его в formData.
import React from "react";
import { useForm } from "react-hook-form";
function App() {
const { register, handleSubmit } = useForm();
const onSubmit = async (data) => {
const formData = new FormData();
formData.append("file", data.file[0]);
const res = await fetch("http://localhost:5000/upload-file", {
method: "POST",
body: formData,
}).then((res) => res.json());
alert(JSON.stringify(`${res.message}, status: ${res.status}`));
};
return (
<div className="App">
<form onSubmit={handleSubmit(onSubmit)}>
<input type="file" {...register("file")} />
<input type="submit" />
</form>
</div>
);
}
export default App;
Наш проект готов! С помощью React Hook Form мы теперь можем отправить выбранный файл на наш сервер в формате multipart/form-data
. Давайте протестируем это!
Вы ищете React Web Framework?
Основанный на React фреймворк для быстрого создания внутренних инструментов. refine предлагает множество готовых функций для быстрой разработки, не ставя под угрозу чрезвычайную настраиваемость. Примеры использования включают, но не ограничиваются админ-панелями, B2B-приложениями и приборными панелями.
🔥 Headless: работает с любым фреймворком пользовательского интерфейса
⚙️ Нулевая конфигурация: Однострочная настройка с помощью супершаблона. Запуск проекта занимает меньше минуты.
📦 Из коробки: Маршрутизация, сеть, аутентификация, управление состоянием, i18n и UI.
🔌 Независимость от бэкенда: подключается к любому пользовательскому бэкенду. Встроенная поддержка REST API, Strapi, NestJs CRUD, Hasura, Nhost, Airtable, Supabase, Appwrite и Altogic.
📝 Native Typescript Core : Вы всегда можете отказаться от использования обычного JavaScript.
🐜 Корпоративный пользовательский интерфейс: Работает без проблем с Ant Design System. (Поддержка нескольких фреймворков UI находится в дорожной карте).
📝 Код без кодовых пластин: Сохраняет вашу кодовую базу чистой и читабельной.
Для получения дополнительной информации обратитесь к документации по refine. →
Как сделать многостороннюю загрузку файлов с помощью Refine и React Hook Form?
Он позволяет управлять формами и отправлять данные на сервер с помощью адаптера refine-react-hook-form, который публикуется вместе с функцией refine headless. С помощью этого адаптера вы можете использовать все возможности React Hook Form в гармонии с refine. Вы также можете легко выполнить операцию Multipart File Upload(multipart/form-data)
с помощью этого адаптера.
Для получения подробной информации обратитесь к документации по адаптеру refine-react-hook-form. →
Источник просмотра
Вы можете очень легко управлять своей формой с помощью адаптера refine-react-hook-form
. Данные, созданные в форме, будут автоматически сохранены в базе данных с помощью метода refine onFinish
.
Это базовое приложение CMS
, которое было создано с помощью функции refine’s headless. Вы можете быстро создавать записи и сохранять их в базе данных с помощью refine. Мы рассмотрим страницу CreatePost этого шага. Мы создадим запись в форме и будем управлять ею с помощью адаптера refine-react-hook-form
.
Refine Create Post Page:
import { useState } from "react";
import { useForm } from "@pankod/refine-react-hook-form";
import { useSelect, useApiUrl } from "@pankod/refine-core";
import axios from "axios";
export const PostCreate: React.FC = () => {
const [isUploading, setIsUploading] = useState<boolean>(false);
const {
refineCore: { onFinish, formLoading },
register,
handleSubmit,
formState: { errors },
setValue,
} = useForm();
const apiURL = useApiUrl();
const { options } = useSelect({
resource: "categories",
});
const onSubmitFile = async () => {
setIsUploading(true);
const inputFile = document.getElementById(
"fileInput",
) as HTMLInputElement;
const formData = new FormData();
formData.append("file", inputFile?.files?.item(0) as File);
const res = await axios.post<{ url: string }>(
`${apiURL}/media/upload`,
formData,
{
withCredentials: false,
headers: {
"Access-Control-Allow-Origin": "*",
},
},
);
setValue("thumbnail", res.data.url);
setIsUploading(false);
};
return (
<form onSubmit={handleSubmit(onFinish)}>
<label>Title: </label>
<input {...register("title", { required: true })} />
{errors.title && <span>This field is required</span>}
<br />
<label>Status: </label>
<select {...register("status")}>
<option value="published">published</option>
<option value="draft">draft</option>
<option value="rejected">rejected</option>
</select>
<br />
<label>Category: </label>
<select
defaultValue={""}
{...register("category.id", { required: true })}
>
<option value={""} disabled>
Please select
</option>
{options?.map((category) => (
<option key={category.value} value={category.value}>
{category.label}
</option>
))}
</select>
{errors.category && <span>This field is required</span>}
<br />
<label>Content: </label>
<br />
<textarea
{...register("content", { required: true })}
rows={10}
cols={50}
/>
{errors.content && <span>This field is required</span>}
<br />
<br />
<label>Image: </label>
<input id="fileInput" type="file" onChange={onSubmitFile} />
<input
type="hidden"
{...register("thumbnail", { required: true })}
/>
{errors.thumbnail && <span>This field is required</span>}
<br />
<br />
<input type="submit" disabled={isUploading} value="Submit" />
{formLoading && <p>Loading</p>}
</form>
);
};
Как вы можете видеть, мы легко сохранили обе наши данные, такие как название, категория, статус и изображение в виде multipart/form-data
в нашу базу данных с помощью адаптера refine-react-hook-form
. В этом руководстве мы только показали, как использовать функцию многочастичной загрузки файлов для нашего примера. Для изучения примера Refine CMS, ознакомьтесь с приведенным ниже codeSandbox.
Refine Multipart Upload Live CodeSandbox пример