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

时间:2016-07-24 08:10:44

标签: javascript reactjs

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

不必在divs内创建PageCompWrapperComp也可以创建它们,但它们必须包装每个子项(在这种情况下每个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

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

  • 我已尝试在ref=上添加divs,但ref只能在PageComp WrapperComp而非divs
  • 我还尝试在WrapperComp内创建ref=并在其中添加data-attribute,但这会产生Refs Must Have Owner Warning

现在我想知道......解决这个问题的反应是什么?

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

为什么我要将节点放在WrapperComp

我想创建一个调整其子项维度的组件。在该示例中,该组件将为clientHeight。这些调整只能在儿童渲染到dom之后进行,例如得到.validate()

1 个答案:

答案 0 :(得分:1)

如果你不限制这需要通过如何获取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>中进行转换,这正如其名称所暗示的那样非常直观。