使用 Next.js 浅路由更新 URL 反应可重用组件,但在刷新时,404

React Reusable Components with Next.js Shallow Routing Updates URL, but on Refresh, 404

我在左侧有一个项目列表,当您单击一个项目时,详细信息会显示在右侧。我在没有页面刷新的情况下呈现 Details.js 的可重用组件并使用 Next.js 浅层路由更新 URL 来完成此操作。

想法:

/pages/projects/index.js

const Projects = () => {
  const { user } = useUser();
  const router = useRouter();
  const [projects, setProjects] = useState([]);
  const [projectSelectedId, setProjectSelectedId] = useState(null);

  useEffect(() => {
    if (!user) return null;

    const fetchProjects = async () => {
      // this is where I get my projects data
    };
    fetchProjects();
  }, [user]);

  const handleProject = (data) => {
    const pid = data.id;
    setProjectSelectedId(pid);
    router.push("/projects/", `/projects/${pid}`, { shallow: true });
  };
  if (!user) return null;

  return (
    <>
      {user && (
        <div>
          <div>
            <h1>Projects</h1>
            <div>
              {projects &&
                projects.map((project, index) => (
                  <div key={index}>
                    <button
                      onClick={() => handleProject(projects[index])}
                    >
                      {project.title}
                    </button>
                  </div>
                ))}
            </div>
          </div>
          <div>
            {projectSelectedId && (
              <Details pid={projectSelectedId} />
            )}
          </div>
        </div>
      )}
    </>
  );
};

export default Projects;

选择项目后,URL 在我使用浅路由时得到更新:

router.push("/projects/", `/projects/${pid}`, { shallow: true });

这很好用,但是当我刷新页面时,我得到 404。我希望它转到选定的项目以及刷新的详细信息。

您的方法存在一些问题,您需要为您的 nextjs 应用程序设置适当的布局

像这样:

  • 在你的 _app.js:
export default function MyApp({ Component, pageProps }) {
  return (
    <Layout>
      <Component {...pageProps} />
    </Layout>
  );
}
  • 如您的 layout.js
export default function Layout({ children }) {
  return (
    <>
      <main className={styles.main}>
        <Sidebar />
        {children}
      </main>
    </>
  );
}
  • 导航侧边栏:
export default function Sidebar() {
  return (
    <nav className={styles.nav}>
      <Link href="/">
        <a>Index</a>
      </Link>
      <Link href="/project/1">
        <a>Project 1</a>
      </Link>
      <Link href="/project/2">
        <a>Project 2</a>
      </Link>
    </nav>
  );
}
  • 依此类推到您的项目页面,您将需要这样的结构:


查看完整示例here