无法添加列表,REACT

Unable to add list, REACT

提问人:Hannan Yusuf Khan 提问时间:11/14/2023 最后编辑:halferHannan Yusuf Khan 更新时间:11/16/2023 访问量:51

问:

我在尝试更新我的列表时遇到了一个问题,我很快点击了表单中的元素。我的目的是从选定的表单元素中获取列表中添加的元素。我已经将我的源代码粘贴到这里。

APP.TSX

import { useState } from "react";
import StudentGradingEvaluationForm from "./assets/Components/StudentGradingEvaluationForm";
import { studentFormData } from "./assets/Components/StudentGradingEvaluationForm";
import GPACalculator from "./assets/Components/GPACalculator";
import CourseListwithGPA from "./assets/Components/CourseListwithGPA";

const App = () => {
  const [formData, setFormData] = useState<studentFormData | null>(null);
  const [isFormSubmitted, setFormSubmitted] = useState(true);
  const [messageAppear, setMessageAppear] = useState(false);
  const [gpa, setGpa] = useState<number>(0);
  const [gpaList, setGpaList] = useState([
    { id: 1, course: "", number: 0, gpa: 0 },
  ]);

  const handleFormSubmit = (data: studentFormData) => {
    if (data) {
      setFormData(data);
      setMessageAppear(true);
      // setFormSubmitted(true);
    }
  };
  const resetForm = () => {
    setFormData(null);
    setFormSubmitted(false);
  };

  const handleGpa = (gpa: number) => {
    setGpa(gpa);
  };

  return (
    <>
      <div style={{ textAlign: "center" }}>
        <h1>Student Grading Evaluation Form</h1>
      </div>
      {isFormSubmitted && (
        <>
          <StudentGradingEvaluationForm onSubmit={handleFormSubmit} />
        </>
      )}
      {messageAppear && (
        <div className="mt-3">
          <p>Form submitted successfully</p>
          <button onClick={resetForm} className="btn btn-outline-danger">
            Reset Form
          </button>
        </div>
      )}
      {formData && formData.course && (
        <>
          <GPACalculator
            name={formData.name}
            course={formData.course}
            number={formData.number}
          />
          <CourseListwithGPA
            students = {(student) => setGpaList([...students, {id: student.id, course: student.course, number: student.number, gpa: student.gpa}])}
          />
        </>
      )}
    </>
  );
};

export default App;
GPACalculator.tsx

interface Props {
  name: string;
  course: string;
  number: number;
}

const GPACalculator = ({ name, course, number }: Props) => {
  const calculateGPA = () => {
    if (number < 100 && number >= 80) return "4.0";
    else if (number < 80 && number >= 65) return "3.5";
    else if (number < 65 && number >= 55) return "3.0";
    else if (number < 55 && number >= 40) return "2.0";
    else return "FAIL";
  };
  return (
    <div>
      <h2>GPA Calculator Result for {name}</h2>
      <p>Course: {course}</p>
      <p>Number: {number}</p>
      <p>GPA: {calculateGPA()}</p>
    </div>
  );
};

export default GPACalculator;
StudentGradingEvaluationForm.tsx

import { z } from "zod";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import courses from "./Courses";

interface Props {
  onSubmit: (data: studentFormData) => void;
}

const schema = z.object({
  name: z.string().min(3),
  course: z.enum(courses),
  number: z.number().int().positive().max(100),
});

export type studentFormData = z.infer<typeof schema>;

const StudentGradingEvaluationForm = ({ onSubmit }: Props) => {
  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm<studentFormData>({
    resolver: zodResolver(schema),
  });
  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <div className="mb-3">
        <label htmlFor="name" className="form-label">
          Name of Student
        </label>
        <input
          {...register("name")}
          id="name"
          type="text"
          className="form-control"
        />
      </div>
      {errors.name && <p className="text-danger">{errors.name.message}</p>}
      <div className="mb-3">
        <label htmlFor="course" className="form-label">
          Select Course
        </label>
        <select {...register("course")} id="course" className="form-select">
          <option value="none">Select a course</option>
          {courses.map((course, index) => (
            <option key={index} value={course}>
              {course}
            </option>
          ))}
        </select>
        {errors.course && (
          <p className="text-danger">{errors.course.message}</p>
        )}
      </div>
      <div className="mb-3">
        <label htmlFor="number" className="form-label">
          Number
        </label>
        <input
          {...register("number", { valueAsNumber: true })}
          id="number"
          type="number"
          className="form-control"
        />
      </div>
      {errors.number && <p className="text-danger">{errors.number.message}</p>}
      <button type="submit" className="btn btn-primary">
        Submit
      </button>
    </form>
  );
};

