从 React 子元素获取 DOM 节点

Getting DOM node from React child element

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

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

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

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

在想要达到 <div> 的示例中,您想要做的是使用 <div ref="myExample">。然后你就可以通过使用 React.findDOMNode(this.refs.myExample).

获得那个 DOM 节点

从那里获得每个 child 的正确 DOM 节点可能就像映射 this.refs.myExample.children 一样简单(我还没有测试过)但你至少会能够使用 ref 属性获取任何特定已安装的 child 节点。

这里是官方 react documentation on refs 了解更多信息。

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

要获取子元素的 DOM 个节点,您需要克隆它们并为其分配新的引用。

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

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

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

<input type="text" ref="myinput">

然后就可以直接:

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

},

他们不需要使用 ReactDOM.findDOMNode(),如果你已经添加了 ref 到任何元素。

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

改用 'react-dom' 中的 ReactDOM.findDOMNode

import ReactDOM from 'react-dom'
let myExample = ReactDOM.findDOMNode(this.refs.myExample)

我找到了一种使用新回调引用的简单方法。您可以将回调作为道具传递给子组件。像这样:

class Container extends React.Component {
  constructor(props) {
    super(props)
    this.setRef = this.setRef.bind(this)
  }

  setRef(node) {
    this.childRef = node
  }

  render() {
    return <Child setRef={ this.setRef }/>
  }
}

const Child = ({ setRef }) => (
    <div ref={ setRef }>
    </div>
)

这是一个使用模态执行此操作的示例:

class Container extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      modalOpen: false
    }
    this.open = this.open.bind(this)
    this.close = this.close.bind(this)
    this.setModal = this.setModal.bind(this)
  }

  open() {
    this.setState({ open: true })
  }

  close(event) {
    if (!this.modal.contains(event.target)) {
      this.setState({ open: false })
    }
  }

  setModal(node) {
    this.modal = node
  }

  render() {
    let { modalOpen } = this.state
    return (
      <div>
        <button onClick={ this.open }>Open</button>
        {
          modalOpen ? <Modal close={ this.close } setModal={ this.setModal }/> : null
        }
      </div>
    )
  }
}

const Modal = ({ close, setModal }) => (
  <div className='modal' onClick={ close }>
    <div className='modal-window' ref={ setModal }>
    </div>
  </div>
)

您可以使用新的 React ref api

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

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

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

  render() {
    return <ChildComponent childRef={this.myRef} />;
  }
}