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

React中含大量子项的少分类列表虚拟化:Emoji选择器优化问询

解决Emoji选择器整体虚拟化的方案

核心思路是将分类标题与过滤后的Emoji打平为统一的列表项数组,对这个完整数组做整体虚拟化,实现全局统一滚动,同时只渲染可见区域内的内容。

具体实现步骤

1. 扁平化处理数据

在父组件中,根据当前搜索条件,把分类标题和符合条件的Emoji合并成带类型标识的数组,方便后续区分渲染:

// 生成扁平化的可渲染列表
const getFlattenedEmojiList = () => {
  const result = [];
  emojiSet.forEach(category => {
    // 添加分类标题项
    result.push({ type: 'category', name: category.Name });
    // 过滤符合搜索条件的Emoji并添加
    const filteredEmojis = category.Icons.filter(emoji => 
      emoji.Names.some(name => name.includes(searchQuery.toLowerCase()))
    );
    filteredEmojis.forEach(emoji => {
      result.push({ type: 'emoji', data: emoji });
    });
  });
  return result;
};

// 根据搜索条件实时生成扁平化列表
const flattenedEmojiList = getFlattenedEmojiList();

2. 使用react-window实现整体虚拟化

用VariableSizeList(适配分类标题与Emoji的高度差)包裹整个列表,实现全局滚动与按需渲染:

import { VariableSizeList as List } from 'react-window';

// 定义每个列表项的高度(根据实际样式调整数值)
const getItemHeight = (index) => {
  const item = flattenedEmojiList[index];
  return item.type === 'category' ? 40 : 32; // 标题40px,Emoji项32px
};

// 渲染单个列表项
const RenderEmojiItem = ({ index, style }) => {
  const item = flattenedEmojiList[index];
  if (item.type === 'category') {
    return (
      <div style={style} className="emoji-category-title">
        <p>{item.name}</p>
      </div>
    );
  }
  return (
    <div style={style} className="emoji-item">
      <Icon url={item.data.Url} />
    </div>
  );
};

3. 替换原有渲染逻辑

把原来的#icons容器替换为虚拟化列表:

<div id="icons" style={{ height: '400px', overflow: 'auto' }}>
  <List
    width="100%"
    height={400} // 容器高度,可根据需求自定义
    itemCount={flattenedEmojiList.length}
    itemSize={getItemHeight}
    overscanCount={5} // 提前渲染可见区域外的5个项,优化滚动流畅度
  >
    {RenderEmojiItem}
  </List>
</div>

4. 调整样式适配

拆分原有的.emoji-category样式,给分类标题和Emoji项分别设置样式,保证布局与原有效果一致:

.emoji-category-title {
  padding: 8px 12px;
  border-bottom: 1px solid #eee;
  font-weight: bold;
}
.emoji-item {
  display: inline-block;
  padding: 4px;
  cursor: pointer;
}

方案优势

  • 解决了单独虚拟化分类导致的多滚动容器问题,实现全局统一滚动
  • 对所有小项(标题+每个Emoji)做虚拟化,直接解决数千个Emoji的渲染性能问题
  • 搜索条件变化时,扁平化列表会自动更新,react-window会同步刷新可见区域内容

内容的提问来源于stack exchange,提问作者Gradyn Wursten

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 22:23:36