You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React TS组件封装:优雅混合自定义与原生Props的方案问询

解决React扩展原生组件时的Props分离问题

问题背景

封装input、button、table等原生元素的扩展组件时,手动添加团队所需的事件处理器和Props过于繁琐。曾尝试让组件Prop类型继承原生Prop类型并自动展开,但出现自定义Props不被类型支持、自定义Props意外传递给原生元素的问题。当前采用的方案需要重复定义所有自定义Prop名称才能分离原生Props,还失去了习惯的props.前缀来区分Props与局部变量。

可行的简洁解决方案

方案1:通用工具函数分离Props

编写一个可复用的工具函数,根据自定义Props的键名,自动将传入的Props拆分为自定义部分和原生部分,既不用重复解构自定义Prop,也能保留类props.的前缀:

import React from 'react';

// 通用Props分离函数,支持所有组件复用
const splitProps = <T, U extends keyof T>(props: T, customKeys: U[]) => {
  const customProps: Pick<T, U> = {} as Pick<T, U>;
  const nativeProps: Omit<T, U> = {} as Omit<T, U>;

  Object.keys(props).forEach(key => {
    if (customKeys.includes(key as U)) {
      (customProps as any)[key] = props[key];
    } else {
      (nativeProps as any)[key] = props[key];
    }
  });

  return { customProps, nativeProps };
};

// 自定义Props类型
type CustomProps = {
  color: string;
  label: React.ReactNode;
};

// 组合类型:自定义Props + 排除重名后的原生button Props
type Props = CustomProps & Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, keyof CustomProps>;

const Button = (props: Props) => {
  // 传入自定义键名数组,一键分离
  const { customProps, nativeProps } = splitProps(props, ['color', 'label']);

  return (
    <>
      {customProps.label}
      <button 
        {...nativeProps} 
        style={{ backgroundColor: customProps.color, ...nativeProps.style }} 
      />
    </>
  );
};

export default Button;

方案2:类型断言+剩余属性(极简写法)

如果不想额外写工具函数,可以结合TypeScript类型断言,仅解构一次自定义键名,同时保留完整props对象用于访问自定义属性:

import React from 'react';

type CustomProps = {
  color: string;
  label: React.ReactNode;
};

type Props = CustomProps & Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, keyof CustomProps>;

const Button = (props: Props) => {
  // 解构出自定义键名,剩余属性自动匹配原生Props类型
  const { color, label, ...nativeProps } = props;
  
  // 依然可以通过props.前缀访问自定义属性,避免和局部变量混淆
  return (
    <>
      {props.label}
      <button 
        {...nativeProps} 
        style={{ backgroundColor: props.color, ...nativeProps.style }} 
      />
    </>
  );
};

export default Button;

注意事项

你之前期望的示例写法不符合React组件规范:React组件仅能接收单个props对象参数,无法拆分为两个独立参数分别接收自定义和原生Props,因此该写法无法正常运行。

内容的提问来源于stack exchange,提问作者MFischer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 12:35:18