最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React DOM offsetHeight before rendering - Stack Overflow

programmeradmin2浏览0评论

I need to be able to position a React DOM element by its offsetHeight.

The problem is that I can't gather the offsetHeight of an element that hasn't been created yet (so the height cannot be passed to the render function as a parameter) and I also cannot calculate the height inside of the render function as noted in the React DOM refs docs:

Never access refs inside of any ponent's render method – or while any ponent's render method is even running anywhere in the call stack.

The DOM element should render relative to an icon that is clicked to display it.

The ponent tree:

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

I need to be able to position a React DOM element by its offsetHeight.

The problem is that I can't gather the offsetHeight of an element that hasn't been created yet (so the height cannot be passed to the render function as a parameter) and I also cannot calculate the height inside of the render function as noted in the React DOM refs docs:

Never access refs inside of any ponent's render method – or while any ponent's render method is even running anywhere in the call stack.

The DOM element should render relative to an icon that is clicked to display it.

The ponent tree:

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

The render function for the tooltip-icon:

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

The render function:

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>
)

Here is the DOM element without the positioning: not positioned

Here is how I would like the position to be rendered (with top: -(offsetHeight)px: positioned

Share Improve this question asked May 17, 2016 at 0:56 cmwallcmwall 4672 gold badges6 silver badges15 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 3

Not sure it's the best solution, but one technique you can use is to keep track of your style through ponent state, initializing it to be empty at first:

this.state = { style: {} };

And then updating that state in a ponentDidMount() function once you can successfully access the element you are looking for:

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

Passing it down as a prop if need be to any child ponent that needs it.

I put together a codepen with some ments to illustrate a little further: http://codepen.io/anon/pen/vGwyVj

I had a similar problem myself, one work around is to use the lifecycle method ponentDidMount, as such you will need to use a controlled or 'smart' ponent.

DEMO

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

in ponentDidMount you set the state of mounted to true, here you will also have access to your ponent:

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

then in your render function you conditionally render the ponent based on that state:

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

评论列表(0)

  1. 暂无评论