React:获取组件子组件之一的DOM位置

时间:2019-02-12 12:35:17

标签: javascript reactjs

我有一个非常烦人的问题,我需要有关组件的帮助。在以下情况下使用它:

<table>
  <thead>/* ... */</thead>
  <tbody>
    <COMPONENT>
      <ChildComponent>/* ... */</ChildComponent>
      <ChildComponent>/* ... */</ChildComponent>
      <ChildComponent>/* ... */</ChildComponent>
    </COMPONENT>
  </tbody>
</table>

ChildComponent 是一个包含其他组件的组件,但最终呈现了简单的HTML <tr>

component.tsx 内部,我需要获取第n个孩子的DOM值(offsetTop和clientHeight)。

我尝试了很多事情:

  • ReactDOM.findDOMNode(children[n])给我:
  

参数似乎不是ReactComponent。键:$$ typeof,类型,键,ref,道具,_owner,_store

  • children[n].ref只是给我空了
  • 无法向孩子添加参考
  • 这类作品:
children.map((child, index) =>
    index === n ? (
        <div style={{display: contents}} key={index} ref={ref}>
    ) : child
)

给我警告(但有效!):

  

index.js:2178警告:validateDOMNesting(...):不能作为的子代出现。       在tr中(由FoldControlContainer创建)...

有更好的解决方案吗?我尝试对DOM组件使用<>或其他“透明”而不是div,但是没有用。

2 个答案:

答案 0 :(得分:1)

使用React.cloneElement设置子项的引用:https://reactjs.org/docs/react-api.html#cloneelement 例如:

React.cloneElement(child, {ref: this.setChildRef})}
export default class Test extends React.Component {

  childrenRefs = {}

  setChildRef = index => el => this.childrenRefs[index] = el;

  showInfo = () => {
    console.log('children', Object.keys(this.childrenRefs).map(key => this.childrenRefs[key].offsetTop))
  }

  render() {

    return (
      <div>
        { React.Children.toArray(this.props.children).map((c, index) => React.cloneElement(
          c,
          {ref: this.setChildRef(index)},
        ))}
        <button onClick={this.showInfo} >test</button>
      </div>
    );
  }
} 

以下是完整示例的链接:https://stackblitz.com/edit/react-cf33ge打开右下角的控制台以查看输出。

答案 1 :(得分:1)

findDOMNode需要一个React.Component的实例。组件应使用ref渲染以获取实例。由于<ChildComponent>/* ... */</ChildComponent>子代中未使用ref,因此应使用ref克隆它们。

如果子级应该是类的组成元素,并且其数量在父级组件的使用期限内没有变化,则情况可以简化为:

childRefs = [...Array(React.Children.count(this.props.children))]
.map(() => React.createRef());

render() {
  return React.Children.map(this.props.children, ((child, i) => 
    React.cloneElement(child, { ref: this.childRefs[i] });
  )
}

安装组件时,DOM元素可用作ReactDOM.findDOMNode(this.childRefs[n].current)