反应如何在 HOC 中获取包装组件的高度?

Posted

技术标签:

【中文标题】反应如何在 HOC 中获取包装组件的高度?【英文标题】:React how to get wrapped component's height in HOC? 【发布时间】:2019-05-22 11:27:10 【问题描述】:

有没有办法获取被包装组件的 DOM 高度?

我尝试添加一个 ref,但控制台错误我 Function components cannot be given refs.

而且我设置了forward ref,但好像不是这样。

export default function withInfiniteScroll(Component)   
  return class extends React.Component 
    componentDidMount() 
      window.addEventListener('scroll', this.onScroll, true);
    
    onScroll = () => 
      // here
      console.log(
        'window.innerHeight????', window.innerHeight,
        '\ndocument.body.offsetHeight????', document.body.offsetHeight,
      );
    
    render() 
      return <Component ...this.props />;
    
  ;

我想记录Component的高度,但是这些记录没有意义,它们是html-body的高度而不是Component的高度。

window.innerHeight???? 767 
document.body.offsetHeight???? 767 

但是当我在 chrome 控制台中时:

console.log(document.getElementsByClassName('home-container')[0].clientHeight)
> 1484

'home-container' 是一个封装组件:

withInfiniteScroll(HomeContainer);

【问题讨论】:

我设置了前向引用,但似乎不是这样 - 你如何设置它?不,情况就是这样。请提供***.com/help/mcve。 @estus 嗨,在 HOC 中我创建了前向 ref,但是如何在我的 HOC 中使用它?我认为这就是重点。 与任何其他参考一样。我举个例子。 【参考方案1】:

包装的组件应该使用forwardRef向底层DOM元素公开一个引用:

function withInfiniteScroll(Component)   
  return class extends React.Component 
    ref = React.createRef();

    componentDidMount() 
      window.addEventListener('scroll', this.onScroll, true);
    

    onScroll = () => 
      console.log(this.ref.current.clientHeight);
    

    render() 
      return <Component ref=this.ref ...this.props />;
    
  ;


const Foo = React.forwardRef((props, ref) => (
  <div ref=ref>Foo</div>
));

const FooWithScroll = withInfiniteScroll(Foo);

或者包装组件应该添加容器DOM元素:

function withInfiniteScroll(Component)   
  return class extends React.Component 
    // ...same as above

    render() 
      return <div ref=this.ref><Component ...this.props /></div>
    
  ;

【讨论】:

是的,谢谢。而且我认为第二种解决方案会将样式混搭起来,因此需要更好地考虑使用它。也很抱歉我尝试添加一个 ref 但控制台错误我,因为我将“home-container”设置为功能组件。将其更改为类将起作用:const innterDom = ReactDOM.findDOMNode(this.innterComponentRef.current) 如果样式有问题,您可以接受具有相应样式/类的自定义容器元素作为道具,例如&lt;FooWithScroll container=&lt;span/&gt;/&gt;。不鼓励使用findDOMNode,也要求组件是一个类,并不总是可能的。子组件应该知道它需要公开一个 ref。这就是 forwardRef 在示例中所做的。如果它并不总是可行或实用,请在包装组件周围使用容器。

以上是关于反应如何在 HOC 中获取包装组件的高度?的主要内容,如果未能解决你的问题,请参考以下文章

之间的区别是什么高阶组件(HOC)和继承反应本地组件

之间的区别是什么高阶组件(HOC)和继承反应本地组件

如何用 HOC 包装每个导出的组件?

在 HoC 中使用反应钩子时的警告

如何从 Next.js 中的服务器获取 HOC 中的数据?

使用 HOC 与使用组件包装之间的区别