React使用Fragment包裹元素仍报unexpected token div错误如何解决
问题根源
这个报错是JSX编译阶段的语法解析错误,不是React运行时的渲染逻辑问题,和Fragment的节点包裹能力没有关系,和你场景完全匹配的触发原因是:
你使用的构建工具内置的JSX解析器版本过旧,对可选链?.语法、render prop内箭头函数隐式返回多行JSX、Fragment内多个平级插值块的组合场景存在解析bug。当解析器无法正确识别itemValue?.type的可选链语法时,会错误判定第一个条件渲染块的大括号闭合边界,导致第二个条件渲染块内的<div>被判定为出现在非法语法位置,抛出unexpected token div错误。当你删掉任意一个条件渲染块时,解析器不会触发边界判定逻辑,代码就能正常编译通过。
修复方案
按优先级尝试以下方案即可解决问题:
- 升级构建依赖:将项目中babel的JSX转换插件
@babel/plugin-transform-react-jsx、ES新语法转换插件升级到和当前React版本匹配的稳定版,确保可选链、Fragment等语法能被正确识别。如果使用React 17及以上版本,可以开启新版JSX转换,无需手动导入React即可正常解析Fragment。 - 调整render prop写法消除解析歧义:不要让箭头函数紧贴组件开标签书写,给箭头函数使用显式大括号+return的写法,返回的多行JSX用圆括号包裹,避免解析器错误拆分词法单元。修改后的代码示例:
const Iterator = ({ items, children, ...props }) => ( <div {...props}> { items.map((data, key) => ( // 外层已经有带key的Fragment,内部无需重复包裹 <Fragment key={key}> { children(data, key) } </Fragment> ))} </div> ); <div className={styles.parent}> <Iterator items={items} className={styles.child} > {itemValue => { return ( <> { itemValue?.type === "a" && <div>A</div> } { itemValue?.type === "b" && <div>B</div> } </> ) }} </Iterator> </div>
- 若暂时无法升级构建依赖,可以把条件判断逻辑移到JSX插值外部,避免在Fragment下出现多个平级的独立插值块,从根源上绕开解析bug,示例:
{itemValue => { switch(itemValue?.type) { case "a": return <div>A</div> case "b": return <div>B</div> default: return null } }}
内容的提问来源于stack exchange,提问作者Grover
相关产品推荐
相关产品推荐

