Ответ 1
Вероятно, имеет смысл передать его как свойство, но если вам действительно нужно его программно и внутри, вы можете дождаться, когда компонент будет монтироваться, найдите его DOM node, а затем посмотрите на его родителя.
Вот пример:
class Application extends React.Component {
constructor() {
super();
this.state = { containerId: "" };
}
componentDidMount() {
this.setState({
containerId: ReactDOM.findDOMNode(this).parentNode.getAttribute("id")
});
}
render() {
return <div>My container ID is: {this.state.containerId}</div>;
}
}
ReactDOM.render(<Application />, document.getElementById("react-app-container"));
Рабочая демонстрация: https://jsbin.com/yayepa/1/edit?html,js,output
Если вы делаете это много или хотите быть действительно фантастическим, вы можете использовать компонент более высокого порядка:
class ContainerIdDetector extends React.Component {
constructor() {
super();
this.state = { containerId: "" };
}
componentDidMount() {
this.setState({
containerId: ReactDOM.findDOMNode(this).parentNode.getAttribute("id")
});
}
render() {
if (!this.state.containerId) {
return <span />;
} else {
return React.cloneElement(
React.Children.only(this.props.children),
{ [this.props.property]: this.state.containerId }
);
}
}
}
ContainerIdDetector.propTypes = {
property: React.PropTypes.string.isRequired
}
// Takes an optional property name `property` and returns a function. This
// returned function takes a component class and returns a new one
// that, when rendered, automatically receives the ID of its parent
// DOM node on the property identified by `property`.
function withContainerId(property = "containerId") {
return (Component) => (props) =>
<ContainerIdDetector property={property}>
<Component {...props} />
</ContainerIdDetector>
}
Здесь withContainerId
- это функция, которая принимает аргумент property
и возвращает новую функцию. Эта функция может принимать тип компонента в качестве единственного аргумента и возвращает компонент более высокого порядка. При визуализации новый компонент будет отображать переданный компонент со всеми его оригинальными реквизитами плюс дополнительную опцию, указывающую родительский идентификатор контейнера в свойстве, указанном аргументом property
.
Вы можете использовать их с декораторами ES7 (как в настоящее время реализованы), если хотите, или с помощью обычного вызова функции:
@withContainerId()
class Application extends React.Component {
render() {
return <div>My containers ID is: {this.props.containerId}</div>;
}
}
// or, if you don't use decorators:
//
// Application = withContainerId()(Application);
ReactDOM.render(<Application />, document.getElementById("react-app-container"));
Рабочая демонстрация: https://jsbin.com/zozumi/edit?html,js,output