[英]React-router-dom with Material-ui working but not mounting components
[英]react-router-dom & material ui : forwardRef issue
尽管我已经应用了几篇文章和 materail-ui 网站示例中提到的 forwardRef,但我仍然在控制台中收到警告。 我真的不明白为什么。
我正在尝试创建一个包含项目列表的抽屉,这些项目是嵌入到 Material-UI 链接组件中的 react-router 链接。 我嵌入它们是为了从我创建的全局 MUI 主题中受益
PS:这是一个 typescript 代码。 参考强类型是地狱;-)
这是重现问题的 CODESANBOX。 确保扩展足够的代码框浏览器页面以显示抽屉
链接组件
import { Link as MUILink, LinkBaseProps } from "@material-ui/core";
import React from "react";
import {
Link as LinkRouter,
LinkProps as RouterLinkProps
} from "react-router-dom";
type RefLinkRouter =
| ((instance: HTMLAnchorElement | null) => void)
| React.RefObject<HTMLAnchorElement>
| null
| undefined;
type ILinkProps = RouterLinkProps;
const fwdLink = (props: ILinkProps, ref: RefLinkRouter): JSX.Element => (
<LinkRouter ref={ref} {...props} />
);
const ForwardedLink = React.forwardRef<HTMLAnchorElement | null, ILinkProps>(
fwdLink
);
const Link: React.FC<ILinkProps & LinkBaseProps> = (
props: ILinkProps & LinkBaseProps
) => {
return (
<MUILink component={ForwardedLink} to={props.to} {...props}>
{props.children}
</MUILink>
);
};
export { Link, ILinkProps };
抽屉组件
import { Link } from "./../Link";
import { List, ListItem, makeStyles } from "@material-ui/core";
import Drawer from "@material-ui/core/Drawer";
import Hidden from "@material-ui/core/Hidden";
import ListItemIcon from "@material-ui/core/ListItemIcon";
import MailIcon from "@material-ui/icons/Mail";
import InboxIcon from "@material-ui/icons/MoveToInbox";
import React from "react";
const drawerWidth = 240;
interface IOptionsValue {
value: string;
label: string;
}
interface IDrawerMenuItemsProps extends IOptionsValue {
to: string;
iconName?: JSX.Element;
}
interface IResponsiveDrawerProps {
container?: number;
menuItems: Array<IDrawerMenuItemsProps>;
}
const useStyles = makeStyles({
list: {
backgroundColor: "blue"
},
drawerMenuItemList: {
color: "white",
backgroundColor: "blue"
}
});
const ResponsiveDrawer: React.FC<IResponsiveDrawerProps> = (
props: IResponsiveDrawerProps
): JSX.Element => {
// const { container } = props;
const { menuItems } = props;
const classes = useStyles();
const [mobileOpen, setMobileOpen] = React.useState(false);
const handleDrawerToggle = () => {
setMobileOpen(!mobileOpen);
};
const drawer = (
<div>
<div />
<List className={classes.drawerMenuItemList}>
{menuItems.map((menuItem: IDrawerMenuItemsProps, index: number) => {
return (
<ListItem
className={classes.drawerMenuItemList}
key={menuItem.value}
component={Link}
to={menuItem.to}
>
<ListItemIcon className={classes.drawerMenuItemList}>
{index % 2 === 0 ? <InboxIcon /> : <MailIcon />}
</ListItemIcon>
<p className={classes.drawerMenuItemList}>{menuItem.label}</p>
</ListItem>
);
})}
</List>
</div>
);
return (
<>
<Hidden smUp implementation="css">
<Drawer
// container={container}
style={{ width: drawerWidth }}
variant="temporary"
anchor={"right"}
open={mobileOpen}
onClose={handleDrawerToggle}
ModalProps={{
keepMounted: true // Better open performance on mobile.
}}
>
{drawer}
</Drawer>
</Hidden>
<Hidden xsDown implementation="css">
<Drawer variant="permanent" open>
{drawer}
</Drawer>
</Hidden>
</>
);
};
export default ResponsiveDrawer;
我称之为抽屉的主页
import React from "react";
import ResponsiveDrawer from "./../ResponsiveDrawer";
const HomePage = () => {
const menuItems = [
{
label: "Menu 1",
value: "menu1",
to: "/app"
},
{
label: "Menu 2",
value: "menu2",
to: "/app"
}
];
return (
<>
<ResponsiveDrawer menuItems={menuItems} />
<div>here were are</div>
</>
);
};
export default HomePage;
根据文档,我们对使用 Refs 有一些注意事项。
https://material-ui.com/guides/composition/#caveat-with-refs
但是,您实现它的方式,我意识到您的想法是利用 Material-UI 的 Link 组件,该组件具有 react-router 的容量并使用 Children 组件。
在这种情况下,您可以使用“组件”属性,但为此您必须使用 React.forwardRef 来转发 ref 以使组件能够访问 DOM 节点。
https://codesandbox.io/s/keen-banzai-o2q24
type LinkProps = LinkBaseProps & RouterLinkProps;
const LinkBehavior = React.forwardRef<any, ILinkProps>((props, ref) => (
<MUILink component={LinkRouter} ref={ref} to={props.to} {...props} />
));
export { LinkBehavior as Link };
export type ILinkProps = LinkProps;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.