我正在构建一个简单的动态搜索过滤器,它过滤掉数据,但不完全是通过姓和名。我需要准确地写出姓和名。例如,如果我输入"to",然后输入名字"tom"或姓氏"tollison"。
组件:
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 && 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中丑陋的过滤器方法移动到一个方法中,以清理它。
您需要使用startsWith
而不是contains
。
const filteredStudent = () => {
return students && 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'>
在我的情况下,我是从mongodb获取我的数据。我将联系人存储为firstName和lastName字段。在我的反应表组件中,我将获取数据并将其命名为"contacts">
然后像下面这样传递我的联系人到我的反应表
<Fragment>
<Card>
<AdvanceTableWrapper
columns={columns}
data={contacts} // <--- here is my redux data
sortable
pagination
perPage={50}
selection
selectionColumnWidth={25}
selectionCallback={selectionCallback}
>
<Row className="flex-start-center mb-3 ml-1">
<Col>
<AdvanceTableSearchBox table/>
</Col>
</Row>
<AdvanceTable
table
headerClassName="bg-200 text-900 font-weight-bold text-nowrap align-middle"
rowClassName="btn-reveal-trigger border-top border-200 align-middle white-space-nowrap"
tableProps={{
striped: true,
className: 'fs--1 font-weight-bold overflow-hidden'
}}
/>
<div className="mt-3 mb-2 pr-2 pl-3 ">
<AdvanceTableFooter
rowCount={contacts?.length} // <-- again my redux data
table
rowInfo
navButtons
rowsPerPageSelection
/>
</div>
</AdvanceTableWrapper>
</Card>
</Fragment>
为了一次搜索两列,我给对象添加了一个新属性,如下所示
const contacts = useSelector((state) => state.contacts)
const contactsTwo = contacts?.map((el) => { return {...el, name: el.firstName + " " + el.lastName }})
//
现在我只需添加一个新列并使用"d-none"隐藏
const columns = [
{
accessor: 'firstName',
Header: 'First Name',
Cell: firstNameFormatter
},
{
accessor: 'lastName',
Header: 'Last Name',
Cell: lastNameFormatter
},
{
accessor: 'name',
headerProps: {
className: "d-none"
},
cellProps: {
className: 'd-none',
}
},
];
现在当我搜索"Jane Doe"如果我在名字后面加一个空格,结果就会消失。