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

如何在React+TypeScript中将framer-motion应用于多态组件?

解决framer-motion在多态React组件中的类型问题

你遇到的错误是因为motion对象不支持通过动态属性名(比如motion.Component)创建组件,正确方式是使用motion()工厂函数包装动态组件。以下是完整修复方案:

步骤1:更新类型定义

引入framer-motion的MotionProps并合并到组件Props中,确保动画属性能被TypeScript正确识别:

import React, { DetailedHTMLProps } from 'react';
import { motion, MotionProps } from 'framer-motion';

type ButtonProps = DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement> & MotionProps;
type AnchorProps = DetailedHTMLProps<React.AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement> & MotionProps;

type Props = (ButtonProps | AnchorProps) & {
    as?: 'button' | 'a';
    secondary?: boolean;
};

步骤2:修改组件实现

用motion()函数包装动态Component,替代错误的motion.Component写法:

const Button: React.FC<Props> = (props: Props) => {
    const { as: Component = 'button', secondary, className, ...restProps } = props;

    // 使用motion()工厂函数创建支持动画的动态组件
    const MotionComponent = motion(Component);

    const baseClassName = secondary
        ? `font-bold text-lg lg:mx-4 sm:mx-2 flex items-center gap-1 select-none`
        : `font-bold text-lg px-4 py-2 select-none rounded-xl text-white bg-primary-base hover:bg-primary-hover mx-4`;

    return (
        <MotionComponent
            className={`${baseClassName} ${className || ''}`}
            {...restProps}
        >
            {props.children}
        </MotionComponent>
    );
};

export default Button;

关键说明

  • motion()工厂函数:framer-motion提供的创建自定义动态组件的方法,接受HTML标签名(如'button'、'a')或React组件,返回支持动画属性的motion版本组件。
  • 类型合并:将MotionProps合并到基础Props中,确保你能传递animate、transition等动画属性,同时保持TypeScript类型检查正常。
  • 简化props处理:通过解构赋值分离自定义属性,避免手动删除属性的繁琐操作,代码更简洁。

现在你可以正常使用带动画的多态组件:

<Button as="a" href="/" animate={{ scale: 1.05 }} whileHover={{ scale: 1.1 }}>
    链接按钮
</Button>

<Button secondary animate={{ opacity: 0.9 }} whileTap={{ opacity: 0.7 }}>
    次要按钮
</Button>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 19:52:38