Как разместить компонент React относительно его родителя?

У меня есть родительский компонент React, содержащий дочерний компонент React.

<div>
  <div>Child</div>
</div>

Мне нужно применить стили к дочернему компоненту, чтобы поместить его в свой родительский элемент, но его положение зависит от размера родителя.

render() {
  const styles = {
    position: 'absolute',
    top: top(),    // computed based on child and parent height
    left: left()   // computed based on child and parent width
  };
  return <div style={styles}>Child</div>;
}

Здесь я не могу использовать процентные значения, потому что верхняя и левая позиции являются функциями ширины и высоты дочернего элемента и родителя.

Что такое способ React для этого?

Ответ 1

Ответ на этот вопрос - использовать ref, как описано в Refs to Components.

Основная проблема заключается в том, что DOM node (и его родительский DOM node) необходим для правильной позиции элемента, но он недоступен только после первого рендеринга. Из статьи, приведенной выше:

Выполнение измерений DOM почти всегда требует обращения к "родному" компоненту и доступа к его базовому DOM node с помощью ссылки. Refs - один из единственных практических способов сделать это надежно.

Вот решение:

getInitialState() {
  return {
    styles: {
      top: 0,
      left: 0
    }
  };
},

componentDidMount() {
  this.setState({
    styles: {
      top: computeTopWith(this.refs.child),
      left: computeLeftWith(this.refs.child)
    }
  })
},

render() {
  return <div ref="child" style={this.state.styles}>Child</div>;
}

Это будет правильно позиционировать элемент сразу после первого рендеринга. Если вам также необходимо переместить элемент после изменения в реквизиты, сделайте изменение состояния в componentWillReceiveProps(nextProps).

Ответ 2

Правильный способ сделать это - использовать CSS. Если вы примените position:relative к родительскому элементу, то дочерний элемент можно перенести с помощью top и left в отношении этого родителя. Вы даже можете использовать проценты, например top:50%, который использует высоту родительского элемента.