如何从 Next.js 中的 URL 获取(查询字符串)参数?

当我点击我的 /index.js链接,它带我到 /about.js页面。

但是,当我将参数名称通过 URL (如 关于? 名字 = leangchhean)从 /index.js传递到 /about.js时,我不知道如何在 /about.js页面中获得它。

Index.js

import Link from 'next/link';
export default () => (
<div>
Click{' '}
<Link href={{ pathname: 'about', query: { name: 'leangchhean' } }}>
<a>here</a>
</Link>{' '}
to read more
</div>
);
381007 次浏览
  • 使用 关于 JS页面中的以下代码获取:

    Enter image description here

// pages/about.js
import Link from 'next/link'
export default ({ url: { query: { name } } }) => (
<p>Welcome to About! { name }</p>
)

从 Next.js 版本6开始,url道具就已经被废弃了: Https://github.com/zeit/next.js/blob/master/errors/url-deprecated.md

要获取查询参数,请使用 getInitialProps:

用于无状态组件

import Link from 'next/link'
const About = ({query}) => (
<div>Click <Link href=\{\{ pathname: 'about', query: { name: 'leangchhean' }}}><a>here</a></Link> to read more</div>
)


About.getInitialProps = ({query}) => {
return {query}
}


export default About;

用于常规组件

class About extends React.Component {


static getInitialProps({query}) {
return {query}
}


render() {
console.log(this.props.query) // The query is available in the props object
return <div>Click <Link href=\{\{ pathname: 'about', query: { name: 'leangchhean' }}}><a>here</a></Link> to read more</div>


}
}

查询对象将类似于: url.com?a=1&b=2&c=3变成: {a:1, b:2, c:3}

对于那些寻找与 静态出口一起工作的解决方案的人,请尝试这里列出的解决方案: https://github.com/zeit/next.js/issues/4804#issuecomment-460754433

简而言之,router.query仅适用于 SSR 应用程序,但 router.asPath仍然可以工作。

因此,可以使用 exportPathMap (非动态)在 next.config.js中配置查询预导出:

    return {
'/': { page: '/' },
'/about': { page: '/about', query: { title: 'about-us' } }
}
}

或者使用 router.asPath,自己使用类似于 Query-string 查询字符串的库来解析查询:

import { withRouter } from "next/router";
import queryString from "query-string";


export const withPageRouter = Component => {
return withRouter(({ router, ...props }) => {
router.query = queryString.parse(router.asPath.split(/\?/)[1]);


return <Component {...props} router={router} />;
});
};

使用路由器挂钩。

您可以在应用程序的任何组件中使用 useRouter hook

Https://nextjs.org/docs/api-reference/next/router#userouter

超过 Param

import Link from "next/link";


<Link href=\{\{ pathname: '/search', query: { keyword: 'this way' } }}><a>path</a></Link>
或者
import Router from 'next/router'


Router.push({
pathname: '/search',
query: { keyword: 'this way' },
})

成分

import { useRouter } from 'next/router'


export default () => {
const router = useRouter()
console.log(router.query);


...
}

Post.getInitialProps = async function(context) {


const data = {}
try{
data.queryParam = queryString.parse(context.req.url.split('?')[1]);
}catch(err){
data.queryParam = queryString.parse(window.location.search);
}
return { data };
};

import { useRouter } from 'next/router';


function componentName() {
const router = useRouter();
console.log('router obj', router);
}

我们可以在路由器中找到查询对象,使用它可以获得所有查询字符串参数。

如果需要从组件外部检索 URL 查询:

import router from 'next/router'


console.log(router.query)


使用 Next.js 9或更高版本,您可以获得查询参数:

router:

import { useRouter } from 'next/router'


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


return(<div>{id}</div>)
}

getInitialProps:

const Index = ({id}) => {
return(<div>{id}</div>)
}


Index.getInitialProps = async ({ query }) => {
const {id} = query


return {id}
}

我知道两种方法:
一种是 服务器端型,一种是 客户端型。

方法 # 1: SSR (服务器端渲染) :

您应该对该页面使用 查询上下文
因此使用 getServerSideProps而不是 getStaticProps

import React from "react";


export async function getServerSideProps(context) {
const page = (parseInt(context.query.page) || 1).toString();
// Here we got the "page" query parameter from Context
// Default value is "1"
  

const res = await fetch(`https://....com/api/products/?page=${page}`);
const products = await res.json();
return {props: {products: products.results}}
// will be passed to the page component as props
}


const Page = (props) =>{
const products = props.products;
return (
<ul>
{products.map((product) => (
<li key={product.id}>{product.name}</li>
))}
</ul>);
}


export default Page

原因是: 这个数据不能在用户请求之前预先呈现,所以每个请求都必须是 服务器端渲染(SSR)。

  • 静态页面: 使用 getStaticProps
  • 更改内容: 使用 getServerSideProps
    这里的内容是基于查询参数而更改的

参考资料: https://nextjs.org/docs/api-reference/data-fetching/get-server-side-props

方法 # 2: 下一个路由器(客户端) :

import {useState, useEffect} from "react";
import { useRouter } from 'next/router'


const Page = () =>{
const [products, setProducts] = useState([]);
const [page, setPage] =useState((useRouter().query.page || 1).toString());
// getting the page query parameter
// Default value is equal to "1"


useEffect(()=>{
(async()=>{
const res = await fetch(`https://....com/api/products/?page=${page}`);
const products = await res.json();
setProducts(products.results);
// This code will be executed only once at begining of the loading of the page
// It will not be executed again unless you cahnge the page
})()
},[page]);


return (
<ul>
{products.map((product) => (
<li key={product.id}>{product.name}</li>
))}
</ul>
);
}


export default Page

参考资料: https://nextjs.org/docs/api-reference/next/router

使用 {useRouter} from "next/router";会有所帮助,但是有时候你不会得到值,而是得到参数名本身作为值。 当你试图通过解构访问查询参数时,这个问题就会发生,比如:

let { categoryId = "", sellerId = "" } = router.query;

我的解决方案是尝试直接从查询对象访问值:

let categoryId  = router.query['categoryId'] || '';
let sellerId  = router.query['sellerId'] || '';