基于输入的每个字母过滤数组

IT技术 arrays reactjs jsx
2021-05-09 17:40:16

我正在根据文本框的输入过滤一组学生。当你输入名字时,我怎样才能让这个工作向学生展示?我的解决方案有效,但显然,如果您要退格,则不会重新填充学生数组。我怎样才能在您输入学生姓名时进行过滤,并在退格时重新填充数组?

function App() {
  const [student, setStudent] = useState([]);

  useEffect(() => {
    fetch(api)
      .then((response) => response.json())
      .then((result) => {
        setStudent(result.students);
        
      })
      .catch((err) => {
        console.error(err);
      });
  }, [setStudent]);

  const filter = (e) => {
    for (let i = 0; i < student.length; i++) {
      const searchedStudent = student.filter((name) => {
        return name.firstName.toLowerCase().includes(e.target.value);
      });

      setStudent(searchedStudent);
    }
  };

  return (
    <>
      <input
        placeholder="Search by name"
        type="text"
        className="filter-students"
        onChange={filter}
      />
      {student.map((students) => {
        let total = 0;
        for (let i = 0; i < students.grades.length; i++) {
          total += parseInt(students.grades[i]);
        }

        const average = total / students.grades.length;
        console.log(average);

        return (
          <ul className="student-container">
            <img className="student-img" src={students.pic} />

            <div className="student-column">
              <li className="student-item">
                {" "}
                {students.firstName} {students.lastName}
              </li>
              <li className="student-item">Email: {students.email}</li>
              <li className="student-item">Company: {students.company}</li>
              <li className="student-item">Skill: {students.skill}</li>

              <li className="student-item">Average: {average}%</li>
            </div>
          </ul>
        );
      })}
    </>
  );
}
2个回答

问题是student每次<input>更改时状态都会更新

请注意,将结果过滤为来自原始数据派生数据。

因此,无需将过滤/导出的结果存储为状态。

相反,您需要为用于过滤的文本设置另一个状态

const [student, setStudent] = useState([]);
const [filter, setFilter] = useState(""); // state for the text filter

<input
  placeholder="Search by name"
  type="text"
  className="filter-students"
  onChange={(e) => setFilter(e.target.value)}
/>

{students
  .filter((name) => name.firstName.toLowerCase().includes(filter)) // use filter state
  .map(/* Add elements here */)
}

不要过滤您的状态并将其保存回自身,这不允许您回到原始状态。相反,在渲染状态时使用单独的状态片段来保存过滤器值和过滤器内联,这样您就可以student通过过滤保持数据完整和不变。

function App() {
  const [student, setStudent] = useState([]);
  const [filterValue, setfilterValue] = useState(""); // <-- filter state

  return (
    <>
      <input
        placeholder="Search by name"
        type="text"
        className="filter-students"
        onChange={(e) => setFilterValue(e.target.value)} // <-- update filter state
      />
      {student
        .filter((name) => { // <-- filter inline
          return name.firstName.toLowerCase().includes(e.target.value);
        })
        .map((students) => {
          let total = 0;
          for (let i = 0; i < students.grades.length; i++) {
            total += parseInt(students.grades[i]);
          }

          const average = total / students.grades.length;
          console.log(average);

          return (
            <ul className="student-container">
              <img className="student-img" src={students.pic} />

              <div className="student-column">
                <li className="student-item">
                  {" "}
                  {students.firstName} {students.lastName}
                </li>
                <li className="student-item">Email: {students.email}</li>
                <li className="student-item">Company: {students.company}</li>
                <li className="student-item">Skill: {students.skill}</li>

                <li className="student-item">Average: {average}%</li>
              </div>
            </ul>
          );
        })}
    </>
  );
}