【问题标题】:React: get DOM position for one of the children of componentReact:获取组件子节点之一的 DOM 位置
【发布时间】:2019-02-12 21:39:09
【问题描述】:

我有一个非常烦人的问题,我需要有关我的组件的帮助。它用于这种情况:

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

ChildComponent是一个包含其他组件但最终呈现简单HTML的组件&lt;tr&gt;

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

我尝试了很多东西:

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

argument 似乎不是 ReactComponent。键:$$typeof, type, key, ref, props, _owner, _store

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

给我警告(但有效!):

index.js:2178 警告:validateDOMNesting(...): 不能作为 . 在 tr (由 FoldControlContainer 创建) ...

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

【问题讨论】:

  • Tr 是什么?请提供。 children[n].ref 只是给我 null - 为什么ref 应该存在? 无法向子项添加 ref - 为什么?
  • 啊抱歉,忘记了,但这是一个常规的 tr :)。我会更新我的代码
  • 如果是&lt;tr&gt;,您将能够获得带有 ref 的 DOM 元素。您到底对 refs 做了什么尝试?
  • @estus:好吧,我不能只是 children[n].ref = myRef,也许有一些功能但找不到它
  • 不,如果您没有提供参考,则不会有 ref reactjs.org/docs/refs-and-the-dom.html 。我会尽力提供答案。如果它不是真的 ,请考虑用您的实际情况更新问题,因为它是不同的。

标签: javascript reactjs


【解决方案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 打开右下角的控制台以查看输出。

【讨论】:

  • 谢谢,它让我将我的子组件转换为类,但它仍然可以正常工作!
【解决方案2】:

findDOMNode 需要 React.Component 的实例。组件应使用 refs 呈现以获取实例。由于 &lt;ChildComponent&gt;/* ... */&lt;/ChildComponent&gt; 子级中不使用 refs,因此应使用 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) 可用。

【讨论】:

  • 感谢您的回答,SlimSim 是第一个非常相似的解决方案,但您的帮助仍然很大!
猜你喜欢
  • 1970-01-01
  • 2015-06-16
  • 1970-01-01
  • 1970-01-01
  • 2021-02-26
  • 1970-01-01
  • 1970-01-01
  • 2014-08-19
  • 1970-01-01
相关资源
最近更新 更多