antd Select组件如何实现忽略emoji仅匹配文本的搜索功能
问题原因
当前自定义的filterOption筛选逻辑直接对option.children整体做包含匹配,而children中同时包含emoji字符、包裹emoji的DOM节点、纯文本内容,没有做内容过滤,导致搜索时会把emoji相关内容纳入匹配范围,无法实现仅匹配文本的需求。
修复方案
核心逻辑分两步:
- 递归遍历选项的children节点,提取所有纯文本内容,过滤掉标签节点
- 剔除提取出的文本中的所有emoji字符,仅保留业务文本后再和用户输入的搜索词做匹配判断
完整可运行代码如下:
import React from 'react'; import 'antd/dist/antd.css'; import './index.css'; import { Select } from 'antd'; const { Option } = Select; // 递归提取React节点中的纯文本内容 const getPureText = (node) => { if (typeof node === 'string' || typeof node === 'number') { return String(node); } if (Array.isArray(node)) { return node.map(getPureText).join(''); } if (node?.props?.children) { return getPureText(node.props.children); } return ''; }; // 移除文本中的所有emoji字符 const removeEmoji = (text) => { return text.replace( /[\p{Emoji_Presentation}\p{Extended_Pictographic}]/gu, '' ).trim(); }; const App = () => ( <Select showSearch style={{ width: 200, }} placeholder="Search to Select" optionFilterProp="children" filterOption={(input, option) => { const targetText = removeEmoji(getPureText(option.children)).toLowerCase(); const searchKey = input.trim().toLowerCase(); return targetText.includes(searchKey); }} > <Option value="1"><span>😁</span> Not Identified</Option> <Option value="2"><span>🙄</span> Closed</Option> <Option value="3"><span>😪</span> Communicated</Option> <Option value="4"><span>😚</span> Identified</Option> <Option value="5"><span>🥱</span> Resolved</Option> <Option value="6"><span>😫</span> Cancelled</Option> </Select> ); export default App;
优化说明
- 采用Unicode属性正则匹配emoji,无需引入第三方依赖,所有现代浏览器均支持
- 匹配逻辑增加了大小写转换、首尾空格去除处理,用户输入时大小写不敏感、首尾误输入空格也能正常匹配
- 递归提取文本的逻辑兼容多层嵌套标签结构,后续选项结构调整增加标签层级也不需要修改筛选逻辑
内容的提问来源于stack exchange,提问作者Subrato Pattanaik
相关产品推荐
相关产品推荐

