使用v0.13.0中引入的React.findDOMNode
方法,我可以通过this.props.children
上的映射获取传递给父组件的每个子组件的DOM节点。
但是,如果某些孩子碰巧是React Elements而不是Components(例如,其中一个孩子是通过JSX创建的<div>
),React会抛出一个不变的违规错误。
有没有办法在挂载后获取每个子节点的正确DOM节点,而不管子节点是什么类?
答案 0 :(得分:52)
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节点。
答案 1 :(得分:17)
如果您想访问任何DOM元素,只需添加ref
属性即可直接访问该元素。
<input type="text" ref="myinput">
然后你可以直接:
componentDidMount: function()
{
this.refs.myinput.select();
},
如果您为任何元素添加了ReactDOM.findDOMNode()
,则无需使用ref
。
答案 2 :(得分:15)
这可以通过使用refs属性来实现。
在想要达到<div>
想要做的事情的示例中,使用的是<div ref="myExample">
。然后,您将能够使用React.findDOMNode(this.refs.myExample)
获取该DOM节点。
从那里获取每个子节点的正确DOM节点可能就像映射this.refs.myExample.children
一样简单(我还没有测试过)但你至少可以通过以下方式获取任何特定的挂载子节点使用ref属性。
以下是官方react documentation on refs了解详情。
答案 3 :(得分:4)
React.findDOMNode(this.refs.myExample)
已被删除。
使用ReactDOM.findDOMNode
中的'react-dom'
代替
import ReactDOM from 'react-dom'
let myExample = ReactDOM.findDOMNode(this.refs.myExample)
答案 4 :(得分:4)
您可以使用新的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}>
}
}
答案 5 :(得分:2)
我发现了使用新的回调引用的简便方法。您可以仅将回调作为道具传递给子组件。像这样:
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>
)