У меня есть компонент, который отображается условно, и я заранее не знаю его высоту (а также хотел бы избежать установки ее вручную). Он должен автоматически быть равен размеру его содержимого.
Чтобы получить эту высоту, я использую ссылку для ее определения. На основе этой высоты я затем хочу выполнить некоторую операцию (например, использовать часть высоты для заполнения, поля и т. д.).
Чтобы уточнить: компонент также условно визуализируется, поэтому не виден с самого начала приложения, а вместо этого становится видимым посредством некоторой модификации состояния (нажатие кнопки и т. д.).
Проблема в том, что стиль нельзя применить непосредственно к первой операции состояния. Я думаю, это происходит потому, что ссылка прикрепляется после первого процесса рендеринга? Не уверен.
Как я могу это решить?
Вот демонстрационный код, поясняющий то, что я имею в виду (а также соответствующий живой пример в codeandbox):
import React, { useEffect, useState } from "react";
const App = () => {
const [isClicked, setClick] = useState(false);
const [dimension, setDimension] = React.useState({ width: 0, height: 0 });
const ref = React.useRef(null);
useEffect(() => {
if (ref.current) {
setDimension({
width: ref.current.clientWidth,
height: ref.current.clientHeight,
});
}
}, [ref.current]);
return (
<div>
<button onClick = {() => setClick(!isClicked)}>Click me</button>
{isClicked && (
<div className = "App">
<div ref = {ref} style = {{ marginTop: dimension.height }}>
<h1>Hello</h1>
<h2>World</h2>
<h3>!</h3>
</div>
</div>
)}
</div>
);
};
export default App;
Этого можно добиться только в том случае, если вы разрешаете рендеринг компонента/div, но скрываете его от пользователя.
Вот рабочий код/пример:
useEffect(() => {
if (isClicked) {
setDimension({
width: ref.current.clientWidth,
height: ref.current.clientHeight,
});
document.getElementById("testButton").style.visibility = "visible";
} else {
document.getElementById("testButton").style.visibility = "hidden";
}
}, [isClicked]);
return (
<div>
<button onClick = {() => setClick(!isClicked)}>Click me</button>
<div className = "App">
<div
id = "testButton"
ref = {ref}
style = {{ marginTop: dimension.height, visibility: "hidden" }}
>
<h1>Hello</h1>
<h2>World</h2>
<h3>!</h3>
</div>
</div>
</div>
);
};
Для получения дополнительной информации вы можете посетить мою песочницу: Песочница
Спасибо! Это решило мою проблему. Чтобы удалить стиль вне потока, я также добавил
float: left
. Возможно, это интересно тем, у кого такая же проблема :)