You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js中使用Ant Design Upload组件报`value`无效属性错误的求助

Next.js中使用Ant Design Upload组件报value无效属性错误的求助

我在Next.js应用里使用Ant Design的Upload组件时,浏览器控制台弹出了错误提示,具体错误信息可以看下面的截图:

控制台错误截图

下面是我写的表单提交相关代码,麻烦帮忙看看哪里出了问题:

"use client";
import {
  Form,
  Upload,
  Input,
  Select,
  Typography,
  Image,
  Button,
  message,
  Row,
  Col,
  Divider,
  Spin,
} from "antd";
import TextArea from "antd/es/input/TextArea";
import React, { useEffect, useState } from "react";
import { InboxOutlined, PlusOutlined, ProductFilled } from "@ant-design/icons";
import SupplierPageTitle from "@/components/supplier/SupplierPageTitle.js";
import useAuthGuard from "@/utils/useAuthGuard.js";
import { AddNewProduct } from "@/services/productService.js";
import { fetchProductCategories } from "@/services/productCategoryService.js";
import SupplierPageContainer from "@/components/supplier/SupplierPageContainer";
import useNotification from "@/utils/useNotification";
import { LoadingOutlined } from "@ant-design/icons";
import "./styles.css";

const { Title } = Typography;

const getBase64 = (file) =>
  new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => resolve(reader.result);
    reader.onerror = (error) => reject(error);
  });

const AddProduct = () => {
  const [previewOpen, setPreviewOpen] = useState(false);
  const [categories, setCategories] = useState([]);
  const [previewImage, setPreviewImage] = useState("");
  const [fileList, setFileList] = useState([]);
  const [videoFile, setVideoFile] = useState(null);
  const [uploading, setUploading] = useState(false);
  const [loading, setLoading] = useState(false);
  const { openNotification, contextHolder } = useNotification();
  const [form] = Form.useForm();

  const { user } = useAuthGuard({ middleware: "auth" });

  const handlePreview = async (file) => {
    if (!file.url && !file.preview) {
      file.preview = await getBase64(file.originFileObj);
    }
    setPreviewImage(file.url || file.preview);
    setPreviewOpen(true);
  };

  const handleImageChange = ({ fileList: newFileList }) => {
    if (newFileList.length > 6) {
      openNotification("error", "Error", "You can only upload up to 6 images!");
    } else {
      setFileList(newFileList);
    }
  };

  const onFinish = async (values) => {
    try {
      if (!fileList || fileList.length !== 6) {
        openNotification("error", "Error", "Please upload at least 6 images.");
        return;
      }

      const seoTagsArray = values.seoTags
        ?.split(",")
        .map((tag) => tag.trim())
        .filter((tag) => tag !== "");

      if (!seoTagsArray || seoTagsArray.length === 0) {
        openNotification(
          "error",
          "Error",
          "Please provide valid SEO tags as comma-separated values."
        );
        return;
      }

      const formData = new FormData();

      fileList.forEach((file, index) => {
        formData.append("images", file.originFileObj, `image${index}.jpg`);
      });

      if (videoFile) {
        formData.append("videoFile", videoFile);
      }

      formData.append("productName", values.productName);
      formData.append("description", values.description);
      formData.append("stockQuantity", values.stockQuantity);
      formData.append("wholesalePrice", values.WholePrice);
      formData.append("retailPrice", values.RetailPrice);
      formData.append("seoTags", JSON.stringify(seoTagsArray));
      formData.append("supplier", user?.id);
      formData.append("category", values.productCategory);

      setLoading(true);
      await AddNewProduct(formData);
      openNotification("success", "Success", "Product added Successfully");
      form.resetFields();
      setFileList([]);
    } catch (error) {
      console.error("Error uploading product:", error);
      openNotification(
        "error",
        "Error",
        "An unexpected error occurred while uploading product"
      );
    } finally {
      setLoading(false);
    }
  };

  const fetchCategories = async () => {
    try {
      const result = await fetchProductCategories();
      setCategories(result);
    } catch (error) {
      console.error("Error fetching categories:", error);
      openNotification("error", "Error", "Failed to fetch categories.");
    }
  };

  useEffect(() => {
    fetchCategories();
  }, []);

  const uploadButton = (
    <button
      style={{
        border: 0,
        background: "none",
      }}
      type="button"
    >
      <PlusOutlined />
      <div
        style={{
          marginTop: 8,
        }}
      >
        Upload
      </div>
    </button>
  );

  return (
    <>
      {contextHolder}

      <Row gutter={[16, 16]} justify="start">
        <Col xs={24} sm={12} md={12} lg={12} xl={12}>
          <SupplierPageTitle
            icon={<ProductFilled />}
            pageTitle="Add new Product"
          />
        </Col>

        <Col span={24}>
          <Divider />
        </Col>
      </Row>
      <SupplierPageContainer
        childern={
          <Row gutter={[16, 16]} justify="start">
            <Col span={24} style={{ position: "relative" }}>
              <Spin
                spinning={loading}
                indicator={
                  <LoadingOutlined
                    style={{
                      fontSize: 48,
                    }}
                    spin
                  />
                }
                style={{
                  position: "absolute",
                  top: "40%",
                }}
                size="large"
              >
                <div className={loading ? "blur-effect" : ""}>
                  <Form
                    form={form}
                    labelCol={{ span: 8 }}
                    wrapperCol={{ span: 16 }}
                    layout="horizontal"
                    style={{ maxWidth: 1000 }}
                    onFinish={onFinish}
                  >
                    <Form.Item
                      label="Product Name"
                      name="productName"
                      rules={[
                        {
                          required: true,
                          message: "Please input product name!",
                        },
                      ]}
                    >
                      <Input />
                    </Form.Item>
                    <Form.Item
                      label="Description"
                      name="description"
                      rules={[
                        { required: true, message: "Please fill description!" },
                      ]}
                    >
                      <TextArea rows={4} />
                    </Form.Item>
                    <Form.Item
                      label="Stock Quantity"
                      name="stockQuantity"
                      rules={[
                        {
                          required: true,
                          message: "Please input stock quantity!",
                        },
                        {
                          validator: (_, value) => {
                            if (!value) {
                              return Promise.reject(
                                new Error("Stock quantity is required.")
                              );
                            }
                            if (!/^\d+$/.test(value)) {
                              return Promise.reject(
                                new Error(
                                  "Stock quantity must be a valid integer."
                                )
                              );
                            }
                            return Promise.resolve();
                          },
                        },
                      ]}
                    >
                      <Input />
                    </Form.Item>
                    <Form.Item
                      label="Whole Sale Price"
                      name="WholePrice"
                      rules={[
                        { required: true, message: "Please input price!" },
                        {
                          validator: (_, value) => {
                            if (!value) {
                              return Promise.reject(
                                new Error("Wholesale price is required.")
                              );
                            }
                            if (!/^\d+(\.\d{1,2})?$/.test(value)) {
                              return Promise.reject(
                                new Error(
                                  "Wholesale price must be a valid float (e.g., 100.00, 999.99)."
                                )
                              );
                            }
                            return Promise.resolve();
                          },
                        },
                      ]}
                    >
                      <Input />
                    </Form.Item>
                  </Form>
                </div>
              </Spin>
            </Col>
          </Row>
        }
      />
    </>
  );
};

export default AddProduct;

备注:内容来源于stack exchange,提问作者salinda yasas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 03:23:18