NextJs 13 实验应用程序目录哈希在路由中不指向哈希 ID

Eri*_*les 7 reactjs next.js hashlink

我正在使用 Nextjs 13 和实验性 App Dir,但不确定我面临的这个问题是否与我面临的问题有关。我的“常见问题解答”主页中有一个 ID,当我单击该链接时,我可以看到它成功转到该链接,但在浏览器中没有执行任何操作。如果我在另一个页面上,我单击该链接,它会将我带到具有正确 url 的主页,但仍停留在页面顶部,并且不会滚动到指示的 id。scroll={false}我确实按照文档中的建议实现了,但这没有什么区别。

这是相关代码部分的片段:

"use client"
import React, { useState } from "react"
import { useRouter } from "next/navigation"
import Link from "next/link"

const Navigation = () => {
  const router = useRouter()
 ...
Run Code Online (Sandbox Code Playgroud)

在回报中:

 <Link scroll={false} href="/#faqs">FAQS</Link>
Run Code Online (Sandbox Code Playgroud)

我什至尝试过:

<button type="button" onClick={() => router.push("/#faqs")}>FAQS</button>
Run Code Online (Sandbox Code Playgroud)

在 React 中,哈希工作得相当好,但在下一个 js 中,即使仅在客户端渲染中,它看起来也很复杂。如果有人知道我做错了什么或者是否有可行的解决办法,我一定会很感激。先感谢您。如果我遗漏了什么,请告诉我。

Des*_*nly 4

我经常使用主题标签,并且计划在未来的项目中开始使用应用程序目录,所以我深入研究了它,但它并不漂亮。显然,NextJS 对客户端应用程序目录组件使用了一个不同的包,称为“next/navigation”。它与“下一个/路由器”有很大不同。另外,当使用“next/link”元素时,NextJS 在更改时不会触发该onRouteChangeComplete事件,但不会。location.hashlocation.pathname

因此,为了检测哈希更改并滚动到关联元素,我最终不得不实现此 hack:

"use client"
import { Inter } from '@next/font/google'
import paragraph from './paragraph'
import Link from 'next/link'
import { useEffect, useState } from 'react'

const inter = Inter({ subsets: ['latin'] })

export default function Home() {
  const [navClick, setNavClick] = useState(false);

  useEffect(() => {
    setTimeout(() => {
      const hash = window.location.hash;
      if (hash) document.querySelector(hash).scrollIntoView();
    }, 0);
  }, [navClick])

  const toggleNavClick = () => setNavClick((oldVal) => !oldVal);

  return (
    <main>
      <nav>
        <ul>
          <li>
            <Link href="/#one" onClick={toggleNavClick}>Section One</Link>
          </li>
          <li>
            <Link href="/#two" onClick={toggleNavClick}>Section Two</Link>
          </li>
          <li>
            <Link href="/#three" onClick={toggleNavClick}>Section Three</Link>
          </li>
        </ul>
      </nav>
      <div className="container">
        <section id="one">
          <h1>Section One</h1>
          <div dangerouslySetInnerHTML={{ __html: paragraph }} />
        </section>
        <section id="two">
          <h1>Section Two</h1>
          <div dangerouslySetInnerHTML={{ __html: paragraph }} />
        </section>
        <section id="three">
          <h1>Section Three</h1>
          <div dangerouslySetInnerHTML={{ __html: paragraph }} />
        </section>
      </div>
    </main>
  )
}
Run Code Online (Sandbox Code Playgroud)

由于没有触发事件而无法检测到哈希更改,因此我基本上通过navClick每次单击链接时进行切换来创建一个事件。导航逻辑包含在setTimeout()函数中,因为它会在window.location更新后触发。

仓库: https: //github.com/designly1/next-hash-test 演示:https://next-hash-test.vercel.app/