Открытие ящика из другого файла (Material-UI, React) - PullRequest
0 голосов
/ 28 февраля 2020

Я пытаюсь открыть ящик в файле «панель инструментов» из файла «Навбар». Как вы уже догадались, я хочу открыть ящик, который должен быть в файле панели инструментов из панели навигации, звучит достаточно просто, но я просто могу заставить его работать. Я пробовал несколько методов, один из работ сорта:


Имея функцию переключения и состояние выдвижного ящика в файле макета, поэтому структура работает следующим образом: Событие Click на панели навигации. js запускает переключение function in Layout -> Toggle функция в макете изменяет состояние boxOpen -> Состояние boxOpen передается в Dashboard. js через реквизиты, которые затем управляют состоянием открытия ящика. Единственным недостатком этого метода является то, что все анимации не работают (медленно показывает ящик внутрь и наружу и т. Д. c)


Так что я подумал, что мне нужно иметь состояние выдвижного ящика и работать непосредственно внутри файла Dashboard, но как мне получить кнопку на панели навигации. js для запуска функции на панели инструментов. js?

Надеюсь, я объяснил это достаточно хорошо, чтобы вы поняли, любая идея будет оценена! Если мне нужно объяснить еще кое-что, пожалуйста, дайте мне знать!

Редактируйте 1 без анимации, работающей
Макет. js (есть конечно больше маршрутов и т.д. c, но я удалил их, чтобы сделать очиститель файлов):

const Layout = () => {
  const [dashBoardSideNavOpen, setDashBoardSideNavOpen] = React.useState(false);

  const dashBoardSideNavToggle = () => {
    setDashBoardSideNavOpen(!dashBoardSideNavOpen);
  };

  const dashBoardSideNavClose = () => {
    setDashBoardSideNavOpen(false);
  };

  return (
    <Router>
      <NavBar
        dashBoardSideNavToggle={dashBoardSideNavToggle}
      />
      <Switch>
        <Route
          path="/dashboard"
          component={props => (
            <DashBoard
              {...props}
              dashBoardSideNavOpen={dashBoardSideNavOpen}
              dashBoardSideNavToggle={dashBoardSideNavToggle}
              dashBoardSideNavClose={dashBoardSideNavClose}
            />
          )}
        />
      </Switch>
    </Router>

  );
};

export default Layout

Navbar. js:

const NavBar = ({dashBoardSideNavToggle}) => {
  return (
    <Fragment>
      <div className={classes.root}>
        <AppBar className={classes.appBar}>
          <Toolbar>     
            <Box style={{ flexGrow: 1 }}>
              <IconButton color="inherit" onClick={dashBoardSideNavToggle}>
                <MenuIcon />
              </IconButton>
            </Box>
            <Typography variant="h4" style={{ flexGrow: 1 }}>
              <Link component={RouterLink} to="/" color="inherit" underline="none">
                Title
              </Link>
            </Typography>
            <IconButton color="inherit" onClick={userSideNavToggle}>
              <MenuIcon />
            </IconButton>
          </Toolbar>
        </AppBar>
      </div>
      <div className={classes.offset} />
    </Fragment>
  );
};

DashBoard. js:

const DashBoard = ({dashBoardSideNavOpen, dashBoardSideNavToggle, dashBoardSideNavClose}) => {
  return (
    <Router>
      <div className={classes.root}>
        <Drawer
          variant="temporary"
          anchor={'left'}
          open={dashBoardSideNavOpen}
          onOpen={dashBoardSideNavToggle}
          onClose={dashBoardSideNavToggle}
          classes={{
            paper: classes.drawerPaper
          }}
          ModalProps={{
            keepMounted: true
          }}
        >
          {drawerContent}
        </Drawer>
        <Fragment>
          <Switch>
            <Route
              exact
              path={'/dashboard/overview'}
              component={Overview}
            />
          </Switch>
        </Fragment>
      </div>
    </Router>
  );
};

1 Ответ

2 голосов
/ 28 февраля 2020

Вам нужно будет сохранить состояние open в общем родительском компоненте на приборной панели и панели навигации, а затем иметь состояние и функцию для обновления состояния, передаваемого в любой компонент, необходимый для его управления. Вот простой минимальный пример типа решения, которое вы ищете:

const Parent = () => {
  const [open, setOpen] = useState(false);

  return (
    <div>
      <Controller open={open} onOpenChange={setOpen} />
      <Drawer open={open} />
    </div>
  )
}

const Controler = ({ open, onOpenChange }) => {
  return <button onClick={() => onOpenChange(!open)}>toggle drawer</button>
}

const Drawer = ({ open }) => {
  if (open) return <div>I am open!!</div>
  return <div>I am closed!!</div>
}

РЕДАКТИРОВАТЬ: <Route> не должен быть передан встроенный компонент (если компонент, который содержит маршруты никогда обновлений. На самом деле вы должны передавать только те компоненты, которые не нуждаются в каких-либо подпорках. При установке component на встроенный функциональный компонент это приведет к тому, что экземпляр визуализированного компонента будет уничтожен и повторно монтирован всякий раз, когда маршрут содержит повторные рендеры (функция функционального компонента переопределяется). Я думаю, именно поэтому ваша анимация, скорее всего, не работает правильно.

Самое простое решение - создать контекст который может посылать необходимые функции ящика вниз по дереву, так что вам не нужно передавать их как реквизиты. Что-то вроде:

const DrawerContext = React.createContext({ setOpen: () => {}, open: false });

const Parent = () => {
  const [open, setOpen] = useState(false);

  return (
    <DrawerContext.Provider value={{setOpen}}>
      <div>
        <Controller/>
        <Drawer />
      </div>
    </DrawerContext.Provider
  )
}

const Controler = () => {
  const { open, setOpen } = useContext(DrawerContext);
  return <button onClick={() => onOpenChange(!open)}>toggle drawer</button>
}

const Drawer = () => {
  const { open } = useContext(DrawerContext);

  if (open) return <div>I am open!!</div>
  return <div>I am closed!!</div>
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...