从 React 子元素获取 DOM 节点

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

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

有没有一种方法可以在挂载后获得每个子节点的正确 DOM 节点,而不管子节点是什么类?

165645 次浏览

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

在想要达到一个 <div>的例子中,你想要做的是使用 <div ref="myExample">。然后,您就可以通过使用 React.findDOMNode(this.refs.myExample)获得该 DOM 节点。

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

这是官方的 对参考文献作出反应的文件更多信息。

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

要获取子元素的 DOM 节点,需要克隆它们并为它们分配一个新的 ref。

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();


},

如果在任何元素中添加了 ref,则它们不需要使用 ReactDOM.findDOMNode()

另一个答案中提到的 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>
)

您可以使用新的 参考 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} />;
}
}