渲染父组件初始化子组件的状态

时间:2021-04-06 07:34:54

标签: reactjs react-hooks components

我想创建一个 GPA 计算器。我有 3 个组件 GPACalculator、Semester 和 CourseInput。 当课程信息发生变化时,应更新学期状态(课程列表及其信息)和包含所有学期的数组(在 GPACalculator 中)以反映更改。

CourseInput 看起来像这样:

import {useState} from 'react',
import {TableRow, TableCell, TextField} from '@material-ui/core';

export default function CourseInput(props) {
  const [course, setCourse] = useState(
  {
    id: props.id,
    name: props.name, 
    credit: props.credit, 
    marksOver100: props.marksOver100, 
    grade: props.grade, 
    semesterNumber: props.number: '',
  }
 );
  
  console.log("rendered course"):

  const handleChange = event => {
    const {name, value} = event.target;
    setCourse(prevCourse => (
      {
        ...prevCourse,
        [`${name}`]: value
      }
    ));
    console.log(course);

    // call function to change the state of the semester
    // problem lies within this function
   props.handleCourseInfoChange(course);
  }

  return ( 
    <>
     <TableRow>
       <TableCell>
         <TextField name="name" value={course.name} size="small" variant="outlined" onchange={handleChange} />
       </TableCell>
       <TableCell>
         <TextField name="credit" value={course.credit} size="small" variant="outlined" onchange={handleChange} />
       </TableCell>
       <TableCell>
         <TextField name="marksOver100" value={course.marksOver100} size="small" variant="outlined" onchange={handleChange} />
       </TableCell>
       <TableCell>{course.grade}</TableCell>
     </TableRow>
   </>
  );
}

学期组成

export default function Semester(props) {
  // Each semester is initialised with 2 courses
  const initialCourses = [{ id: '1', name: '', credit: '', marksOver100: '', grade: '-', semesterNumber: props.number }, { id: '2', name: '', credit: '', marksOver100: '', grade: '-', semesterNumber: props.number }];

  const [semester, setSemester] = useState(
  { number: props.number, gpa: props.gpa, courses: initialCourses });

  console.log("rendered semester");

  const handleCourseInfoChange = modifiedCourse => {
    // First remove the modified course from the list of courses
    var unchangedCourses = semester.courses.filter(course => course.id !== modifiedCourse.id); 
    // now add the modified course with it's new info unchangedCourses.push(modifiedCourse);
    const newCourses = unchangedCourses;

    // First problem lies here
    setSemester(prevState => ({
     ...prevState, 
     courses: newCourses
    });

    // Now update the array of semesters
    props.refreshSemesters(semester);

  return (
    <>
      ...
      <span>{semester.number}</span>
      ...
      {semester.courses.map(
      course => (
        <CourseInput
          key={course.id}
          id={course.id}
          name={course.name}
          grade={course.grade}
          marksOver100={course.marksOver100}
          credit={course.credit}
          semesterNumber={course.semesterNumber}
          semester={semester}
          handleCourseInfoChange={handleCourseInfoChange} 
        />
       )
     )}
     ...
     <span>GPA: {props.gpa}</span>
   </>
  );
}

现在在主要组件GPACalculator

function GPACalculator() {
  const [semesters, setSemesters] = useState([]);
  console.log("rendered semesters");

  // Function to add a semester, functions correctly
  const addSemester = () => {
    let numSemesters = semesters.length;
    let semesterNum;
    
    if (numSemesters !== 0)
      semesterNum = semesters[numSemesters-1].number + 1;
    else semesterNum = 1;
    
    setSemesters(prevState => ([
      ...prevState,
      {number: semesterNum, gpa: '-', courses: initialCourses}
    ]));
}
    
    // This function has a prob I don't know 
  const refreshSemesters = modifiedSemester => {
    var unmodifiedSemesters = semesters.filter(semester => semester.number !== modifiedSemester.number);
    unmodifiedSemesters.push(modifiedSemester);
    const newSemesters = unmodifiedSemesters;
    setSemesters(newSemesters);
}

  return (
   <>
     ...
     {semesters.map(
       semester => 
        <>
         <span>{semester.number}</span> 
         <Semester key={semester.number} number={semester.number} gpa={semester.gpa} semesters={semesters} refreshSemesters={refreshSemesters} />
         <br />
       </>
      )}
    <button onClick={addSemester}>Add a semester</button>
   ...
 </>
);

当我在课程表单的任何输入框中输入一个字符时,

  • 焦点离开输入框
  • 输入框中没有显示任何字符
  • 学期编号发生变化。例如,如果我有 3 个学期(编号为 1 到 3),当我在前两个学期中插入一些内容时,所有学期的编号都会更改!我不明白为什么,可能与重新渲染所有学期有关。

0 个答案:

没有答案