【问题标题】:React, get bound parent dom element name within component反应,在组件中获取绑定的父 dom 元素名称
【发布时间】:2015-12-27 14:08:21
【问题描述】:

在我的组件中,如何访问嵌套在其中的父组件的名称?

所以如果我的渲染是这样的:

ReactDOM.render(
      <RadialsDisplay data={imagedata}/>,
      document.getElementById('radials-1')
);

如何从组件本身中检索 id 名称 #radials-1?

【问题讨论】:

  • 你不能只使用 document.getElementById('radials-1')?
  • 我有多个渲染这个组件的不同ID
  • 传递 'radials-1' 作为道具?
  • 没有。需要比这更有活力。

标签: dom reactjs components parent-child


【解决方案1】:

将它作为属性传递可能是最有意义的,但是如果您真的需要以编程方式获取它,并且从组件内部,您可以等待要挂载的组件,找到它的 DOM 节点,然后查看它的父节点。

这是一个例子:

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's 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 的参数并返回一个新函数。此函数可以将组件类型作为其唯一参数,并返回一个高阶组件。渲染时,新组件将渲染 passed 组件及其所有原始道具,以及在 property 参数指定的属性上指定父容器 ID 的附加道具。

如果您愿意,可以将它们与 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

【讨论】:

  • 状态是否是父 ID 的最佳位置,因为随着组件状态通过 setState 更新,这不会发生变化?
  • @DavidGlass 有什么替代方案?如果您在实例本身上设置它(例如this.containerId = ...),那么您必须添加一个forceUpdate 调用。 setState 自动重新渲染,并且容器 ID 是组件状态的一部分,即使它以后不会改变。
  • 我的错,我没有看到您将父 ID 渲染到节点的位置
  • 我不确定为什么,但你的 jsbin 示例似乎不再有效。
  • 对 ReactDOM 的过时引用导致 jsbin 停止运行。不过答案很好!
猜你喜欢
  • 2013-01-22
  • 1970-01-01
  • 2017-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-20
  • 2011-02-08
  • 1970-01-01
相关资源
最近更新 更多