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

React表单提交未触发函数且页面刷新问题的解决方案咨询

问题分析与解决方案

我来帮你梳理下当前遇到的问题,主要是两个核心点:表单提交时页面默认刷新导致函数未执行,以及表单数据无法正确传递到EditJob函数,下面一步步给你解决:

一、解决页面刷新+函数未触发的问题

浏览器中表单默认的提交行为会触发页面跳转刷新,这会导致你的EditJob函数还没执行完就被中断了。同时你当前的onSubmit回调没有传递事件对象,EditJob里自然拿不到表单数据。

修复代码:

<Form onSubmit={async (event) => {
  event.preventDefault(); // 关键:阻止表单默认刷新行为
  try {
    await EditJob(job.id, event); // 传递event参数给EditJob
    editJob(); // 执行更新后的状态刷新
    handleClose(); // 提交成功后关闭模态框
  } catch (error) {
    console.error("更新失败:", error);
    alert("职位更新失败,请重试");
  }
}}>

二、确保EditJob函数能正确获取表单数据

现在你已经把event传递给了EditJob,函数里通过event.target.xxx.value的写法是可行的,但要注意几个细节:

  1. 确保headers变量在EditJob函数的作用域内可访问(如果headers是在Jobs组件内定义的,建议把EditJob移到组件内部,或者把headers作为参数传入)
  2. 表单字段的name属性要和你在updateJob里取的键名完全一致(比如你的internalcode和internalCode控制ID,这里name是对的,没问题)

修正后的EditJob(如果移到组件内):

export default function Jobs () {
  const classes = useStyles()
  const [jobs, locations, departments, tags, deleteJob, editJob] = useJobs()
  const [show, setShow] = React.useState(false)
  const handleClose = () => setShow(false)
  const handleShow = () => setShow(true)

  // 把EditJob移到组件内部,确保能访问headers等变量
  const EditJob = async (jobid, event) => {
    console.log('editjob fired 1')
    console.log(jobid)
    const updateJob = {
      title: event.target.jobtitle.value,
      company_name: event.target.companyname.value,
      internal_code: event.target.internalcode.value,
      department: event.target.department.value,
      location: event.target.jlocation.value,
      tags: event.target.tags.value,
      benefits: event.target.benefits.value,
      description: event.target.description.value,
      requirements: event.target.requirements.value
    }
    return axios({
      method: 'put',
      url: `/api/jobs/update-job/${jobid}`,
      headers: headers, // 确保headers在此处可访问
      data: updateJob
    })
  }

  // ... 剩余渲染代码
}

三、可选优化:简化表单数据获取

如果你觉得手动逐个取表单字段太繁琐,可以用FormData来简化:

const EditJob = async (jobid, event) => {
  const formData = new FormData(event.target);
  const updateJob = Object.fromEntries(formData);
  // 可以在这里补充额外字段,或者调整字段名
  return axios({
    method: 'put',
    url: `/api/jobs/update-job/${jobid}`,
    headers: headers,
    data: updateJob
  })
}

这种方式会自动收集所有带name属性的表单字段,不用手动写每个字段的取值逻辑。

四、额外优化:避免重复渲染Modal

你当前在jobs.map里渲染了多个Modal,这会导致每个职位都对应一个Modal,性能和逻辑上都不太合理。建议把Modal移到map外面,用状态控制当前编辑的职位:

export default function Jobs () {
  // 新增状态存储当前要编辑的职位
  const [currentEditJob, setCurrentEditJob] = useState(null);
  const handleShow = (job) => {
    setCurrentEditJob(job);
    setShow(true);
  };

  // ... 其他状态和函数

  return (
    <>
      {jobs.map(job => (
        // 这里是职位列表项,比如一个编辑按钮触发handleShow
        <Button key={job.id} onClick={() => handleShow(job)}>编辑职位</Button>
      ))}

      {/* Modal移到map外面 */}
      <Modal show={show} onHide={handleClose}>
        <Modal.Header closeButton>
          <Modal.Title>Edit Job Position</Modal.Title>
        </Modal.Header>
        {currentEditJob && (
          <Modal.Body>
            <div className='container'>
              <Form onSubmit={async (event) => {
                event.preventDefault();
                try {
                  await EditJob(currentEditJob.id, event);
                  editJob();
                  handleClose();
                } catch (err) {
                  console.error(err);
                }
              }}>
                {/* 表单内容用currentEditJob的字段 */}
                <Form.Group controlId='jobtitle'>
                  <Form.Label style={{ color: 'green' }}>Job Title :</Form.Label>
                  <Form.Control type='textbox' defaultValue={currentEditJob.title} name='jobtitle' required placeholder='Enter Job Title' />
                </Form.Group>
                {/* 其他字段同理 */}
                <Button variant='success' type='submit'>Edit Job Position</Button>
              </Form>
            </div>
          </Modal.Body>
        )}
      </Modal>
    </>
  )
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 19:22:45