#reactjs #react-hooks #material-ui #rerender #use-ref
Вопрос:
У меня есть некоторые проблемы с пропуском повторного рендеринга при нажатии кнопки, которая открывает компонент диалогового окна. В настоящее время я использую флаг useState, который переключает мой компонент диалога, но я должен избегать повторного рендеринга, потому что есть дорогостоящие операции с большими данными.
Кто-нибудь знает, как открыть диалог с помощью кнопки Open
и Close
Диалог, нажав на кнопку диалога Exit
.
const Item = () => {
const popupRef = useRef()
const dialog = () => {
return(
<Dialog ref={popupRef}
keepMounted
fullWidth
maxWidth="md"
aria-labelledby="alert-dialog-slide-title"
aria-describedby="alert-dialog-slide-description">
<DialogTitle id="alert-dialog-slide-title">
<WrapperDialogHeader>Filters</WrapperDialogHeader>
<WrapperDialogCloseBtn>
<IconButton aria-label="close" >
<CloseIcon />
</IconButton>
</WrapperDialogCloseBtn>
</DialogTitle>
<DialogContent>
Something
</DialogContent>
<DialogActions>
<Button variant="outlined"
// onClick={ What handler here? }
color="primary">
<WrapperDialogOptionBtn>Exit</WrapperDialogOptionBtn>
</Button>
</DialogActions>
</Dialog>
)
}
return(
<>
<IconButton onClick={ /* What method here */ }>
<Typography variant="body1" color="primary">
<FilterListIcon fontSize="small" color="primary"/><WrapperFontSpecialSmall>Filters</WrapperFontSpecialSmall>
</Typography>
</IconButton>
{ dialog() }
</>
Методы, подобные popupRef.current.click()
тем, которые не существуют в ES6, я полагаю.
Как создать механизм, который переключает диалоговое окно без повторного отображения всего элемента компонента.
Ответ №1:
Переместите диалоговое окно в его собственный компонент и оберните в memo()
const Dialog = ({ open, onClose }) => {
return (
<Dialog
keepMounted // why? you said the content is huge, so why keep it mounted
fullWidth
maxWidth="md"
aria-labelledby="alert-dialog-slide-title"
aria-describedby="alert-dialog-slide-description"
open={open}
onClose={onClose}
>
<DialogTitle id="alert-dialog-slide-title">
<WrapperDialogHeader>Filters</WrapperDialogHeader>
<WrapperDialogCloseBtn>
<IconButton aria-label="close" >
<CloseIcon />
</IconButton>
</WrapperDialogCloseBtn>
</DialogTitle>
<DialogContent>
Something
</DialogContent>
<DialogActions>
<Button variant="outlined" onClick={onClose} color="primary">
<WrapperDialogOptionBtn>Exit</WrapperDialogOptionBtn>
</Button>
</DialogActions>
</Dialog>
)
};
export default memo(Dialog); // IMPORTANT
В Item
компоненте,
const Item = () => {
const [dialogOpen, setDialogOpen] = useState(false);
const handleDialogOpen = () => setDialogOpen(true);
// prevent function being recreated on state change
const handleDialogClose = useCallback(() => setDialogOpen(false), []);
return (
<>
<IconButton onClick={handleDialogOpen}>
<Typography variant="body1" color="primary">
<FilterListIcon fontSize="small" color="primary" /><WrapperFontSpecialSmall>Filters</WrapperFontSpecialSmall>
</Typography>
</IconButton>
<Dialog open={dialogOpen} onClose={handleDialogClose} />
</>
);
}
Примечание: похоже, что диалоговое окно содержит какой-то пользовательский интерфейс фильтра, предположительно один или несколько списков. Возможно, вам захочется взглянуть на react-окно, если вы собираетесь создавать длинные списки.