You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ReactJS如何使用两个搜索框对同一份数据按姓名和笔记过滤

React 学生数据双条件过滤实现方案

1. 核心思路

通过两个状态分别存储两个搜索框的输入值,用useMemo做记忆化计算实时生成过滤结果,过滤逻辑通过两个独立匹配规则组合实现,天然覆盖你提出的4种过滤场景。

2. 完整实现代码

import { useState, useMemo } from 'react'

// 学生数据接口定义
interface StudentInterface {
  email: string;
  firstName: string;
  notes: string [];
  id: string;
  lastName: string;
}

// 示例组件
const StudentFilter = () => {
  // 原始学生数据,可替换为接口请求返回的数据
  const [originalStudents, setOriginalStudents] = useState<StudentInterface[]>([])
  // 姓名搜索关键词
  const [nameQuery, setNameQuery] = useState<string>('')
  // 笔记搜索关键词
  const [noteQuery, setNoteQuery] = useState<string>('')

  // 过滤后结果,依赖变化时才重新计算
  const filteredStudents = useMemo(() => {
    // 统一转小写实现不区分大小写匹配
    const formatNameQuery = nameQuery.trim().toLowerCase()
    const formatNoteQuery = noteQuery.trim().toLowerCase()

    return originalStudents.filter(student => {
      // 姓名匹配规则:无输入时默认匹配所有,否则模糊匹配全名
      const nameMatch = !formatNameQuery
        ? true
        : `${student.firstName} ${student.lastName}`.toLowerCase().includes(formatNameQuery)
      
      // 笔记匹配规则:无输入时默认匹配所有,否则匹配笔记数组任意一项
      const noteMatch = !formatNoteQuery
        ? true
        : student.notes.some(note => note.toLowerCase().includes(formatNoteQuery))
      
      // 同时满足两个匹配规则才返回
      return nameMatch && noteMatch
    })
  }, [originalStudents, nameQuery, noteQuery])

  return (
    <div className="filter-container">
      {/* 姓名搜索框 */}
      <input
        type="text"
        placeholder="按姓名搜索"
        value={nameQuery}
        onChange={(e) => setNameQuery(e.target.value)}
      />
      {/* 笔记搜索框 */}
      <input
        type="text"
        placeholder="按笔记内容搜索"
        value={noteQuery}
        onChange={(e) => setNoteQuery(e.target.value)}
      />

      {/* 渲染过滤后的学生列表 */}
      <ul className="student-list">
        {filteredStudents.map(student => (
          <li key={student.id}>
            <p>姓名:{student.firstName} {student.lastName}</p>
            <p>邮箱:{student.email}</p>
            <div>
              笔记:
              <ul>
                {student.notes.map((note, index) => (
                  <li key={index}>{note}</li>
                ))}
              </ul>
            </div>
          </li>
        ))}
      </ul>
    </div>
  )
}

export default StudentFilter

3. 逻辑说明

  • 姓名匹配:将学生的firstName和lastName拼接为完整姓名,忽略大小写模糊匹配输入关键词,关键词为空时默认匹配所有学生
  • 笔记匹配:遍历学生的notes数组,只要有任意一项忽略大小写包含搜索关键词即匹配,关键词为空时默认匹配所有学生
  • 组合规则:只有同时满足当前生效的匹配规则的学生才会被返回,自动覆盖单条件过滤、双条件过滤、无输入返回全量数据的所有场景

可选优化

如果学生数据量较大,可以给搜索输入添加防抖逻辑,延迟过滤计算的触发时机,提升输入流畅度,比如使用useDebounce钩子封装搜索关键词,将防抖后的值作为useMemo的依赖即可。

界面参考

两个搜索框界面示意图

内容的提问来源于stack exchange,提问作者Edzio Auditore

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 19:15:04