React基于传入props动态渲染react-icons骰子图标组件的实现方法
动态渲染骰子图标组件的正确实现
问题根因
JSX的组件识别有两层硬规则,之前的实现同时违反了这两个规则:
- 标签名如果全小写开头,JSX解析器会将其判定为原生HTML/DOM节点,不会关联自定义组件
- 只有当标签位置的变量存储的是真实的组件引用(也就是你import进来的FaDiceOne这类值),才会被当做自定义组件渲染;如果变量存的是字符串文本,不管变量名叫什么,都只会被解析为普通文本或自定义元素
你之前的代码把randomDice赋值为模板字符串拼接出的"FaDiceOne"这类文本值,哪怕把变量名改成大写,也和你import进来的图标组件没有任何关联,自然无法正常加载图标。而同位置硬编码的FaDiceTwo能正常显示,是因为它是直接的组件引用,符合渲染规则。
推荐实现方式
因为你已经把全部6个骰子图标都手动引入了,最稳妥、适配前端打包规则的实现是建立props值与图标的映射表,通过父组件传入的参数直接匹配对应的图标组件引用:
- 在Dice组件内部维护传入值和引入图标的一一对应关系
- 从映射表取出匹配的组件后,以首字母大写的变量承接,再用JSX渲染
示例代码:
// Dice.js 顶部已提前引入的图标组件 import { FaDiceOne, FaDiceTwo, FaDiceThree, FaDiceFour, FaDiceFive, FaDiceSix } from 'react-icons/fa'; // 建立 props 值到图标的静态映射 const diceIconMap = { One: FaDiceOne, Two: FaDiceTwo, Three: FaDiceThree, Four: FaDiceFour, Five: FaDiceFive, Six: FaDiceSix }; class Dice extends Component { render() { // 从映射表取出对应组件(此处拿到的是组件引用,不是字符串) const TargetDiceIcon = diceIconMap[this.props.dice]; return ( <div className="dice-container"> {/* 首字母大写的组件变量可被正常识别渲染 */} <TargetDiceIcon size={48} color="#222" /> </div> ) } }
关键注意事项
- 不要尝试通过字符串拼接名称、再到全局作用域查找组件的实现方式,这种写法会破坏打包工具的tree-shaking能力,还存在注入类安全风险
- 渲染自定义组件时,承接组件引用的变量必须首字母大写,否则React会将其判定为原生DOM标签,无法触发组件渲染逻辑
- 这种静态映射方式的渲染效率和硬编码写死图标没有差异,不会带来额外的性能开销
内容的提问来源于stack exchange,提问作者Prasanth Perli
相关产品推荐
相关产品推荐

