Избегайте повторной визуализации при открытии/закрытии компонента диалогового окна материал-пользовательский интерфейс

#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-окно, если вы собираетесь создавать длинные списки.