在渲染

时间:2016-05-17 00:56:01

标签: javascript css reactjs

我需要能够通过其offsetHeight来定位React DOM元素。

问题是我无法收集尚未创建的元素的offsetHeight(因此高度不能作为参数传递给渲染函数)而且我也无法计算渲染内部的高度函数,如React DOM refs docs中所述:

  

永远不要访问任何组件的render方法中的refs - 或者当任何组件的render方法甚至在调用堆栈中的任何位置运行时。

DOM元素应该相对于单击的图标进行渲染以显示它。

组件树:

|— FormInputGroup
  |— Label
    |— TooltipIcon
  |— Tooltip
  |— Input

tooltip-icon的渲染功能:

const TooltipIcon = ({ attribute, setCurrentTooltip }) => (
  <Icon
    name="tooltip"
    style={{
      position: "relative",
      top: "1px",
      marginLeft: "10px",
      "cursor": "pointer",
    }}
    onClick={() => setCurrentTooltip(attribute)}
  />
)

渲染功能:

const Tooltip = ({ title, content, setCurrentTooltip }) => (
  <div className="popover"
    style={{
//      top: "-"+ ReactDOM.findDOMNode(this).offsetHeight +"px",
    }}
  >
    <h3 className="popover-title">{title}</h3>
    <div className="popover-close-button"
      onClick={() => setCurrentTooltip(null)}
    />
    <div className="popover-content">{content}</div>
  </div>
)

这是没有定位的DOM元素: not positioned

以下是我想要渲染位置的方法(顶部: - (offsetHeight)px: positioned

2 个答案:

答案 0 :(得分:3)

不确定它是最好的解决方案,但您可以使用的一种技术是通过组件状态跟踪您的样式,首先将其初始化为空:

this.state = { style: {} };

然后,一旦您可以成功访问您要查找的元素,就可以在componentDidMount()函数中更新该状态:

componentDidMount() {
  this.setState(
    {style: { top: "-" + (ReactDOM.findDOMNode(this).offsetHeight) + "px" } }
  );
} 

如果需要,将其作为道具传递给需要它的任何子组件。

我将一个带有一些注释的codepen放在一起,以进一步说明:http://codepen.io/anon/pen/vGwyVj

答案 1 :(得分:1)

我自己也有类似的问题,一个解决方法是使用生命周期方法componentDidMount,因此您需要使用受控或“智能”组件。

DEMO

class Tooltip extends React.component {
  constructor(props) {
    super(props);
    this.state = {
      mounted: false,
      ... other state stuff
    };
  }
  ....
}

componentDidMount中,您将mounted的状态设置为true,此处您还可以访问您的组件:

componentDidMount() {
  this.setState({mounted: true})
  // get your style here...
}

然后在渲染函数中,您有条件地根据该状态渲染组件:

render() {
   if (this.state.mounted) {
     // return your component with the offset style
     // which you can pass in as a prop...
   } else {
     // you can return a version of the component that is not offset here, 
     // I chose not to do this, React is pretty fast. 
     }
}