React使用forEach遍历时未渲染内部HTML元素问题排查
问题根因
forEach不会返回遍历生成的JSX节点集合:Array.prototype.forEach的设计目标是纯遍历执行副作用,返回值固定为undefined,你在回调里return的p标签不会被收集,React拿到这部分插入值是undefined,自然不会渲染任何内容。你在回调里打印能拿到值,只是因为forEach确实执行了遍历逻辑,没有把返回值透传出来而已。
另外代码里还有一处隐藏问题:{{ __html: name.info }}是React原生HTML注入的专属配置对象,不能直接作为span的子元素渲染,会直接抛出对象渲染错误。
修复方法
把所有数组遍历位置的forEach替换为Array.prototype.map:map会把每一项回调返回的内容收集为新数组返回,正好符合React渲染列表的入参要求。同时给每个遍历生成的根节点加上唯一key属性,修正dangerouslySetInnerHTML的写法。
修复后的完整组件代码:
const Credit = props => { const credit = type => { if (props.current.credits.hasOwnProperty(type)) { if (type === "recorded") { return ( <div className="credit"> <h2>{titles[type]}</h2> { props.current.credits[type].map((name, idx) => { return ( <p className="location" key={`${name.studio}-${name.city}-${idx}`}> <span className="studio">{name.studio}</span> <span className="city">{name.city}</span> </p> ) }) } </div> ) } if (type === "samples" || type === "interpolates") { return ( <div className="credit"> <h2>{titles[type]}</h2> { props.current.credits[type].map((name, idx) => { return ( <p className="location" key={`${name.title}-${idx}`}> <span className="studio">{name.title}</span> <span className="city" dangerouslySetInnerHTML={{ __html: name.info }} /> </p> ) }) } </div> ) } return ( <div className="credit"> <h2>{titles[type]}</h2> { props.current.credits[type].map((name, idx) => { return ( <p key={`${name}-${idx}`}>{name}</p> ) }) } </div> ) } return null; } return ( <div> {credit("samples")} </div> ) }
额外注意点
- 列表项的key尽量用数据里的唯一业务字段(比如作品ID、人名唯一标识),如果数据里确实没有唯一标识,短列表可以暂时用遍历索引兜底,不要用随机数当key。
- 如果
name.info里没有富文本HTML内容,直接写{name.info}即可,不需要用dangerouslySetInnerHTML。
内容的提问来源于stack exchange,提问作者Davy Kamanzi
相关产品推荐
相关产品推荐

