جافاسكريبت - ReactJS - الحصول على ارتفاع عنصر
كيف يمكنني الحصول على ارتفاع عنصر بعد أن يقوم React بعرض هذا العنصر؟
إتش تي إم إل
<div id="container">
<!-- This element's contents will be replaced with your component. -->
<p>
jnknwqkjnkj<br>
jhiwhiw (this is 36px height)
</p>
</div>
ريأكت جي إس
var DivSize = React.createClass({
render: function() {
let elHeight = document.getElementById('container').clientHeight
return <div className="test">Size: <b>{elHeight}px</b> but it should be 18px after the render</div>;
}
});
ReactDOM.render(
<DivSize />,
document.getElementById('container')
);
النتيجة
Size: 36px but it should be 18px after the render
يحسب ارتفاع الحاوية قبل العرض (36 بكسل). أريد الحصول على الارتفاع بعد العرض. النتيجة الصحيحة يجب أن تكون 18 بكسل في هذه الحالة. jsfiddle
الإجابة رقم 1
بالنسبة لأولئك المهتمين باستخدام react hooks، قد يساعدكم هذا في البدء.
import React, { useState, useEffect, useRef } from 'react'
export default () => {
const [height, setHeight] = useState(0)
const ref = useRef(null)
useEffect(() => {
setHeight(ref.current.clientHeight)
})
return (
<div ref={ref}>
{height}
</div>
)
}
الإجابة رقم 2
فيما يلي مثال محدث على ES6 باستخدام المرجع.
تذكر أنه يجب علينا استخدام مكون فئة في React لأننا نحتاج إلى الوصول إلى طريقة دورة الحياة componentDidMount() لأنه لا يمكننا تحديد ارتفاع عنصر إلا بعد عرضه في DOM.
import React, {Component} from 'react'
import {render} from 'react-dom'
class DivSize extends Component {
constructor(props) {
super(props)
this.state = {
height: 0
}
}
componentDidMount() {
const height = this.divElement.clientHeight;
this.setState({ height });
}
render() {
return (
<div
className="test"
ref={ (divElement) => { this.divElement = divElement } }
>
Size: <b>{this.state.height}px</b> but it should be 18px after the render
</div>
)
}
}
render(<DivSize />, document.querySelector('#container'))
يمكنك العثور على المثال الجاري هنا: https://codepen.io/bassgang/pen/povzjKw
الإجابة رقم 3
انظر إلى هذا المثال (في الواقع قمت بتحديث مثالِك)
تحتاج إلى الربط مع componentDidMount الذي يتم تنفيذه بعد طريقة العرض render. هناك، تحصل على الارتفاع الفعلي للعنصر.
var DivSize = React.createClass({
getInitialState() {
return { state: 0 };
},
componentDidMount() {
const height = document.getElementById('container').clientHeight;
this.setState({ height });
},
render: function() {
return (
<div className="test">
Size: <b>{this.state.height}px</b> but it should be 18px after the render
</div>
);
}
});
ReactDOM.render(
<DivSize />,
document.getElementById('container')
);
<script src="https://facebook.github.io/react/js/jsfiddle-integration-babel.js"></script>
<div id="container">
<p>
jnknwqkjnkj<br>
jhiwhiw (this is 36px height)
</p>
<!-- This element's contents will be replaced with your component. -->
</div>
الإجابة رقم 4
بدلاً من استخدام document.getElementById(...)، الحل الأفضل (والأكثر حداثة) هو استخدام هوك useRef في React الذي يخزن مرجعًا للمكوّن/العنصر، مع دمجه مع هوك useEffect الذي يُنفّذ عند عرض المكوّن.
import React, {useState, useEffect, useRef} from 'react';
export default App = () => {
const [height, setHeight] = useState(0);
const elementRef = useRef(null);
useEffect(() => {
setHeight(elementRef.current.clientHeight);
}, []); //empty dependency array so it only runs once at render
return (
<div ref={elementRef}>
{height}
</div>
)
}
الإجابة رقم 5
قد يظهر صفرًا. تساعد setTimeout في الحصول على القيمة الصحيحة وتحديث الحالة.
import React, { useState, useEffect, useRef } from 'react'
export default () => {
const [height, setHeight] = useState(0)
const ref= useRef(null)
useEffect(() => {
if(ref.current.clientHeight){
setTimeout(() => {
setHeight(ref.current.clientHeight)
}, 1000)
}
})
return (
<div ref={ref}>
{height}
</div>
)
}
الإجابة رقم 6
ستريد أيضًا استخدام المراجع على العنصر بدلًا من استخدام document.getElementById، فهو مجرد شيء أكثر متانة قليلًا.
