我怎样才能让每个学生添加自己的标识符标签?

How can I make each student add their own identifier tags?

我正在阅读 API 并将每个学生的信息显示到网络浏览器上。 我的目标是让每个学生都有一个文本输入字段,您可以在其中为特定学生添加'tag'。

我的问题: 目前,我已经给每个学生一个文本输入字段,但是当我为任何一个学生输入 'tag' 时,它只会添加标签给第一个学生。


Home.jsx

import axios from 'axios';
import { useState, useEffect } from 'react';
import Students from '../components/Students';
import styles from "./Home.module.css";

const Home = () => {

  const [students, setStudents] = useState([]);
  const [filteredStudents, setFilteredStudents] = useState([]);

  const fetchStudents = async () => {
    const response = await axios.get(`https://api.hatchways.io/assessment/students`);
    setStudents(response.data.students);
    setFilteredStudents(response.data.students);
    console.log(response.data.students);

  }

  const searchStudentName = async (searchName) => { 
    const searchNameFiltered = searchName.toLowerCase();
    console.log(searchNameFiltered);
    
    if (searchNameFiltered === "") {
      fetchStudents();
      return;
    }

    var newArray = await students.filter((student) => {
      return student.firstName.toLowerCase().includes(searchNameFiltered)
      || student.lastName.toLowerCase().includes(searchNameFiltered);
    })

    await setFilteredStudents(newArray);
  }

  useEffect(() => {
    fetchStudents();

  }, [])

  return(
    <>
      <div>
        <input className={styles.nameSearchInput} type="text" placeholder="Search by name" onChange={(event) => searchStudentName(event.target.value) }/>
        {filteredStudents.map((student) => (
          <Students key={student.id} student={student} />
        ))}
      </div>
    </>
  )
  
}

export default Home;

Students.jsx

import { useState } from 'react';
import styles from "../views/Home.module.css";
import { v4 as uuidv4 } from 'uuid';
import AddIcon from '@mui/icons-material/Add';
import RemoveIcon from '@mui/icons-material/Remove';

const Students = ({student}) => {

  const [isShown, setIsShown] = useState(true);

  const findAverageGrade = arr => {
    let sum = 0;
    for (let i = 0; i < arr.length; i++) {
      sum += parseInt(arr[i]);
    }
    return sum / arr.length;
  }

  const addTag = (event) => {
    if (event.key === 'Enter') {
      document.getElementById("tag-output").innerHTML += `
        <p id="tag">${event.target.value}</p>
      `;
      document.getElementById("tag-input").value = "";
    }    

  }

  return (
    <div key={student.email} className={styles.studentItem}>
      <img className={styles.studentImage} src={student.pic} />
      <div className={styles.studentInfoContainer}>
        <div className={styles.studentHeader}>
          <p className={styles.studentName}>{student.firstName.toUpperCase()} {student.lastName.toUpperCase()}</p>
          <button className={styles.expandBtn} onClick={() => {
            setIsShown(!isShown);
          }}>
            { isShown ? <AddIcon className={styles.expandBtn} /> : <RemoveIcon className={styles.expandBtn} /> }
          </button>
        </div>
        <ul className={styles.studentDetail}>
          <li>Email: {student.email}</li>
          <li>Company: {student.company}</li>
          <li>Skill: {student.skill}</li>
          <li>Average: {findAverageGrade(student.grades)}%</li>

          {!isShown ? <div>
            <table className={styles.gradesTable}>
              <tbody>
                {student.grades.map((grade) => (
                  <tr key={uuidv4()}>
                    <td>Test</td>
                    <td>{grade}%</td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
          : null }
          <div id="tag-output"></div>
          <input id="tag-input" className={styles.addTagInput} type="text" placeholder="Add a tag" onKeyPress={(e) => addTag(e)}/>
        </ul>
      </div>
    </div>
  )
}

export default Students;

使用数组状态并附加新值,如下所示

在此处播放实时代码live_demo

import React, { useState } from "react";

    export default function Main(props) {
      const [tags, setTags] = useState([]);
      return (
        <div className="App">
          <input
            type="text"
            onKeyDown={(e) => {
              if (e.key === "Enter" && !e.shiftKey && e.target.value !== "") {
                let val = e.target.value;
                e.target.value = "";
                setTags([...tags, val]);
              }
            }}
          />
          <div className="tags">
            <ol className="each-tag">
              {tags.map((tag, i) => {
                return <li key={i}>{tag}</li>;
              })}
            </ol>
          </div>
        </div>
      );
    }