React中使用&&条件渲染motion.div出现Parsing error解析错误
问题背景
对motion.div组件做条件渲染时触发解析错误,错误定位在return语句后条件渲染的起始位置,抛出的错误信息为:
Line 36:19: Parsing error: Unexpected token, expected "," (36:19)
出错的原始代码如下:
return ( {showIntro && <motion.div className="intro" animate={{ opacity: 0 }} transition={{ delay: 4, duration: 1}} exit={{ opacity: 0 }}> <div className="text"> <motion.svg width="1000" height="20" viewBox="0 0 10 10" initial="hidden" animate="visible"> <motion.line x1="200" y1="10" x2="-200" y2="10" stroke="white" variants={draw} custom={1.1}/> </motion.svg> <motion.h1 initial={{opacity: 0}} animate={{ opacity: 1 }} transition={{ delay: 0.5, duration: 2}} exit={{ opacity: 0 }}> Welcome.</motion.h1> <motion.svg width="1000" height="20" viewBox="0 0 10 10" initial="hidden" animate="visible"> <motion.line x1="-200" y1="10" x2="200" y2="10" stroke="white" variants={draw} custom={0.9}/> </motion.svg> </div> </motion.div>} )
项目使用Create React App默认的ESLint配置,配置项如下:
"eslintConfig": { "extends": [ "react-app", "react-app/jest" ] }
错误原因
这个报错和ESLint配置无关,是纯JSX语法书写错误:
JSX中,大括号{}的插值语法仅能在JSX节点的子节点位置或者JSX节点的属性值位置使用。你在return后的分组括号内直接写了一层外层大括号,这个位置属于普通JS表达式上下文,解析器会把这层大括号识别为对象字面量的起始标记,按照对象语法规则解析内部内容,看到showIntro && <motion.div>时,认为这不符合对象属性的书写规范,因此抛出「期望逗号」的解析错误。
修复方案
两种方案二选一即可:
- 方案1:去掉多余的外层大括号,直接返回条件运算的结果。
&&条件运算的返回值本身就是合法的React可渲染节点,不需要额外套大括号:
return ( showIntro && <motion.div className="intro" animate={{ opacity: 0 }} transition={{ delay: 4, duration: 1}} exit={{ opacity: 0 }}> <div className="text"> <motion.svg width="1000" height="20" viewBox="0 0 10 10" initial="hidden" animate="visible"> <motion.line x1="200" y1="10" x2="-200" y2="10" stroke="white" variants={draw} custom={1.1}/> </motion.svg> <motion.h1 initial={{opacity: 0}} animate={{ opacity: 1 }} transition={{ delay: 0.5, duration: 2}} exit={{ opacity: 0 }}> Welcome.</motion.h1> <motion.svg width="1000" height="20" viewBox="0 0 10 10" initial="hidden" animate="visible"> <motion.line x1="-200" y1="10" x2="200" y2="10" stroke="white" variants={draw} custom={0.9}/> </motion.svg> </div> </motion.div> )
- 方案2:如果后续需要在同层级并列返回其他节点,或者需要配合Framer Motion的相关逻辑,可以用空标签(React Fragment)作为外层根节点,此时条件渲染内容作为Fragment的子节点,就可以正常使用大括号插值:
return ( <> {showIntro && <motion.div className="intro" animate={{ opacity: 0 }} transition={{ delay: 4, duration: 1}} exit={{ opacity: 0 }}> <div className="text"> <motion.svg width="1000" height="20" viewBox="0 0 10 10" initial="hidden" animate="visible"> <motion.line x1="200" y1="10" x2="-200" y2="10" stroke="white" variants={draw} custom={1.1}/> </motion.svg> <motion.h1 initial={{opacity: 0}} animate={{ opacity: 1 }} transition={{ delay: 0.5, duration: 2}} exit={{ opacity: 0 }}> Welcome.</motion.h1> <motion.svg width="1000" height="20" viewBox="0 0 10 10" initial="hidden" animate="visible"> <motion.line x1="-200" y1="10" x2="200" y2="10" stroke="white" variants={draw} custom={0.9}/> </motion.svg> </div> </motion.div>} </> )
注意:motion组件使用了
exit属性实现退出动画,必须将条件渲染的motion组件包裹在AnimatePresence组件内部,退出动画才会正常生效。
内容的提问来源于stack exchange,提问作者murt3.1415
相关产品推荐
相关产品推荐

