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

TypeScript+React+Styled Components下keyframes动画属性无效报错

解决TSX中Styled Components传递animation prop的DOM警告问题

问题背景

JSX代码正常运行,但转为TSX后出现以下警告:

Warning: Invalid value for prop animation on tag. Either remove it from the element, or pass a string or number value to keep it in the DOM

问题出在自定义Gauge组件的props传递逻辑及Styled Components的默认行为上。

问题根源

  1. 无效DOM属性转发:Styled Components默认会把所有传入的props转发给底层HTML元素(此处为<img>),但animation是样式专用参数,并非<img>的合法DOM属性,且传递的是函数类型,完全不符合DOM属性的类型要求。
  2. props类型与值不匹配:你定义的Gauge组件animation类型为() => {},但实际需要的是keyframes返回的动画对象;同时传递函数的方式会导致样式无法正确获取动画值。

解决方案

方案1:使用Transient Props(推荐)

通过给props名添加$前缀,标记为仅用于样式的临时props,Styled Components会自动跳过将其转发到DOM元素。

修改后的Styled Components代码

import styled, { keyframes } from 'styled-components';

export const gaugeRotation = (firstMove: number, secondMove: number, thirdMove: number, fourthMove: number) => keyframes`
    0%   {transform: rotate(${firstMove}deg); }
    35% {transform: rotate(${secondMove}deg);}
    50% {transform: rotate(${thirdMove}deg);}
    100% {transform: rotate(${fourthMove}deg);}
`;

// 用$animation作为props名,修正类型为keyframes返回值
export const Gauge = styled.img<{ $animation: ReturnType<typeof gaugeRotation> }>`
    width: 30%;
    height: auto;
    position: absolute;
    top: 64%;
    left: 48%;
    animation: ${(props) => props.$animation} 3s;
    transform-origin: 10% 54%;
    animation-iteration-count: 1;
    animation-fill-mode: forwards;
`;

修改后的React元素代码

<Gauge 
  src={gauge}
  // 直接调用gaugeRotation获取动画对象,传递给$animation
  $animation={gaugeRotation(firstMove, secondMove, thirdMove, fourthMove)}
  onAnimationEnd={() => {
    setFirstMove(fourthMove)
    setSecondMove(fourthMove)
    setThirdMove(fourthMove)
  }} 
/>

方案2:使用shouldForwardProp过滤props

如果不想修改props名,可以通过withConfig配置shouldForwardProp,明确指定哪些props不转发给DOM元素。

export const Gauge = styled.img.withConfig({
  shouldForwardProp: (prop) => prop !== 'animation'
})<{ animation: ReturnType<typeof gaugeRotation> }>`
    width: 30%;
    height: auto;
    position: absolute;
    top: 64%;
    left: 48%;
    animation: ${(props) => props.animation} 3s;
    transform-origin: 10% 54%;
    animation-iteration-count: 1;
    animation-fill-mode: forwards;
`;

对应的React元素代码只需调整为直接传递gaugeRotation的返回值:

<Gauge 
  src={gauge}
  animation={gaugeRotation(firstMove, secondMove, thirdMove, fourthMove)}
  onAnimationEnd={() => {
    setFirstMove(fourthMove)
    setSecondMove(fourthMove)
    setThirdMove(fourthMove)
  }} 
/>

关键修改点总结

  • 阻止样式专用props转发到DOM元素:通过transient props或shouldForwardProp过滤。
  • 修正props值类型:直接传递keyframes返回的动画对象,而非包装函数。
  • 完善TypeScript类型定义:将props类型指定为ReturnType<typeof gaugeRotation>,确保类型安全。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 15:13:11