Ответ 1
Немного поздно с ответом, но технически вы можете получить элемент hight таким образом:
var node = ReactDOM.findDOMNode(this.refs[ref-name]);
if (node){
var calculatedHeight = node.clientHeight;
}
Я пытаюсь интегрировать или создать версию React https://github.com/kumailht/gridforms, для этого мне нужно нормализовать высоту столбцов внутри строки. Оригинал берет высоту строки сетки и применяет ее к столбцам детей.
Я планировал получить высоту строки, а затем сопоставить ее с свойством ребенка, хотя из моих попыток я думаю, что это может быть не идеальным или даже возможным?
Ниже мой текущий код.
GridRow = React.createClass({
render(){
const children = _.map(this.props.children, child => {
child.props.height = // somehow get row component height
return child
})
return (<div data-row-span={this.props.span} {...this.props}>
{children}
</div>)
}
})
GridCol = React.createClass({
render(){
return (<div data-field-span={this.props.span} style={{height:this.props.height}} {...this.props}>
{this.props.children}
</div>)
}
})
Я тестировал установку стиля таким образом, и он будет работать, но получить высоту нет.
EDIT: Fiddle:
https://jsfiddle.net/4wm5bffn/2/
Немного поздно с ответом, но технически вы можете получить элемент hight таким образом:
var node = ReactDOM.findDOMNode(this.refs[ref-name]);
if (node){
var calculatedHeight = node.clientHeight;
}
В соответствии с текущими документами React предпочтительное использование refs - передать ему обратный вызов, а не строку, доступ к которой можно получить в другом месте this.refs. Таким образом, чтобы получить высоту div (в классе React.Component):
componentDidMount() {
this.setState({ elementHeight: this.divRef.clientHeight });
}
render() {
return <div ref={element => this.divRef = element}></div>
}
Или он работает таким образом, хотя я не знаю, является ли это целесообразным, поскольку мы устанавливаем состояние в методе рендеринга.
getHeight(element) {
if (element && !this.state.elementHeight) { // need to check that we haven't already set the height or we'll create an infinite render loop
this.setState({ elementHeight: element.clientHeight });
}
}
render() {
return <div ref={this.getHeight}></div>;
}
Ссылка: https://facebook.github.io/react/docs/more-about-refs.html
Вот пример использования refs
и clientWidth
/clientHeight
:
import React, { Component } from 'react';
import MyImageSrc from './../some-random-image.jpg'
class MyRandomImage extends Component {
componentDidMount(){
let { clientHeight, clientWidth } = this.refs.myImgContainer;
console.log(clientHeight, clientWidth);
}
render() {
return (
<div ref="myImgContainer">
<img src={MyImageSrc} alt="MyClickable" />
</div>
);
}
}
export default MyRandomImage;
Примечание: это работает для width
надежно, но не height
. Будет редактировать, если я найду исправление...
Не знаю ни о ком другом, но я всегда должен получить его на следующем тике, чтобы быть уверенным в правильной высоте и ширине. Чувствует себя бестолково, но я предполагаю, что это связано с циклом рендеринга, но сейчас я его возьму. onLayout может работать лучше в определенных случаях использования.
componentDidMount() {
setTimeout(() => {
let ref = this.refs.Container
console.log(ref.clientHeight)
console.log(ref.clientWidth)
}, 1)
}
Согласно этому ответу размеры компонента могут быть получены с нулевой шириной или высотой внутри обработчика события componentDidMount
. Так что я вижу несколько способов решить это.
Обработайте событие в компоненте React верхнего уровня и либо пересчитайте размеры там, либо перерисовайте конкретный дочерний компонент.
Установите обработчик события загрузки для componentDidMount
чтобы обрабатывать загрузку ячеек в компонент реагирования для пересчета нужных размеров:
componentDidMount = () => {
this.$carousel = $(this.carousel)
window.addEventListener('load', this.componentLoaded)
}
Затем в методе componentLoaded
просто сделайте то, что вам нужно.
Мое личное мнение состоит в том, чтобы попытаться избежать использования статических и измеренных размеров, как это, если вы можете избежать этого, потому что это может осложнить приложение без необходимости. Но иногда вы не можете обойти это. Ваш компонент нужно будет установить, прежде чем вы сможете получить от него размер.
Общий подход:
.clientHeight
и/или .clientWidth
В вашем случае вы хотите захватить размер столбца, вы можете сделать что-то вроде:
GridRow = React.createClass({
render(){
const children = _.map(this.props.children, child => {
child.props.height = // somehow get row component height
return child
})
return (<div data-row-span={this.props.span} {...this.props}>
<GridCol onSizeChange={(size) => {
//Set it to state or whatever
console.log("sizeOfCol", size);
}} />
</div>)
}
})
GridCol = React.createClass({
componentDidMount(){
//Set stizes to the local state
this.setState({
colH: this.col.clientHeight,
colW: this.col.clientWidth
});
//Use a callback on the props to give parent the data
this.props.onSizeChange({colH: this.col.clientHeight, colW: this.col.clientWidth})
}
render(){
//Here you save a ref (col) on the class
return (<div ref={(col) => {this.col = col}} data-field-span={this.props.span} style={{height:this.props.height}} {...this.props}>
<.... >
</div>)
}
})
Я бы предпочел сделать это в componentDidUpdate, но, убедившись, что выполняется условие для предотвращения бесконечного цикла:
componentDidUpdate(prevProps, prevState) {
const articleContainer = document.getElementById('yourId');
const width = articleContainer.clientWidth;
if (this.state.width !== width) {
this.setState({ width });
}
}