将React Hooks参考与类和函数一起使用

时间:2019-07-07 16:35:01

标签: reactjs react-hooks

我已经退出React游戏已有一段时间了。回来,我正在尝试实现已由Hooks重写的Material UI库。

在我看来,这似乎是非常令人困惑的+ spagetti代码。

我只是想引用一个函数,以便可以切换抽屉,该怎么办?

// Old class
export default class DefaultContainer extends Component<ViewProps, any> {

    render() {
        return (
            <View>

                <MainAppBar
                    onPress={() => this.onMenuPressed()}
                />

                {this.props.children}

                <MainDrawer
                    ref={'drawer'}
                />
            </View>
        );
    }

    onMenuPressed = () => {
       // TODO The bit that isn't working
       (this.refs['drawer'] as Drawer).handleToggle()
    }
}

现在使用新的材质UI抽屉

// New Drawer (3x more code now..)
const useStyles = makeStyles({
    list: {
        width: 280,
    },
    fullList: {
        width: 'auto',
    },
})

type Props = {
}

function MainDrawer(props: Props, ref: any) {

    const classes = useStyles();
    const [state, setState] = React.useState({
        left: false,
    });

    const toggleDrawer = () => (
        event: React.KeyboardEvent | React.MouseEvent,
    ) => {
        if (
            event.type === 'keydown' &&
            ((event as React.KeyboardEvent).key === 'Tab' ||
                (event as React.KeyboardEvent).key === 'Shift')
        ) {
            return;
        }

        setState({ ...state, left: true });
    };

    const inputRef = useRef();
    useImperativeHandle(ref, () => {
        toggleDrawer()
    });

    const sideList = () => (
        <div
            className={classes.list}
            role="presentation"
            onClick={toggleDrawer()}
            onKeyDown={toggleDrawer()}
        >
            <List>
                <ListItem button key={'drawer_item'}>
                    <ListItemIcon><GroupIcon /></ListItemIcon>
                    <ListItemText primary={'Test Item'} />
                </ListItem>
            </List>
        </div>
    );

    return (
        <div>
            <Button onClick={toggleDrawer()}>Open Left</Button>
            <Drawer open={state.left} onClose={toggleDrawer()}>
                {sideList()}
            </Drawer>
        </div>
    );
}

export default forwardRef(MainDrawer);

1 个答案:

答案 0 :(得分:1)

我正在努力理解为什么您需要从MainDrawer内部调用一个函数,而不是仅仅利用props这样的

容器

export default function DefaultContainer(props: ViewProps) {
  const [drawerOpen, setDrawerOpen] = React.useState(false);
  // assuming it's a toggle?
  const toggleMenu = React.useCallback(() => setDrawerOpen(open => !open));
  return (
    <View>
        <MainAppBar onPress={toggleMenu} />
        {this.props.children}
        <MainDrawer open={drawerOpen} />
    </View>
  )
}

MainDrawer

function MainDrawer(props: Props) {
  const [open, setOpen] = React.useState(props.open);
  ...
  const toggleDrawer = React.useCallback(() => setOpen(open => !open));
  return (
    <div>
        <Button onClick={toggleDrawer}>Open Left</Button>
        // use prop to determine whether drawer is open or closed
        <Drawer open={open} onClose={toggleDrawer}>
          {sideList()}
        </Drawer>
    </div>
  );
}