Next.js 13 中 URL 的哈希值发生变化

ais*_*ais 6 reactjs next.js react-hooks next.js13

是否可以在 Next.js 13v 应用程序中监视 #hash?

我做错了什么?看起来“hashchange”事件根本不起作用——仅适用于第一个应用程序渲染。

现在我正在尝试这样做,但它不起作用:

我的布局.tsx:

import './globals.css'
import './page.css'
import type { Metadata } from 'next'
import { TheMenu } from '@/components/TheMenu'

export const metadata: Metadata = {
    title: 'Test app',
    description: 'Generated by create next app'
}

export default function RootLayout({ children }: { children: React.ReactNode }) {
    return (
        <html>
            <body>
                {children}
                <TheMenu />
            </body>
        </html>
    )
}

Run Code Online (Sandbox Code Playgroud)

我的 TheMenu.tsx 组件 - 实际上更改了 #hash:

'use client'

import './menu.css'
import Link from 'next/link'
import route from '@/config/routing'
import { useState } from 'react'

const TheMenu = () => {
    const [open, setOpen] = useState(false)

    const toggleMenu = () => {
        setOpen(!open)
    }

    return (
        <div className="menu__wrapper">
            <button className={`menu__btn`} type="button" onClick={toggleMenu}>
                Open/Close
            </button>
            {open && (
                <ul className="menu__list">
                    {Object.entries(route.modules).map(([key, item]) => (
                        <li key={key}>
                            <Link className={`menu__link`} href={item.href} onClick={toggleMenu}>
                                {item.name}
                            </Link>
                        </li>
                    ))}
                </ul>
            )}
        </div>
    )
}

export { TheMenu }
Run Code Online (Sandbox Code Playgroud)

最后是 page.tsx,我需要根据当前 #hash 渲染不同的组件:

'use client'

import route from '@/config/routing'
import { Component1 } from '@/components/other_components/Component1 '
import { Component2 } from '@/components/other_components/Component2 '
import { Barlow } from 'next/font/google'
import { useEffect, useState } from 'react'

const barlow = Barlow({ subsets: ['latin'], weight: '900' })

export default function Home() {
    const [component, setComponent] = useState(<Component1 />)

    const componentSwitcher = () => {
        console.log(window.location.hash)
        switch (window.location.hash) {
            case '#component1':
                setComponent(<Component1 />)
                break
            case '#component2':
                setComponent(<Component2 />)
                break
            default:
                setComponent(<Component1 />)
                break
        }
    }

    useEffect(() => {
        window.addEventListener('hashchange', componentSwitcher)

        componentSwitcher()

        return () => {
            window.removeEventListener('hashchange', componentSwitcher)
        }
    }, [])

    return (
        <>
            <div className="container">
                <div className="main__wrapper">
                    <p className={`${barlow.className} welcome__text`}>
                        Lorem ipsum, dolor sit amet consectetur adipisicing elit. Soluta placeat necessitatibus animi quam, ipsum minima possimus enim cumque nesciunt distinctio.
                    </p>
                </div>
            </div>
            {component}
        </>
    )
}
Run Code Online (Sandbox Code Playgroud)