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

在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 00:15:39