从React子元素获取DOM节点

Gra*_*ett 50 reactjs

使用React.findDOMNodev0.13.0中引入的方法,我能够通过映射获取传递给父组件的每个子组件的DOM节点this.props.children.

但是,如果某些孩子恰好是React Elements而不是Components(例如,其中一个孩子是<div>通过JSX创建的),React会抛出一个不变的违规错误.

有没有办法在挂载后获取每个子节点的正确DOM节点,而不管子节点是什么类?

Ale*_*erg 53

this.props.children 应该是ReactElement或ReactElement数组,而不是组件.

要获取children元素的DOM节点,您需要克隆它们并为它们分配新的ref.

render() {
  return (
    <div>
      {React.Children.map(this.props.children, (element, idx) => {
        return React.cloneElement(element, { ref: idx });
      })}
    </div>
  );
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以通过访问子组件this.refs[childIdx],并通过它检索其DOM节点ReactDOM.findDOMNode(this.refs[childIdx]).

  • 这不会破坏分配给父母中孩子的任何现有`ref`吗?换句话说,如果你有`<div ref ="a"/>`作为你的孩子,那么这会不会破坏对`refs.a`的任何引用,因为你将它覆盖为`idx`? (3认同)
  • 确实如此.如果你想保留refs,你应该使用[callback refs](https://facebook.github.io/react/docs/more-about-refs.html#the-ref-callback-attribute).`{ref:node => this.node = node; element.ref(节点); }` (3认同)
  • 请注意,`this.props.children`可以包含纯文本节点(就像我在设计灵活的&lt;Tooltip&gt;`组件时可能所做的那样,该组件可以包装在任何有效的jsx中)。这将导致`React.cloneElement(element)`中的错误。因此,值得检查`React.isValidElement(element)`和/或`typeof element ==='string'`。 (3认同)
  • 如何从更高阶的组件中公开ref?例如,导出默认值为InputMask(withRequired(withReadOnly(withMinMax(withHidden(TextInput))))); 如果我想从withInputMask访问TextInput中的dom元素,我将如何实现它?我已经尝试了回调引用,但它没有在withInputMask中提供.它未定义. (2认同)

adn*_*ili 18

如果要访问任何DOM元素,只需添加ref属性即可直接访问该元素.

<input type="text" ref="myinput">
Run Code Online (Sandbox Code Playgroud)

然后你可以直接:

componentDidMount: function() 
{
    this.refs.myinput.select();

},
Run Code Online (Sandbox Code Playgroud)

ReactDOM.findDOMNode()如果您已添加ref任何元素,则无需使用它们.

  • 请注意,只有在向DOM元素添加了引用(例如<div ref ="myRef"/>)时才需要findDOMNode.如果你在React组件节点上使用ref(例如<MyComponent ref ="myRef"/>),你确实需要它.在第一种情况下this.refs.myRef是DOM节点,而在第二种情况下它是React组件实例. (3认同)

Pav*_*ati 15

这可以通过使用refs属性来实现.

在想要达到<div>你想要做的事情的例子中,使用is <div ref="myExample">.然后,您将能够通过使用获取该DOM节点React.findDOMNode(this.refs.myExample).

从那里获得每个子节点的正确DOM节点可能就像映射一样简单this.refs.myExample.children(我还没有测试过)但你至少可以通过使用ref属性来获取任何特定的挂载子节点.

以下是关于refs的官方反应文档以获取更多信息.


bha*_*arc 5

React.findDOMNode(this.refs.myExample) 在另一个答案中提到的已被弃用。

使用ReactDOM.findDOMNode来自'react-dom'代替

import ReactDOM from 'react-dom'
let myExample = ReactDOM.findDOMNode(this.refs.myExample)
Run Code Online (Sandbox Code Playgroud)


Lau*_*ren 5

您可以使用新的React ref api进行此操作。

function ChildComponent({childRef}) {
 returns (<div ref={childRef} />)
}

class Parent extends Component {
  myRef = React.createRef()

  get doSomethingWithChildRef() {
     console.log(this.myRef) // Will access child DOM node.
  }

  render() {
    <ChildComponent childRef={this.myRef}>
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 你如何适应未知数量的“孩子”? (3认同)