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

React搜索框关闭重开后无法输入问题求助

问题原因及解决方案

核心问题

  1. AnimatePresence 用法错误:你在每个条件分支(!isSearchOpen 和 isSearchOpen)里单独嵌套了 AnimatePresence,但它需要直接包裹会被挂载/卸载的目标元素,才能正确监听组件进出并触发动画。当前写法会导致组件卸载时的 exit 动画无法被正确捕获,进而引发 DOM 元素状态异常,导致再次打开时输入框无法交互。
  2. XMarkIcon 多余事件干扰:关闭按钮内的 XMarkIcon 绑定了错误的 setIsMobOpen 事件,会干扰搜索框的关闭逻辑。
  3. exit 动画的宽度设置问题:关闭时设置 width: 0 会直接挤压输入框所在容器,可能导致 DOM 元素尺寸计算异常,再次打开时无法恢复正常交互状态。

修改后的代码

{/* Login and Search Button Start */}
<div className="hidden md:block">
  <AnimatePresence>
    {!isSearchOpen ? (
      <motion.div
        key="search-button"
        initial={{ opacity: 0 }}
        animate={{ opacity: 1 }}
        exit={{ opacity: 0 }}
        className="md:flex md:items-center md:gap-3"
      >
        <button
          onClick={() => setIsSearchOpen(!isSearchOpen)}
          className="cursor-pointer flex items-center justify-between gap-2 w-32 px-3 h-8 bg-gray-200 hover:bg-gray-300 border border-solid border-gray-200 rounded-lg"
        >
          <span className="text-green-900 font-medium">Search</span>
          <MagnifyingGlassIcon className="h-5 w-5 text-green-900" />
        </button>
        <LoginButton />
      </motion.div>
    ) : (
      <motion.div
        key="search-input"
        initial={{ width: 0, opacity: 0 }}
        animate={{ width: "auto", opacity: 1 }}
        exit={{ width: 0, opacity: 0 }}
        className="md:flex md:items-center"
      >
        <form>
          <input
            placeholder="Search for workshops, articles, and videos"
            type="text"
            className="md:w-96 md:px-3 md:mr-3 md:h-7 md:bg-gray-300 md:border-solid md:border-gray-200 md:rounded-lg md:text-sm"
          />
        </form>
        <button onClick={() => setIsSearchOpen(!isSearchOpen)}>
          <XMarkIcon
            className="md:h-7 md:w-7 md:text-green-900 md:cursor-pointer"
          />
        </button>
      </motion.div>
    )}
  </AnimatePresence>
</div>
{/* Login and Search Button End */}

关键修改点说明

  • 统一包裹 AnimatePresence:将 AnimatePresence 移到条件渲染外层,确保它能正确监听两个状态元素的挂载/卸载,触发对应动画。
  • 添加唯一 key:给两个 motion.div 分别设置 key="search-button" 和 key="search-input",让 React 正确识别不同组件实例,避免复用旧 DOM 元素导致状态异常。
  • 移除错误事件:删掉 XMarkIcon 上的 setIsMobOpen 事件,确保关闭逻辑只由外层按钮的 setIsSearchOpen 控制。
  • 优化容器对齐:给搜索输入框的 motion.div 添加 md:items-center,确保输入框和关闭按钮垂直对齐,避免布局偏移。

额外建议

如果关闭时的 width: 0 动画仍然导致输入框异常,可以尝试将 exit 动画改为只使用 opacity,或者给输入框容器添加 overflow: hidden,避免尺寸变化挤压内部元素:

exit={{ opacity: 0, width: 0 }}
className="md:flex md:items-center overflow-hidden"

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 01:52:53