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

React表单无法提交:代码报错排查及修改方案咨询

React表单提交MongoDB的代码错误修复方案

问题背景

在React中实现了一个任务创建表单,意图将表单值保存到MongoDB的tasks集合,但运行代码时出现了Hook调用错误、变量未定义等一系列问题。

原代码

import React, { useState, useEffect } from 'react';
import 'bootstrap/dist/css/bootstrap.css';
import axios from 'axios';

export default function Task({}) {

  const loggedInUser = localStorage.getItem('loggedInUser')
  const [taskValues, setTaskValues] = useState({
    task: '',
    userStory: ' ', // Default value
    createdBy: loggedInUser,       // Default value
    status: ' ',       // Default value
  });

  const [allTask, setAllTask] = useState([{}]);
  const [assigned, setAllAssign] = useState([]);
  const[allStories, setAllStories] = useState([{}]);
  


  const assignedUserStories = allStories.filter((story) => {
    return assigned.some(({
      user_story_id
    }) => user_story_id === story._id)
  });

  
  
  const handleInputChange = (event) => {
    
    const { name, value } = event.target;
    setTaskValues({ ...taskValues, [name]: value });
   };

  
    // Post taskValues data to your server endpoint
    axios.post('http://localhost:9000/createTask', taskValues)
    .then((res) => {
      if (res.data) {
        alert('Task creation Successful');
      }
    })
    .catch((err) => {
      alert('Error in creating the task');
    });
  };

    useEffect(() => {
      axios.get('http://localhost:9000/getTaskList').then(function (response) {
      const Taskdata = response.data;
      setAllTask(Taskdata);
    });

    axios.get('http://localhost:9000/getUserstory').then(function (response) {
      const Allstories = response.data;
      setAllStories(Allstories);
    });

    axios.get('http://localhost:9000/getAssignedstories').then(function (response) {
      const Allassignedstories = response.data;
      setAllAssign(Allassignedstories);
    });


  }, []);
 
  const handleSubmit = (event) => {
    event.preventDefault();

  


  return (
    <div className="container mt-5">
      <div className="row justify-content-center">
        <div className="col-md-6 col-lg-4">
          <div className="card">
            <div className="card-body">
              <h2 className="card-title">Create a New Task</h2>
              <form onSubmit={handleSubmit}>
                <div className="form-group">
                  <label>Task:</label>
                  <textarea
                    className="form-control"
                    name="task"
                    value={taskValues.task}
                    onChange={handleInputChange}
                  />
                </div>

                <div className="form-group">
                  <label>User Story:</label>
                  <select
                    className="form-control"
                    name="userStory"
                    value={taskValues.userStory}
                    onChange={handleInputChange}
                  >
                    {assignedUserStories.map((stories) =>
                      <option key={stories._id} value={stories._id}>{stories.user_story}</option>
                    
                    )}
                   
                  </select>
                </div>

                <div className="form-group">
                  <label>Created by:</label>
                  <select
                    className="form-control"
                    name="createdBy"
                    value={taskValues.createdBy}
                    onChange={handleInputChange}
                  >
                    <option value="user1">User 1</option>
                    <option value="user2">User 2</option>
                    <option value="user3">User 3</option>
                  </select>
                </div>

                <div className="form-group">
                  <label>Status:</label>
                  <select
                    className="form-control"
                    name="status"
                    value={taskValues.status}
                    onChange={handleInputChange}
                  >
                    <option value="New">New</option>
                    <option value="In Progress">In Progress</option>
                    <option value="Awaiting Confirmation">Awaiting Confirmation</option>
                    <option value="Completed">Completed</option>
                    
                  </select>
                </div>

                <button type="submit" className="btn btn-primary btn-block">
                  Create Task
                </button>
              </form>
            </div>
          </div>
          
        </div>
      </div>
    </div>
  );
 }

报错信息

src\components\Task.js
  Line 48:5:    React Hook "useEffect" cannot be called at the top level. React Hooks must be called in a React function component or a custom React Hook function  react-hooks/rules-of-hooks
  Line 51:7:    'setAllTask' is not defined                                                                                                         
                no-undef
  Line 56:7:    'setAllStories' is not defined                                                                                                      
                no-undef
  Line 61:7:    'setAllAssign' is not defined                                                                                                       
                no-undef
  Line 86:28:   'taskValues' is not defined                                                                                                         
                no-undef
  Line 87:31:   'handleInputChange' is not defined                                                                                                  
                no-undef
  Line 96:28:   'taskValues' is not defined                                                                                                         
                no-undef
  Line 97:31:   'handleInputChange' is not defined                                                                                                  
                no-undef
  Line 99:22:   'assignedUserStories' is not defined                                                                                                
                no-undef
  Line 112:28:  'taskValues' is not defined 

具体修改步骤

1. 修复代码结构错误

原代码中handleInputChange函数结束后,错误地添加了一个额外的};,导致后续的useEffect、handleSubmit和组件返回部分都被抛出了组件函数的作用域,这是所有"未定义"错误的核心原因。需要删除这个多余的};,并将原本放在外层的axios.post请求逻辑移到handleSubmit函数内部。

