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

React.js+Formik图片上传至MySQL报错:imageHandler未定义

解决Formik表单图片上传的编译错误及实现方案

问题描述

在React.js项目中使用Formik表单实现图片上传并存储到MySQL数据库时,出现编译错误,ESLint提示“'imageHandler' is not defined”,同时代码中存在函数组件不兼容的写法问题。

错误原因

  1. 文件输入框绑定了this.imageHandler作为onChange回调,但代码中从未定义过imageHandler函数,实际定义的处理函数名为handleChange,且函数组件不能使用this关键字。
  2. 函数组件中错误使用this.setState和this.props,函数组件无实例对象,需通过Formik提供的方法管理表单状态。
  3. 文件输入框的name属性错误绑定this.props.Image,应直接对应Formik初始值中的image字段。
  4. Yup校验规则存在拼写错误:value[0].sienter应为value.size。

修正后的完整代码

import React from 'react';
import { Formik, Form, Field, ErrorMessage } from "formik";
import * as Yup from "yup";
import axios from 'axios';

function Registration() {
    const initialValues = {
        firstName: "",
        lastName: "",
        address: "",
        gender: "",
        email: "",
        number: "",
        adminType: "",
        image: "",
        username: "",
        password: "",
    };

    const validationSchema = Yup.object().shape({
        firstName: Yup.string().min(2).required(),
        lastName: Yup.string().min(2).required(),
        address: Yup.string().min(10).required(),
        gender: Yup.string().min(4).max(6).required(),
        email: Yup.string().email().required(),
        number: Yup.string().matches(/^\d{11}$/, "必须是11位数字").required(),
        adminType: Yup.string().required(),
        image: Yup.mixed()
                .required("必须选择文件")
                .test("fileSize", "文件体积过大(最大2MB)", (value) => {
                    return value && value.size <= 2000000;
                })
                .test("type", "仅支持以下格式:.jpeg, .jpg, .bmp, .png, .pdf, .doc", (value) => {
                    return value && (
                        value.type === "image/jpeg" ||
                        value.type === "image/bmp" ||
                        value.type === "image/png" ||
                        value.type === 'application/pdf' ||
                        value.type === "application/msword"
                    );
                }),
        username: Yup.string().min(3).max(20).required(),
        password: Yup.string().min(2).max(20).required(),
    });

    const onSubmit = async (data) => {
        const formData = new FormData();
        Object.keys(data).forEach(key => {
            formData.append(key, data[key]);
        });
        
        try {
            await axios.post("http://localhost:3001/auth", formData, {
                headers: {
                    'Content-Type': 'multipart/form-data'
                }
            });
            console.log("注册成功");
        } catch (err) {
            console.error("注册失败", err);
        }
    };

    return (
        <div>
            <h1>注册</h1>
            <Formik
                initialValues={initialValues}
                validationSchema={validationSchema}
                onSubmit={onSubmit}
            >
                {({ setFieldValue }) => (
                    <Form>
                        <label>名字</label>
                        <ErrorMessage name="firstName" component="span"/>
                        <Field
                            autoComplete="off"
                            id="firstName"
                            name="firstName"
                            placeholder= "请输入名字"
                        />

                        <label>姓氏</label>
                        <ErrorMessage name="lastName" component="span"/>
                        <Field
                            autoComplete="off"
                            id="lastName"
                            name="lastName"
                            placeholder= "请输入姓氏"
                        />

                        <label>地址</label>
                        <ErrorMessage name="address" component="span"/>
                        <Field
                            autoComplete="off"
                            id="address"
                            name="address"
                            placeholder= "请输入地址"
                        />

                        <label>性别</label>
                        <ErrorMessage name="gender" component="span"/>
                        <Field
                            autoComplete="off"
                            id="gender"
                            name="gender"
                            placeholder= "请输入性别"
                        />

                        <label>邮箱</label>
                        <ErrorMessage name="email" component="span"/>
                        <Field
                            autoComplete="off"
                            id="email"
                            name="email"
                            placeholder= "请输入邮箱"
                        />

                        <label>手机号</label>
                        <ErrorMessage name="number" component="span"/>
                        <Field
                            type="text"
                            autoComplete="off"
                            id="number"
                            name="number"
                            placeholder= "请输入11位手机号"
                        />

                        <label>管理员类型</label>
                        <ErrorMessage name="adminType" component="span"/>
                        <Field
                            autoComplete="off"
                            id="adminType"
                            name="adminType"
                            placeholder= "请输入管理员类型"
                        />

                        <label>附件</label>
                        <ErrorMessage name="image" component="span"/>
                        <input
                            autoComplete="off"
                            id="image"
                            name="image"
                            type="file"
                            onChange={(event) => {
                                setFieldValue('image', event.target.files[0]);
                            }}
                        />

                        <label>用户名</label>
                        <ErrorMessage name="username" component="span" />
                        <Field
                            autoComplete="off"
                            id="username"
                            name="username"
                            placeholder="例如: guko"
                        />

                        <label>密码</label>
                        <ErrorMessage name="password" component="span" />
                        <Field
                            autoComplete="off"
                            type="password"
                            id="password"
                            name="password"
                            placeholder="例如: guko1234"
                        />

                        <button type="submit">注册</button>
                    </Form>
                )}
            </Formik>
        </div>
    )
}

export default Registration

关键修改说明

  • 移除未使用的handleChange函数,直接在文件输入框的onChange事件中通过Formik提供的setFieldValue更新image字段,解决imageHandler未定义的错误。
  • 移除函数组件中错误的this用法,改用Formik上下文方法管理表单状态。
  • 修正Yup校验规则中的拼写错误,调整单文件上传的校验逻辑。
  • 优化手机号校验:将输入类型改为text,用正则确保输入为11位数字,避免数字输入框的长度限制问题。
  • 补充邮箱格式校验,提升表单合法性验证能力。
  • 调整提交逻辑:使用FormData封装表单数据并设置正确的请求头,确保后端能正确接收文件。

内容的提问来源于stack exchange,提问作者Ramel Jay Cuña

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 03:05:28