问题
Is it possible to get an HTML tag name from a React element (return from a component)? For example:
function Foo() {
return <span>Hello</span>;
}
The HTML tag name would be span
. I know you can look into the type
property of the React element, but it gets really difficult between SFC and normal components, and even harder when the component depth is rather large. For example:
function Bar() {
return <Foo />;
}
Should still return span
.
回答1:
No.
React Elements are a virtual construct, and they don't directly represent DOM elements. There are two types of React Elements - "regular" HTML DOM elements, and instantiations of a React Class. The first one has a "type" because it is extremely simple, stateless, and immutable, and is created only to render its corresponding DOM element (but don't confuse it with the DOM element itself!) An example of this would be <div>Foo</div>
in JSX or React.createElement("div", null, "Foo")
in JS.
However instantiations of a React Class don't have a "type" because they don't represent a typical DOM element. When we instantiate a React Class we call it a "Component" to identify it as a single instance of the Class, having a render
method, encapsulated state, etc. It's impossible to retrieve the "type" of a Component because the actual DOM elements that it will render are completely dependent on its internal state and what the render
method decides to return. An example of this would be a React Class defined somewhere and then instantiated with <Foo />
or React.createElement(Foo)
.
The only way to know what DOM elements a Component is actually rendering is to, well, mount and render it and see what it does. There is no "type" inherent to the component itself. You could conceivably mount a Component, use ref
to capture the DOM element as it's rendered, and then use a callback function to pass this information back to parent(s).
var Child = React.createClass({
render: function() {
return <div ref={function(el){this.props.whatElementAmI(el)}.bind(this)} >Oh My!</div>
}
});
var Parent = React.createClass({
whatElementAmI: function(el) {
console.log(el.nodeName); // "DIV"
},
render: function() {
return <div><Child whatElementAmI={this.whatElementAmI.bind(this)} /></div>
}
});
https://facebook.github.io/react/docs/glossary.html#react-elements
回答2:
You can use React's Top-Level API to grab the DOM node. Two caveats: 1) this doesn't work on stateless functional components as you can't put refs on them, and 2) it only works if the component outputs a native DOM element, so it won't work in your second case where the component outputs another React component.
import ReactDOM from 'react-dom';
class MyComponent extends React.Component {
render() {
return <span>Hello</span>;
}
}
class Container extends React.Component {
componentDidMount() {
var domNode = ReactDOM.findDOMNode(this._component);
console.log(domNode.tagName); // "DIV"
}
render() {
return <MyComponent ref={(c) => this._component = c} />
}
}
来源:https://stackoverflow.com/questions/40121680/get-html-tag-name-from-react-element