从 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} />;
}
}
使用 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)
.
从那里获得每个 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} />;
}
}