NextJS 中图像上传(云)的更好选择
Better option for image upload (cloud) in NextJS
我目前正在使用 NextJS 和 MongoDB 为客户开发我的第一个真正的项目,但我在上传图片时遇到了问题。我正在使用 Cloudinary,但它无法接收多个文件,而且我在状态管理方面也遇到了问题,因为当提交表单时,我的数据库没有收到文件,而 Cloudinary 可以。
API 工作正常,所以我 post 这里是表单代码 (REACT)。
export default function NewProduct() {
const initialState = {
title: "",
price: 0,
description: "",
content: "",
images: [],
category: "tortas",
};
const [product, setProduct] = useState(initialState);
const { title, price, description, content, category } = product;
const [files, setFile] = useState("");
//const handleChangeInput = (e) => {
// setProduct({ ...product, [e.target.name]: e.target.value });
//};
const handleUploadInput = async (e) => {
const uploadFiles = [...e.target.files];
setFile([...files, uploadFiles]);
};
const handleSubmit = async (e) => {
e.preventDefault();
const formData = new FormData();
for (let file of files) {
formData.append("file", file);
}
formData.append("upload_preset", "balbla");
const res = await fetch(
"https://api.cloudinary.com/v1_1/blabla/image/upload",
{
method: "POST",
body: formData,
}
);
const data = await res.json();
setProduct((p) => ({ ...p, images: data.secure_url}));
await createProduct();
setProduct(initialState);
};
const createProduct = async () => {
try {
const res = await fetch("http://localhost:3000/api/products", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(product),
});
const data = await res.json();
console.log(data);
} catch (err) {
console.log(err);
}
};
return (
<Layout>
<div className={styles.formDiv}>
<form className={styles.form} onSubmit={handleSubmit}>
<input
type="file"
name="file"
onChange={handleUploadInput}
multiple
accept="image/*"
/>
<button type="submit">Crear</button>
</form>
</div>
</Layout>
);
}
如果使用 Cloudinary 不是 NextJS 的最佳选择,我还可以使用其他哪些云或东西?
我希望我说清楚了。
提前谢谢你。
Cloudinary 上传 API 遗憾的是不支持在单个请求中上传多个资源,因此您可能需要遍历所有媒体项目并分别上传它们。
就产品创建而言,我无法确定,但您可能正在尝试在产品状态更新之前创建产品。
在 createProduct
中,您是否检查过您期望的所有数据在 运行 时是否可用?
您可以尝试监听 product
状态的更新,并使用 useEffect 挂钩基于该状态创建产品,例如:
useEffect(() => {
// Check if product is available or perform
// a check that you know isn't ready to create yet
if ( !product ) return;
(async function run() {
await createProduct(product);
setProduct(initialState);
})()
}, [product])
我目前正在使用 NextJS 和 MongoDB 为客户开发我的第一个真正的项目,但我在上传图片时遇到了问题。我正在使用 Cloudinary,但它无法接收多个文件,而且我在状态管理方面也遇到了问题,因为当提交表单时,我的数据库没有收到文件,而 Cloudinary 可以。
API 工作正常,所以我 post 这里是表单代码 (REACT)。
export default function NewProduct() {
const initialState = {
title: "",
price: 0,
description: "",
content: "",
images: [],
category: "tortas",
};
const [product, setProduct] = useState(initialState);
const { title, price, description, content, category } = product;
const [files, setFile] = useState("");
//const handleChangeInput = (e) => {
// setProduct({ ...product, [e.target.name]: e.target.value });
//};
const handleUploadInput = async (e) => {
const uploadFiles = [...e.target.files];
setFile([...files, uploadFiles]);
};
const handleSubmit = async (e) => {
e.preventDefault();
const formData = new FormData();
for (let file of files) {
formData.append("file", file);
}
formData.append("upload_preset", "balbla");
const res = await fetch(
"https://api.cloudinary.com/v1_1/blabla/image/upload",
{
method: "POST",
body: formData,
}
);
const data = await res.json();
setProduct((p) => ({ ...p, images: data.secure_url}));
await createProduct();
setProduct(initialState);
};
const createProduct = async () => {
try {
const res = await fetch("http://localhost:3000/api/products", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(product),
});
const data = await res.json();
console.log(data);
} catch (err) {
console.log(err);
}
};
return (
<Layout>
<div className={styles.formDiv}>
<form className={styles.form} onSubmit={handleSubmit}>
<input
type="file"
name="file"
onChange={handleUploadInput}
multiple
accept="image/*"
/>
<button type="submit">Crear</button>
</form>
</div>
</Layout>
);
}
如果使用 Cloudinary 不是 NextJS 的最佳选择,我还可以使用其他哪些云或东西? 我希望我说清楚了。 提前谢谢你。
Cloudinary 上传 API 遗憾的是不支持在单个请求中上传多个资源,因此您可能需要遍历所有媒体项目并分别上传它们。
就产品创建而言,我无法确定,但您可能正在尝试在产品状态更新之前创建产品。
在 createProduct
中,您是否检查过您期望的所有数据在 运行 时是否可用?
您可以尝试监听 product
状态的更新,并使用 useEffect 挂钩基于该状态创建产品,例如:
useEffect(() => {
// Check if product is available or perform
// a check that you know isn't ready to create yet
if ( !product ) return;
(async function run() {
await createProduct(product);
setProduct(initialState);
})()
}, [product])