无法 运行 单个对象的唯一迭代

Unable to run unique iterations for individual objects

我试图在页面上显示 25 个条目(namecompanyskill 等),但无法获取唯一信息。

即我一遍又一遍地只看到第一个条目。我不确定如何重申新信息,因为它只会是 response.data.students[0].

这是我的代码现在的样子,其中的映射是:

export default function StudentList() {
  let [loaded, setLoaded] = useState(false);

  let [students, setStudent] = useState(" ");
  function doInfo(response) {
    console.log(response.data);
    setStudent(response.data.students);
    setLoaded(true);
  }

  if (loaded) {
    return (
      <div className="StudentList">
        <div className="row">
          <div className="col">
            {students.map(function (data, index) {
              return <StudentInfo data={data} key={index} />;
            })}
          </div>
        </div>
      </div>
    );
  } else {
    let url = "https://api.hatchways.io/assessment/students";
    axios.get(url).then(doInfo);
  }
}

这里是StudentInfo组件的代码供参考:

export default function StudentInfo() {
  const [info, addInfo] = useState(" ");

  function setInfo(response) {
    addInfo({
      number: response.data.students[0].id,
      first: response.data.students[0].firstName,
      last: response.data.students[0].lastName,
      email: response.data.students[0].email,
      company: response.data.students[0].company,
      skill: response.data.students[0].skill,
      average: response.data.students[0].grades[0],
    });
  }

  let url = "https://api.hatchways.io/assessment/students";
  axios.get(url).then(setInfo);

  return (
    <div className="StudentInfo">
      <h1>{info.number}.</h1>
      <h2>
        Name: {info.first} {info.last}
      </h2>
      <h2>Email: {info.email}</h2>
      <h2>Company: {info.company}</h2>
      <h2>Skill: {info.skill}</h2>
      <h2>Average: {info.average}</h2>
    </div>
  );
}

谁能帮我编写代码,使其遍历所有 25 个条目,而不仅仅是第一个条目?

尝试这样的事情:

  • 设置数组进入状态
  • useEffect(..., []) 触发数据加载(仅一次)。
  • 在映射的数组扩展上设置 key={id}(或者出于不适合这种特殊情况的充分理由而做出反应)。
function StudentList() {
  const [students, setStudents] = useState(null);
 
  useEffect(() => {
    const url = "https://api.hatchways.io/assessment/students";
    axios.get(url).then(({ data: { students } }) => setStudents(students));
  }, []);

  if (!students) {
     return ( <div>loading...</div> );
  }

  return (
    <div className="StudentList">
      <div className="row">
        <div className="col">
          { students.map(student => ( <StudentInfo key={student.id} info={student} /> )) }
        </div>
      </div>
    </div>
  );
}

StudentInfo不需要重新加载任何东西,只需格式化已经获取的数据

export default function StudentInfo({ info }) { // edit: previous had { props: { info } } here, oops
  return (
    <div className="StudentInfo">
      <h1>{info.number}.</h1>
      <h2>
        Name: {info.first} {info.last}
      </h2>
      <h2>Email: {info.email}</h2>
      <h2>Company: {info.company}</h2>
      <h2>Skill: {info.skill}</h2>
      <h2>Average: {info.average}</h2>
    </div>
  );
}

您的子组件 (StudentInfo) 没有使用您的父组件传递的数据。不要再次调用 API 获取学生信息,而是使用 prop.

export default function StudentInfo({ data }) {
  const info = {
    number: data.id,
    first: data.firstName,
    last: data.lastName,
    email: data.email,
    company: data.company,
    skill: data.skill,
    average: data.grades[0]
  };

  return (
    <div className="StudentInfo">
      <h1>{info.number}.</h1>
      <h2>
        Name: {info.first} {info.last}
      </h2>
      <h2>Email: {info.email}</h2>
      <h2>Company: {info.company}</h2>
      <h2>Skill: {info.skill}</h2>
      <h2>Average: {info.average}</h2>
    </div>
  );
}

问题

I only see the first entry over and over. I'm not sure how to reiterate new information since it's only going to be response.data.students[0]

这是因为子组件 StudentInfo 是 re-requesting 学生数据并且只访问每个映射学生的第 0 个元素。

export default function StudentInfo() {
  const [info, addInfo] = useState(" ");

  function setInfo(response) {
    addInfo({
      number: response.data.students[0].id, // <-- (2) update state to first student!
      first: response.data.students[0].firstName,
      last: response.data.students[0].lastName,
      email: response.data.students[0].email,
      company: response.data.students[0].company,
      skill: response.data.students[0].skill,
      average: response.data.students[0].grades[0],
    });
  }

  let url = "https://api.hatchways.io/assessment/students";
  axios.get(url).then(setInfo); // <-- (1) fetch all students!

  return (
    <div className="StudentInfo">
      <h1>{info.number}.</h1>
      <h2>
        Name: {info.first} {info.last}
      </h2>
      <h2>Email: {info.email}</h2>
      <h2>Company: {info.company}</h2>
      <h2>Skill: {info.skill}</h2>
      <h2>Average: {info.average}</h2>
    </div>
  );
}

解决方案

您只需在父组件中请求一次学生评估,并将相关数据作为道具传递。

示例:

function StudentList() {
  const [loaded, setLoaded] = useState(false);

  const [students, setStudent] = useState([]);

  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await axios.get(url);
        console.log(response.data);
        setStudent(response.data.students);
      } catch (error) {
        console.error(error);
      } finally {
        setLoaded(true);
      }
    };

    fetchData();
  }, []);

  return loaded ? (
    <div className="StudentList">
      <div className="row">
        <div className="col">
          {students.map(function (data) {
            return <StudentInfo data={data} key={data.id} />;
          })}
        </div>
      </div>
    </div>
  ) : (
    "Fetching Student Assessments."
  );
}

...

function StudentInfo({ data }) {
  const name = [data.firstName, data.lastName].join(" ");
  const average = (
    data.grades.reduce((total, grade) => total + Number(grade), 0) /
    data.grades.length
  ).toFixed(2);
  
  return (
    <div className="StudentInfo">
      <h1>{data.id}.</h1>
      <h2>Name: {name}</h2>
      <h2>Email: {data.email}</h2>
      <h2>Company: {data.company}</h2>
      <h2>Skill: {data.skill}</h2>
      <h2>Average: {average}</h2>
    </div>
  );
}