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

React+Typescript+Material-UI表单验证及提交时接口调用实现咨询

实现方案

接口调整

你现有postTicket接口没有接收提交的表单数据,需要先修改成支持传参:

export interface TicketDTO {
    title?: string;
}

// 新增data参数,接收要提交的工单数据
export async function postTicket(data: TicketDTO): Promise<AxiosResponse<TicketDTO[]>> {
  return await axios.post<TicketDTO[]>(
    `${baseUrl}/support/tickets/create`,
    data // 把表单数据放到请求体里
  );
}

组件完整实现

我们通过React内置useState维护表单状态、校验错误、加载状态,结合MUI TextField的自带错误提示能力实现校验,提交时触发接口请求:

import { useState } from 'react';
import { Container, Box, TextField, Button, CircularProgress, Alert } from '@mui/material';
// 导入你的接口和类型
import { postTicket, TicketDTO } from '你的接口文件路径';

export default function OpenTicket(props: any) {
    const classes = useStyles();
    // 表单状态
    const [formData, setFormData] = useState<TicketDTO>({ title: '' });
    // 校验错误状态
    const [errors, setErrors] = useState<{title?: string}>({});
    // 提交加载状态
    const [loading, setLoading] = useState(false);
    // 提交结果提示
    const [submitMsg, setSubmitMsg] = useState<{type: 'success'|'error', content: string}|null>(null);

    // 输入框内容变化同步
    const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
        const { name, value } = e.target;
        setFormData(prev => ({ ...prev, [name]: value }));
        // 输入时清除对应字段的错误提示
        if (errors[name as keyof typeof errors]) {
            setErrors(prev => ({ ...prev, [name]: undefined }));
        }
    };

    // 表单校验逻辑
    const validateForm = () => {
        const newErrors: {title?: string} = {};
        // 这里可以自定义校验规则,比如title必填,最小长度等
        if (!formData.title?.trim()) {
            newErrors.title = '工单标题不能为空';
        } else if (formData.title.trim().length < 5) {
            newErrors.title = '标题长度不能少于5个字符';
        }
        setErrors(newErrors);
        // 没有错误则校验通过
        return Object.keys(newErrors).length === 0;
    };

    const formHandler = async (e: React.FormEvent<HTMLFormElement>) => {
        e.preventDefault();
        setSubmitMsg(null);
        // 先校验表单
        const isValidatePass = validateForm();
        if (!isValidatePass) return;

        // 校验通过提交接口
        try {
            setLoading(true);
            await postTicket(formData);
            setSubmitMsg({ type: 'success', content: '工单提交成功' });
            // 提交成功清空表单
            setFormData({ title: '' });
        } catch (err) {
            setSubmitMsg({ type: 'error', content: '工单提交失败,请稍后重试' });
            console.error('提交错误:', err);
        } finally {
            setLoading(false);
        }
    };

    return (
            <Container>
                <Box m={5}>
                    <div className={classes.root}>
                      <form onSubmit={formHandler}>
                            {/* 提交结果提示 */}
                            {submitMsg && <Alert severity={submitMsg.type} sx={{ mb: 2 }}>{submitMsg.content}</Alert>}
                            
                            <TextField
                              id="outlined-full-width"
                              label="Name"
                              name="title" // 要和formData里的字段名对应
                              value={formData.title || ''}
                              onChange={handleInputChange}
                              error={!!errors.title} // 控制错误状态
                              helperText={errors.title} // 错误提示内容
                              fullWidth
                              margin="normal"
                              />
                            <Button
                               type="submit" // 一定要加type="submit"才能触发form的onSubmit事件
                               variant="contained"
                               disabled={loading} // 加载时禁用按钮
                            >
                               {loading ? <CircularProgress size={20} color="inherit" /> : 'Submit'}
                            </Button> 
                        </form>
                    </div>
                </Box>
            </Container>
    );
}

关键说明

  • 给提交按钮加上type="submit"属性,点击时才会自动触发form的onSubmit事件
  • 如果有更复杂的多字段校验、联动校验需求,推荐搭配react-hook-form+zod实现,代码会更简洁,TS类型适配也更友好
  • 加载状态下禁用按钮可以避免重复提交的问题

内容的提问来源于stack exchange,提问作者Peter Penzov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 07:57:03