2. 完善handleSubmit函数

原handleSubmit函数只有阻止默认行为的逻辑,没有实际的提交操作。需要把发送POST请求的代码移到这里,确保只有点击提交按钮时才触发数据提交,还可以在提交成功后重置表单:

const handleSubmit = (event) => {
  event.preventDefault();
  // Post taskValues data to your server endpoint
  axios.post('http://localhost:9000/createTask', taskValues)
  .then((res) => {
    if (res.data) {
      alert('Task creation Successful');
      // 提交成功后重置表单
      setTaskValues({
        task: '',
        userStory: '',
        createdBy: loggedInUser || 'user1',
        status: 'New',
      });
    }
  })
  .catch((err) => {
    alert('Error in creating the task');
  });
};

3. 修正状态默认值

原userStory和status的默认值是空格' ',但下拉选项的value中没有空格,会导致初始状态下拉框没有选中项。建议改为空字符串或者匹配选项的默认值(比如status设为'New'),同时给createdBy增加兜底默认值,避免localStorage无值时出错:

const [taskValues, setTaskValues] = useState({
  task: '',
  userStory: '',
  createdBy: loggedInUser || 'user1',
  status: 'New',
});

4. 确保Hooks在组件内部调用

修正结构后,useEffect会回到组件函数内部,符合React Hooks的调用规则,解决"React Hook cannot be called at the top level"的错误。

修正后的完整代码

import React, { useState, useEffect } from 'react';
import 'bootstrap/dist/css/bootstrap.css';
import axios from 'axios';

export default function Task({}) {
  const loggedInUser = localStorage.getItem('loggedInUser');
  const [taskValues, setTaskValues] = useState({
    task: '',
    userStory: '',
    createdBy: loggedInUser || 'user1',
    status: 'New',
  });

  const [allTask, setAllTask] = useState([{}]);
  const [assigned, setAllAssign] = useState([]);
  const [allStories, setAllStories] = useState([{}]);

  const assignedUserStories = allStories.filter((story) => {
    return assigned.some(({ user_story_id }) => user_story_id === story._id);
  });

  const handleInputChange = (event) => {
    const { name, value } = event.target;
    setTaskValues({ ...taskValues, [name]: value });
  };

  useEffect(() => {
    axios.get('http://localhost:9000/getTaskList').then(function (response) {
      const Taskdata = response.data;
      setAllTask(Taskdata);
    });

    axios.get('http://localhost:9000/getUserstory').then(function (response) {
      const Allstories = response.data;
      setAllStories(Allstories);
    });

    axios.get('http://localhost:9000/getAssignedstories').then(function (response) {
      const Allassignedstories = response.data;
      setAllAssign(Allassignedstories);
    });
  }, []);

  const handleSubmit = (event) => {
    event.preventDefault();
    axios.post('http://localhost:9000/createTask', taskValues)
      .then((res) => {
        if (res.data) {
          alert('Task creation Successful');
          setTaskValues({
            task: '',
            userStory: '',
            createdBy: loggedInUser || 'user1',
            status: 'New',
          });
        }
      })
      .catch((err) => {
        alert('Error in creating the task');
      });
  };

  return (
    <div className="container mt-5">
      <div className="row justify-content-center">
        <div className="col-md-6 col-lg-4">
          <div className="card">
            <div className="card-body">
              <h2 className="card-title">Create a New Task</h2>
              <form onSubmit={handleSubmit}>
                <div className="form-group">
                  <label>Task:</label>
                  <textarea
                    className="form-control"
                    name="task"
                    value={taskValues.task}
                    onChange={handleInputChange}
                    required
                  />
                </div>

                <div className="form-group">
                  <label>User Story:</label>
                  <select
                    className="form-control"
                    name="userStory"
                    value={taskValues.userStory}
                    onChange={handleInputChange}
                    required
                  >
                    <option value="">Select a User Story</option>
                    {assignedUserStories.map((story) => (
                      <option key={story._id} value={story._id}>
                        {story.user_story}
                      </option>
                    ))}
                  </select>
                </div>

                <div className="form-group">
                  <label>Created by:</label>
                  <select
                    className="form-control"
                    name="createdBy"
                    value={taskValues.createdBy}
                    onChange={handleInputChange}
                  >
                    <option value="user1">User 1</option>
                    <option value="user2">User 2</option>
                    <option value="user3">User 3</option>
                  </select>
                </div>

                <div className="form-group">
                  <label>Status:</label>
                  <select
                    className="form-control"
                    name="status"
                    value={taskValues.status}
                    onChange={handleInputChange}
                  >
                    <option value="New">New</option>
                    <option value="In Progress">In Progress</option>
                    <option value="Awaiting Confirmation">Awaiting Confirmation</option>
                    <option value="Completed">Completed</option>
                  </select>
                </div>

                <button type="submit" className="btn btn-primary btn-block">
                  Create Task
                </button>
              </form>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 07:45:54