#reactjs #search #filter #react-hooks
Вопрос:
Я создаю простой динамический поисковый фильтр, который отфильтровывает данные, но не точно по имени и фамилии. Мне нужно, чтобы это было точно по имени и фамилии. Например, если я наберу «кому» и имя, например «том», или фамилию, например «толлисон».
Вот компонент:
import React, { useState, useEffect } from "react"
import SearchBar from "./components/SearchBar"
import axios from "axios"
import "./App.css"
function App() {
const [students, setStudents] = useState(null)
const [searchTerm, setSearchTerm] = useState("")
useEffect(() => {
const fetchStudents = async () => {
const result = await axios("https://api.hatchways.io/assessment/students")
setStudents(result.data.students)
}
fetchStudents()
}, [])
const convertStudentGrades = (grades) =>
grades.map((grade) => parseInt(grade))
const getStudentAverage = (grades) =>
grades.reduce((sum, elem) => sum elem, 0) / grades.length
const capitalizeFullName = (first, last) => (
<span>{`${first.toUpperCase()} ${last.toUpperCase()}`}</span>
)
return (
<div className='container'>
<input type="text" value={searchTerm} onChange={e => setSearchTerm(e.target.value)} placeholder="Search..." />
{students amp;amp; students.filter(student => {
if (searchTerm == "") {
return student
} else if (student.firstName[0].includes(searchTerm.toLowerCase()) || student.lastName.includes(searchTerm.toLowerCase())) {
return student
}
}).map(student => (
<div className='row' key={student.id}>
<div className='student-image'>
<img src={student.pic} alt='' />
</div>
<div className='student-info'>
<h1>
<span>
{capitalizeFullName(student.firstName, student.lastName)}
</span>
</h1>
<p>Email: {student.email}</p>
<p>Company: {student.company}</p>
<p>Skill: {student.skill}</p>
<p>
Average:{" "}
{getStudentAverage(convertStudentGrades(student.grades))}
</p>
</div>
</div>
))}
</div>
)
}
export default App
Я также хотел бы переместить этот уродливый метод фильтрации в JSX в метод, чтобы немного его очистить.
Ответ №1:
Вам нужно использовать startsWith
вместо contains
.
const filteredStudent = () => {
return students amp;amp; searchTerm !== "" ? students.filter(student => student.firstName[0].startsWith(searchTerm.toLowerCase()) || student.lastName.startsWith(searchTerm.toLowerCase())) : students;
}
return (
<div className='container'>
<input type="text" value={searchTerm} onChange={e => setSearchTerm(e.target.value)} placeholder="Search..." />
{filteredStudent().map(student => (
<div className='row' key={student.id}>
<div className='student-image'>