【问题标题】:React js : Invalid attempt to spread non-iterable instance. In order to be iterable, non-array objects must have a [Symbol.iterator]() methodReact js:传播不可迭代实例的无效尝试。为了可迭代,非数组对象必须有一个 [Symbol.iterator]() 方法
【发布时间】:2021-03-06 14:16:25
【问题描述】:

我正在尝试制作需要字母等级和学分来计算 gpa 的 gpa 计算器。字母等级有助于查找分数,例如 A+ 表示 4.00 或 D 表示 1.00。

问题是,当我多次更改成绩值时,我得到了这个错误,我的错误行总是在 handlePoints()函数中,确切的行是

const newPoints = [...points];
newPoints[i] = 4;
setPoints(...newPoints);

下面是我所有的代码

import React, { useEffect, useState } from "react";
import SgpaComponent from "./SgpaComponent";

function Sgpa() {
  const [subjects, setSubjects] = useState(["Subject Name"]);
  const [grades, setGrades] = useState(["A+"]);
  const [points, setPoints] = useState([4]);
  const [credits, setCredits] = useState([3]);
  const [sgpa, setSgpa] = useState();
  function handleAdd() {
    setSubjects((prev) => [...prev, "Subject Name"]);
    setGrades((prev) => [...prev, "A+"]);
    setPoints((prev) => [...prev, 4]);
    setCredits((prev) => [...prev, 3]);
  }
  useEffect(() => {
    handlePoints();
    calcSgpa();
  });

  function calcSgpa() {
    let totalCredits = 0;
    let totalPoints = 0;
    for (let i = 0; i < credits.length; i++) {
      totalCredits += credits[i];
    }
    for (let i = 0; i < points.length; i++) {
      totalPoints += points[i];
    }
    setSgpa((totalCredits * totalPoints) / totalCredits);
  }

  function handleGrade(event, i) {
    let newGrades = [...grades];
    newGrades[i] = event.target.value;
    setGrades(...newGrades);
    
  }
  function handleCredits(event, i) {
    let newCredits = [...credits];
    newCredits[i] = event.target.value;
    setCredits(...newCredits);
  }

  function handlePoints() {
    for (let i = 0 ; i<grades.length ; i++){
    if (grades[i] === "A+" || grades[i] === "A") {
      const newPoints = [...points];
      newPoints[i] = 4;
      setPoints(...newPoints);
    }
    if (grades[i] === "A-") {
      let newPoints = [...points];
      newPoints[i] = 3.67;
      setPoints(...newPoints);
    }
    if (grades[i] === "B+") {
      let newPoints = [...points];
      newPoints[i] = 3.33;
      setPoints(...newPoints);
    }

    if (grades[i] === "B") {
      let newPoints = [...points];
      newPoints[i] = 3.0;
      setPoints(...newPoints);
    }
    if (grades[i] === "B-") {
      let newPoints = [...points];
      newPoints[i] = 2.67;
      setPoints(...newPoints);
    }
    if (grades[i] === "C+") {
      let newPoints = [...points];
      newPoints[i] = 2.33;
      setPoints(...newPoints);
    }
    if (grades[i] === "C") {
      let newPoints = [...points];
      newPoints[i] = 2.0;
      setPoints(...newPoints);
    }
    if (grades[i] === "C-") {
      let newPoints = [...points];
      newPoints[i] = 1.67;
      setPoints(...newPoints);
    }
    if (grades[i] === "D+") {
      let newPoints = [...points];
      newPoints[i] = 1.37;
      setPoints(...newPoints);
    }
    if (grades[i] === "D") {
      let newPoints = [...points];
      newPoints[i] = 1.0;
      setPoints(...newPoints);
    }
    if (grades[i] === "F") {
      let newPoints = [...points];
      newPoints[i] = 0;
      setPoints(...newPoints);
    }
    }
  }

  return (
    <>
      <h3>Sgpa : {sgpa}</h3>
      {subjects.map((subject, i) => {
        return (
          <SgpaComponent
            subject={subject}
            grade={grades[i]}
            credit={credits[i]}
            point={points[i]}
            index={i}
            handleGrade={handleGrade}
            handleCredits={handleCredits}
          />
        );
      })}
      <button onClick={handleAdd}>+</button>
    </>
  );
}

export default Sgpa;

【问题讨论】:

  • setPoints(...newPoints); 应该是setPoints(newPoints);

标签: javascript reactjs use-effect use-state


【解决方案1】:

当你像setPoints(...newPoints); 这样设置你的状态时,你实际上会导致状态从持有一个数组变为一个元素。所以下次你调用它时,你没有数组,因此你不能传播它

设置状态的正确方法是使用setPoints(newPoints)setGrades(...newGrades);setCredits(...newCredits); 需要做同样的事情,这将变为 setGrades(newGrades);setCredits(newCredits);

此外,setPoints(...newPoints); 的所有实例都应在您的代码中更新为 setPoints(newPoints)

【讨论】:

    【解决方案2】:

    问题出在这一行(重复多次):

    setPoints(...newPoints)
    

    应该是:

    setPoints(newPoints)
    

    newPoints 是一个数组,其中包含您要分配给 points 状态变量的新数组 - 因此使用该数组作为参数调用 setPoints 正是您想要的。

    而当您使用“spread”运算符时,您调用setPoints 时带有多个参数,一个用于数组中的每个元素。由于 React 的“状态更新”函数只接受一个参数,因此您实际上将状态设置为数组的第一个元素。由于它本身不是一个数组,这意味着下次执行此代码时,它会尝试在诸如4 这样的普通数字上“传播”(使用...),因此会出现错误消息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-22
      • 2021-11-15
      • 1970-01-01
      • 1970-01-01
      • 2021-07-14
      • 2023-01-23
      • 2019-06-25
      • 1970-01-01
      相关资源
      最近更新 更多