React迁移Next.js后出现TypeError: 无法解构null的'future'属性问题排查
问题分析与解决方案
核心原因
- Next.js 自带路由系统,无需依赖
react-router-dom,混用会导致路由上下文(Context)无法正常初始化,触发useContext(...)返回null的错误。 - 原代码中
Navbar直接嵌套在<Routes>标签内,违反了react-router的规则(<Routes>仅允许包含<Route>组件),进一步破坏了路由上下文的传递。
具体修复步骤
1. 移除react-router-dom依赖
执行命令卸载不必要的包:
npm uninstall react-router-dom react-router
2. 修改Navbar组件,替换为Next.js的Link
将react-router-dom的NavLink替换为Next.js的next/link组件,并适配激活状态逻辑:
'use client'; import React, { useState, useEffect } from 'react'; import Link from 'next/link'; import { Nav, Bars, CloseIcon, IconWrapper, NavMenu, NavLinkStyled, // 自定义样式组件替代原react-router的NavLink } from './navbarElements'; import Image from 'next/image'; const Navbar = () => { const [isOpen, setIsOpen] = useState(false); const [isMobile, setIsMobile] = useState(false); const toggleMenu = () => { setIsOpen(!isOpen); } const closeMenu = () => { setIsOpen(false); } useEffect(() => { const handleResize = () => { const isCurrentlyMobile = typeof window !== 'undefined' && window.innerWidth < 769; if (!isCurrentlyMobile) { setIsOpen(false); } setIsMobile(isCurrentlyMobile); }; handleResize(); window.addEventListener('resize', handleResize); return () => window.removeEventListener('resize', handleResize); }, []); // 获取当前路径判断激活状态 const currentPath = typeof window !== 'undefined' ? window.location.pathname : ''; return ( <Nav> <Link href="/" onClick={closeMenu}> <Image src="/logo.png" alt="Logo" className="navbar-logo" width={100} height={50} /> {/* Next.js Image需指定width/height或使用fill属性 */} </Link> <IconWrapper onClick={toggleMenu}> <Bars isOpen={isOpen} /> <CloseIcon isOpen={isOpen} /> </IconWrapper> <NavMenu className={isOpen ? 'active' : ''} isMobile={isMobile}> <Link href="/produse" onClick={closeMenu}> <NavLinkStyled $isActive={currentPath === '/produse'}>Produse</NavLinkStyled> </Link> <Link href="/aboutus" onClick={closeMenu}> <NavLinkStyled $isActive={currentPath === '/aboutus'}>Despre noi</NavLinkStyled> </Link> <Link href="/portofolio" onClick={closeMenu}> <NavLinkStyled $isActive={currentPath === '/portofolio'}>Portofoliu</NavLinkStyled> </Link> <Link href="/contact" onClick={closeMenu}> <NavLinkStyled $isActive={currentPath === '/contact'}>Contact</NavLinkStyled> </Link> </NavMenu> </Nav> ); }; export default Navbar;
对应的navbarElements.js调整样式逻辑,通过props判断激活状态(以styled-components为例):
import styled from 'styled-components'; export const NavLinkStyled = styled.a` color: #333; text-decoration: none; padding: 0.5rem 1rem; transition: all 0.3s ease; ${props => props.$isActive && ` color: #ff5722; border-bottom: 2px solid #ff5722; `} `; // 保留其他原有样式组件(Nav, Bars等)
3. 重构根布局(适配Next.js App Router)
Next.js 13+使用App Router,在app/layout.js中设置全局布局,替代原App.js:
import './globals.css'; import Navbar from '@/components/navbar'; import Footer from '@/components/footer'; import ScrollToTopButton from '@/components/scrollToTop'; export default function RootLayout({ children }) { return ( <html lang="ro"> <body> <Navbar /> {children} <ScrollToTopButton /> <Footer /> </body> </html> ); }
4. 调整页面结构
将原页面组件移动到app目录,确保路由路径与文件名对应:
app/page.js→ 对应根路径/(原Home组件)app/produse/page.js→ 对应/produse(原Produse组件)app/aboutus/page.js→ 对应/aboutus(原About组件)app/portofolio/page.js→ 对应/portofolio(原Portofolio组件)app/contact/page.js→ 对应/contact(原Contact组件)
5. 清理冗余代码
删除原App.js文件,确保项目中不再残留react-router-dom相关代码。
验证修复
完成所有步骤后,执行:
npm install npm run dev
启动项目后,导航栏的跳转和激活状态应正常工作,原错误消失。
内容的提问来源于stack exchange,提问作者user27286705
相关产品推荐
相关产品推荐

