Next.js点击按钮触发动画跳转时Hook报错问题求助
解决Next.js中点击按钮跳转时的Invalid Hook Call错误
问题描述
我用最新版Next.js搭建作品集框架,想要实现点击按钮后的流程:页面内容淡出 → 显示Loading_ui组件动画 → 预加载目标页面后延迟跳转。目前HomeButtons组件点击按钮能给body添加fade-out类,但延迟后触发「Invalid hook call」错误,原因是在setTimeout里调用usePathname违反了Hook规则,求解决办法。
错误信息
Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
- React与渲染器(如React DOM)版本不匹配
- 违反了Hook规则
- 应用中存在多个React副本
核心问题分析
Hook必须在函数组件的顶层作用域调用,不能嵌套在定时器、条件判断等逻辑内部。另外原代码逻辑存在错误:用当前路径判断跳转目标完全逻辑倒置,点击按钮时直接明确目标路径即可,无需判断当前路径。
解决代码及说明
修改后的HomeButtons组件代码:
import { useRouter } from "next/navigation"; import styles from "./homeButtons.module.css"; import React, { useState, useEffect } from "react"; import Loading_ui from "./Loading_ui"; // 引入Loading组件 export default function HomeButtons() { const router = useRouter(); const [targetPath, setTargetPath] = useState(null); // 存储要跳转的目标路径 // 通用点击事件,接收目标路径参数 const handleButtonClick = (path) => { setTargetPath(path); }; useEffect(() => { if (targetPath) { // 触发页面淡出效果,修改标题 document.body.classList.add("fade-out"); document.title = "Loading..."; const animationDuration = 500; const timer = setTimeout(() => { // 执行跳转 router.push(targetPath); // 跳转后重置状态并清理样式 setTargetPath(null); document.body.classList.remove("fade-out"); }, animationDuration + 100); // 组件卸载时清理定时器,避免内存泄漏 return () => clearTimeout(timer); } }, [targetPath, router]); return ( <div> <button onClick={() => handleButtonClick("/mywork")} id="my_work" className={styles.cybr_btn}> My Work<span aria-hidden>_</span> <span aria-hidden className={styles.cybr_btn__glitch}> 爪ㄚ 山ㄖ尺Ҝ </span> <span aria-hidden className={styles.cybr_btn__tag}> R25 </span> </button> <button onClick={() => handleButtonClick("/me")} id="me" className={styles.cybr_btn}> Me<span aria-hidden>_</span> <span aria-hidden className={styles.cybr_btn__glitch}> 爪ㄖ </span> <span aria-hidden className={styles.cybr_btn__tag}> R25 </span> </button> {/* 跳转过程中显示Loading动画 */} {targetPath && <Loading_ui />} </div> ); }
关键优化点
- 合并重复的点击事件,通过参数传递目标路径,减少冗余代码
- 用
targetPath状态替代原animationActive,同时标记动画状态和存储跳转目标,逻辑更清晰 - 移除了违规在定时器内调用的usePathname,完全符合Hook规则
- 添加定时器清理函数,避免组件卸载后定时器仍执行的问题
- 跳转后自动移除
fade-out类,防止回到首页时页面状态异常 - 动态渲染Loading_ui组件,实现跳转过程中的动画展示
内容的提问来源于stack exchange,提问作者b4n
相关产品推荐
相关产品推荐

