ReactJS中如何更优地批量渲染本地SVG格式emoji列表
更简洁高效的实现方案
你当前手动逐个导入SVG的方式维护成本很高,每次新增emoji都要重复写导入语句、手动往配置数组加项,直接用构建工具自带的静态资源批量导入能力即可,不需要手动维护导入列表,后续新增SVG文件会自动被收录。
Vite 环境实现(绝大多数现代React项目使用)
直接替换你原来emojis配置文件的内容即可,业务组件的渲染逻辑完全不用改动:
// 批量匹配目录下所有svg文件,以React组件形式同步导入 const emojiModules = import.meta.glob( '../assets/emojiIcons/*.svg', { eager: true, // 静态构建时直接导入,不需要异步加载 query: '?react', // 对应SVG转React组件的导入规则,和你之前{ ReactComponent as Xxx }的导入效果一致 import: 'default' } ) // 自动生成标准配置数组 const DEFAULT_EMOJI_OPTIONS = Object.entries(emojiModules).map(([filePath, SvgComponent]) => { // 从文件路径提取文件名作为label,例如 ../assets/emojiIcons/rocket.svg 提取为 rocket const fileName = filePath.split('/').pop() const label = fileName.replace('.svg', '') return { emoji: SvgComponent, label } }) export { DEFAULT_EMOJI_OPTIONS }
如果你没配置过SVG转React组件的能力,给Vite装一下
@vitejs/plugin-react-svgr插件就行,配置方法和你之前支持{ ReactComponent as Xxx }导入的规则完全一致。
Webpack/Create React App 环境实现
如果是旧版基于webpack的CRA项目,用require.context实现同样的批量导入效果:
const emojiContext = require.context( '../assets/emojiIcons', false, // 不递归遍历子目录 /\.svg$/ // 匹配所有.svg后缀文件 ) const DEFAULT_EMOJI_OPTIONS = emojiContext.keys().map(filePath => { const label = filePath.replace('./', '').replace('.svg', '') const { ReactComponent: SvgComponent } = emojiContext(filePath) return { emoji: SvgComponent, label } }) export { DEFAULT_EMOJI_OPTIONS }
方案优势
- 零维护成本:后续往
src/assets/emojiIcons目录新增SVG文件时,不需要修改任何配置代码,列表会自动收录新表情 - 渲染层无侵入:原来业务组件里的map遍历渲染逻辑完全不用改,直接复用即可
- 如果需要自定义表情排序、给个别表情加额外属性(比如分类、点击事件名),只需要在自动生成数组后加一层排序/属性覆写逻辑即可,比全量手写配置效率高很多。
内容的提问来源于stack exchange,提问作者r121
相关产品推荐
相关产品推荐

