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

如何阻止React为自闭合HTML标签<source>添加闭合标签?

如何阻止React渲染时生成闭合标签?

我用HTML的<picture>、<source>和<img>标签创建了一个React组件,组件会生成多个<source>选项,末尾设置了备用的<img>标签。React渲染组件时,<img>能正确以自闭合形式呈现,但每个<source>元素都被自动添加了闭合标签</source>,导致W3C验证报错,请问该如何阻止这种行为?

我定义了六个存储不同分辨率图片的变量,JSX代码如下:

<source
   media={`(max-width: 200px)`}
   srcset={`${small_src}, ${small_src2x} 2x`}
/>
<source
   media={`(max-width: 400px)`}
   srcset={`${mid_src}, ${mid_src2x} 2x`}
/>
<img
   src={large_source}
   srcset={`${large_source}, ${large_source2x} 2x`}
/>

渲染后的HTML结果为:

<picture>
  <source 
    media="(max-width: 200px)" srcset="..pathToSmall, ..pathToSmall@2x 2x">
  </source>
  <source 
    media="(max-width: 400px)" srcset="..pathToMid, ..pathToMid@2x 2x">
  </source>
  <img
    src="..pathToLarge"
    srcset="..pathToLarge, ..pathToLarge@2x 2x">
</picture>

可见<img>没有多余的闭合标签,但<source>被添加了</source>。虽然浏览器能正常运行,但W3C验证会标记错误:

<picture>
  <source media="(max-width: 200px)" srcset="pic1.jpg, pic1@2x.jpg 2x"></source>
  <source media="(max-width: 400px)" srcset="pic2.jpg, pic2@2x.jpg 2x"></source>
  
  <img alt="hi" src="pic2.jpg">
</picture>

错误提示:Stray end tag source.


解决办法

1. 使用React.createElement手动创建<source>元素

JSX编译器会对部分空元素自动补全闭合标签,直接用createElement可以精准控制输出,避免生成多余的闭合标签。示例代码:

import React from 'react';

function ResponsivePicture() {
  // 定义图片路径变量
  const small_src = 'path/to/small.jpg';
  const small_src2x = 'path/to/small@2x.jpg';
  const mid_src = 'path/to/mid.jpg';
  const mid_src2x = 'path/to/mid@2x.jpg';
  const large_source = 'path/to/large.jpg';
  const large_source2x = 'path/to/large@2x.jpg';

  return (
    <picture>
      {React.createElement('source', {
        media: '(max-width: 200px)',
        srcset: `${small_src}, ${small_src2x} 2x`
      })}
      {React.createElement('source', {
        media: '(max-width: 400px)',
        srcset: `${mid_src}, ${mid_src2x} 2x`
      })}
      <img
        src={large_source}
        srcset={`${large_source}, ${large_source2x} 2x`}
        alt="描述图片内容" // 记得添加alt属性提升可访问性
      />
    </picture>
  );
}

export default ResponsivePicture;

2. 借助dangerouslySetInnerHTML(不推荐)

如果不想用createElement,也可以通过dangerouslySetInnerHTML直接插入HTML字符串,但这种方式存在XSS风险,仅在确定内容安全的场景下使用:

import React from 'react';

function ResponsivePicture() {
  const small_src = 'path/to/small.jpg';
  const small_src2x = 'path/to/small@2x.jpg';
  const mid_src = 'path/to/mid.jpg';
  const mid_src2x = 'path/to/mid@2x.jpg';
  const large_source = 'path/to/large.jpg';
  const large_source2x = 'path/to/large@2x.jpg';

  const pictureHTML = `
    <picture>
      <source media="(max-width: 200px)" srcset="${small_src}, ${small_src2x} 2x">
      <source media="(max-width: 400px)" srcset="${mid_src}, ${mid_src2x} 2x">
      <img src="${large_source}" srcset="${large_source}, ${large_source2x} 2x" alt="描述图片内容">
    </picture>
  `;

  return <div dangerouslySetInnerHTML={{ __html: pictureHTML }} />;
}

export default ResponsivePicture;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 01:33:27