Как правильно отследить изменение размера div-элемента компонента React JS?
Очень нужна помощь в понимании, как отслеживать в функциональном компоненте, с учетом всех этапов жизненного цикла, размеры некоторых блоков компонента и уже от этого выстраивать перерисовку компонента.
Есть сетка grid компонента React и мне нужно получать размер одного из элементов этой сетки при изменении его размера. Я использую функциональный тип компонентов, но все никак не могу корректно считать эти значения при изменении окна. Использую useEffect для начального считывания значения элемента - все выходит, но не соображу как правильно отлавливать дальнейшее изменение этого элемента. Вот код компонента:
import './css/mainbanner.css';
import React, { useEffect, useRef } from 'react';
import { REACT_APP_API_URL } from '../../utils/constants';
const MainBanner = () => {
const sliderLine = useRef();
const sliderWrapper = useRef();
const mb = {
'mb': {
list: [
{
title: 'Слайд 1',
descr: 'Описание.',
btn_title: 'Подробнее',
image: 'b-01.jpg',
link: '/',
style: 1
},
{
title: 'Слайд 2',
descr: 'Описание … подходящий под новые размеры.',
btn_title: 'Смотреть сейчас',
image: 'b-02.jpg',
link: '/',
style: 1
},
]
}
}
const resizeSlider = () => {
console.log(sliderWrapper.current.offsetWidth);
}
useEffect(() => {
if (sliderWrapper.current) resizeSlider();
}, []);
return (
<div className="banner-wrapper">
<div className="mb" ref={sliderWrapper}>
<div className="sliderline" ref={sliderLine}>
<div className="slide" style={{ backgroundImage: `url(${REACT_APP_API_URL}banners/b-01.jpg` }}>
Hello world
</div>
<div className="slide" style={{ backgroundImage: `url(${REACT_APP_API_URL}banners/b-02.jpg` }}>
Hello world
</div>
</div>
</div>
<div className="b1"></div>
<div className="b2"></div>
<div className="b3"></div>
<div className="b4"></div>
</div>
);
};
export default MainBanner;
Ответы (2 шт):
Можно при изменении размера окна обновлять состояние компонента и при рендере использовать полученные данные примерно так:
// import React from "react";
const App = () => {
const [size, setSize] = React.useState({});
const ref = React.useRef();
const resizeHandler = () => {
const { clientHeight, clientWidth } = ref.current || {};
setSize({ clientHeight, clientWidth });
};
React.useEffect(() => {
window.addEventListener("resize", resizeHandler);
resizeHandler();
return () => {
window.removeEventListener("resize", resizeHandler);
};
}, []);
return (
<div>
<h3>Please resize window ... </h3>
<div
ref={ref}
style={{ border: "1px solid red", margin: "2rem", height: "70vh" }}
>
<div>
clientHeight: {size.clientHeight}, clientWidth:{size.clientWidth}
</div>
</div>
</div>
);
};
// export default App;
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>
Закину в копилку решений:
const [windowWidth, setWindowWidth] = React.useState(window.screen.width);
React.useEffect(() => {
window.onresize = () => {setWindowWidth(window.screen.width)};
// Ваш код
return () => {window.onresize = false};
}, [windowWidth]);