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

为什么我封装的PopUp弹窗HOC高阶组件无法正常工作?

问题原因

你现在的HOC用法完全错误。HOC每次调用都会返回一个独立的新组件,每个被包裹的组件都持有独立的内部状态,状态之间完全不互通。
你目前只给ButtonsOur按钮组件套了这个HOC,点击按钮时变更的active状态,是这个被包裹的按钮组件私有的状态,PopUpExc弹窗组件根本访问不到这个状态。就算你给弹窗也套一层同一个HOC,也会生成一份全新的独立active状态,和按钮那边的状态完全不同步,自然不会响应按钮的点击操作。
本质上你写的这个HOC只能给单个组件注入状态和方法,根本实现不了跨组件的状态共享。

修复方案

方案1:状态提升到公共父组件(优先推荐,符合React设计原则)

直接弃用当前的HOC,把弹窗开关状态、控制方法写在按钮和弹窗的共同父组件中,再通过props分别下发给两个组件即可,代码示例:

// 按钮与弹窗的公共父组件
function PageSection() {
  const [active, setActive] = useState(false);
  const openPop = () => setActive(true);
  const closePop = () => setActive(false);

  return (
    <div>
      {/* 其他页面内容 */}
      <ButtonsOur open={openPop} />
      <PopUpExc activevvv={active} close={closePop} />
    </div>
  )
}

// 按钮组件无需包裹HOC,直接接收props
function ButtonsOur({ open }) {
  return (
    <div className="base__routes__button">
      <Buttons className="base__button__moreInf open-popup-exc" Click={open} >Докладніше</Buttons>
      <Buttons className="base__button__moreInf open-popup-exc" Click={open} >Забронювати</Buttons>
    </div>
  )
}

// 弹窗组件无需包裹HOC,直接接收props
function PopUpExc({activevvv, close}) {
  return (
    <div 
      className={activevvv ? "popup__bg__exc active" : "popup__bg__exc"}
      onClick={close} // 补充点击遮罩关闭弹窗的逻辑
    >
        <div className="popup__exc" onClick={e => e.stopPropagation()}>
            <img onClick={close} src={Close} alt="close-popup" className="close-popup_exc" />
            <div className="container">
                <div className="row">
                  {/* 原有弹窗内容 */}
                </div>
            </div>
        </div>
    </div>
  )
}

方案2:改造HOC为组合式HOC,统一管理两个组件的状态

如果你一定要保留HOC的写法,可以改造HOC让它同时接收触发组件和弹窗组件,在HOC内部维护唯一的状态,再把对应props分发给两个组件,代码示例:

const withPopUpControl = (TriggerComponent, PopupComponent) => {
  const Controller = (restProps) => {
    const [active, setActive] = useState(false);
    const open = () => setActive(true);
    const close = () => setActive(false);

    useEffect(() => {
      console.log(active)
    }, [active])

    return (
      <>
        <TriggerComponent open={open} {...restProps.triggerProps} />
        <PopupComponent activevvv={active} close={close} {...restProps.popupProps} />
      </>
    )
  }
  return Controller;
}

// 一次性传入按钮和弹窗组件,生成绑定好状态的组合组件
const BookPopUp = withPopUpControl(ButtonsOur, PopUpExc);

// 使用时直接渲染组合组件即可
function Page() {
  return (
    <div>
      {/* 其他页面内容 */}
      <BookPopUp />
    </div>
  )
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 03:39:30