如何仅在一处定义React组件的默认Props?
解决React组件默认Props重复定义的问题
你提到的官方写法里默认值在注释和函数参数里重复出现的问题确实存在,以下几种方法可以实现只在一处定义默认值:
1. 提取默认值为常量
把默认值单独定义成常量,然后在注释和函数参数里引用这个常量,这样默认值只需要维护一处:
const DEFAULT_AVATAR_SIZE = 100; interface Props { /** * 默认值:{DEFAULT_AVATAR_SIZE} */ size?: number; } function Avatar({ size = DEFAULT_AVATAR_SIZE }: Props) { // 组件逻辑 }
这种方式保留了官方推荐的函数参数默认值写法,同时避免了默认值硬编码两次,改值时只需要修改常量即可。
2. 从默认值对象推导Props类型
定义一个包含所有默认值的对象,再通过TypeScript的类型工具推导Props类型,这样默认值只在对象里写一次:
// 定义默认值对象,只在这里写一次默认值 const DEFAULT_PROPS = { size: 100, } as const; // 推导Props类型:所有属性都是可选的 type Props = Partial<typeof DEFAULT_PROPS>; function Avatar(props: Props) { // 合并传入的props和默认值 const mergedProps = { ...DEFAULT_PROPS, ...props }; // 直接使用mergedProps.size,无需再处理默认值 return <div style={{ width: mergedProps.size, height: mergedProps.size }}>Avatar</div>; }
如果需要给属性加注释,可以直接写在默认值对象的属性上:
const DEFAULT_PROPS = { /** * 头像尺寸,默认100px */ size: 100, } as const;
3. 使用defaultProps(需配合TypeScript类型处理)
虽然React现在更推荐函数参数默认值,但也可以用传统的defaultProps,并通过类型工具让组件内部的属性变成必填:
interface Props { size?: number; } // 定义defaultProps,只写一次默认值 const Avatar = ({ size }: Props) => { // 这里size可能是undefined,需要处理 const finalSize = size ?? 100; return <div style={{ width: finalSize, height: finalSize }}>Avatar</div>; }; Avatar.defaultProps = { size: 100, }; // 可选:用类型工具让组件内部的props变成必填 type PropsWithDefaults = Required<Pick<Props, 'size'>> & Omit<Props, 'size'>; const AvatarWithDefaults = Avatar as React.FC<PropsWithDefaults>;
这种方式适合习惯传统写法的场景,但需要额外处理TypeScript的类型问题。
总的来说,提取常量或从默认值对象推导类型的方式更简洁,能有效避免默认值重复定义的问题。
内容的提问来源于stack exchange,提问作者yN.
相关产品推荐
相关产品推荐

