反应菜单汉堡导致布局儿童重新阅读



我使用的是React和Material UI v5。我的布局中有一个菜单组件,它有子项。单击菜单时,会使子菜单刷新。我试着通过将children组件封装在React.memo(child(中来解决这个问题,但结果仍然是一样的。我做错了什么?

菜单组件

const MyMenu = ({ menuAnchorEl, setMenuAnchorEl }) => {
const menuOpen = Boolean(menuAnchorEl);
const handleMenuClose = () => {
setMenuAnchorEl(null);
};
const menuOptions = [
{
link: '/overview',
Icon: Dashboard,
label: 'Overview',
},
];
const MenuOption = ({
link,
Icon,
label,
}: {
link: string;
Icon: OverridableComponent<SvgIconTypeMap<unknown, 'svg'>> & {
muiName: string;
};
label: string;
}) => {
return (
<NavLink href={link}>
<MenuItem>
<ListItemIcon>
<Icon color="secondary" fontSize="small" />
</ListItemIcon>
<ListItemText sx={{ color: 'text.primary' }}>
{label}
</ListItemText>
<Typography variant="body2"></Typography>
</MenuItem>
</NavLink>
);
};
return (
<Menu
anchorEl={menuAnchorEl}
open={menuOpen}
onClose={handleMenuClose}
variant="selectedMenu"
>
<MenuList>
{menuOptions.map((n) => (
<MenuOption key={n.link} {...n} />
))}
</MenuList>
</Menu>
);
};

布局组件

const MyLayout = observer(({ children }: IProps) => {
const classes = useStyles();
const [menuAnchorEl, setMenuAnchorEl] = React.useState<null | HTMLElement>(
null,
);
return (
<>
<Hidden mdDown implementation="css">
<InstallerMenu
menuAnchorEl={menuAnchorEl}
setMenuAnchorEl={setMenuAnchorEl}
/>
<div className={classes.appFrame}>
<div className={classes.container}>{children}</div>
</div>
</Hidden>
</>
);
});

您在MyMenu内部有MenuOption组件,每次react重新渲染主组件MyMenu时,MenuOption都会被重新定义,并导致所有子组件重新渲染,为了解决这个问题,您必须将MenuOption带到主组件之外,并将所需的道具传递给它,您的代码将看起来像这个

alos阅读这篇文章,了解更多为什么组件内部的组件不好

const MyMenu = ({ menuAnchorEl, setMenuAnchorEl }) => {
const menuOpen = Boolean(menuAnchorEl);
const handleMenuClose = () => {
setMenuAnchorEl(null);
};
const menuOptions = [
{
link: '/overview',
Icon: Dashboard,
label: 'Overview',
},
];
return (
<Menu
anchorEl={menuAnchorEl}
open={menuOpen}
onClose={handleMenuClose}
variant="selectedMenu"
>
<MenuList>
{menuOptions.map((n) => (
<MenuOption key={n.link} {...n} />
))}
</MenuList>
</Menu>
);
};

function MenuOption({requiredProps}){
return (
<NavLink href={link}>
<MenuItem>
<ListItemIcon>
<Icon color="secondary" fontSize="small" />
</ListItemIcon>
<ListItemText sx={{ color: 'text.primary' }}>
{label}
</ListItemText>
<Typography variant="body2"></Typography>
</MenuItem>
</NavLink>
);
};

最新更新