I was trying to get the queries from my url pattern like localhost:3000/post?loc=100
by using useRouter()
from "next/router" and fetching some data using that id from my server. It worked when I used it in a Stateless Functional Component.
But the page showing "Invalid hook call" then. I tried calling getInitalProps()
of a Stateless Functional Component, but it didn't work there either and showed the same error. Is there any rule to use this method?
I was developing a front-end using React Library and Next.js Framework.
constructor(props) {
this.state = {
loc: useRouter().query.loc,
loaded: false
};
}
Hooks can be used only inside functional components, not inside classes. I would recommend to use withRouter HOC as per next.js documentation:
use the
useRouter
hook, orwithRouter
for class components.
Or see From Classes to Hooks if you want to switch to hooks.
const MyClassWithRouter = (props) => { const router = useRouter() return <MyClass {...props} router={router} /> } class MyClass... constructor(props) { this.state = { loc: props.router.query.loc, loaded: false }; }
withRouter
example
https://stackoverflow.com/a/57029032/895245 mentioned it, but a newbie like me needed a bit more details. A more detailed/direct description would be:
Function component:
import { useRouter } from "next/router";
export default function Post() {
const router = useRouter();
return (
<div>{ router.query.id }</div>
)
}
Class component equivalent:
import { withRouter } from 'next/router'
import React from "react";
export default withRouter(class extends React.Component {
render() {
return (
<div>{ this.props.router.query.id }</div>
)
}
})
I tested this out more concretely as follows. First I took vercel/next-learn-starter/basics-final/pages/posts/[id].js
and I hacked it to use the router:
diff --git a/basics-final/pages/posts/[id].js b/basics-final/pages/posts/[id].js
index 28faaad..52954d3 100644
--- a/basics-final/pages/posts/[id].js
+++ b/basics-final/pages/posts/[id].js
@@ -4,13 +4,17 @@ import Head from 'next/head'
import Date from '../../components/date'
import utilStyles from '../../styles/utils.module.css'
+import { useRouter } from "next/router"
+
export default function Post({ postData }) {
+ const router = useRouter();
return (
<Layout>
<Head>
<title>{postData.title}</title>
</Head>
<article>
+ <div>router.query.id = {router.query.id}</div>
<h1 className={utilStyles.headingXl}>{postData.title}</h1>
<div className={utilStyles.lightText}>
<Date dateString={postData.date} />
Then, I ran it as:
git clone https://github.com/vercel/next-learn-starter
cd next-learn-starter
git checkout 5c2f8513a3dac5ba5b6c7621d8ea0dda881235ea
cd next-learn-starter
npm install
npm run dev
Now when I visit: http://localhost:3000/posts/ssg-ssr I see:
router.query.id = ssg-ssr
Then I converted it to the class equivalent:
import Layout from '../../components/layout'
import { getAllPostIds, getPostData } from '../../lib/posts'
import Head from 'next/head'
import Date from '../../components/date'
import utilStyles from '../../styles/utils.module.css'
import { withRouter } from 'next/router'
import React from "react"
export default withRouter(class extends React.Component {
render() {
return (
<Layout>
<Head>
<title>{this.props.postData.title}</title>
</Head>
<article>
<div>router.query.id = {this.props.router.query.id}</div>
<h1 className={utilStyles.headingXl}>{this.props.postData.title}</h1>
<div className={utilStyles.lightText}>
<Date dateString={this.props.postData.date} />
</div>
<div dangerouslySetInnerHTML={{ __html: this.props.postData.contentHtml }} />
</article>
</Layout>
)
}
})
export async function getStaticPaths() {
const paths = getAllPostIds()
return {
paths,
fallback: false
}
}
export async function getStaticProps({ params }) {
const postData = await getPostData(params.id)
return {
props: {
postData
}
}
}
and everything seemed to be unchanged.
Tested on Next.js 10.2.2.
write your component and then، export it with withRouter(YourClassName)
like :
class App extends React.Component{
render(){
<h2> this is an example router query params : {this.props.router.query.id} <h2/>
}
}
export default withRouter(Page)
so you can access router from component's prop like above example :)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.