2016-05-17 76 views
4

我需要能够通过其offsetHeight定位React DOM元素。在渲染前反应DOM offsetHeight

问题是我无法收集尚未创建的元素的offsetHeight(所以高度无法作为参数传递给渲染函数),而且我也无法计算其中的高度渲染功能的阵营DOM文档裁判指出:

永远不能访问任何裁判组件的渲染方法的内 - 或在任何组件的渲染方法,即使在调用堆栈在任何地方运行。

DOM元素应渲染相对于单击的图标来显示它。

组件树:

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

工具提示图标渲染功能:

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

渲染FUNC重刑:

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

不知道这是最好的解决办法,但一个技术,你可以使用通过组件的状态,以保持跟踪你的风格,初始化它是空的,首先:

this.state = { style: {} }; 

,然后更新该州在componentDidMount()函数一次您可以成功访问您正在寻找的元素:

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

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

我把一些codepen放在一起,用一些评论来说明一下:http://codepen.io/anon/pen/vGwyVj

1

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

DEMO

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

您设置的mounted真状态,在这里你也将有机会获得您的组件:在你的渲染功能

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. 
    } 
}