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

React中如何阻止将className和style属性传递给自定义组件

React+TypeScript 自定义按钮排除className、style属性实现方案

核心思路

需要同时完成类型层面的属性限制和运行时的属性过滤两步,仅用Omit做类型声明无法完全禁止外部样式传入。

完整实现代码

首先定义组件类型,通过Omit移除原生按钮属性中的className和style,再显式将两个属性设为never避免类型合并时的遗漏:

import React, { ButtonHTMLAttributes, forwardRef } from 'react';

// 组件属性定义
type CustomButtonProps = Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'className' | 'style'> & {
  // 你自己的自定义属性,示例如下
  variant?: 'primary' | 'secondary' | 'text';
  size?: 'small' | 'middle' | 'large';
  // 显式禁止传入className、style,优先级高于其他合并来的类型
  className?: never;
  style?: never;
};

// 组件实现(支持ref透传)
const CustomButton = forwardRef<HTMLButtonElement, CustomButtonProps>((props, ref) => {
  const {
    variant = 'primary',
    size = 'middle',
    // 运行时过滤掉禁止透传的属性,就算用户强制传入也不会生效
    className: _ignoreClassName,
    style: _ignoreStyle,
    ...restNativeProps
  } = props;

  // 组件内部固定样式,外部无法修改
  const internalClassName = `custom-btn custom-btn-${variant} custom-btn-${size}`;

  return (
    <button
      ref={ref}
      className={internalClassName}
      {...restNativeProps}
    >
      {props.children}
    </button>
  );
});

CustomButton.displayName = 'CustomButton';
export default CustomButton;

此前Omit不生效的常见原因

  • 仅做了类型层面的Omit声明,没有在运行时解构过滤属性,导致用户传入的className/style仍然被透传给原生button元素
  • Omit第二个参数拼写错误,比如大小写错误、单词拼写错误
  • 类型交叉时引入了其他包含className/style的类型,覆盖了Omit的排除效果,增加显式的never声明即可解决
  • 未开启TypeScript严格模式,多余属性检查未生效,用户传入未定义属性时不会触发类型报错

内容的提问来源于stack exchange,提问作者The Lost JavaScripter

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 16:57:04