Как заставить компонент реагировать вызывать функцию из другого Typescript пользовательского интерфейса материала - PullRequest
1 голос
/ 05 марта 2020

Есть два компонента Drawer и AppBar. Панель приложения имеет кнопку меню, и она должна вызывать событие, которое открывает ящик, я застрял в том, как это сделать, я попытался добавить "onClick = {toggleDrawer ('left', true)}" линия, которая существует в кнопке от Drawer до IconButton в TopBar, и это пошло не так. Как сказать TopBar, что «toggleDrawer» - это функция из MyDrawer?

MyDrawer.tsx

import React from 'react';
import Drawer from '@material-ui/core/Drawer';
export default function MyDrawer() {
    const classes = useStyles();
    const [state, setState] = React.useState({
        top: false,
        left: false,
        bottom: false,
        right: false,
    });
    type DrawerSide = 'top' | 'left' | 'bottom' | 'right';
    const toggleDrawer = (side: DrawerSide, open: boolean) => (
        event: React.KeyboardEvent | React.MouseEvent,
    ) => {
        if (
            event.type === 'keydown' &&
                ((event as React.KeyboardEvent).key === 'Tab' ||
                (event as React.KeyboardEvent).key === 'Shift')
            ) {
        return;
    }
    setState({ ...state, [side]: open });
    }; 
//drawer list of links
    return (
            <div>
                {/* <Button onClick={toggleDrawer('left', true)}>Open Left</Button>  */}          
                <Drawer open={state.left} onClose={toggleDrawer('left', false)}>
                    {sideList('left')}
                </Drawer>            
            </div>
        );

TopBar.tsx

import MyDrawer from '../Drawer/Drawer'
export default function TopBar() {
const renderDrawer = (
    <OlimpoDrawer/>
  );
return (
    <div className={classes.grow}>
      <AppBar position="static">
        <Toolbar>
          <IconButton
            edge="start"
            className={classes.menuButton}
            color="inherit"
            aria-label="abrir menu"
          >
            <MenuIcon />
          </IconButton>
//Toolbar features
</Toolbar>
      </AppBar>      
      {renderDrawer}
    </div>
  );
}

Ответы [ 3 ]

1 голос
/ 05 марта 2020

Как заставить компонент реагировать вызывать функцию из другого типа пользовательского интерфейса материала

//...
const toggleDrawer = (side: DrawerSide, open: boolean) => (event: React.KeyboardEvent | React.MouseEvent) => {
   if (/* ... */)
    ) {
        return;
    }
    setState({ ...state, [side]: open });
};

Поскольку toggleDrawer зависит от setState, который ограничен только внутри MyDrawer функциональный компонент, поэтому он должен оставаться внутри toggleDrawer, невозможно сделать что-то вроде export TopBar функции, которую TopBar можно использовать напрямую.

Если все, что вам нужно, это где-то хранить открытые состояния и для других компонентов, чтобы совместно использовать функцию обратного вызова, я предлагаю либо использовать компонент более высокого уровня (который они оба совместно используют), либо Redux для хранения открытого состояния MyDrawer.

1 голос
/ 05 марта 2020

Дайте мне понять ваш вопрос. Вы хотите, чтобы IconButton делал то же самое, что и Button, прокомментировал в MyDrawer.

Если это то, что вы хотите. Вы должны создать и передать функцию из TopBar в MyDrawer. toggleDrawer должно быть определено в TopBar и затем помещено в onClick из IconButton и Button, которые вы прокомментировали.

     setState(preState => ({ ...preState, [side]: open }));

Примечание: setState таким образом лучше.

0 голосов
/ 06 марта 2020

В конце концов, я, хотя и более «из коробки», сделал самое простое

В MyDrawer.tsx я изменил визуализацию, создавая кнопку меню точно так же, как и один ящик

return (
        <div>
            <IconButton
            edge="start"
            className={classes.menuButton}
            color="inherit"
            aria-label="abrir menu"
            onClick={toggleDrawer('left', true)}
            > 
                <MenuIcon />
            </IconButton>            
            <Drawer open={state.left} onClose={toggleDrawer('left', false)}>
                {sideList('left')}
            </Drawer>            
        </div>
    );
}

В TopBar.tsx

<div className={classes.grow}>
      <AppBar position="static">      
        <Toolbar>
          <MyDrawer/>
          {/* <IconButton
            edge="start"
            className={classes.menuButton}
            color="inherit"
            aria-label="abrir menu"            
          >
            <MenuIcon />
          </IconButton> */}
...