next.js 检索任意元件中的布线参数

ddrv8njm  于 2023-01-25  发布在  其他
关注(0)|答案(2)|浏览(99)

bounty将在5天后过期。此问题的答案可获得+250声望奖励。Page not found正在寻找规范答案

假设我的URL如下所示:

/blog/[post_id]/something

$post_id向下传递到树中任何位置的任何组件的推荐方法是什么?
我知道如何使用getInitialProps检索路由参数,但是向下传递这些值总是让我感到困难。
对于pages,从技术上讲,我可以使用React Contexts,尽管对于这样一个微不足道的用例来说,这似乎有点过大。
对于layouts,老实说我完全迷失了方向,因为页面是布局的子级,getInitialProps的返回值传递给页面而不是布局。
我的组件可以使用useRouter,但这需要useEffect,而且还会使我的组件依赖于路由本身...
欢迎提出任何建议(:

xxhby3vn

xxhby3vn1#

我的组件可以使用useRouter,但这需要useEffect,而且还会使我的组件依赖于路由本身...
useRouter似乎是显而易见的解决方案。我不完全理解您对组件依赖于路由的担忧。我猜它确实使Layout不太灵活,因为它需要知道post id存储在post_id查询变量中。但无论如何我都会这样做:)它为您提供了一种很好且简单的方式来访问查询变量,这些变量可以在BlogPost之外的Layout中使用,也可以在BlogPost内部使用的深度嵌套组件中使用。
使用每页布局方法:
/components/Layout

import { useRouter } from "next/router";
import { ReactNode } from "react";

export default function Layout({ children }: { children: ReactNode }) {
    const router = useRouter();
    return (
        <div>
            <h3>You are viewing post id #{router.query.post_id}</h3>
            {children}
        </div>
    );
}

/pages/blog/[post_id].jsx

import Layout from '../../components/Layout';

export default function BlogPost() {
    return <div>Hello World</div>
}

BlogPost.getLayout = function getLayout(page) {
    return (
        <Layout>
           {page}
        </Layout>
    )
}

/pages/_app.tsx(支持每页布局,从文档复制)

export default function MyApp({ Component, pageProps }) {
    // Use the layout defined at the page level, if available
    const getLayout = Component.getLayout || ((page) => page)

    return getLayout(<Component {...pageProps} />)
}
a14dhokn

a14dhokn2#

我认为最简单和最干净的方法是使用window.location.pathname。这会给予你域名后面的部分。例如

http://localhost:3001/blog/[post_id]/something

你将得到/blog/[post_id]/something

const pathname=window.location.pathname
const splittedPathname=pathname.split("/") // ['', 'blog', '[post_id]', 'something']

const dynamicId=splittedPathname[2]

你可以在useEffect中运行上面的代码并设置一个状态。或者你可以写一个钩子并在dynamicId组件下的组件中使用它

import React, { useState, useEffect } from "react";

const usePathname = () => {
  const [postId, setPostId] = useState("");

  useEffect(() => {
    const pathname = window.location.pathname;
    const splittedPathname = pathname.split("/");
    const dynamicId = splittedPathname[2];
    setPostId(dynamicId);
  }, []);

  return { postId };
};

export default usePathname;

相关问题