emotion/styled v11中WrappedButton组件aria-label报错解决问询
问题根源
你当前的错误是因为把所有组件props直接展开到了Emotion的样式回调对象里,Emotion会将aria-label这类kebab-case格式的属性误认为是CSS属性,因此抛出错误;改用驼峰式ariaLabel后,React虽然能识别,但原生<button>元素需要的是aria-label属性,所以最终标签不生效。
解决方案
核心思路是把组件props和Emotion的样式逻辑彻底分开,同时通过shouldForwardProp确保非样式属性能正确传递给原生按钮,同时保留styled(WrappedButton)({...})的定制能力。
修改后的完整代码
import styled from '@emotion/styled'; import { forwardRef } from 'react'; type ButtonPropsType = React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>; type RefType = React.Ref<HTMLButtonElement>; // 配置shouldForwardProp,确保非样式属性能正确转发给原生button const StylableButton = styled.button<ButtonPropsType>( {}, { shouldForwardProp: (prop) => { // 只排除Emotion内部专用的属性,其他所有props都转发给底层button return !['css', 'theme'].includes(prop); }, } ); // 默认type设为button,覆盖原生默认的submit const defaultProps: ButtonPropsType = { type: 'button', }; export const WrappedButton = forwardRef<HTMLButtonElement, ButtonPropsType>((props, ref) => { return <StylableButton {...defaultProps} ref={ref} {...props} />; }); WrappedButton.displayName = 'Button';
关键修正点
正确配置
shouldForwardProp:
之前你把shouldForwardProp写在了样式回调对象里,这是错误的。它应该作为styled函数的第二个参数(配置对象)的属性,用来告诉Emotion哪些属性需要转发给底层DOM元素,哪些需要作为样式处理。不再将props混入样式对象:
原代码里把...(props as any)放到样式回调的返回值中,导致所有props被当成CSS属性解析。现在让StylableButton正常接收props并通过shouldForwardProp规则转发,彻底避免属性混淆。保留样式定制能力:
修正后的StylableButton依然是Emotion可识别的样式组件,因此外层依然可以通过styled(WrappedButton)({...})来定制按钮样式,完全兼容原有使用场景。
验证使用示例
test('A', () => { render(<WrappedButton aria-label='foo'>a</WrappedButton>); // 此时控制台无报错,aria-label会正确渲染到<button>元素上 });
内容的提问来源于stack exchange,提问作者DarkTrick
相关产品推荐
相关产品推荐

