能否将作为Prop传入的组件传给MUI styled()工具?
能否将Prop传入的组件传递给MUI的styled工具?
答案是可以实现,但不能直接在组件外部用styled(props.icon)的方式创建样式组件——因为styled在组件渲染前就会执行,此时组件的props还未被传入,必然会报错。
正确实现方案
根据父组件传入的是「JSX元素」还是「组件本身」,有两种不同的处理方式:
场景1:父组件传入的是JSX元素(比如带内联样式的<AddIcon />)
这种情况下,子组件无法直接对传入的元素使用styled,但可以通过外层样式容器来覆盖或添加样式:
// 父组件代码 import AddIcon from '@mui/icons-material/Add'; import ButtonWithIcon from './ButtonWithIcon'; function Parent() { return ( <ButtonWithIcon icon={<AddIcon style={{ fontSize: 24 }} />} /> ); }
// 子组件 ButtonWithIcon.jsx import { styled } from '@mui/material/styles'; // 创建一个样式容器包裹传入的图标 const IconWrapper = styled('div')(({ theme }) => ({ color: theme.palette.primary.main, marginRight: theme.spacing(1), // 直接通过后代选择器修改图标样式 '& > svg': { transition: 'color 0.2s', '&:hover': { color: theme.palette.primary.dark, }, }, })); export default function ButtonWithIcon({ icon }) { return <IconWrapper>{icon}</IconWrapper>; }
场景2:父组件传入的是组件本身(比如icon={AddIcon})
这种情况下,可以创建一个接收组件作为props的styled组件,动态渲染传入的组件并应用样式:
// 父组件代码 import AddIcon from '@mui/icons-material/Add'; import ButtonWithIcon from './ButtonWithIcon'; function Parent() { return ( <ButtonWithIcon icon={AddIcon} /> ); }
// 子组件 ButtonWithIcon.jsx import { styled } from '@mui/material/styles'; // 创建一个动态styled组件,接收IconComponent作为props const StyledIcon = styled(({ IconComponent, ...props }) => ( <IconComponent {...props} /> ))(({ theme }) => ({ color: theme.palette.error.main, fontSize: 32, cursor: 'pointer', '&:hover': { color: theme.palette.error.dark, }, })); export default function ButtonWithIcon({ icon: IconComponent }) { return <StyledIcon IconComponent={IconComponent} />; }
关键注意点
styled工具是在组件外部初始化的,无法访问组件内部的props,所以不能直接写styled(props.icon)。- 如果需要给传入的图标添加动态样式(比如基于组件其他props),可以在
styled的样式函数中接收组件props,再做逻辑判断:const StyledIcon = styled(({ IconComponent, isActive, ...props }) => ( <IconComponent {...props} /> ))(({ theme, isActive }) => ({ color: isActive ? theme.palette.success.main : theme.palette.grey[500], }));
内容的提问来源于stack exchange,提问作者jimbus
相关产品推荐
相关产品推荐

