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

Material UI表单校验后调用axios POST提交数据问题求助

解决方案

核心问题说明

当前代码在校验通过后仅打印了表单数据日志,没有编写axios请求逻辑,也没有对校验结果做拦截判断,所以无法提交数据。

直接修改现有代码的方案

第一步:安装依赖并新增状态

首先安装axios(已安装可跳过)

npm install axios

在组件头部引入axios,同时新增提交loading、提交结果提示状态,避免重复提交:

import axios from 'axios'
// 其余原有import保持不变

export default function CreateAccountMuiForm() {
  const classes = useStyles();
  // 原有状态保留,新增以下状态
  const [loading, setLoading] = useState(false)
  const [submitMsg, setSubmitMsg] = useState('')
  // ...其余原有状态

第二步:修改handleSubmit提交逻辑

替换原有handleSubmit逻辑,校验通过后触发axios POST请求:

const handleSubmit = async (e) => {
  e.preventDefault();
  setEmailError(false);
  setPasswordError(false);
  setSubmitMsg('');

  let isValid = true;
  if (!values.email || !/\S+@\S+\.\S+/.test(values.email)) {
    setEmailError(true);
    isValid = false;
  }
  if (!values.password || values.password.length < 5) {
    setPasswordError(true);
    isValid = false;
  }
  // 校验不通过直接终止流程
  if (!isValid) return;

  try {
    setLoading(true)
    // 替换为实际后端注册接口地址
    const res = await axios.post('/api/user/register', {
      email: values.email,
      password: values.password,
      // 非盈利组织字段仅传非空值,也可直接传空字符串,可根据后端要求调整
      ...(values.nonProfit.trim() && {nonProfit: values.nonProfit})
    })
    // 提交成功后可自定义后续逻辑,比如跳转到登录页、清空表单
    setSubmitMsg('注册成功')
    setValues({email: '', password: '', nonProfit: ''})
  } catch (err) {
    // 可根据后端返回的错误格式调整提示内容
    setSubmitMsg(err.response?.data?.message || '注册失败,请稍后重试')
  } finally {
    setLoading(false)
  }
};

第三步:页面新增提示和按钮loading状态

修改按钮组件并添加提交结果提示:

{/* 提交结果提示 */}
{submitMsg && <p style={{color: submitMsg.includes('成功') ? 'green' : 'red', marginLeft: '8px'}}>{submitMsg}</p>}
<Button
  variant="contained"
  type="submit"
  className={classes.button}
  disabled={loading}
>
  {loading ? '提交中...' : 'Create an account'}
</Button>

抽离自定义Hook方案

可把表单状态、校验、提交逻辑抽为单独文件useRegisterForm.js,实现逻辑复用,简化组件代码:

自定义Hook代码(useRegisterForm.js)

import { useState } from 'react'
import axios from 'axios'

export default function useRegisterForm() {
  const [values, setValues] = useState({
    email: '',
    password: '',
    nonProfit: '',
  })
  const [errors, setErrors] = useState({
    email: false,
    password: false
  })
  const [loading, setLoading] = useState(false)
  const [submitMsg, setSubmitMsg] = useState('')

  const handleChange = (e) => {
    const { name, value } = e.target
    setValues(prev => ({...prev, [name]: value}))
    // 输入时清除对应字段的错误提示
    if (errors[name]) setErrors(prev => ({...prev, [name]: false}))
  }

  const handleSubmit = async (e, successCallback) => {
    e.preventDefault()
    setErrors({email: false, password: false})
    setSubmitMsg('')
    let isValid = true

    if (!values.email || !/\S+@\S+\.\S+/.test(values.email)) {
      setErrors(prev => ({...prev, email: true}))
      isValid = false
    }
    if (!values.password || values.password.length < 5) {
      setErrors(prev => ({...prev, password: true}))
      isValid = false
    }
    if (!isValid) return

    try {
      setLoading(true)
      const res = await axios.post('/api/user/register', {
        email: values.email,
        password: values.password,
        ...(values.nonProfit.trim() && {nonProfit: values.nonProfit})
      })
      setSubmitMsg('注册成功')
      setValues({email: '', password: '', nonProfit: ''})
      // 支持传入成功回调,比如跳转登录页
      successCallback?.()
      return res.data
    } catch (err) {
      setSubmitMsg(err.response?.data?.message || '注册失败,请稍后重试')
      return Promise.reject(err)
    } finally {
      setLoading(false)
    }
  }

  return {
    values,
    errors,
    loading,
    submitMsg,
    handleChange,
    handleSubmit
  }
}

组件中使用自定义Hook

原组件可简化为:

// 其余原有import保持不变,移除原有表单状态、校验、提交逻辑
import useRegisterForm from './useRegisterForm'

export default function CreateAccountMuiForm() {
  const classes = useStyles();
  const [showPassword, setShowPassword] = useState(false);
  const handleClickShowPassword = () => setShowPassword(!showPassword);
  const handleMouseDownPassword = () => setShowPassword(!showPassword);

  // 引入自定义Hook
  const {values, errors, loading, submitMsg, handleChange, handleSubmit} = useRegisterForm()

  return (
    <FormControl>
      <form className={classes.root} noValidate autoComplete="off" onSubmit={(e) => handleSubmit(e, () => console.log('提交成功后自定义逻辑'))}>
        <div>
          <TextField
            name="email"
            placeholder="Email"
            type="email"
            autoComplete="current-email"
            variant="outlined"
            required
            error={errors.email}
            value={values.email}
            onChange={handleChange}
          />
          <TextField
            name="password"
            placeholder="password"
            type={showPassword ? 'text' : 'password'}
            autoComplete="current-password"
            variant="outlined"
            required
            error={errors.password}
            value={values.password}
            onChange={handleChange}
            InputProps={{
              endAdornment: (
                <InputAdornment position="end">
                  <IconButton
                    aria-label="toggle password visibility"
                    onClick={handleClickShowPassword}
                    onMouseDown={handleMouseDownPassword}
                  >
                    {showPassword ? <Visibility /> : <VisibilityOff />}
                  </IconButton>
                </InputAdornment>
              ),
            }}
          />
          <TextField
            name="nonProfit"
            placeholder="Select you nonprofit (optional)"
            type="text"
            autoComplete="none"
            variant="outlined"
            value={values.nonProfit}
            onChange={handleChange}
          />
          {submitMsg && <p style={{color: submitMsg.includes('成功') ? 'green' : 'red', margin: '8px'}}>{submitMsg}</p>}
          <Button
            variant="contained"
            type="submit"
            className={classes.button}
            disabled={loading}
          >
            {loading ? '提交中...' : 'Create an account'}
          </Button>
          <p className="terms-of-use">
            By creating an account you agree to our
            <Link to="/termsofuse" style={{ textDecoration: 'none', color: '#909090' }}>
              <strong> Terms of use</strong>
            </Link>
          </p>
        </div>
      </form>
    </FormControl>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 13:39:01