在Next.js导航栏中使用react-transition-group遇组件导入错误
问题
我正尝试为移动端导航栏添加打开时的平滑动画,避免直接弹出的生硬效果。但使用react-transition-group的CSSTransitionGroup组件后,出现如下服务器错误:
Server Error Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports
相关受影响代码如下:
<nav className='lg:block lg:static absolute top-0 left-0 fade pb-2 w-full'> <button aria-label='Open Navigational Menu on Mobile' className='pt-2.5 pl-2.5 mt-0 m-3 rounded lg:hidden text-black ml-auto hover:text-gray-500 outline-none' onClick={handleClick}> </button> <CSSTransitionGroup in={active} timeout={300}> <div className={`${ active ? '' : 'hidden' } w-full lg:flex lg:flex-grow lg:w-auto transition-all`} > <div className='bg-white bg-opacity-95 lg:flex divide-y divide-slate-200 lg:flex-row lg:w-screen lg:bg-white lg:text-2xl lg:font-semibold lg:font-poppins lg:justify-center lg:align-middle lg:gap-12 w-full items-start flex flex-col'> <Link href='/'> {currentPage === "/" ? ( <a className='text-navPurple font-bold lg:hover:drop-shadow-md lg:w-auto w-full lg:p-0 px-3 py-3 lg:border-none' onClick={()=>setActive(false)}>Home</a> ) : ( <a className='lg:hover:drop-shadow-md lg:w-auto w-full lg:p-0 px-3 py-3 text-navGreen hover:font-semibold lg:border-none' onClick={()=>setActive(false)}>Home</a> )} </Link> <Link href='/aboutme'> {currentPage === "/aboutme" ? ( <a className='text-navPurple font-bold lg:hover:drop-shadow-md lg:w-auto w-full lg:p-0 px-3 py-3 lg:border-none' onClick={()=>setActive(false)}>About Me</a> ) : ( <a className='lg:hover:drop-shadow-md lg:w-auto w-full lg:p-0 px-3 py-3 text-navGreen hover:font-semibold lg:border-none' onClick={()=>setActive(false)}>About Me</a> )} </Link> <Link href='/portfolio'> {currentPage === "/portfolio" ? ( <a className='text-navPurple font-bold lg:hover:drop-shadow-md lg:w-auto w-full lg:p-0 px-3 py-3 lg:border-none' onClick={()=>setActive(false)}>Portfolio</a> ) : ( <a className='lg:hover:drop-shadow-md lg:w-auto w-full lg:p-0 px-3 py-3 text-navGreen hover:font-semibold lg:border-none' onClick={()=>setActive(false)}>Portfolio</a> )} </Link> <Link href='/links'> {currentPage === "/links" ? ( <a className='text-navPurple font-bold lg:hover:drop-shadow-md lg:w-auto w-full lg:p-0 px-3 py-3 lg:border-none' onClick={()=>setActive(false)}>Favorite Links</a> ) : ( <a className='lg:hover:drop-shadow-md lg:w-auto w-full lg:p-0 px-3 py-3 text-navGreen hover:font-semibold lg:border-none' onClick={()=>setActive(false)}>Favorite Links</a> )} </Link> <Link href='/blog'> {currentPage === "/blog" ? ( <a className='text-navPurple font-bold lg:hover:drop-shadow-md lg:w-auto w-full lg:p-0 px-3 py-3 lg:border-none' onClick={()=>setActive(false)}>Blog</a> ) : ( <a className='lg:hover:drop-shadow-md lg:w-auto w-full lg:p-0 px-3 py-3 text-navGreen hover:font-semibold lg:border-none' onClick={()=>setActive(false)}>Blog</a> )} </Link> <Link href='/contact'> {currentPage === "/contact" ? ( <a className='text-navPurple font-bold lg:hover:drop-shadow-md lg:w-auto w-full lg:p-0 px-3 py-3 lg:border-none' onClick={()=>setActive(false)}>Contact Me</a> ) : ( <a className='lg:hover:drop-shadow-md lg:w-auto w-full lg:p-0 px-3 py-3 text-navGreen hover:font-semibold lg:border-none' onClick={()=>setActive(false)}>Contact Me</a> )} </Link> </div> </div> </CSSTransitionGroup> <div className={`${ active ? '' : 'hidden' } fixed -z-10 inset-0 bg-gray-600 bg-opacity-70 overflow-y-auto h-full w-full`} id="my-modal" onClick={()=>setActive(false)} ></div> </nav>
我尝试调整过CSSTransitionGroup的各类属性,但错误仍未解决。不确定是组件放置位置错误、库不兼容,还是其他问题,也未找到Tailwind中能实现该平滑动画的方案,希望得到解决办法。
解决方案
1. 修复组件导入错误
你遇到的错误核心是组件导入问题:
- react-transition-group v4+版本已移除
CSSTransitionGroup,改用TransitionGroup配合CSSTransition组件组合使用。 - 正确导入方式:
import { TransitionGroup, CSSTransition } from 'react-transition-group'; - 若使用旧版本,需确认导入的是
CSSTransitionGroup,但推荐升级到最新版本使用组合式API。
2. 正确实现react-transition-group动画
替换原有的CSSTransitionGroup,用以下结构重构代码:
<TransitionGroup> {active && ( <CSSTransition timeout={300} classNames="nav-transition"> <div className="w-full lg:flex lg:flex-grow lg:w-auto"> {/* 导航菜单原有内容 */} </div> </CSSTransition> )} </TransitionGroup>
然后在全局CSS中定义动画类:
.nav-transition-enter { opacity: 0; transform: translateY(-20px); } .nav-transition-enter-active { opacity: 1; transform: translateY(0); transition: opacity 300ms, transform 300ms; } .nav-transition-exit { opacity: 1; transform: translateY(0); } .nav-transition-exit-active { opacity: 0; transform: translateY(-20px); transition: opacity 300ms, transform 300ms; }
注意:不要用hidden类控制显示隐藏,交给CSSTransition处理状态切换。
3. 纯Tailwind实现平滑动画(无需第三方库)
如果不想依赖react-transition-group,直接用Tailwind过渡类即可实现:
- 移除
CSSTransitionGroup,修改导航容器的className:
<div className={`w-full lg:flex lg:flex-grow lg:w-auto transition-all duration-300 ease-in-out ${ active ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-[-20px] pointer-events-hidden' }`} > {/* 导航菜单原有内容 */} </div>
- 背景遮罩也添加过渡效果:
<div className={`fixed -z-10 inset-0 bg-gray-600 bg-opacity-70 overflow-y-auto h-full w-full transition-opacity duration-300 ${ active ? 'opacity-100' : 'opacity-0 pointer-events-none' }`} onClick={()=>setActive(false)} ></div>
用pointer-events-none替代hidden,确保隐藏状态下菜单不响应点击,同时保留过渡动画。
额外注意事项
- 确保
active状态通过React的useState正确管理:const [active, setActive] = useState(false); - 移动端按钮的点击事件需正确切换状态:
const handleClick = () => setActive(!active);
内容的提问来源于stack exchange,提问作者Robby Hoover
相关产品推荐
相关产品推荐

