反应 forwardRef HoC 不引用容器元素

Mar*_*aus 5 javascript reactjs higher-order-components

我正在尝试为关闭元素构建一个通用 HOC,点击其空间外(通用关闭外部解决方案)。

在我看来,这可以通过 forwardRef 和 HOC 实现来实现,尽管官方文档中有一个示例,但我似乎无法正确理解。

所以我希望我的 HOC 创建对组件容器的引用。它正在包装,因为它具有跟踪点击并对其采取行动的处理程序。例如,假设我们有一个通用的 Dropdown 组件,人们希望我可以在该组件区域外的任何单击时关闭它。

我目前拥有的代码:

import React from 'react';

function withClose(Component) {
 class ClickContainer extends React.Component {
    constructor() {
      super();
      this.handleClose = this.handleClose.bind(this);
    }

    componentDidMount() {
      document.addEventListener('click', this.handleClose);
    }

    componentWillUnmount() {
      document.removeEventListener('click', this.handleClose);
    }

    handleClose(e) {
      // I expect having here context of container of wrapped component to do something like
      const { forwardedRef } = this.props; // <- I expect having context in forwardedRef variable
    }

    render() {
      const { forwardedRef, ...rest } = this.props;
      return <Component ref={forwardedRef} {...rest} />;
    }
  }

  return React.forwardRef((props, ref) => {
    return <ClickContainer {...props} forwardedRef={ref} />;
  });
}

export default withClose;
Run Code Online (Sandbox Code Playgroud)

我在这里缺少什么?我不能让它工作,我只得到包装组件的上下文而不是元素本身。

谢谢一堆!

Ora*_*rar 3

Ref 应向下传递给元素

结账https://codesandbox.io/s/7yzoqm747x

假设

export const Popup = (props,) => {
  const { name, forwardRef } = props;
  return (
   <div ref={forwardRef}>  // You need to pass it down from props
     {name}
   </div>
  )
}
Run Code Online (Sandbox Code Playgroud)

和 HOC

export function withClose(Component) {
  class ClickContainer extends React.Component {
    constructor() {
     super();
     this.handleClose = this.handleClose.bind(this);
    }

    componentDidMount() {
      document.addEventListener('click', this.handleClose);
    }

    componentWillUnmount() {
      document.removeEventListener('click', this.handleClose);
    }

    handleClose(e) { 
     const { forwardRef } = this.props;
     console.log(forwardRef);
    }

    render() {
      const { forwardRef, ...rest } = this.props;
      return <Component forwardRef={forwardRef} {...rest} />;
    }
  }

  return React.forwardRef((props, ref) => {
    return <ClickContainer {...props} forwardRef={ref} />;
  });
}
Run Code Online (Sandbox Code Playgroud)

并期待

 const CloseablePopup = withClose(Popup);

  class App extends Component {
    popupRef = React.createRef();
    render() {
      return (<CloseablePopup ref={popupRef} name="Closable Popup" />);
    }
  }
Run Code Online (Sandbox Code Playgroud)