Next.js:一页与根“ /”和动态路由“ / param”匹配

时间:2020-05-30 08:54:40

标签: javascript reactjs next.js

我有一个网站作为使用Next.js的单个页面。我有路线/上的主页,其中显示了产品列表。该页面的代码位于pages/index.js中。每个产品都有一个id,所以我可以使用/#product-id跳转到它。

为了使其对网址更友好,我将product-id作为第二个参数使用/product-id复制了此行为,例如:product-id

我要做的只是使用useRouter()查看const selectedProductId = useRouter().query['product-id'] 参数:

js

然后使用document.getElementById(selectedProductId ).scrollIntoView() 滚动到具有此ID的元素:

/pages/index.js

因此,我将脚本名称从/pages/[product-id].js更改为/1234

因此,路由/现在可以正常工作了,但是如果我去/,则会收到错误404。

有人知道如何使用一个/param文件匹配js if (queue.size() > 5) return 2; else return 1; 吗?

2 个答案:

答案 0 :(得分:2)

Nextjs具有基于文件系统的路由,因此,如果您删除/pages/index.js,则当然会出现404错误。 /pages/index.js/pages/[product-id].js还将呈现两个单独的页面。

要回答您的问题,如果可以使用nextjs在一个文件中匹配//[productId]之类的两条路由,我认为这是不可能的,但是通过使用浅表可以实现类似的结果特定于您的用例的路由。

因此,对于您的用例,我建议使用浅层路由,除非您只是想在两个页面中呈现相同的组件只是为了获得product-id或想使用哈希URL。

您可以使product-id为查询字符串参数,并使用浅层路由对其进行更新。这是一个例子,

保持/pages/index.js

import { useRouter } from 'next/router';

const router = useRouter()

// when want to change the productId call
router.push('/?productId=1234', undefined, { shallow: true })

// call the scrollToView inside a useEffect hook
useEffect(() => {
    const productId = router.query.productId
    // get the element using the productId above then call scrollIntoView()
})

// if using useEffect with the dependency router.query.productId, 
// when you change the productId once and scroll up and try to change to the same -
// productId again it will not scroll to view, hence not using the dependency array
// at all

进一步解释浅层路由的作用

浅路由将允许更改URL,而无需再次运行数据获取方法,即getStaticPropsgetServerSideProps。这将使更新的查询和路径名可用而不会更改状态。进一步了解nextjs docs

答案 1 :(得分:1)

选项1:提取共享代码

您可以将Page组件提取到单独的文件中,然后将其导入/pages/index.js/pages/[product-id].js中,这样就不会重复代码。

选项2:使用实验性rewrites功能

假设您拥有/pages/[product-id].js,则可以在用户请求/时显示此页面。

您需要添加next.config.js

module.exports = {
  experimental: {
    async rewrites() {
      return [
        { source: "/", destination: "/[product-id]" },
      ];
    }
  }
}

因此,当用户请求/时,他们会看到/[product-id]的内容,只是带有空的产品ID。

请注意,当前重写不支持自动呈现的动态页面,因此您必须禁用动态页面的自动呈现

您可以通过将getServerSideProps添加到/pages/[product-id].js来实现。

export async function getServerSideProps() {
  return {
    props: {},
  }
}