在React中获取子组件的高度

oll*_*lie 1 javascript reactjs

我需要访问React中的子组件的高度,但无法找到关于如何最好地执行它的任何明确指导.我的组件看起来像这样:

/* index.js */
import Blocks from './Blocks'

ReactDOM.render(<Blocks />, document.body)

/* Blocks.jsx */
import Block from './Block'

class Blocks extends Component {
  render () {
    const eles = [0, 1, 2, 3, 4]

    return (
      <div>
        {eles.map(e => <Block key={e}>{e}</Block>)}
      </div>
    )
  }
}
Run Code Online (Sandbox Code Playgroud)

我想知道每个人Block的大小和位置,因为我想稍后自己定位.

据我所知,这种方法不允许我用来this.props.children访问令人讨厌的元素,因为以这种方式渲染块对我来说要好得多(Block后面将会有关于哪种类型的渲染的逻辑).为了解决这个问题,我尝试将Blocks 的渲染移动到索引文件中,如下所示:

/* index.js */
import Blocks from './Blocks'
import Block from './Block'

const eles = [0, 1, 2, 3, 4]

ReactDOM.render(
  <Blocks>
    {eles.map(e => <Block key={e}>{e}</Block>)}
  </Blocks>
)

/* Blocks.jsx */
class Blocks extends Component {
  render () {
    return (
      <div>
        {this.props.children}
      </div>
    )
  }
}
Run Code Online (Sandbox Code Playgroud)

这允许我做的是refs在单个Block组件内部使用它来返回getBoundingClientRect我应该能够通过父级访问的函数的结果,但我现在正在阅读使用refs不鼓励而不是如何使用React.

我需要能够将某些Blocks固定到屏幕的顶部,因为它们滚动过去并且无法想到其他任何方式,而不是知道它们在父组件中的大小和位置并使用它来管理它们.有没有办法做到这一点?理想情况下,我想将该循环移回Blocks组件内部,否则我将在一个不相关的组件中使用它的某些逻辑似乎不正确.

我也考虑过使用react-sticky但是我正在构建的应用程序已经在固定位置元素内(这是不可避免的)我不认为它会帮助我.

Pei*_*Han 7

尝试在Block Component中使用回调函数将ref发送到Parent Component

Block.js

import React, { Component } from 'react';

class Block extends Component {
  componentDidMount() {
    this.props.getRef(this.block, this.props.i);
  }
  render() {
    return (
      <div ref={n => this.block = n}>
        <p>{this.props.children}</p>
      </div>
    );
  }
}

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

将refs保存到变量或状态中index.js,然后在componentDidMount方法中,您可以获得Block组件高度或其他属性.index.js

const eles = [0, 1, 2, 3, 4];

class App extends Component {
  constructor() {
    super();
    this.blocks = [];
  }


  componentDidMount() {
    console.log(this.blocks);
    this.blocks.forEach((block, i) => {
      console.log(i, block.getBoundingClientRect().height)
    })
  }

  getRef = (ref, i) => {
    this.blocks[i] = ref;
  };

  render() {
    return (
      <div>
        {eles.map((e, i) => (
          <Block key={e} i={i} getRef={this.getRef}>{e}</Block>
        ))}
      </div>
    );
  }
}

render(<App />, document.getElementById('root'));
Run Code Online (Sandbox Code Playgroud)

控制台中的结果 在此输入图像描述