I'am currently working on a navbar with a drawer element from the material-ui libary.
I want to forward the <Drawer>
Component to the parent navbar, which should let me call the
toggleDrawer
function of my NavDrawer
component. I used the forwardRef function from the react libary but my ref ist always null
.
The parent component
function ParentComponent() {
const drawerRef = useRef<DrawerHandle>(null);
const toggleDrawer = () => {
// drawerRef.current is null >:(
drawerRef.current?.toggleDrawer(true)
};
return (
<>
<AppBar position={"sticky"}>
<Button onClick={toggleDrawer} />
</AppBar>
<NavigationDrawer open={false} ref={drawerRef}/>
</>
);
}
and the forwarded drawer component
import React, {forwardRef, useState} from 'react';
import {Drawer} from "@mui/material";
type Props = {
open: boolean
};
export type DrawerHandle = {
alterToggle: () => void
}
const NavigationDrawer = forwardRef<DrawerHandle, Props>((props, ref) => {
const [isOpen, setIsOpen] = useState(props.open)
const toggleDrawer =
(open: boolean) =>
(event: React.KeyboardEvent | React.MouseEvent) => {
if (
event.type === 'keydown' &&
((event as React.KeyboardEvent).key === 'Tab' ||
(event as React.KeyboardEvent).key === 'Shift')
) {
return;
}
setIsOpen(open)
};
return (
<Drawer
ref={ref}
anchor={"left"}
open={isOpen}
onClose={toggleDrawer(false)}
>
<p>Item1</p>
<p>Item2</p>
</Drawer>
);
})
I cant wrap my head around the issue here, maybe its type related but than the ref object should be an wrongly typed object but not null.
You don't have to pass ref
to the Drawer
since you don't need access to it's properties. All you need is just imperativeHandle
to return the handler to the parent.
// in NavDrawer
useImperativeHandle(ref,
() => ({
toggleDrawer,
}),
[]);
Then the ref.current
object in ParentComponent
will contain toggleDrawer
method.