如何正确处理自定义组件中MUI组件Props的ref属性?
MUI自定义组件中ref传递的正确方式
我基于MUI的Paper组件封装了一个自定义组件,希望它同时支持自定义属性和Paper自带的PaperProps,但对于ref属性的处理拿不准,目前有两种实现思路,想知道哪种才是正确的,以及是否需要在ComponentProps里显式Omit"ref"属性:
方式一:直接向下传递props
// ... import { PaperProps, styled } from '@mui/material'; type ComponentProps = PaperProps & { a: string, b: string }; export const MyPaper = styled(Paper)(/* ... */); const Component: FC<ComponentProps> = (props) => { const { a, b, ...other } = props; // ... return <MyPaper {...other}>...</MyPaper>; };
方式二:使用forwardRef并Omit ref
// ... import { PaperProps, styled } from '@mui/material'; type ComponentProps = Omit<PaperProps, 'ref'> & { a: string, b: string }; const Component = forwardRef<HTMLDivElement, ComponentProps>((props, ref) => { const { a, b, ...other } = props; // ... return <MyPaper ref={ref} {...other}>...</MyPaper>; });
解析与结论
如果你的组件需要让外部获取到底层Paper元素的ref:必须用第二种
forwardRef的方式,同时要在ComponentProps里Omit掉ref。原因很简单:FC类型的组件不接收ref作为props参数(ref是React的特殊属性,不属于常规props),直接把ref包含在ComponentProps里的话,外部调用时传递的ref无法正确绑定到底层元素,还会触发TypeScript类型错误。如果你的组件不需要对外暴露ref:第一种写法看似能运行,但存在隐患——
PaperProps里的ref会被打包进other传给MyPaper,但外部调用组件时如果尝试传ref,TypeScript会直接报错(因为FC的props不支持ref)。所以更严谨的做法是依然显式Omit掉ref,既避免类型错误,也能明确告知使用者:这个组件不支持ref传递。
总结:
- 需暴露ref:用
forwardRef+Omit<PaperProps, 'ref'>,这是React自定义组件暴露ref的标准范式。 - 无需暴露ref:推荐显式
Omit<PaperProps, 'ref'>,规范类型定义,避免误用。
内容的提问来源于stack exchange,提问作者GoncaloNGT
相关产品推荐
相关产品推荐

