如何在不向其父元素/子元素添加逻辑的情况下获取组件中子元素的dom节点

How do I get the dom node of a child element in a component without adding logic to its parent/children?

本文关键字:元素 获取 情况下 组件 节点 dom 添加      更新时间:2023-09-26

在以下示例中,WrapperComp需要访问第5行和第8行中divs的dom节点,而无需向PageCompItemComp添加逻辑。我在PageComp中唯一可以更改的就是div标记。例如,我可以向它们添加refpropdata-attribute等。

divs不必在PageComp内部创建。WrapperComp也可以创建它们,但它们必须包装它的每个子级(在这种情况下,每个ItemComp)。

示例

class PageComp extends React.Component {
  render() {
    return (
    <WrapperComp>
      <div>
        <ItemComp/>
      </div>
      <div>
        <ItemComp/>
      </div>
    </WrapperComp>
    );
  }
}
class WrapperComp extends React.Component {
  render() {
    return (
      <div>
        <h1>A wrapper</h1>
        {this.props.children}
      </div>
    );
  }
}
class ItemComp extends React.Component {
  render() {
    return (
      <div>
        <h1>An item</h1>
      </div>
    );
  }
}
ReactDOM.render(
  <PageComp/>,
  document.getElementById('app')
);

JSBIN

到目前为止我尝试了什么:

  • 我已经尝试在divs上放置ref=,但ref只能在PageComp中使用,而不能在WrapperComp中使用
  • 我还试图在WrapperComp中创建divs,并从那里在它们上放置ref=,但这会导致Refs必须具有所有者警告

现在我想。。解决这个问题的合适方法是什么?

到目前为止,我想到的唯一解决方案是在每个div上放一个data-attribute,并在componentDidMount之后的dom中搜索它们,就像这样:document.querySelectorAll('[data-xxx]')。也许我不确定你是不是这样做的。。

为什么我想在WrapperComp中获取节点?

我想创建一个组件来调整其子级的尺寸。在该示例中,该组件将是WrapperComp。只有在子级渲染到dom之后才能进行调整,例如获得clientHeight

如果你不限制这需要通过如何获得DOM、传递它们等来解决,我会摆脱这个难题,从不同的方向来解决它。

由于你对<PageComp>没有太多的控制权,而<WrapperComp>似乎很灵活,我会在后面通过将传递的孩子转化为你需要的样子来完成包装。

class PageComp extends React.Component {
  render() {
    return (
      <WrapperComp>
        <ItemComp/>
        <ItemComp/>
      </WrapperComp>
    );
  }
}
class WrapperComp extends React.Component {
  render() {
    const wrappedChldren = React.Children.map(this.props.children, function(child) {
      return (
        <div ref={function(div) {
            this.setState{clientHeight: div.clientHeight}
        }}>
          <h1>A wrapper</h1>
          { child }
        </div>
      ); 
    });
    return <div>{ wrappedChildren }</div>;
  }
}

有了这个浓缩物,就可以在<WrapperComp>中进行转换,顾名思义,这是非常直观的。