如何在onClick事件中使用Web Animations API?解决React Hook调用错误
解决React Hook调用错误并实现狗狗点击跳跃动画
嘿,我来帮你搞定这个问题!你遇到的Invalid hook call错误是React的核心规则导致的——Hooks只能在函数组件的顶层作用域调用,绝对不能放在事件处理函数、循环或者条件判断里。你的useWebAnimations是在点击事件的回调DogJump里调用的,这就违反了规则,所以才会报错。
咱们来一步步修正代码,同时实现点击狗狗触发跳跃动画的效果:
修正后的完整代码
import React from "react"; import useWebAnimations from "@wellyshen/use-web-animations"; import "./App.css"; import Dog from "./images/dog.gif"; import Ball from "./images/ball.gif"; function App() { // 1. 在组件顶层调用useWebAnimations,符合Hook规则 const { ref: dogRef, play, getAnimation } = useWebAnimations({ // 定义跳跃动画的关键帧:原地→跳起来→回到原地 keyframes: [ { transform: "translate(0, 0)" }, { transform: "translate(200px, -60px)" }, { transform: "translate(0, 0)" } ], timing: { duration: 1200, // 动画时长1.2秒,更自然 easing: "ease-in-out", // 缓动效果,模拟真实跳跃 autoplay: false // 初始不自动播放,点击后再触发 } }); const handleDogJump = () => { // 2. 点击时重置并播放动画,避免多次点击导致动画混乱 const animation = getAnimation(); if (animation) { animation.cancel(); // 先取消当前正在运行的动画 play(); // 重新播放跳跃动画 } }; return ( <div> <img className="ball" src={Ball} alt="ball" /> {/* 3. 用Hook返回的ref绑定狗狗图片,替代getElementById */} <img ref={dogRef} className="dog" src={Dog} alt="dog" onClick={handleDogJump} /> </div> ); } export default App;
关键改动说明
- Hook调用位置修正:把
useWebAnimations移到了组件的顶层作用域,完全符合React Hook的调用规则,解决了报错问题。 - React Ref替代DOM查询:用Hook返回的
dogRef绑定到img元素,这是React官方推荐的DOM操作方式,比getElementById更安全、更符合React的数据流。 - 动画触发逻辑优化:关闭了
autoplay,确保页面加载时动画不会自动播放;点击时先取消当前动画再重新播放,避免多次点击导致动画叠加混乱。 - 动画效果优化:调整了关键帧的y轴偏移,让动画更像真实的跳跃,同时增加了缓动效果,提升视觉体验。
如果需要调整动画的时长、跳跃高度或者重复次数,直接修改timing配置里的参数就可以啦,比如添加iterations: 2让动画重复两次。
内容的提问来源于stack exchange,提问作者New Programmer
相关产品推荐
相关产品推荐

