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

React中搜索文本高亮失效问题求助

搜索结果文本高亮问题解决方案

问题根源

你的代码存在两个核心问题:

  • 仅在过滤逻辑里给字符串添加<mark>标签,但渲染时仍直接输出原始字段值,完全没用到处理后的高亮文本
  • React中直接插入HTML字符串不会自动解析,就算生成了带<mark>的字符串,放在{}里只会显示纯文本标签

修复步骤

1. 编写高亮处理函数

先实现一个工具函数,将字符串中匹配搜索词的部分用<mark>标签包裹:

const highlightMatch = (text, searchTerm) => {
  if (!searchTerm.trim()) return text;
  const regex = new RegExp(`(${searchTerm})`, 'gi');
  return text.replace(regex, '<mark>$1</mark>');
};

该函数会忽略大小写,把所有匹配的子串替换为带高亮标签的版本。

2. 简化过滤逻辑

过滤阶段只需判断是否包含搜索词,无需添加<mark>,简化后的过滤代码:

onlineUserData?.filter(onlineUserInfo => {
  if (!searchTerm.trim()) return true;
  const lowerTerm = searchTerm.toLowerCase().replace(/\s+/g, '');
  return (
    onlineUserInfo.userName.toLowerCase().replace(/\s+/g, '').includes(lowerTerm) ||
    onlineUserInfo.userStandard.toLowerCase().replace(/\s+/g, '').includes(lowerTerm) ||
    onlineUserInfo.userRole.toLowerCase().replace(/\s+/g, '').includes(lowerTerm) ||
    onlineUserInfo.userEmail.toLowerCase().replace(/\s+/g, '').includes(lowerTerm) ||
    onlineUserInfo.loginTime.toLowerCase().replace(/\s+/g, '').includes(lowerTerm)
  );
})

3. 渲染时解析HTML

在map渲染阶段,使用dangerouslySetInnerHTML解析带<mark>的HTML字符串:

.map((onlineUserInfo, index) => (
  <tr key={index}>
    <td>{onlineUserInfo.serialNumber}.</td>
    <td dangerouslySetInnerHTML={{ __html: highlightMatch(onlineUserInfo.userName, searchTerm) }} />
    <td dangerouslySetInnerHTML={{ __html: highlightMatch(onlineUserInfo.userStandard || "N/A", searchTerm) }} />
    <td dangerouslySetInnerHTML={{ __html: highlightMatch(onlineUserInfo.userRole, searchTerm) }} />
    <td dangerouslySetInnerHTML={{ __html: highlightMatch(onlineUserInfo.userEmail, searchTerm) }} />
    <td dangerouslySetInnerHTML={{ __html: highlightMatch(onlineUserInfo.loginTime, searchTerm) }} />
  </tr>
))

4. 可选:自定义高亮样式

默认<mark>样式可能不符合需求,可添加CSS自定义:

mark {
  background-color: #ffeb3b;
  padding: 0 2px;
  border-radius: 2px;
}

完整修改后代码片段

const highlightMatch = (text, searchTerm) => {
  if (!searchTerm.trim()) return text;
  const regex = new RegExp(`(${searchTerm})`, 'gi');
  return text.replace(regex, '<mark>$1</mark>');
};

// ... 其他代码 ...

<tbody>
  {onlineUserData
    ?.filter(onlineUserInfo => {
      if (!searchTerm.trim()) return true;
      const lowerTerm = searchTerm.toLowerCase().replace(/\s+/g, '');
      return (
        onlineUserInfo.userName.toLowerCase().replace(/\s+/g, '').includes(lowerTerm) ||
        onlineUserInfo.userStandard.toLowerCase().replace(/\s+/g, '').includes(lowerTerm) ||
        onlineUserInfo.userRole.toLowerCase().replace(/\s+/g, '').includes(lowerTerm) ||
        onlineUserInfo.userEmail.toLowerCase().replace(/\s+/g, '').includes(lowerTerm) ||
        onlineUserInfo.loginTime.toLowerCase().replace(/\s+/g, '').includes(lowerTerm)
      );
    })
    ?.map((onlineUserInfo, index) => (
      <tr key={index}>
        <td>{onlineUserInfo.serialNumber}.</td>
        <td dangerouslySetInnerHTML={{ __html: highlightMatch(onlineUserInfo.userName, searchTerm) }} />
        <td dangerouslySetInnerHTML={{ __html: highlightMatch(onlineUserInfo.userStandard || "N/A", searchTerm) }} />
        <td dangerouslySetInnerHTML={{ __html: highlightMatch(onlineUserInfo.userRole, searchTerm) }} />
        <td dangerouslySetInnerHTML={{ __html: highlightMatch(onlineUserInfo.userEmail, searchTerm) }} />
        <td dangerouslySetInnerHTML={{ __html: highlightMatch(onlineUserInfo.loginTime, searchTerm) }} />
      </tr>
    ))}
</tbody>

内容的提问来源于stack exchange,提问作者Aazim Sheikh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 15:45:46