使用0.13.0中引入的 React.findDOMNode方法,我能够通过映射 this.props.children获得传递给父组件的每个子组件的 DOM 节点。
React.findDOMNode
this.props.children
但是,如果一些子元素恰好是 React Elements 而不是 Component (例如,其中一个子元素是通过 JSX 创建的 <div>) ,React 会抛出一个不变的违规错误。
<div>
有没有一种方法可以在挂载后获得每个子节点的正确 DOM 节点,而不管子节点是什么类?
这可以通过使用 refs 属性来实现。
在想要达到一个 <div>的例子中,你想要做的是使用 <div ref="myExample">。然后,您就可以通过使用 React.findDOMNode(this.refs.myExample)获得该 DOM 节点。
<div ref="myExample">
React.findDOMNode(this.refs.myExample)
从这里获取每个子节点的正确 DOM 节点可能就像映射到 this.refs.myExample.children一样简单(我还没有测试过) ,但是至少可以通过使用 ref 属性获取任何特定的挂载的子节点。
this.refs.myExample.children
这是官方的 对参考文献作出反应的文件更多信息。
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 节点。
this.refs[childIdx]
ReactDOM.findDOMNode(this.refs[childIdx])
如果您想访问任何 DOM 元素,只需添加 ref属性,就可以直接访问该元素。
ref
<input type="text" ref="myinput">
然后你就可以直接:
componentDidMount: function() { this.refs.myinput.select(); },
如果在任何元素中添加了 ref,则它们不需要使用 ReactDOM.findDOMNode()。
ReactDOM.findDOMNode()
另一个答案中提到的 React.findDOMNode(this.refs.myExample)已被否定。
使用来自 'react-dom'的 ReactDOM.findDOMNode代替
'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} />; } }