简体   繁体   English

NextJS URL 参数类似于 React-Router

[英]NextJS URL params like React-Router

I'm a newbie to NextJS , It looks so good on the first impression.我是NextJS的新手,第一印象看起来很不错。 But after giving it a chance I've faced some problems like URL routing with custom params like react-router .但是在给它一个机会之后,我遇到了一些问题,比如 URL 路由和自定义参数,比如react-router

Currently what We can do with NextJS目前我们可以用 NextJS 做什么

https://url.com/users?id:123

What We need to have for better URL pattern为了更好的 URL 模式,我们需要具备什么

https://url.com/users/123

In react-router It has perfect example here https://reacttraining.com/react-router/web/example/url-params在 react-router 这里有完美的例子https://reacttraining.com/react-router/web/example/url-params

For anyone arriving late to this party, we now have dynamic routing in Next 9.对于迟到的任何人,我们现在在 Next 9 中有动态路由

Which would allow for a url structure to be crafted like this by using the file structure, and without additional packages.这将允许通过使用文件结构来制作这样的 url 结构,而无需额外的包。

You could create a file pages/user/[id].js你可以创建一个文件pages/user/[id].js

With

import { useRouter } from 'next/router'

const User = () => {
  const router = useRouter()
  const { id } = router.query

  return <p>User: {id}</p>
}

export default User

For older version: < 9.x对于旧版本:< 9.x

You can use next/link 's as feature:您可以使用next/link as功能:

<Link prefetch as={`/product/${slug}`} href={`/product?slug=${slug}`}>

Link on the browser will appear as /product/slug which internally maps to /product?slug=slug浏览器上的链接将显示为/product/slug内部映射到/product?slug=slug

You need to have a custom server for server-side mapping:您需要有一个用于服务器端映射的自定义服务器

server.get("/product/:slug", (req, res) => {
  return app.render(req, res, "/product", { slug: req.params.slug })
})

For 9.x and higher对于 9.x 及更高版本

Next 9.x supports file system based dynamic routing . Next 9.x 支持基于文件系统的动态路由 You don't need a custom server anymore.您不再需要自定义服务器。

Next.js supports creating routes with basic named parameters, a pattern popularized by path-to-regexp (the library that powers Express ). Next.js 支持使用基本命名参数创建路由,这是一种由path-to-regexp (支持Express的库)推广的模式。

Creating a page that matches the route /product/:slug can now be achieved by creating a file in your pages directory named: pages/product/[slug].js .现在可以通过在您的 pages 目录中创建一个名为pages/product/[slug].js的文件来创建一个匹配路由/product/:slug的页面。

Multiple dynamic URL segments are also supported!还支持多个动态 URL 段!

./pages/blog/[blogId]/comments/[commentId].js
./pages/posts/[pid]/index.js

this example will help you define your parameterized, named routes.此示例将帮助您定义参数化的命名路由。 it uses nest/routes and let you define your custom routes of preference.它使用嵌套/路由并让您定义您的自定义偏好路由。 hope it will help you.希望它会帮助你。

https://github.com/zeit/next.js/tree/master/examples/with-next-routes https://github.com/zeit/next.js/tree/master/examples/with-next-routes

First import Router首先导入路由器

import Router from 'next/router'

Then if you want to use it in a Link tag然后,如果您想在 Link 标签中使用它

<Link href={{ pathname: '/about', query: { name: 'Sajad' } }}>

If you want to use it in a function or after a callback如果您想在函数中或回调后使用它

Router.push({
    pathname: '/about',
    query: { name: 'Sajad' },
  })

Problem: query Object Always Empty问题: query对象始终为空

In recent versions, dynamic routing is fully supported.在最近的版本中,完全支持动态路由 The docs even show a super simple example of how it works.文档甚至展示了一个超级简单的例子来说明它是如何工作的。 Sadly, it is all a big lie!可悲的是,这都是一个很大的谎言! For some reason, the docs fail to mention the issue of hydration.出于某种原因,文档没有提到水合作用的问题。

This blog post explains some extra details.这篇博文解释了一些额外的细节。

The gist is: in many dynamic rendering scenarios (including the default), during initial render on the client, the page first gets rendered without any parameters (probably due to hydration, based on a static state that cannot take the dynamic path into account).要点是:在许多动态渲染场景中(包括默认),在客户端初始渲染期间,页面首先在没有任何参数的情况下被渲染(可能是由于水化,基于无法考虑动态路径的静态状态) . Only the second time, parameters come through.只有第二次,参数才能通过。

Solution解决方案

Allow your component to "kinda work" even if router.query is empty, eg:即使router.query为空,也允许您的组件“有点工作”,例如:

function MyComp() {
  const router = useRouter();
  const { id } = router.query;

  useEffect(() => {
    if (!id) {
      return;  // NOTE: router.query might be empty during initial render
    }

    doSomethingWithData(id);
  }, [...]);

  if (!id) {
    // we are still waiting for dynamic data to be available
    return 'loading...';
  }

  return theActualContent;
}

There even is the crucial Router.isReady field that tells you whether query data is available, but, for some reason, they do not mention it in the Dynamic Routes documentation .甚至还有一个关键的Router.isReady字段可以告诉您查询数据是否可用,但出于某种原因,他们没有在Dynamic Routes文档中提及它。

I have been through the same issue, but I found this package, https://github.com/fridays/next-routes我遇到过同样的问题,但我找到了这个包, https://github.com/fridays/next-routes

It works almost the same as react-router, I have tried it and it works for me.它的工作原理与 react-router 几乎相同,我已经尝试过了,它对我有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM