#reactjs #material-ui
#reactjs #материал-пользовательский интерфейс
Вопрос:
Я использую Material UI для своего проекта React, и я нахожусь в ситуации, когда я хочу получить высоту диалогового окна. Итак, я попытался сделать что-то вроде этого:
import Dialog from '@material-ui/core/Dialog';
class MyDialog extends React.Component {
constructor(props) {
super(props);
this.dialogRef = React.createRef();
}
render() {
if (this.dialogRef.curent) {
console.log(this.dialogRef.current);
}
return (
<Dialog maxWidth='sm'
innerRef={this.dialogRef}
>
// Rest removed for brevity
</Dialog>
);
}
}
export default connect(mapStateToProps, mapDispatchToProps)(withStyles(styles)(withLocalize(MyDialog)));
Теперь с помощью приведенного выше кода я вижу объект, напечатанный с помощью console.log(this.dialogRef)
строки, и у него есть свойство с именем refs
, которое является пустым объектом. Как я могу получить высоту Dialog
в этом случае? Либо внутри MyDialog
компонента, либо предполагая, что у меня есть другой вызываемый компонент, Main
который вызывает MyDialog
внутри своего метода рендеринга?
Пожалуйста, обратите внимание, что я использую "react": "^16.6.3"
и "@material-ui/core": "^3.6.1"
.
Ответ №1:
Я полагаю, что RootRef в этом случае найдет неправильный элемент DOM. Я думаю, вы хотите, чтобы div из компонента Paper внутри диалогового окна получал высоту. Вы можете сделать это, переопределив компонент для документа:
const PaperComponent = ({ dialogRef, ...other }) => {
return <div ref={dialogRef} {...other} />;
};
<Dialog
PaperProps={{ component: PaperComponent, dialogRef: this.dialogRef }}
>
Вот модифицированная версия вашей песочницы: https://codesandbox.io/s/2vxz5lq1jr
Комментарии:
1. Спасибо, Райан, это кажется намного ближе к тому, чего я хочу достичь. Я вижу, вы используете
useEffect
для регистрации offsetHeight. Могу ли я каким-то образом сохранить высоту внутри переменной, чтобы я мог получить к ней доступ также из класса, который отображает диалоговое окно? Потому что, если я попытаюсь записать в консоль значение смещения внутри класса, оно выдает null при открытии диалогового окна и фактическое значение при его закрытии.2. @terett Я думаю, что это вопрос времени. К открытию диалогового окна применяется переход, поэтому вам нужна некоторая задержка, прежде чем высота будет доступна.
3. @terett Вы могли бы попросить компонент Paper поместить высоту в контекст эффекта, чтобы передать ее чему-то более высокому в иерархии.
4. На самом деле мне даже не нужно передавать его чему-то более высокому. Я также выступаю
style
заPaperProps
. Дело в том, что я хочу изменить стиль в зависимости от высоты диалогового окна. Итак, небольшая задержка может сработать, я думаю. Как я могу этого добиться?5. Вот пример использования useLayoutEffect для этого: codesandbox.io/s/942ym6k964 . Поскольку вам не нужна ссылка в другом месте, это означает, что это можно еще больше упростить для использования
useRef
непосредственно в PaperComponent, а не передавать ссылку в качестве реквизита.
Ответ №2:
Вы можете использовать ref
prop напрямую, начиная с Material-UI версии 4.0.0-alpha.3.
function MyComponent() {
const myRef = React.useRef();
return <Dialog ref={myRef} />;
}
Комментарии:
1. Понятно, спасибо. Итак, нет способа сделать это в более ранней версии Material UI и полагаться на withStyles?
2. Вы можете использовать
RootRef
компонент с Material-UI v3.3. Спасибо, кажется, это работает, если я окружаю
<Dialog>
внутри<RootRef>
, но я не могу получить высоту. Он всегда показывает 0. Я пыталсяoffsetHeight
,clientHeight,
дажеgetBoundingClientRect()
. Все значения равны 0. Кроме того, при первом открытии диалогового окна ссылка равна нулю. Мне нужно закрыть и повторно открыть диалоговое окно, чтобы получить фактический элемент DOM. Но, как я уже сказал, даже тогда значения равны 0.4. @OlivierTassinari Мой ответ показывает способ, который работает для версии v3, но, пожалуйста, сообщите, если считаете, что есть способ получше.
5. @terett Я думаю, что даже для версии 4 ссылка на диалоговое окно не предоставит нужный вам элемент DOM, поскольку он получает
div
для модального компонента, который, похоже, имеет полную высоту окна браузера, а не высоту содержимого диалогового окна.