export default StudentGradingEvaluationForm;
CourseListwithGPA.tsx

import { useState, useEffect } from "react";

interface StudentInfo {
  id: number;
  name: string;
  course: string;
  number: number;
}

interface StudentInfoWithGPA extends StudentInfo {
  gpa: number;
}

interface Props {
  students: (data: StudentInfoWithGPA) => void;
}

const CourseListwithGPA = ({ students }: Props) => {
  const [gpa, setGpa] = useState("");

  useEffect(() => {
    const calculatedGPA = calculateGPA();
    const newGpa = parseFloat(calculatedGPA[0]);
    if (newGpa !== parseFloat(gpa)) {
      setGpa(calculatedGPA.join(", "));
      // Replace onGpaChange with the function you want to call when the GPA changes
      // onGpaChange("", 0, newGpa);
      console.log("GPA changed to:", newGpa);
    }
  }, [students, gpa]);

  const calculateGPA = () => {
    return students.map((student) => {
      if (student.number < 100 && student.number >= 80) return "4.0";
      else if (student.number < 80 && student.number >= 65) return "3.5";
      else if (student.number < 65 && student.number >= 55) return "3.0";
      else if (student.number < 55 && student.number >= 40) return "2.0";
      else return "FAIL";
    });
  };

  return (
    <>
      <div className="mb-3">
        <h1>Report Card of {students.map((student) => student.name)}</h1>
      </div>
      <table className="table table-bordered">
        <thead>
          <tr>
            <td>Name of Course</td>
            <td>Marks Obtained</td>
            <td>GPA</td>
          </tr>
        </thead>
        <tbody>
          {students.map((student) => (
            <tr key={student.id}>
              <td>{student.course}</td>
              <td>{student.number}</td>
              <td>{gpa}</td>
            </tr>
          ))}
        </tbody>
      </table>
    </>
  );
};

export default CourseListwithGPA;
Courses.ts


const courses = [
  "Mechanics of Materials - I",
  "Fluid Dynamics - I",
  "Ordinary Differential Equations",
  "Thermodynamics - II",
  "Basic Electrical and Electronics Engineering",
] as const;

export default courses;

我的目的是在列表中展示所有具有 GPA 的课程。作为参考,我添加了屏幕截图。enter image description here

如您所见,对象仍为空。我需要有人调整我的代码,以便每当我更新我的表单时,它都会被添加到列表中。

但我不能这样做。我正在使用以下依赖项:

npm 创建 [email protected] npm i 引导程序 npm i [电子邮件保护] npm i [电子邮件保护] npm i @hookform/[电子邮件保护]

reactjs typescript 列表 前端 渲染

评论

1赞 Shaavin 11/14/2023
我不太清楚你要解决什么问题,这里有太多的代码让我无法理解发生了什么。您是否可以尝试专注于创建一个最小的、可重复的示例,该示例仅包含与您的问题最相关的部分?如果你提供一些例子,说明你希望得到什么信息,在哪里,以及你已经尝试过什么,以及为什么你认为这些方法不起作用,这也会有所帮助。
0赞 Hannan Yusuf Khan 11/14/2023
@Shaavin 我已经编辑了我的帖子并添加了屏幕截图。我希望现在这更加简洁明了。
0赞 Shaavin 11/14/2023
同样,这里的代码太多了,任何人都无法帮助你。我可以猜到你想完成什么,但你对问题的描述太短,无法理解感知到的问题在哪里。请仔细查看 Stack Overflow 如何寻求帮助指南并更新您的帖子 - 特别关注在发布任何代码之前引入问题和帮助他人重现问题部分。仅仅复制粘贴整个程序并添加屏幕截图不足以让我们理解。

答: 暂无答案